18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant - Layer2 packet handling example with dummy functions 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2003-2005, 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 * This file can be used as a starting point for layer2 packet implementation. 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "l2_packet.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct l2_packet_data { 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char ifname[17]; 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 own_addr[ETH_ALEN]; 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*rx_callback)(void *ctx, const u8 *src_addr, 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len); 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *rx_callback_ctx; 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int l2_hdr; /* whether to include layer 2 (Ethernet) header data 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * buffers */ 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int fd; 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(addr, l2->own_addr, ETH_ALEN); 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto, 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len) 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2 == NULL) 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: Send frame (may need different implementation depending on 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * whether l2->l2_hdr is set). 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx) 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct l2_packet_data *l2 = eloop_ctx; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[2300]; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: receive frame (e.g., recv() using sock */ 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0] = 0; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = 0; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->rx_callback(l2->rx_callback_ctx, NULL /* TODO: src addr */, 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, res); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct l2_packet_data * l2_packet_init( 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ifname, const u8 *own_addr, unsigned short protocol, 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*rx_callback)(void *ctx, const u8 *src_addr, 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len), 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *rx_callback_ctx, int l2_hdr) 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct l2_packet_data *l2; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2 = os_zalloc(sizeof(struct l2_packet_data)); 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2 == NULL) 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(l2->ifname, ifname, sizeof(l2->ifname)); 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->rx_callback = rx_callback; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->rx_callback_ctx = rx_callback_ctx; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->l2_hdr = l2_hdr; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: open connection for receiving frames 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt l2->fd = -1; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL); 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return l2; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid l2_packet_deinit(struct l2_packet_data *l2) 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2 == NULL) 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (l2->fd >= 0) { 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_read_sock(l2->fd); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: close connection */ 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(l2); 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len) 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: get interface IP address */ 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid l2_packet_notify_auth_start(struct l2_packet_data *l2) 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* This function can be left empty */ 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 118