1 /* 2 * WPA Supplicant - Layer2 packet handling example with dummy functions 3 * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 * 8 * This file can be used as a starting point for layer2 packet implementation. 9 */ 10 11 #include "includes.h" 12 13 #include "common.h" 14 #include "eloop.h" 15 #include "l2_packet.h" 16 17 18 struct l2_packet_data { 19 char ifname[17]; 20 u8 own_addr[ETH_ALEN]; 21 void (*rx_callback)(void *ctx, const u8 *src_addr, 22 const u8 *buf, size_t len); 23 void *rx_callback_ctx; 24 int l2_hdr; /* whether to include layer 2 (Ethernet) header data 25 * buffers */ 26 int fd; 27 }; 28 29 30 int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) 31 { 32 os_memcpy(addr, l2->own_addr, ETH_ALEN); 33 return 0; 34 } 35 36 37 int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto, 38 const u8 *buf, size_t len) 39 { 40 if (l2 == NULL) 41 return -1; 42 43 /* 44 * TODO: Send frame (may need different implementation depending on 45 * whether l2->l2_hdr is set). 46 */ 47 48 return 0; 49 } 50 51 52 static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx) 53 { 54 struct l2_packet_data *l2 = eloop_ctx; 55 u8 buf[2300]; 56 int res; 57 58 /* TODO: receive frame (e.g., recv() using sock */ 59 buf[0] = 0; 60 res = 0; 61 62 l2->rx_callback(l2->rx_callback_ctx, NULL /* TODO: src addr */, 63 buf, res); 64 } 65 66 67 struct l2_packet_data * l2_packet_init( 68 const char *ifname, const u8 *own_addr, unsigned short protocol, 69 void (*rx_callback)(void *ctx, const u8 *src_addr, 70 const u8 *buf, size_t len), 71 void *rx_callback_ctx, int l2_hdr) 72 { 73 struct l2_packet_data *l2; 74 75 l2 = os_zalloc(sizeof(struct l2_packet_data)); 76 if (l2 == NULL) 77 return NULL; 78 os_strlcpy(l2->ifname, ifname, sizeof(l2->ifname)); 79 l2->rx_callback = rx_callback; 80 l2->rx_callback_ctx = rx_callback_ctx; 81 l2->l2_hdr = l2_hdr; 82 83 /* 84 * TODO: open connection for receiving frames 85 */ 86 l2->fd = -1; 87 if (l2->fd >= 0) 88 eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL); 89 90 return l2; 91 } 92 93 94 struct l2_packet_data * l2_packet_init_bridge( 95 const char *br_ifname, const char *ifname, const u8 *own_addr, 96 unsigned short protocol, 97 void (*rx_callback)(void *ctx, const u8 *src_addr, 98 const u8 *buf, size_t len), 99 void *rx_callback_ctx, int l2_hdr) 100 { 101 return l2_packet_init(br_ifname, own_addr, protocol, rx_callback, 102 rx_callback_ctx, l2_hdr); 103 } 104 105 106 void l2_packet_deinit(struct l2_packet_data *l2) 107 { 108 if (l2 == NULL) 109 return; 110 111 if (l2->fd >= 0) { 112 eloop_unregister_read_sock(l2->fd); 113 /* TODO: close connection */ 114 } 115 116 os_free(l2); 117 } 118 119 120 int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len) 121 { 122 /* TODO: get interface IP address */ 123 return -1; 124 } 125 126 127 void l2_packet_notify_auth_start(struct l2_packet_data *l2) 128 { 129 /* This function can be left empty */ 130 } 131 132 133 int l2_packet_set_packet_filter(struct l2_packet_data *l2, 134 enum l2_packet_filter_type type) 135 { 136 return -1; 137 } 138