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) { 47fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_printf(MSG_ERROR, "L2: sendmsg(cmd): %s", strerror(errno)); 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54293335998d38c497293b1c41f7ad8342b507d458Dmitry 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) { 85fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_printf(MSG_ERROR, "L2: sendmsg(packet_send): %s", 86fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt strerror(errno)); 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx) 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct l2_packet_data *l2 = eloop_ctx; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[2300]; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un from; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socklen_t fromlen = sizeof(from); 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&from, 0, sizeof(from)); 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &from, 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &fromlen); 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 106fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_printf(MSG_ERROR, "l2_packet_receive - recvfrom: %s", 107fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt strerror(errno)); 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < ETH_ALEN) { 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "L2: Too show packet received"); 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (from.sun_family != AF_UNIX || 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(from.sun_path, l2->priv_addr.sun_path, 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(from.sun_path)) != 0) { 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "L2: Received message from unexpected " 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "source"); 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->rx_callback(l2->rx_callback_ctx, buf, buf + ETH_ALEN, 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res - ETH_ALEN); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct l2_packet_data * l2_packet_init( 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ifname, const u8 *own_addr, unsigned short protocol, 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*rx_callback)(void *ctx, const u8 *src_addr, 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len), 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *rx_callback_ctx, int l2_hdr) 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct l2_packet_data *l2; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *own_dir = "/tmp"; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *priv_dir = "/var/run/wpa_priv"; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static unsigned int counter = 0; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un addr; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fd_set rfds; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct timeval tv; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 reply[ETH_ALEN + 1]; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reg_cmd[2]; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2 = os_zalloc(sizeof(struct l2_packet_data)); 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2 == NULL) 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->rx_callback = rx_callback; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->rx_callback_ctx = rx_callback_ctx; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(own_dir) + 50; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->own_socket_path = os_malloc(len); 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2->own_socket_path == NULL) { 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2); 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(l2->own_socket_path, len, "%s/wpa_privsep-l2-%d-%d", 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt own_dir, getpid(), counter++); 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->priv_addr.sun_family = AF_UNIX; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(l2->priv_addr.sun_path, sizeof(l2->priv_addr.sun_path), 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s/%s", priv_dir, ifname); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->fd = socket(PF_UNIX, SOCK_DGRAM, 0); 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2->fd < 0) { 167fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno)); 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2->own_socket_path); 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->own_socket_path = NULL; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2); 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&addr, 0, sizeof(addr)); 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sun_family = AF_UNIX; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(addr.sun_path, l2->own_socket_path, sizeof(addr.sun_path)); 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bind(l2->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 178fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_printf(MSG_ERROR, "l2-pkt-privsep: bind(PF_UNIX): %s", 179fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt strerror(errno)); 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_cmd[0] = protocol; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_cmd[1] = l2_hdr; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_priv_cmd(l2, PRIVSEP_CMD_L2_REGISTER, reg_cmd, sizeof(reg_cmd)) 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt < 0) { 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "L2: Failed to register with wpa_priv"); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FD_ZERO(&rfds); 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FD_SET(l2->fd, &rfds); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tv.tv_sec = 5; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tv.tv_usec = 0; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = select(l2->fd + 1, &rfds, NULL, NULL, &tv); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 && errno != EINTR) { 197fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_printf(MSG_ERROR, "select: %s", strerror(errno)); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (FD_ISSET(l2->fd, &rfds)) { 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = recv(l2->fd, reply, sizeof(reply), 0); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 204fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_printf(MSG_ERROR, "recv: %s", strerror(errno)); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "L2: Timeout while waiting for " 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "registration reply"); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != ETH_ALEN) { 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "L2: Unexpected registration reply " 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%d)", res); 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(l2->own_addr, reply, ETH_ALEN); 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL); 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return l2; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(l2->fd); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->fd = -1; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unlink(l2->own_socket_path); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2->own_socket_path); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->own_socket_path = NULL; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2); 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 234aff761db795db8b506c6f6af7ff607856cf85a81Dmitry Shmidtstruct l2_packet_data * l2_packet_init_bridge( 235aff761db795db8b506c6f6af7ff607856cf85a81Dmitry Shmidt const char *br_ifname, const char *ifname, const u8 *own_addr, 236aff761db795db8b506c6f6af7ff607856cf85a81Dmitry Shmidt unsigned short protocol, 237aff761db795db8b506c6f6af7ff607856cf85a81Dmitry Shmidt void (*rx_callback)(void *ctx, const u8 *src_addr, 238aff761db795db8b506c6f6af7ff607856cf85a81Dmitry Shmidt const u8 *buf, size_t len), 239aff761db795db8b506c6f6af7ff607856cf85a81Dmitry Shmidt void *rx_callback_ctx, int l2_hdr) 240aff761db795db8b506c6f6af7ff607856cf85a81Dmitry Shmidt{ 241aff761db795db8b506c6f6af7ff607856cf85a81Dmitry Shmidt return l2_packet_init(br_ifname, own_addr, protocol, rx_callback, 242aff761db795db8b506c6f6af7ff607856cf85a81Dmitry Shmidt rx_callback_ctx, l2_hdr); 243aff761db795db8b506c6f6af7ff607856cf85a81Dmitry Shmidt} 244aff761db795db8b506c6f6af7ff607856cf85a81Dmitry Shmidt 245aff761db795db8b506c6f6af7ff607856cf85a81Dmitry Shmidt 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid l2_packet_deinit(struct l2_packet_data *l2) 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2 == NULL) 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2->fd >= 0) { 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_priv_cmd(l2, PRIVSEP_CMD_L2_UNREGISTER, NULL, 0); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_read_sock(l2->fd); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(l2->fd); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2->own_socket_path) { 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unlink(l2->own_socket_path); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2->own_socket_path); 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 261293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2); 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len) 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid l2_packet_notify_auth_start(struct l2_packet_data *l2) 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_priv_cmd(l2, PRIVSEP_CMD_L2_NOTIFY_AUTH_START, NULL, 0); 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 277fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 278fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 279fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtint l2_packet_set_packet_filter(struct l2_packet_data *l2, 280fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt enum l2_packet_filter_type type) 281fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt{ 282fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt return -1; 283fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt} 284