链路层访问修改

  • Post author:
  • Post category:其他



首先例子中, 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看下,可以看到预期的效果。