Linux下的Packet Socket的使用

Linux下的Packet Socket的使用

Hanse <hansel@163.com>
2009-4-3

Linux支持PF_PACKET类型的套接字,用于实现用户层的网络协议。通过该SOCK_RAW类型的Packet socket,应用程序可以直接接收带完整二层数据帧,处理完毕后再使用该socket发出二层数据帧。因此可以实现更底层的网络协议。也可以通过该类型的Socket实现网络抓包,当然,如果要抓取不是自己的网络报文,还需要把网卡设置为混杂模式。

1、创建Packet Socket

<pre>

       #include <sys/socket.h>
       #include <netpacket/packet.h>
       #include <net/ethernet.h> /* the L2 protocols */

       packet_socket = socket(PF_PACKET, int socket_type, int protocol);

</pre>

其中socket_type可以是SOCK_DGRAM,SOCK_RAW。设置为SOCK_RAW则接收到的报文中包含二层协议头,否则只有二层数据帧内容。

 例如:
 int skfd;

        skfd = socket(PF_PACKET, SOCK_RAW, htons(protocol));

2、绑定到网络接口
这一步是可选的。如果不绑定,则所有接口上的二层数据帧都会收到。
 struct sockaddr_ll ll;
 struct ifreq ifr;

 strncpy(ifr.ifr_name, l2->ifname, sizeof(ifr.ifr_name));
 memset(l2, 0, sizeof(*l2));
 strncpy(l2->ifname, ifname, sizeof(l2->ifname));

 memset(&ll, 0, sizeof(ll));
 ll.sll_family = PF_PACKET;
 ll.sll_ifindex = ifr.ifr_ifindex;
 ll.sll_protocol = htons(protocol);
 if (bind(l2->fd, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
  perror("bind[PF_PACKET]");
  close(l2->fd);
  free(l2);
  return NULL;
 }

protocol是需要监听的协议类型,如果为ETH_P_ALL,则接收所有数据帧。

注意:
桥中接收不到转发的非自己的报文

ssize_t recvfrom(int s, void *buf, size_t len, int flags,
                        struct sockaddr *from, socklen_t *fromlen);
如果传入fromlen为0则不会填充from参数。


参考文档:

1、Linux Man: packet(7)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值