1 |
|
|
/* $OpenBSD: llc.c,v 1.6 2015/01/16 06:40:17 deraadt Exp $ */ |
2 |
|
|
|
3 |
|
|
/* |
4 |
|
|
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@openbsd.org> |
5 |
|
|
* |
6 |
|
|
* Permission to use, copy, modify, and distribute this software for any |
7 |
|
|
* purpose with or without fee is hereby granted, provided that the above |
8 |
|
|
* copyright notice and this permission notice appear in all copies. |
9 |
|
|
* |
10 |
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 |
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 |
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 |
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 |
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
15 |
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 |
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 |
|
|
*/ |
18 |
|
|
|
19 |
|
|
#include <sys/ioctl.h> |
20 |
|
|
#include <sys/types.h> |
21 |
|
|
#include <sys/socket.h> |
22 |
|
|
#include <sys/time.h> |
23 |
|
|
|
24 |
|
|
#include <net/if.h> |
25 |
|
|
#include <net/if_dl.h> |
26 |
|
|
#include <net/if_media.h> |
27 |
|
|
#include <net/if_arp.h> |
28 |
|
|
#include <net/if_llc.h> |
29 |
|
|
#include <net/bpf.h> |
30 |
|
|
|
31 |
|
|
#include <netinet/in.h> |
32 |
|
|
#include <netinet/if_ether.h> |
33 |
|
|
#include <arpa/inet.h> |
34 |
|
|
|
35 |
|
|
#include <fcntl.h> |
36 |
|
|
#include <stdio.h> |
37 |
|
|
#include <stdlib.h> |
38 |
|
|
#include <string.h> |
39 |
|
|
#include <unistd.h> |
40 |
|
|
#include <limits.h> |
41 |
|
|
|
42 |
|
|
#include "hostapd.h" |
43 |
|
|
|
44 |
|
|
void |
45 |
|
|
hostapd_llc_init(struct hostapd_config *cfg) |
46 |
|
|
{ |
47 |
|
|
struct hostapd_iapp *iapp = &cfg->c_iapp; |
48 |
|
|
struct ifreq ifr; |
49 |
|
|
u_int i; |
50 |
|
|
|
51 |
|
|
iapp->i_raw = hostapd_bpf_open(O_WRONLY); |
52 |
|
|
cfg->c_flags |= HOSTAPD_CFG_F_RAW; |
53 |
|
|
|
54 |
|
|
bzero(&ifr, sizeof(struct ifreq)); |
55 |
|
|
(void)strlcpy(ifr.ifr_name, iapp->i_iface, sizeof(ifr.ifr_name)); |
56 |
|
|
|
57 |
|
|
/* Associate the wired network interface to the BPF descriptor */ |
58 |
|
|
if (ioctl(iapp->i_raw, BIOCSETIF, &ifr) == -1) |
59 |
|
|
hostapd_fatal("failed to set BPF interface \"%s\": %s\n", |
60 |
|
|
iapp->i_iface, strerror(errno)); |
61 |
|
|
|
62 |
|
|
i = 1; |
63 |
|
|
if (ioctl(iapp->i_raw, BIOCSHDRCMPLT, &i) == -1) |
64 |
|
|
hostapd_fatal("failed to set BPF header completion: %s\n", |
65 |
|
|
strerror(errno)); |
66 |
|
|
|
67 |
|
|
/* Lock the BPF descriptor, no further configuration */ |
68 |
|
|
if (ioctl(iapp->i_raw, BIOCLOCK, NULL) == -1) |
69 |
|
|
hostapd_fatal("failed to lock BPF interface on \"%s\": %s\n", |
70 |
|
|
iapp->i_iface, strerror(errno)); |
71 |
|
|
} |
72 |
|
|
|
73 |
|
|
int |
74 |
|
|
hostapd_llc_send_xid(struct hostapd_config *cfg, struct hostapd_node *node) |
75 |
|
|
{ |
76 |
|
|
struct hostapd_iapp *iapp = &cfg->c_iapp; |
77 |
|
|
struct hostapd_llc *llc; |
78 |
|
|
u_int8_t buf[ETHER_HDR_LEN + (LLC_UFRAMELEN * 2)]; |
79 |
|
|
|
80 |
|
|
/* |
81 |
|
|
* Send an IEEE 802.3 LLC XID frame which will possibly force |
82 |
|
|
* our switch port on the wired network to learn the station's |
83 |
|
|
* new MAC address. |
84 |
|
|
*/ |
85 |
|
|
bzero(&buf, sizeof(buf)); |
86 |
|
|
llc = (struct hostapd_llc *)&buf; |
87 |
|
|
memset(&llc->x_hdr.ether_dhost, 0xff, |
88 |
|
|
sizeof(llc->x_hdr.ether_dhost)); |
89 |
|
|
bcopy(&node->ni_macaddr, &llc->x_hdr.ether_shost, |
90 |
|
|
sizeof(llc->x_hdr.ether_shost)); |
91 |
|
|
llc->x_hdr.ether_type = htons(sizeof(buf)); |
92 |
|
|
llc->x_llc.llc_control = IAPP_LLC; |
93 |
|
|
llc->x_llc.llc_fid = IAPP_LLC_XID; |
94 |
|
|
llc->x_llc.llc_class = IAPP_LLC_CLASS; |
95 |
|
|
llc->x_llc.llc_window = IAPP_LLC_WINDOW; |
96 |
|
|
|
97 |
|
|
if (write(iapp->i_raw, &buf, sizeof(buf)) == -1) |
98 |
|
|
return (errno); |
99 |
|
|
return (0); |
100 |
|
|
} |