Supplicant层socket与内核网口、socket的对应连接

来源:互联网 发布:怎样在淘宝上注册网店 编辑:程序博客网 时间:2024/06/05 17:32

◆创建socket从内核接收数据包例子(PF_PACKET)
创建family为PF_PACKET的socket,接收eapol包;

l2->fd = socket(PF_PACKET, l2_hdr ? SOCK_RAW : SOCK_DGRAM, ETH_P_EAPOL);

找到网口名对应的index

os_memset(&ifr, 0, sizeof(ifr));os_strlcpy(ifr.ifr_name, l2->ifname,    sizeof(ifr.ifr_name));ioctl(l2->fd, SIOCGIFINDEX, &ifr)

通过网口的index,把socket绑定到ifname的网口

os_memset(&ll, 0, sizeof(ll));ll.sll_family = PF_PACKET;ll.sll_ifindex = ifr.ifr_ifindex;ll.sll_protocol = htons(protocol);bind(l2->fd, (struct sockaddr *) &ll, sizeof(ll))

后续就可以通过socket与ifname网口收发数据;
◆ 通过socket操作网口例子(PF_INET)
创建family为PF_INET的socket,现知道的功能是控制网口

drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);

操作网口的时候,需要把操作的网口名作为一个参数传递下去

os_memset(&ifr, 0, sizeof(ifr));os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);ioctl(sock, SIOCGIFFLAGS, &ifr)ioctl(sock, SIOCSIFFLAGS, &ifr)

◆ Supplicant使用nl的操作接口

struct wpa_supplicant {    struct wpa_global *global; …… void *drv_priv;   /* 使用nl80211 driver时,指向i802_bss *bss */ … …}struct wpa_global {    … …    void **drv_priv;  /* 使用nl80211 driver时,指向nl80211_global */ … …}

使用nl80211 driver:
drv_priv由nl80211_global_init初始化,

global->netlink = netlink_init(cfg);  // 初始化netlink route的通信socket;

●wpa_driver_nl80211_init_nl_global函数中初始化global->nl(nl_handle),
nl中的s_fd指向最终通信的socket,由socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC)创建,后面还进行family、multicast_id等初始化;

global->nl80211_id = genl_ctrl_resolve(global->nl, "nl80211")初始化nl80211_id;

●最后还初始化:global->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0),现在见到ioctl_sock的操作有网口的up,down;

使用nl80211 driver:
●drv_priv由wpa_driver_nl80211_init(wpa_driver_nl80211_drv_init)初始化,
初始化时参数ifname确定该drv_priv最终指向那个网口,同时通过if_nametoindex(bss->ifname)把网口名转成ifindex,储存在bss->ifindex;

●有了上面的初始化信息,在supplicant发送一个nl命令时,就可以确定该nl命令发送给内核哪一个网口的wiphy进行处理
在创建nl msg的nl80211_cmd_msg函数中,通过
nl80211_cmd、nl80211_set_iface_id函数设置相关信息到msg中。
nl80211_cmd调用genlmsg_put(msg, 0, 0, drv->global->nl80211_id,
0, flags, cmd, 0)进行nl80211_id设置,同时也设置了该nl msg包含的cmd(如扫描命令的cmd为:NL80211_CMD_TRIGGER_SCAN);
nl80211_set_iface_id调用nla_put_u32(msg, NL80211_ATTR_IFINDEX, bss->ifindex)进行ifindex设置;
最后该msg通过nl的s_fd socket进行发送,有了这些信息,内核就可以确定该
msg由那个协议族、那个wiphy进行处理。

0 0
原创粉丝点击