From 179fb230564474ac8bbbd251dcbc9b73a6ffc3d5 Mon Sep 17 00:00:00 2001 From: rpaulo Date: Wed, 12 Apr 2006 15:29:14 +0000 Subject: [PATCH] New functions/changes required by wpa_supplicant and hostapd 0.4.8. --- usr.sbin/wpa/l2_packet.c | 78 +++++++++++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 9 deletions(-) diff --git a/usr.sbin/wpa/l2_packet.c b/usr.sbin/wpa/l2_packet.c index d6fa674c5394..2111cc9dc984 100644 --- a/usr.sbin/wpa/l2_packet.c +++ b/usr.sbin/wpa/l2_packet.c @@ -1,4 +1,4 @@ -/* $NetBSD: l2_packet.c,v 1.2 2006/03/18 12:35:19 dan Exp $ */ +/* $NetBSD: l2_packet.c,v 1.3 2006/04/12 15:29:14 rpaulo Exp $ */ /* * WPA Supplicant - Layer2 packet handling @@ -19,7 +19,7 @@ * NetBSD-specific implementation. * * Based on: - * $FreeBSD: /repoman/r/ncvs/src/usr.sbin/wpa/l2_packet.c,v 1.1 2005/06/05 21:18:53 sam Exp $ + * $FreeBSD: src/usr.sbin/wpa/l2_packet.c,v 1.3 2006/03/07 05:54:19 sam Exp $ */ #include @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include "common.h" #include "eloop.h" @@ -45,8 +47,8 @@ struct l2_packet_data { pcap_t *pcap; char ifname[100]; u8 own_addr[ETH_ALEN]; - void (*rx_callback)(void *ctx, unsigned char *src_addr, - unsigned char *buf, size_t len); + void (*rx_callback)(void *ctx, const u8 *src_addr, + const u8 *buf, size_t len); void *rx_callback_ctx; int rx_l2_hdr; /* whether to include layer 2 (Ethernet) header in calls * to rx_callback */ @@ -66,9 +68,66 @@ l2_packet_set_rx_l2_hdr(struct l2_packet_data *l2, int rx_l2_hdr) } int -l2_packet_send(struct l2_packet_data *l2, u8 *buf, size_t len) +l2_packet_send(struct l2_packet_data *l2, + const u8 *dst_addr, u16 proto, const u8 *buf, size_t len) { - return pcap_inject(l2->pcap, buf, len); + + if (!l2->rx_l2_hdr) { + int ret; + struct l2_ethhdr *eth = malloc(sizeof(*eth) + len); + + if (eth == NULL) + return -1; + memcpy(eth->h_dest, dst_addr, ETH_ALEN); + memcpy(eth->h_source, l2->own_addr, ETH_ALEN); + eth->h_proto = htons(proto); + memcpy(eth + 1, buf, len); + ret = pcap_inject(l2->pcap, (u8 *) eth, len + sizeof(*eth)); + free(eth); + return ret; + } else + return pcap_inject(l2->pcap, buf, len); +} + +int +l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len) +{ + pcap_if_t *devs, *dev; + struct pcap_addr *addr; + struct sockaddr_in *saddr; + int found = 0; + char err[PCAP_ERRBUF_SIZE + 1]; + + if (pcap_findalldevs(&devs, err) < 0) { + wpa_printf(MSG_DEBUG, "pcap_findalldevs: %s\n", err); + return -1; + } + + for (dev = devs; dev && !found; dev = dev->next) { + if (strcmp(dev->name, l2->ifname) != 0) + continue; + + addr = dev->addresses; + while (addr) { + saddr = (struct sockaddr_in *) addr->addr; + if (saddr && saddr->sin_family == AF_INET) { + snprintf(buf, len, "%s", + inet_ntoa(saddr->sin_addr)); + found = 1; + break; + } + addr = addr->next; + } + } + + pcap_freealldevs(devs); + + return found ? 0 : -1; +} + +void +l2_packet_notify_auth_start(struct l2_packet_data *l2) +{ } static void @@ -193,9 +252,9 @@ eth_get(const char *device, u8 ea[ETH_ALEN]) struct l2_packet_data * l2_packet_init(const char *ifname, const u8 *own_addr, unsigned short protocol, - void (*rx_callback)(void *ctx, unsigned char *src_addr, - unsigned char *buf, size_t len), - void *rx_callback_ctx) + void (*rx_callback)(void *ctx, const u8 *src_addr, + const u8 *buf, size_t len), + void *rx_callback_ctx, int rx_l2_hdr) { struct l2_packet_data *l2; @@ -206,6 +265,7 @@ l2_packet_init(const char *ifname, const u8 *own_addr, unsigned short protocol, strncpy(l2->ifname, ifname, sizeof(l2->ifname)); l2->rx_callback = rx_callback; l2->rx_callback_ctx = rx_callback_ctx; + l2->rx_l2_hdr = rx_l2_hdr; if (eth_get(l2->ifname, l2->own_addr) < 0) { fprintf(stderr, "Failed to get link-level address for "