18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant - Layer2 packet handling with privilege separation 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2007, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <sys/un.h> 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "l2_packet.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/privsep_commands.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct l2_packet_data { 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int fd; /* UNIX domain socket for privsep access */ 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*rx_callback)(void *ctx, const u8 *src_addr, 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len); 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *rx_callback_ctx; 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 own_addr[ETH_ALEN]; 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *own_socket_path; 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un priv_addr; 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_priv_cmd(struct l2_packet_data *l2, int cmd, 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const void *data, size_t data_len) 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct msghdr msg; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct iovec io[2]; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[0].iov_base = &cmd; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[0].iov_len = sizeof(cmd); 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[1].iov_base = (u8 *) data; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[1].iov_len = data_len; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.msg_iov = io; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.msg_iovlen = data ? 2 : 1; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.msg_name = &l2->priv_addr; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.msg_namelen = sizeof(l2->priv_addr); 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sendmsg(l2->fd, &msg, 0) < 0) { 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("L2: sendmsg(cmd)"); 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(addr, l2->own_addr, ETH_ALEN); 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto, 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len) 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct msghdr msg; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct iovec io[4]; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int cmd = PRIVSEP_CMD_L2_SEND; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[0].iov_base = &cmd; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[0].iov_len = sizeof(cmd); 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[1].iov_base = &dst_addr; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[1].iov_len = ETH_ALEN; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[2].iov_base = &proto; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[2].iov_len = 2; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[3].iov_base = (u8 *) buf; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[3].iov_len = len; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.msg_iov = io; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.msg_iovlen = 4; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.msg_name = &l2->priv_addr; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.msg_namelen = sizeof(l2->priv_addr); 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sendmsg(l2->fd, &msg, 0) < 0) { 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("L2: sendmsg(packet_send)"); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx) 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct l2_packet_data *l2 = eloop_ctx; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[2300]; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un from; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socklen_t fromlen = sizeof(from); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&from, 0, sizeof(from)); 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &from, 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &fromlen); 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("l2_packet_receive - recvfrom"); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < ETH_ALEN) { 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "L2: Too show packet received"); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (from.sun_family != AF_UNIX || 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(from.sun_path, l2->priv_addr.sun_path, 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(from.sun_path)) != 0) { 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "L2: Received message from unexpected " 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "source"); 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->rx_callback(l2->rx_callback_ctx, buf, buf + ETH_ALEN, 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res - ETH_ALEN); 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct l2_packet_data * l2_packet_init( 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ifname, const u8 *own_addr, unsigned short protocol, 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*rx_callback)(void *ctx, const u8 *src_addr, 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len), 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *rx_callback_ctx, int l2_hdr) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct l2_packet_data *l2; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *own_dir = "/tmp"; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *priv_dir = "/var/run/wpa_priv"; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static unsigned int counter = 0; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un addr; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fd_set rfds; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct timeval tv; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 reply[ETH_ALEN + 1]; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reg_cmd[2]; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2 = os_zalloc(sizeof(struct l2_packet_data)); 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2 == NULL) 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->rx_callback = rx_callback; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->rx_callback_ctx = rx_callback_ctx; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(own_dir) + 50; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->own_socket_path = os_malloc(len); 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2->own_socket_path == NULL) { 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2); 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(l2->own_socket_path, len, "%s/wpa_privsep-l2-%d-%d", 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt own_dir, getpid(), counter++); 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->priv_addr.sun_family = AF_UNIX; 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(l2->priv_addr.sun_path, sizeof(l2->priv_addr.sun_path), 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s/%s", priv_dir, ifname); 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->fd = socket(PF_UNIX, SOCK_DGRAM, 0); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2->fd < 0) { 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("socket(PF_UNIX)"); 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2->own_socket_path); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->own_socket_path = NULL; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2); 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&addr, 0, sizeof(addr)); 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sun_family = AF_UNIX; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(addr.sun_path, l2->own_socket_path, sizeof(addr.sun_path)); 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bind(l2->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 17604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt perror("l2-pkt-privsep: bind(PF_UNIX)"); 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_cmd[0] = protocol; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_cmd[1] = l2_hdr; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_priv_cmd(l2, PRIVSEP_CMD_L2_REGISTER, reg_cmd, sizeof(reg_cmd)) 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt < 0) { 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "L2: Failed to register with wpa_priv"); 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FD_ZERO(&rfds); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FD_SET(l2->fd, &rfds); 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tv.tv_sec = 5; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tv.tv_usec = 0; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = select(l2->fd + 1, &rfds, NULL, NULL, &tv); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 && errno != EINTR) { 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("select"); 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (FD_ISSET(l2->fd, &rfds)) { 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = recv(l2->fd, reply, sizeof(reply), 0); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("recv"); 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "L2: Timeout while waiting for " 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "registration reply"); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != ETH_ALEN) { 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "L2: Unexpected registration reply " 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%d)", res); 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(l2->own_addr, reply, ETH_ALEN); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL); 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return l2; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(l2->fd); 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->fd = -1; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unlink(l2->own_socket_path); 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2->own_socket_path); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->own_socket_path = NULL; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid l2_packet_deinit(struct l2_packet_data *l2) 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2 == NULL) 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2->fd >= 0) { 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_priv_cmd(l2, PRIVSEP_CMD_L2_UNREGISTER, NULL, 0); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_read_sock(l2->fd); 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(l2->fd); 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2->own_socket_path) { 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unlink(l2->own_socket_path); 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2->own_socket_path); 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2); 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len) 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid l2_packet_notify_auth_start(struct l2_packet_data *l2) 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_priv_cmd(l2, PRIVSEP_CMD_L2_NOTIFY_AUTH_START, NULL, 0); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 262