Linux网络编程原始套接字的魔力【下】.pdf

Linux网络编程原始套接字的魔力【下】.pdf

ID:51492862

大小:944.81 KB

页数:6页

时间:2020-03-25

Linux网络编程原始套接字的魔力【下】.pdf_第1页
Linux网络编程原始套接字的魔力【下】.pdf_第2页
Linux网络编程原始套接字的魔力【下】.pdf_第3页
Linux网络编程原始套接字的魔力【下】.pdf_第4页
Linux网络编程原始套接字的魔力【下】.pdf_第5页
资源描述:

《Linux网络编程原始套接字的魔力【下】.pdf》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

1、Linux网络编程:原始套接字的魔力【下】星期四,8月232012,10:47下午可以接收链路层MAC帧的原始套接字前面我们介绍过了通过原始套接字socket(AF_INET,SOCK_RAW,protocol)我们可以直接实现自行构造整个IP报文,然后对其收发。提醒一点,在用这种方式构造原始IP报文时,第三个参数protocol不能用IPPROTO_IP,这样会让系统疑惑,不知道该用什么协议来伺候你了。今天我们介绍原始套接字的另一种用法:直接从链路层收发数据帧,听起来好像很神奇的样子。在Linux系统中要从链路层(MAC)直接收发数帧,比较普遍的做法就是用libpcap和libnet两个动态

2、库来实现。但今天我们就要用原始套接字来实现这个功能。这里的2字节帧类型用来指示该数据帧所承载的上层协议是IP、ARP或其他。为了实现直接从链路层收发数据帧,我们要用到原始套接字的如下形式:socket(PF_PACKET,type,protocol)1、其中type字段可取SOCK_RAW或SOCK_DGRAM。它们两个都使用一种与设备无关的标准物理层地址结构structsockaddr_ll{},但具体操作的报文格式不同:SOCK_RAW:直接向网络硬件驱动程序发送(或从网络硬件驱动程序接收)没有任何处理的完整数据报文(包括物理帧的帧头),这就要求我们必须了解对应设备的物理帧帧头结构,才能正

3、确地装载和分析报文。也就是说我们用这种套接字从网卡驱动上收上来的报文包含了MAC头部,如果我们要用这种形式的套接字直接向网卡发送数据帧,那么我们必须自己组装我们MAC头部。这正符合我们的需求。SOCK_DGRAM:这种类型的套接字对于收到的数据报文的物理帧帧头会被系统自动去掉,然后再将其往协议栈上层传递;同样地,在发送时数据时,系统将会根据sockaddr_ll结构中的目的地址信息为数据报文添加一个合适的MAC帧头。2、protocol字段,常见的,一般情况下该字段取ETH_P_IP,ETH_P_ARP,ETH_P_RARP或ETH_P_ALL,当然链路层协议很多,肯定不止我们说的这几个,但我

4、们一般只关心这几个就够我们用了。这里简单提一下网络数据收发的一点基础。协议栈在组织数据收发流程时需要处理好两个方面的问题:“从上倒下”,即数据发送的任务;“从下到上”,即数据接收的任务。数据发送相对接收来说要容易些,因为对于数据接收而言,网卡驱动还要明确什么样的数据该接收、什么样的不该接收等问题。protocol字段可选的四个值及其意义如下:protocol值作用ETH_P_IP0X0800只接收发往目的MAC是本机的IP类型的数据帧ETH_P_ARP0X0806只接收发往目的MAC是本机的ARP类型的数据帧ETH_P_RARP0X8035只接受发往目的MAC是本机的RARP类型的数据帧ETH

5、_P_ALL0X0003接收发往目的MAC是本机的所有类型(ip,arp,rarp)的数据帧,同时还可以接收从本机发出去的所有数据帧。在混杂模式打开的情况下,还会接收到发往目的MAC为非本地硬件地址的数据帧。protocol字段可取的所有协议参见/usr/include/linux/if_ether.h头文件里的定义。最后,格外需要留心一点的就是,发送数据的时候需要自己组织整个以太网数据帧。和地址相关的结构体就不能再用前面的structsockaddr_in{}了,而是structsockaddr_ll{},如下:点击(此处)折叠或打开1.structsockaddr_ll{2.unsigne

6、dshortsll_family;/*总是AF_PACKET*/3.unsignedshortsll_protocol;/*物理层的协议*/4.intsll_ifindex;/*接口号*/5.unsignedshortsll_hatype;/*报头类型*/6.unsignedcharsll_pkttype;/*分组类型*/7.unsignedcharsll_halen;/*地址长度*/8.unsignedcharsll_addr[8];/*物理层地址*/9.};sll_protocoll:取值在linux/if_ether.h中,可以指定我们所感兴趣的二层协议;sll_ifindex:置为0表

7、示处理所有接口,对于单网卡的机器就不存在“所有”的概念了。如果你有多网卡,该字段的值一般通过ioctl来搞定,模板代码如下,如果我们要获取eth0接口的序号,可以使用如下代码来获取:点击(此处)折叠或打开1.structsockaddr_llsll;2.structifreqifr;3.4.strcpy(ifr.ifr_name,"eth0");5.ioctl(sockfd,SIOCGIFINDE

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。