1 /* 2 * Wired Ethernet driver interface 3 * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi> 4 * Copyright (c) 2004, Gunter Burchardt <tira@isx.de> 5 * 6 * This software may be distributed under the terms of the BSD license. 7 * See README for more details. 8 */ 9 10 #include "includes.h" 11 12 #include "common.h" 13 #include "eloop.h" 14 #include "driver.h" 15 #include "driver_wired_common.h" 16 17 #include <sys/ioctl.h> 18 #ifdef __linux__ 19 #include <netpacket/packet.h> 20 #include <net/if_arp.h> 21 #endif /* __linux__ */ 22 #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) 23 #include <net/if_dl.h> 24 #include <net/if_media.h> 25 #endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) */ 26 #ifdef __sun__ 27 #include <sys/sockio.h> 28 #endif /* __sun__ */ 29 30 #ifdef _MSC_VER 31 #pragma pack(push, 1) 32 #endif /* _MSC_VER */ 33 34 struct ieee8023_hdr { 35 u8 dest[6]; 36 u8 src[6]; 37 u16 ethertype; 38 } STRUCT_PACKED; 39 40 #ifdef _MSC_VER 41 #pragma pack(pop) 42 #endif /* _MSC_VER */ 43 44 45 struct wpa_driver_wired_data { 46 struct driver_wired_common_data common; 47 48 int dhcp_sock; /* socket for dhcp packets */ 49 int use_pae_group_addr; 50 }; 51 52 53 /* TODO: detecting new devices should eventually be changed from using DHCP 54 * snooping to trigger on any packet from a new layer 2 MAC address, e.g., 55 * based on ebtables, etc. */ 56 57 struct dhcp_message { 58 u_int8_t op; 59 u_int8_t htype; 60 u_int8_t hlen; 61 u_int8_t hops; 62 u_int32_t xid; 63 u_int16_t secs; 64 u_int16_t flags; 65 u_int32_t ciaddr; 66 u_int32_t yiaddr; 67 u_int32_t siaddr; 68 u_int32_t giaddr; 69 u_int8_t chaddr[16]; 70 u_int8_t sname[64]; 71 u_int8_t file[128]; 72 u_int32_t cookie; 73 u_int8_t options[308]; /* 312 - cookie */ 74 }; 75 76 77 #ifdef __linux__ 78 static void handle_data(void *ctx, unsigned char *buf, size_t len) 79 { 80 #ifdef HOSTAPD 81 struct ieee8023_hdr *hdr; 82 u8 *pos, *sa; 83 size_t left; 84 union wpa_event_data event; 85 86 /* must contain at least ieee8023_hdr 6 byte source, 6 byte dest, 87 * 2 byte ethertype */ 88 if (len < 14) { 89 wpa_printf(MSG_MSGDUMP, "handle_data: too short (%lu)", 90 (unsigned long) len); 91 return; 92 } 93 94 hdr = (struct ieee8023_hdr *) buf; 95 96 switch (ntohs(hdr->ethertype)) { 97 case ETH_P_PAE: 98 wpa_printf(MSG_MSGDUMP, "Received EAPOL packet"); 99 sa = hdr->src; 100 os_memset(&event, 0, sizeof(event)); 101 event.new_sta.addr = sa; 102 wpa_supplicant_event(ctx, EVENT_NEW_STA, &event); 103 104 pos = (u8 *) (hdr + 1); 105 left = len - sizeof(*hdr); 106 drv_event_eapol_rx(ctx, sa, pos, left); 107 break; 108 109 default: 110 wpa_printf(MSG_DEBUG, "Unknown ethertype 0x%04x in data frame", 111 ntohs(hdr->ethertype)); 112 break; 113 } 114 #endif /* HOSTAPD */ 115 } 116 117 118 static void handle_read(int sock, void *eloop_ctx, void *sock_ctx) 119 { 120 int len; 121 unsigned char buf[3000]; 122 123 len = recv(sock, buf, sizeof(buf), 0); 124 if (len < 0) { 125 wpa_printf(MSG_ERROR, "recv: %s", strerror(errno)); 126 return; 127 } 128 129 handle_data(eloop_ctx, buf, len); 130 } 131 132 133 static void handle_dhcp(int sock, void *eloop_ctx, void *sock_ctx) 134 { 135 int len; 136 unsigned char buf[3000]; 137 struct dhcp_message *msg; 138 u8 *mac_address; 139 union wpa_event_data event; 140 141 len = recv(sock, buf, sizeof(buf), 0); 142 if (len < 0) { 143 wpa_printf(MSG_ERROR, "recv: %s", strerror(errno)); 144 return; 145 } 146 147 /* must contain at least dhcp_message->chaddr */ 148 if (len < 44) { 149 wpa_printf(MSG_MSGDUMP, "handle_dhcp: too short (%d)", len); 150 return; 151 } 152 153 msg = (struct dhcp_message *) buf; 154 mac_address = (u8 *) &(msg->chaddr); 155 156 wpa_printf(MSG_MSGDUMP, "Got DHCP broadcast packet from " MACSTR, 157 MAC2STR(mac_address)); 158 159 os_memset(&event, 0, sizeof(event)); 160 event.new_sta.addr = mac_address; 161 wpa_supplicant_event(eloop_ctx, EVENT_NEW_STA, &event); 162 } 163 #endif /* __linux__ */ 164 165 166 static int wired_init_sockets(struct wpa_driver_wired_data *drv, u8 *own_addr) 167 { 168 #ifdef __linux__ 169 struct ifreq ifr; 170 struct sockaddr_ll addr; 171 struct sockaddr_in addr2; 172 int n = 1; 173 174 drv->common.sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_PAE)); 175 if (drv->common.sock < 0) { 176 wpa_printf(MSG_ERROR, "socket[PF_PACKET,SOCK_RAW]: %s", 177 strerror(errno)); 178 return -1; 179 } 180 181 if (eloop_register_read_sock(drv->common.sock, handle_read, 182 drv->common.ctx, NULL)) { 183 wpa_printf(MSG_INFO, "Could not register read socket"); 184 return -1; 185 } 186 187 os_memset(&ifr, 0, sizeof(ifr)); 188 os_strlcpy(ifr.ifr_name, drv->common.ifname, sizeof(ifr.ifr_name)); 189 if (ioctl(drv->common.sock, SIOCGIFINDEX, &ifr) != 0) { 190 wpa_printf(MSG_ERROR, "ioctl(SIOCGIFINDEX): %s", 191 strerror(errno)); 192 return -1; 193 } 194 195 os_memset(&addr, 0, sizeof(addr)); 196 addr.sll_family = AF_PACKET; 197 addr.sll_ifindex = ifr.ifr_ifindex; 198 wpa_printf(MSG_DEBUG, "Opening raw packet socket for ifindex %d", 199 addr.sll_ifindex); 200 201 if (bind(drv->common.sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) 202 { 203 wpa_printf(MSG_ERROR, "bind: %s", strerror(errno)); 204 return -1; 205 } 206 207 /* filter multicast address */ 208 if (wired_multicast_membership(drv->common.sock, ifr.ifr_ifindex, 209 pae_group_addr, 1) < 0) { 210 wpa_printf(MSG_ERROR, "wired: Failed to add multicast group " 211 "membership"); 212 return -1; 213 } 214 215 os_memset(&ifr, 0, sizeof(ifr)); 216 os_strlcpy(ifr.ifr_name, drv->common.ifname, sizeof(ifr.ifr_name)); 217 if (ioctl(drv->common.sock, SIOCGIFHWADDR, &ifr) != 0) { 218 wpa_printf(MSG_ERROR, "ioctl(SIOCGIFHWADDR): %s", 219 strerror(errno)); 220 return -1; 221 } 222 223 if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { 224 wpa_printf(MSG_INFO, "Invalid HW-addr family 0x%04x", 225 ifr.ifr_hwaddr.sa_family); 226 return -1; 227 } 228 os_memcpy(own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); 229 230 /* setup dhcp listen socket for sta detection */ 231 if ((drv->dhcp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { 232 wpa_printf(MSG_ERROR, "socket call failed for dhcp: %s", 233 strerror(errno)); 234 return -1; 235 } 236 237 if (eloop_register_read_sock(drv->dhcp_sock, handle_dhcp, 238 drv->common.ctx, NULL)) { 239 wpa_printf(MSG_INFO, "Could not register read socket"); 240 return -1; 241 } 242 243 os_memset(&addr2, 0, sizeof(addr2)); 244 addr2.sin_family = AF_INET; 245 addr2.sin_port = htons(67); 246 addr2.sin_addr.s_addr = INADDR_ANY; 247 248 if (setsockopt(drv->dhcp_sock, SOL_SOCKET, SO_REUSEADDR, (char *) &n, 249 sizeof(n)) == -1) { 250 wpa_printf(MSG_ERROR, "setsockopt[SOL_SOCKET,SO_REUSEADDR]: %s", 251 strerror(errno)); 252 return -1; 253 } 254 if (setsockopt(drv->dhcp_sock, SOL_SOCKET, SO_BROADCAST, (char *) &n, 255 sizeof(n)) == -1) { 256 wpa_printf(MSG_ERROR, "setsockopt[SOL_SOCKET,SO_BROADCAST]: %s", 257 strerror(errno)); 258 return -1; 259 } 260 261 os_memset(&ifr, 0, sizeof(ifr)); 262 os_strlcpy(ifr.ifr_ifrn.ifrn_name, drv->common.ifname, IFNAMSIZ); 263 if (setsockopt(drv->dhcp_sock, SOL_SOCKET, SO_BINDTODEVICE, 264 (char *) &ifr, sizeof(ifr)) < 0) { 265 wpa_printf(MSG_ERROR, 266 "setsockopt[SOL_SOCKET,SO_BINDTODEVICE]: %s", 267 strerror(errno)); 268 return -1; 269 } 270 271 if (bind(drv->dhcp_sock, (struct sockaddr *) &addr2, 272 sizeof(struct sockaddr)) == -1) { 273 wpa_printf(MSG_ERROR, "bind: %s", strerror(errno)); 274 return -1; 275 } 276 277 return 0; 278 #else /* __linux__ */ 279 return -1; 280 #endif /* __linux__ */ 281 } 282 283 284 static int wired_send_eapol(void *priv, const u8 *addr, 285 const u8 *data, size_t data_len, int encrypt, 286 const u8 *own_addr, u32 flags, int link_id) 287 { 288 struct wpa_driver_wired_data *drv = priv; 289 struct ieee8023_hdr *hdr; 290 size_t len; 291 u8 *pos; 292 int res; 293 294 len = sizeof(*hdr) + data_len; 295 hdr = os_zalloc(len); 296 if (hdr == NULL) { 297 wpa_printf(MSG_INFO, 298 "malloc() failed for wired_send_eapol(len=%lu)", 299 (unsigned long) len); 300 return -1; 301 } 302 303 os_memcpy(hdr->dest, drv->use_pae_group_addr ? pae_group_addr : addr, 304 ETH_ALEN); 305 os_memcpy(hdr->src, own_addr, ETH_ALEN); 306 hdr->ethertype = htons(ETH_P_PAE); 307 308 pos = (u8 *) (hdr + 1); 309 os_memcpy(pos, data, data_len); 310 311 res = send(drv->common.sock, (u8 *) hdr, len, 0); 312 os_free(hdr); 313 314 if (res < 0) { 315 wpa_printf(MSG_ERROR, 316 "wired_send_eapol - packet len: %lu - failed: send: %s", 317 (unsigned long) len, strerror(errno)); 318 } 319 320 return res; 321 } 322 323 324 static void * wired_driver_hapd_init(struct hostapd_data *hapd, 325 struct wpa_init_params *params) 326 { 327 struct wpa_driver_wired_data *drv; 328 329 drv = os_zalloc(sizeof(struct wpa_driver_wired_data)); 330 if (drv == NULL) { 331 wpa_printf(MSG_INFO, 332 "Could not allocate memory for wired driver data"); 333 return NULL; 334 } 335 336 drv->common.ctx = hapd; 337 os_strlcpy(drv->common.ifname, params->ifname, 338 sizeof(drv->common.ifname)); 339 drv->use_pae_group_addr = params->use_pae_group_addr; 340 341 if (wired_init_sockets(drv, params->own_addr)) { 342 os_free(drv); 343 return NULL; 344 } 345 346 return drv; 347 } 348 349 350 static void wired_driver_hapd_deinit(void *priv) 351 { 352 struct wpa_driver_wired_data *drv = priv; 353 354 if (drv->common.sock >= 0) { 355 eloop_unregister_read_sock(drv->common.sock); 356 close(drv->common.sock); 357 } 358 359 if (drv->dhcp_sock >= 0) { 360 eloop_unregister_read_sock(drv->dhcp_sock); 361 close(drv->dhcp_sock); 362 } 363 364 os_free(drv); 365 } 366 367 368 static void * wpa_driver_wired_init(void *ctx, const char *ifname) 369 { 370 struct wpa_driver_wired_data *drv; 371 372 drv = os_zalloc(sizeof(*drv)); 373 if (drv == NULL) 374 return NULL; 375 376 if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) { 377 os_free(drv); 378 return NULL; 379 } 380 381 return drv; 382 } 383 384 385 static void wpa_driver_wired_deinit(void *priv) 386 { 387 struct wpa_driver_wired_data *drv = priv; 388 389 driver_wired_deinit_common(&drv->common); 390 os_free(drv); 391 } 392 393 394 const struct wpa_driver_ops wpa_driver_wired_ops = { 395 .name = "wired", 396 .desc = "Wired Ethernet driver", 397 .hapd_init = wired_driver_hapd_init, 398 .hapd_deinit = wired_driver_hapd_deinit, 399 .hapd_send_eapol = wired_send_eapol, 400 .get_ssid = driver_wired_get_ssid, 401 .get_bssid = driver_wired_get_bssid, 402 .get_capa = driver_wired_get_capa, 403 .init = wpa_driver_wired_init, 404 .deinit = wpa_driver_wired_deinit, 405 }; 406