没有合适的资源?快使用搜索试试~ 我知道了~
linuxsock_raw原始套接字编程.pdf
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 116 浏览量
2021-11-05
08:45:05
上传
评论
收藏 60KB PDF 举报
温馨提示
试读
11页
linuxsock_raw原始套接字编程.pdf
资源推荐
资源详情
资源评论
linux sock_raw原始套接字编程
sock_raw 原始套接字编程可以接收到本机网卡上的数据帧或者数据包 ,对与监听
网络的流量和分析是很有作用的 .一共可以有 3 种方式创建这种 socket
1.socket(AF_INET, SOCK_RAW, IPPROTO_TCP|IPPROTO_UDP|IPPROTO_ICMP)
发送接收 ip 数据包
2.socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))
发送接收以太网数据帧
3.socket(AF_INET, SOCK_PACKET, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))
过时了 ,不要用啊
理解一下 SOCK_RAW 的原理 , 比如网卡收到了一个 14+20+8+100+4 的 udp 的
以太网数据帧 .
首先 ,网卡对该数据帧进行硬过滤 (根据网卡的模式不同会有不同的动作 ,如果设
置了 promisc 混杂模式的话 ,则不做任何过滤直接交给下一层输 入例程 ,否则非本
机 mac或者广播 mac 会被直接丢弃 ).按照上面的例子 ,如果成功的话 ,会进入 ip 输
入 例 程 . 但 是 在 进 入 ip 输 入 例 程 之 前 , 系 统 会 检 查 系 统 中 是 否 有 通 过
socket(AF_PACKET, SOCK_RAW, ..)创建的套接字 .如果有的话并且协议相符 ,在
这个例子中就是需要 ETH_P_IP 或者 ETH_P_ALL 类型 .系统就给每个这样的
socket接收缓 冲区发送一个数据帧拷贝 .然后进入下一步 .
其次 ,进入了 ip 输入例程 (ip 层会对该数据包进行软过滤 ,就是检查校验或者丢弃
非本机 ip 或者广播 ip 的数据包等 ,具体要参考源代码 ),例子 中就是如果成功的话
会进入 udp 输入例程 .但是在交给 udp 输入例程之前 ,系统会检查系统中是否有通
过 socket(AF_INET, SOCK_RAW, ..)创建的套接字 .如果有的话并且协议相符 ,在
这个例子中就是需要 IPPROTO_UDP 类型.系统就给每个这样的 socket接收缓冲
区发送一个数据 帧拷贝 .然后进入下一步 .
最后 ,进入 udp 输入例程 ...
ps:如果校验和出错的话 ,内核会直接丢弃该数据包的 .而不会拷贝给 sock_raw 的
套接字 ,因为校验和都出错了 ,数据肯定有问题的包括所有信息都没有意义了 .
进一步分析他们的能力 .
1. socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
能:该套接字可以接收协议类型为 (tcp udp icmp等)发往本机的 ip 数据包 ,从上面看
的就是 20+8+100.
不能 :不能收到非发往本地 ip 的数据包 (ip 软过滤会丢弃这些不是发往本机 ip 的
数据包 ).
不能 :不能收到从本机发送出去的数据包 .
发送的话需要自己组织 tcp udp icmp 等头部 .可以 setsockopt来自己包装 ip 头部
这种套接字用来写个 ping 程序比较适合
2. socket(PF_PACKET, SOCK_RAW, htons(x));
这个套接字比较强大 ,创建这种套接字可以监听网卡上的所有数据帧 .从上面看就
是 20+20+8+100.最后一个以太网 crc 从来都不算进来的 ,因为内核已经判断过了 ,
对程序来说没有任何意义了 .
能: 接收发往本地 mac的数据帧
能: 接收从本机发送出去的数据帧 (第 3 个参数需要设置为 ETH_P_ALL)
能: 接收非发往本地 mac 的数据帧 (网卡需要设置为 promisc 混杂模式 )
协议类型一共有四个
ETH_P_IP 0x800 只接收发往本机 mac 的 ip 类型的数据帧
ETH_P_ARP 0x806 只接受发往本机 mac 的 arp 类型的数据帧
ETH_P_ARP 0x8035 只接受发往本机 mac 的 rarp 类型的数据帧
ETH_P_ALL 0x3 接收发往本机 mac 的所有类型 ip arp rarp 的数据帧 , 接
收从本机发出的所有类型的数据帧 .(混杂模式打开的情况下 ,会接收到非发往本
地 mac的数据帧 )
发 送 的时 候需 要自 己组 织 整个 以太 网数 据帧 .所有 相关 的地 址使 用 struct
sockaddr_ll 而不是 struct sockaddr_in(因为协议簇是 PF_PACKET 不是 AF_INET
了),比如发送给某个机器 ,对方的地址需要使用 struct sockaddr_ll.
这种 socket大小通吃 ,强悍
下面是一段相关的代码 :
...
int sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
struct sockaddr_ll sll;
memset( &sll, 0, sizeof(sll) );
sll.sll_family = AF_PACKET;
struct ifreq ifstruct;
strcpy(ifstruct.ifr_name, "eth0");
ioctl(sockfd, SIOCGIFINDEX, &ifstruct);
sll.sll_ifindex = ifstruct.ifr_ifindex;
sll.sll_protocol = htons(ETH_P_ALL);
if(bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1 ) {
perror("bind()");
}
int set_promisc(char *interface, int fd) {
struct ifreq ifr;
strcpy(ifr.ifr_name, interface);
if(ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {
perror("iotcl()");
剩余10页未读,继续阅读
资源评论
筱筱笎琞
- 粉丝: 8
- 资源: 15万+
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功