应用程序使用RAW socket从内核中抓取指定协议的数据包流程分析;

应用程序使用RAW socket从内核中抓取指定协议的数据包流程分析;

应用程序:

int init_sockets()

{

    struct ifreq ifr;

    struct sockaddr_ll addr;

    struct sockaddr_in addr2;

 

    drv->sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_PAE));//802.1x协议(0x888e)

    if (drv->sock < 0) {

        perror("socket[PF_PACKET,SOCK_RAW]");

        return -1;

    }

 

    os_memset(&ifr, 0, sizeof(ifr));

    os_strlcpy(ifr.ifr_name, “eth0”, sizeof(ifr.ifr_name));//指定接口eth0

    if (ioctl(drv->sock, SIOCGIFINDEX, &ifr) != 0) {//获取eth0接口的index

        perror("ioctl(SIOCGIFINDEX)");

        return -1;

    }

 

    os_memset(&addr, 0, sizeof(addr));

    addr.sll_family = AF_PACKET;

    addr.sll_ifindex = ifr.ifr_ifindex;

    

    if (bind(drv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {//绑定sock

        perror("bind");

        return -1;

}

...

    return 0;

}

 

void read(int sock...)

{

    int len;

    unsigned char buf[3000];

len = recv(sock, buf, sizeof(buf), 0);

...

}

int send(int sock, char *buf, int bufsize)

{

return send(sock, buf, bufsize, 0);

...

}

 

 

内核协议:(net/packet/af_packet.c)

函数

说明

static int packet_create(struct net *net, struct socket *sock, int protocol)

Create a packet of type SOCK_PACKET.

static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)

Bind the sock to the protocol

static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protocol)

Attach a packet hook

void dev_add_pack(struct packet_type *pt)

Add a protocol handler to the networking stack

static int packet_ioctl(struct socket *sock, unsigned int cmd,

                                          unsigned long arg)

ioctl

static int packet_notifier(struct notifier_block *this, unsigned long msg, void *data)

setup a packet notifier

static int packet_getsockopt(struct socket *sock, int level, int optname,

                                               char __user *optval, int __user *optlen)

getsocket()

static int

packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)

setsocket()

static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)

join in multicast group

static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq)

leave multicast group

static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,

                                            struct msghdr *msg, size_t len, int flags)

Pull a packet from our receive queue and hand it to the user. If necessary we block.

static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,

                            struct msghdr *msg, size_t len)

send msg to

static int packet_release(struct socket *sock)

Close a PACKET socket. This is fairly simple. We immediately go to 'closed' state and remove our protocol entry in the device list.

 

用户空间

内核空间

说明

socket()

packet_create()

创建特定类型socket

ioctl()

packet_ioctl()

 

bind()

packet_bind()

绑定socket

recv()

packet_recvmsg()

 

send()

packet_sendmsg()

 

setsocket()

packet_setsockopt()

 

getsocket()

packet_getsockopt()

 

注意:如果没有注册对802.1x协议包的监听操作,则802.1x协议包在netif_receive_skb()函数中将在最后被丢弃。

         if (pt_prev) {

//监听并处理802.1x协议包

                   ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);

         } else {

//如果没有监听操作,802.1x协议包将在这里丢弃

                   kfree_skb(skb);

                   /* Jamal, now you will not able to escape explaining

                    * me how you were going to use this. :-)

                    */

                   ret = NET_RX_DROP;

         }

 

 

 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值