struct netlink_data * netlink_init(struct netlink_config *cfg) { struct netlink_data *netlink; struct sockaddr_nl local; netlink = os_zalloc(sizeof(*netlink)); if (netlink == NULL) return NULL; netlink->cfg = cfg; netlink->sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (netlink->sock < 0) { wpa_printf(MSG_ERROR, "netlink: Failed to open netlink " "socket: %s", strerror(errno)); netlink_deinit(netlink); return NULL; } os_memset(&local, 0, sizeof(local)); local.nl_family = AF_NETLINK; local.nl_groups = RTMGRP_LINK; if (bind(netlink->sock, (struct sockaddr *) &local, sizeof(local)) < 0) { wpa_printf(MSG_ERROR, "netlink: Failed to bind netlink " "socket: %s", strerror(errno)); netlink_deinit(netlink); return NULL; } eloop_register_read_sock(netlink->sock, netlink_receive, netlink, NULL); return netlink; }
int main() { int ret; struct nl_cb * nl_cb; struct nl_handle * nl_handle; struct netlink_data * netlink; int ioctl_sock = -1; struct dl_list interfaces; int if_add_ifindex = -1; dl_list_init(&interfaces); /* * global_init */ ret = netlink_init_nl80211_event_rtm(&netlink,NULL,nl80211_event_rtm_newlink,nl80211_event_rtm_dellink); if (ret == -1 || netlink == NULL) { goto err; } ret = nl80211_init_event(&nl_cb, &nl_handle); if (ret == -1) { wpa_printf(MSG_DEBUG, "nl80211: Init failure "); goto err; } wpa_printf(MSG_INFO, "nl80211: wait for event... "); nl_cb_set(nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_set(nl_cb, NL_CB_VALID, NL_CB_CUSTOM, process_event, NULL); eloop_register_wrapper(nl_socket_get_fd(nl_handle), nl80211_event_receive, nl_cb, nl_handle); ioctl_sock = init_ioctl_sock(); if (ioctl_sock < 0) { perror("socket(PF_INET,SOCK_DGRAM)"); goto err; } /* * hapd_init */ eloop_run(); return 0; err: netlink_deinit(netlink); nl_destroy_handles(&nl_handle); nl_cb_put(nl_cb); if (ioctl_sock >= 0) { close(ioctl_sock); } return -1; }
static void atheros_deinit(void *priv) { struct atheros_driver_data *drv = priv; netlink_deinit(drv->netlink); (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); if (drv->ioctl_sock >= 0) close(drv->ioctl_sock); if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) l2_packet_deinit(drv->sock_recv); if (drv->sock_xmit != NULL) l2_packet_deinit(drv->sock_xmit); if (drv->sock_raw) l2_packet_deinit(drv->sock_raw); free(drv); }
static void hostap_driver_deinit(void *priv) { struct hostap_driver_data *drv = priv; netlink_deinit(drv->netlink); (void) hostap_set_iface_flags(drv, 0); (void) hostap_ioctl_prism2param(drv, PRISM2_PARAM_HOSTAPD, 0); (void) hostap_ioctl_prism2param(drv, PRISM2_PARAM_HOSTAPD_STA, 0); if (drv->ioctl_sock >= 0) close(drv->ioctl_sock); if (drv->sock >= 0) close(drv->sock); os_free(drv->generic_ie); os_free(drv->wps_ie); free(drv); }
static void ar6000_deinit(void *priv) { struct ar6000_driver_data *drv = priv; netlink_deinit(drv->netlink); (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); if (drv->ioctl_sock >= 0) close(drv->ioctl_sock); if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) l2_packet_deinit(drv->sock_recv); if (drv->sock_xmit != NULL) l2_packet_deinit(drv->sock_xmit); if (drv->sock_raw) l2_packet_deinit(drv->sock_raw); wpabuf_free(drv->wpa_ie); wpabuf_free(drv->wps_beacon_ie); wpabuf_free(drv->wps_probe_resp_ie); free(drv); }