数据链路访问示例

来源:互联网 发布:删除视图的sql语句 编辑:程序博客网 时间:2024/05/21 13:54
    《unix网络编程》第一卷第三版的数据链路访问一章中有个例子,主要用到libpcap/libnet及原始套接字模拟dns请求,并在数据链路层进行数据过滤。但例子中本身有不少问题,还需要改造下。

      首先例子中, udpcksum.h包含了两个头文件 ip_var.h/udp_var.h,我是centos5.5的,系统中并无这些头文件。如果自己隐掉,编译时明显就会报struct udpiphdr结构不存在。可在udpcksum.h中增加以下代码:

struct ipvolg{
    u_char  ih_x1 [9];  //9 bit
    u_char  ih_pr;      //1 bit
    u_short     ih_len;  //2 bytes
    struct in_addr  ih_src; //4 bytes;
    struct in_addr  ih_dst; //4 bytes;
};
struct udpiphdr{
    struct ipvolg ui_i;
    struct udphdr ui_u;
};

#define ui_x1           ui_i.ih_x1
#define ui_pr           ui_i.ih_pr
#define ui_sum          ui_i.ih_len
#define ui_src          ui_i.ih_src
#define ui_dst          ui_i.ih_dst
#define ui_sport        ui_u.source
#define ui_dport        ui_u.dest
#define ui_ulen         ui_u.len
      free bsd系统中,应该是有这个结构声明的,网上有这些文件说明。参考udpwrite.c文件中的udp_write函数,可以看出些端倪。

         ip = (struct ip *) buf;
         ui = (struct udpiphdr *) buf;
     明显就是对ip的头和udp的头进行设置,具体字段的设置,请参照tcp/ip的协议。

      当然,里面有部分代码需要改造下,我觉得应该是bug,以centos的系统为例,其他系统并未验证过。

   udpwrite.c/udp_write()

       ui->ui_len = htons((uint16_t) (sizeof(struct udphdr) + userlen)); 替换成 ui->ui_ulen = htons((uint16_t) (sizeof(struct udphdr) + userlen));
      ui->ui_ulen = ui->ui_len;  注释掉


  udpwrite.c/open_output(void)

       rawfd = Socket(dest->sa_family, SOCK_RAW, 0); 应改成      rawfd = Socket(dest->sa_family, SOCK_RAW, IPPROTO_RAW);,否则提示协议不支持


udpwrite.c/udpread.c  都用到了in_cksum函数,但Makefile文件并没有把相应实现包含进来,需要在makefile文件中补充下。

main.c 的main函数,在参数解析时, aip = Host_serv(argv[optind], argv[optind+1], AF_INET, SOCK_DGRAM); 要留意下,并不能获取正确的服务器 ip和端口


      最后make一下,senddnsquery-libnet.c仍旧有错误,但并不影响使用,暂时为解决这个错误。用wireshark活tcpdump看下,可以看到预期的效果。

原创粉丝点击