| /* |
| * WPA Supplicant - Layer2 packet handling example with dummy functions |
| * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> |
| * |
| * This software may be distributed under the terms of the BSD license. |
| * See README for more details. |
| * |
| * This file can be used as a starting point for layer2 packet implementation. |
| */ |
| |
| #include "includes.h" |
| |
| #include "common.h" |
| #include "eloop.h" |
| #include "l2_packet.h" |
| |
| |
| struct l2_packet_data { |
| char ifname[17]; |
| u8 own_addr[ETH_ALEN]; |
| void (*rx_callback)(void *ctx, const u8 *src_addr, |
| const u8 *buf, size_t len); |
| void *rx_callback_ctx; |
| int l2_hdr; /* whether to include layer 2 (Ethernet) header data |
| * buffers */ |
| int fd; |
| }; |
| |
| |
| int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) |
| { |
| os_memcpy(addr, l2->own_addr, ETH_ALEN); |
| return 0; |
| } |
| |
| |
| int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto, |
| const u8 *buf, size_t len) |
| { |
| if (l2 == NULL) |
| return -1; |
| |
| /* |
| * TODO: Send frame (may need different implementation depending on |
| * whether l2->l2_hdr is set). |
| */ |
| |
| return 0; |
| } |
| |
| |
| static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx) |
| { |
| struct l2_packet_data *l2 = eloop_ctx; |
| u8 buf[2300]; |
| int res; |
| |
| /* TODO: receive frame (e.g., recv() using sock */ |
| buf[0] = 0; |
| res = 0; |
| |
| l2->rx_callback(l2->rx_callback_ctx, NULL /* TODO: src addr */, |
| buf, res); |
| } |
| |
| |
| struct l2_packet_data * l2_packet_init( |
| const char *ifname, const u8 *own_addr, unsigned short protocol, |
| void (*rx_callback)(void *ctx, const u8 *src_addr, |
| const u8 *buf, size_t len), |
| void *rx_callback_ctx, int l2_hdr) |
| { |
| struct l2_packet_data *l2; |
| |
| l2 = os_zalloc(sizeof(struct l2_packet_data)); |
| if (l2 == NULL) |
| return NULL; |
| os_strlcpy(l2->ifname, ifname, sizeof(l2->ifname)); |
| l2->rx_callback = rx_callback; |
| l2->rx_callback_ctx = rx_callback_ctx; |
| l2->l2_hdr = l2_hdr; |
| |
| /* |
| * TODO: open connection for receiving frames |
| */ |
| l2->fd = -1; |
| eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL); |
| |
| return l2; |
| } |
| |
| |
| void l2_packet_deinit(struct l2_packet_data *l2) |
| { |
| if (l2 == NULL) |
| return; |
| |
| if (l2->fd >= 0) { |
| eloop_unregister_read_sock(l2->fd); |
| /* TODO: close connection */ |
| } |
| |
| os_free(l2); |
| } |
| |
| |
| int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len) |
| { |
| /* TODO: get interface IP address */ |
| return -1; |
| } |
| |
| |
| void l2_packet_notify_auth_start(struct l2_packet_data *l2) |
| { |
| /* This function can be left empty */ |
| } |