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