iapp.c (252726) | iapp.c (281806) |
---|---|
1/* 2 * hostapd / IEEE 802.11F-2003 Inter-Access Point Protocol (IAPP) 3 * Copyright (c) 2002-2007, 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 * Note: IEEE 802.11F-2003 was a experimental use specification. It has expired --- 190 unchanged lines hidden (view full) --- 199 add->seq_num = host_to_be16(seq_num); 200 201 os_memset(&addr, 0, sizeof(addr)); 202 addr.sin_family = AF_INET; 203 addr.sin_addr.s_addr = iapp->multicast.s_addr; 204 addr.sin_port = htons(IAPP_UDP_PORT); 205 if (sendto(iapp->udp_sock, buf, (char *) (add + 1) - buf, 0, 206 (struct sockaddr *) &addr, sizeof(addr)) < 0) | 1/* 2 * hostapd / IEEE 802.11F-2003 Inter-Access Point Protocol (IAPP) 3 * Copyright (c) 2002-2007, 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 * Note: IEEE 802.11F-2003 was a experimental use specification. It has expired --- 190 unchanged lines hidden (view full) --- 199 add->seq_num = host_to_be16(seq_num); 200 201 os_memset(&addr, 0, sizeof(addr)); 202 addr.sin_family = AF_INET; 203 addr.sin_addr.s_addr = iapp->multicast.s_addr; 204 addr.sin_port = htons(IAPP_UDP_PORT); 205 if (sendto(iapp->udp_sock, buf, (char *) (add + 1) - buf, 0, 206 (struct sockaddr *) &addr, sizeof(addr)) < 0) |
207 perror("sendto[IAPP-ADD]"); | 207 wpa_printf(MSG_INFO, "sendto[IAPP-ADD]: %s", strerror(errno)); |
208} 209 210 211static void iapp_send_layer2_update(struct iapp_data *iapp, u8 *addr) 212{ 213 struct iapp_layer2_update msg; 214 215 /* Send Level 2 Update Frame to update forwarding tables in layer 2 --- 10 unchanged lines hidden (view full) --- 226 msg.control = 0xaf; /* XID response lsb.1111F101. 227 * F=0 (no poll command; unsolicited frame) */ 228 msg.xid_info[0] = 0x81; /* XID format identifier */ 229 msg.xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */ 230 msg.xid_info[2] = 1 << 1; /* XID sender's receive window size (RW) 231 * FIX: what is correct RW with 802.11? */ 232 233 if (send(iapp->packet_sock, &msg, sizeof(msg), 0) < 0) | 208} 209 210 211static void iapp_send_layer2_update(struct iapp_data *iapp, u8 *addr) 212{ 213 struct iapp_layer2_update msg; 214 215 /* Send Level 2 Update Frame to update forwarding tables in layer 2 --- 10 unchanged lines hidden (view full) --- 226 msg.control = 0xaf; /* XID response lsb.1111F101. 227 * F=0 (no poll command; unsolicited frame) */ 228 msg.xid_info[0] = 0x81; /* XID format identifier */ 229 msg.xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */ 230 msg.xid_info[2] = 1 << 1; /* XID sender's receive window size (RW) 231 * FIX: what is correct RW with 802.11? */ 232 233 if (send(iapp->packet_sock, &msg, sizeof(msg), 0) < 0) |
234 perror("send[L2 Update]"); | 234 wpa_printf(MSG_INFO, "send[L2 Update]: %s", strerror(errno)); |
235} 236 237 238/** 239 * iapp_new_station - IAPP processing for a new STA 240 * @iapp: IAPP data 241 * @sta: The associated station 242 */ 243void iapp_new_station(struct iapp_data *iapp, struct sta_info *sta) 244{ | 235} 236 237 238/** 239 * iapp_new_station - IAPP processing for a new STA 240 * @iapp: IAPP data 241 * @sta: The associated station 242 */ 243void iapp_new_station(struct iapp_data *iapp, struct sta_info *sta) 244{ |
245 struct ieee80211_mgmt *assoc; 246 u16 seq; | 245 u16 seq = 0; /* TODO */ |
247 248 if (iapp == NULL) 249 return; 250 | 246 247 if (iapp == NULL) 248 return; 249 |
251 assoc = sta->last_assoc_req; 252 seq = assoc ? WLAN_GET_SEQ_SEQ(le_to_host16(assoc->seq_ctrl)) : 0; 253 | |
254 /* IAPP-ADD.request(MAC Address, Sequence Number, Timeout) */ 255 hostapd_logger(iapp->hapd, sta->addr, HOSTAPD_MODULE_IAPP, 256 HOSTAPD_LEVEL_DEBUG, "IAPP-ADD.request(seq=%d)", seq); 257 iapp_send_layer2_update(iapp, sta->addr); 258 iapp_send_add(iapp, sta->addr, seq); 259 | 250 /* IAPP-ADD.request(MAC Address, Sequence Number, Timeout) */ 251 hostapd_logger(iapp->hapd, sta->addr, HOSTAPD_MODULE_IAPP, 252 HOSTAPD_LEVEL_DEBUG, "IAPP-ADD.request(seq=%d)", seq); 253 iapp_send_layer2_update(iapp, sta->addr); 254 iapp_send_add(iapp, sta->addr, seq); 255 |
260 if (assoc && WLAN_FC_GET_STYPE(le_to_host16(assoc->frame_control)) == 261 WLAN_FC_STYPE_REASSOC_REQ) { 262 /* IAPP-MOVE.request(MAC Address, Sequence Number, Old AP, 263 * Context Block, Timeout) 264 */ 265 /* TODO: Send IAPP-MOVE to the old AP; Map Old AP BSSID to 266 * IP address */ 267 } | 256 /* TODO: If this was reassociation: 257 * IAPP-MOVE.request(MAC Address, Sequence Number, Old AP, 258 * Context Block, Timeout) 259 * TODO: Send IAPP-MOVE to the old AP; Map Old AP BSSID to 260 * IP address */ |
268} 269 270 271static void iapp_process_add_notify(struct iapp_data *iapp, 272 struct sockaddr_in *from, 273 struct iapp_hdr *hdr, int len) 274{ 275 struct iapp_add_notify *add = (struct iapp_add_notify *) (hdr + 1); 276 struct sta_info *sta; 277 278 if (len != sizeof(*add)) { | 261} 262 263 264static void iapp_process_add_notify(struct iapp_data *iapp, 265 struct sockaddr_in *from, 266 struct iapp_hdr *hdr, int len) 267{ 268 struct iapp_add_notify *add = (struct iapp_add_notify *) (hdr + 1); 269 struct sta_info *sta; 270 271 if (len != sizeof(*add)) { |
279 printf("Invalid IAPP-ADD packet length %d (expected %lu)\n", 280 len, (unsigned long) sizeof(*add)); | 272 wpa_printf(MSG_INFO, "Invalid IAPP-ADD packet length %d (expected %lu)", 273 len, (unsigned long) sizeof(*add)); |
281 return; 282 } 283 284 sta = ap_get_sta(iapp->hapd, add->mac_addr); 285 286 /* IAPP-ADD.indication(MAC Address, Sequence Number) */ 287 hostapd_logger(iapp->hapd, add->mac_addr, HOSTAPD_MODULE_IAPP, 288 HOSTAPD_LEVEL_INFO, --- 32 unchanged lines hidden (view full) --- 321 struct iapp_hdr *hdr; 322 323 /* Handle incoming IAPP frames (over UDP/IP) */ 324 325 fromlen = sizeof(from); 326 len = recvfrom(iapp->udp_sock, buf, sizeof(buf), 0, 327 (struct sockaddr *) &from, &fromlen); 328 if (len < 0) { | 274 return; 275 } 276 277 sta = ap_get_sta(iapp->hapd, add->mac_addr); 278 279 /* IAPP-ADD.indication(MAC Address, Sequence Number) */ 280 hostapd_logger(iapp->hapd, add->mac_addr, HOSTAPD_MODULE_IAPP, 281 HOSTAPD_LEVEL_INFO, --- 32 unchanged lines hidden (view full) --- 314 struct iapp_hdr *hdr; 315 316 /* Handle incoming IAPP frames (over UDP/IP) */ 317 318 fromlen = sizeof(from); 319 len = recvfrom(iapp->udp_sock, buf, sizeof(buf), 0, 320 (struct sockaddr *) &from, &fromlen); 321 if (len < 0) { |
329 perror("recvfrom"); | 322 wpa_printf(MSG_INFO, "iapp_receive_udp - recvfrom: %s", 323 strerror(errno)); |
330 return; 331 } 332 333 if (from.sin_addr.s_addr == iapp->own.s_addr) 334 return; /* ignore own IAPP messages */ 335 336 hostapd_logger(iapp->hapd, NULL, HOSTAPD_MODULE_IAPP, 337 HOSTAPD_LEVEL_DEBUG, --- 7 unchanged lines hidden (view full) --- 345 hdr = (struct iapp_hdr *) buf; 346 hlen = be_to_host16(hdr->length); 347 hostapd_logger(iapp->hapd, NULL, HOSTAPD_MODULE_IAPP, 348 HOSTAPD_LEVEL_DEBUG, 349 "RX: version=%d command=%d id=%d len=%d\n", 350 hdr->version, hdr->command, 351 be_to_host16(hdr->identifier), hlen); 352 if (hdr->version != IAPP_VERSION) { | 324 return; 325 } 326 327 if (from.sin_addr.s_addr == iapp->own.s_addr) 328 return; /* ignore own IAPP messages */ 329 330 hostapd_logger(iapp->hapd, NULL, HOSTAPD_MODULE_IAPP, 331 HOSTAPD_LEVEL_DEBUG, --- 7 unchanged lines hidden (view full) --- 339 hdr = (struct iapp_hdr *) buf; 340 hlen = be_to_host16(hdr->length); 341 hostapd_logger(iapp->hapd, NULL, HOSTAPD_MODULE_IAPP, 342 HOSTAPD_LEVEL_DEBUG, 343 "RX: version=%d command=%d id=%d len=%d\n", 344 hdr->version, hdr->command, 345 be_to_host16(hdr->identifier), hlen); 346 if (hdr->version != IAPP_VERSION) { |
353 printf("Dropping IAPP frame with unknown version %d\n", 354 hdr->version); | 347 wpa_printf(MSG_INFO, "Dropping IAPP frame with unknown version %d", 348 hdr->version); |
355 return; 356 } 357 if (hlen > len) { | 349 return; 350 } 351 if (hlen > len) { |
358 printf("Underflow IAPP frame (hlen=%d len=%d)\n", hlen, len); | 352 wpa_printf(MSG_INFO, "Underflow IAPP frame (hlen=%d len=%d)", 353 hlen, len); |
359 return; 360 } 361 if (hlen < len) { | 354 return; 355 } 356 if (hlen < len) { |
362 printf("Ignoring %d extra bytes from IAPP frame\n", 363 len - hlen); | 357 wpa_printf(MSG_INFO, "Ignoring %d extra bytes from IAPP frame", 358 len - hlen); |
364 len = hlen; 365 } 366 367 switch (hdr->command) { 368 case IAPP_CMD_ADD_notify: | 359 len = hlen; 360 } 361 362 switch (hdr->command) { 363 case IAPP_CMD_ADD_notify: |
369 iapp_process_add_notify(iapp, &from, hdr, hlen - sizeof(*hdr)); | 364 iapp_process_add_notify(iapp, &from, hdr, len - sizeof(*hdr)); |
370 break; 371 case IAPP_CMD_MOVE_notify: 372 /* TODO: MOVE is using TCP; so move this to TCP handler once it 373 * is implemented.. */ 374 /* IAPP-MOVE.indication(MAC Address, New BSSID, 375 * Sequence Number, AP Address, Context Block) */ 376 /* TODO: process */ 377 break; 378 default: | 365 break; 366 case IAPP_CMD_MOVE_notify: 367 /* TODO: MOVE is using TCP; so move this to TCP handler once it 368 * is implemented.. */ 369 /* IAPP-MOVE.indication(MAC Address, New BSSID, 370 * Sequence Number, AP Address, Context Block) */ 371 /* TODO: process */ 372 break; 373 default: |
379 printf("Unknown IAPP command %d\n", hdr->command); | 374 wpa_printf(MSG_INFO, "Unknown IAPP command %d", hdr->command); |
380 break; 381 } 382} 383 384 385struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface) 386{ 387 struct ifreq ifr; --- 10 unchanged lines hidden (view full) --- 398 iapp->udp_sock = iapp->packet_sock = -1; 399 400 /* TODO: 401 * open socket for sending and receiving IAPP frames over TCP 402 */ 403 404 iapp->udp_sock = socket(PF_INET, SOCK_DGRAM, 0); 405 if (iapp->udp_sock < 0) { | 375 break; 376 } 377} 378 379 380struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface) 381{ 382 struct ifreq ifr; --- 10 unchanged lines hidden (view full) --- 393 iapp->udp_sock = iapp->packet_sock = -1; 394 395 /* TODO: 396 * open socket for sending and receiving IAPP frames over TCP 397 */ 398 399 iapp->udp_sock = socket(PF_INET, SOCK_DGRAM, 0); 400 if (iapp->udp_sock < 0) { |
406 perror("socket[PF_INET,SOCK_DGRAM]"); | 401 wpa_printf(MSG_INFO, "iapp_init - socket[PF_INET,SOCK_DGRAM]: %s", 402 strerror(errno)); |
407 iapp_deinit(iapp); 408 return NULL; 409 } 410 411 os_memset(&ifr, 0, sizeof(ifr)); 412 os_strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); 413 if (ioctl(iapp->udp_sock, SIOCGIFINDEX, &ifr) != 0) { | 403 iapp_deinit(iapp); 404 return NULL; 405 } 406 407 os_memset(&ifr, 0, sizeof(ifr)); 408 os_strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); 409 if (ioctl(iapp->udp_sock, SIOCGIFINDEX, &ifr) != 0) { |
414 perror("ioctl(SIOCGIFINDEX)"); | 410 wpa_printf(MSG_INFO, "iapp_init - ioctl(SIOCGIFINDEX): %s", 411 strerror(errno)); |
415 iapp_deinit(iapp); 416 return NULL; 417 } 418 ifindex = ifr.ifr_ifindex; 419 420 if (ioctl(iapp->udp_sock, SIOCGIFADDR, &ifr) != 0) { | 412 iapp_deinit(iapp); 413 return NULL; 414 } 415 ifindex = ifr.ifr_ifindex; 416 417 if (ioctl(iapp->udp_sock, SIOCGIFADDR, &ifr) != 0) { |
421 perror("ioctl(SIOCGIFADDR)"); | 418 wpa_printf(MSG_INFO, "iapp_init - ioctl(SIOCGIFADDR): %s", 419 strerror(errno)); |
422 iapp_deinit(iapp); 423 return NULL; 424 } 425 paddr = (struct sockaddr_in *) &ifr.ifr_addr; 426 if (paddr->sin_family != AF_INET) { | 420 iapp_deinit(iapp); 421 return NULL; 422 } 423 paddr = (struct sockaddr_in *) &ifr.ifr_addr; 424 if (paddr->sin_family != AF_INET) { |
427 printf("Invalid address family %i (SIOCGIFADDR)\n", 428 paddr->sin_family); | 425 wpa_printf(MSG_INFO, "IAPP: Invalid address family %i (SIOCGIFADDR)", 426 paddr->sin_family); |
429 iapp_deinit(iapp); 430 return NULL; 431 } 432 iapp->own.s_addr = paddr->sin_addr.s_addr; 433 434 if (ioctl(iapp->udp_sock, SIOCGIFBRDADDR, &ifr) != 0) { | 427 iapp_deinit(iapp); 428 return NULL; 429 } 430 iapp->own.s_addr = paddr->sin_addr.s_addr; 431 432 if (ioctl(iapp->udp_sock, SIOCGIFBRDADDR, &ifr) != 0) { |
435 perror("ioctl(SIOCGIFBRDADDR)"); | 433 wpa_printf(MSG_INFO, "iapp_init - ioctl(SIOCGIFBRDADDR): %s", 434 strerror(errno)); |
436 iapp_deinit(iapp); 437 return NULL; 438 } 439 paddr = (struct sockaddr_in *) &ifr.ifr_addr; 440 if (paddr->sin_family != AF_INET) { | 435 iapp_deinit(iapp); 436 return NULL; 437 } 438 paddr = (struct sockaddr_in *) &ifr.ifr_addr; 439 if (paddr->sin_family != AF_INET) { |
441 printf("Invalid address family %i (SIOCGIFBRDADDR)\n", 442 paddr->sin_family); | 440 wpa_printf(MSG_INFO, "Invalid address family %i (SIOCGIFBRDADDR)", 441 paddr->sin_family); |
443 iapp_deinit(iapp); 444 return NULL; 445 } 446 inet_aton(IAPP_MULTICAST, &iapp->multicast); 447 448 os_memset(&uaddr, 0, sizeof(uaddr)); 449 uaddr.sin_family = AF_INET; 450 uaddr.sin_port = htons(IAPP_UDP_PORT); 451 if (bind(iapp->udp_sock, (struct sockaddr *) &uaddr, 452 sizeof(uaddr)) < 0) { | 442 iapp_deinit(iapp); 443 return NULL; 444 } 445 inet_aton(IAPP_MULTICAST, &iapp->multicast); 446 447 os_memset(&uaddr, 0, sizeof(uaddr)); 448 uaddr.sin_family = AF_INET; 449 uaddr.sin_port = htons(IAPP_UDP_PORT); 450 if (bind(iapp->udp_sock, (struct sockaddr *) &uaddr, 451 sizeof(uaddr)) < 0) { |
453 perror("bind[UDP]"); | 452 wpa_printf(MSG_INFO, "iapp_init - bind[UDP]: %s", 453 strerror(errno)); |
454 iapp_deinit(iapp); 455 return NULL; 456 } 457 458 os_memset(&mreq, 0, sizeof(mreq)); 459 mreq.imr_multiaddr = iapp->multicast; 460 mreq.imr_address.s_addr = INADDR_ANY; 461 mreq.imr_ifindex = 0; 462 if (setsockopt(iapp->udp_sock, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, 463 sizeof(mreq)) < 0) { | 454 iapp_deinit(iapp); 455 return NULL; 456 } 457 458 os_memset(&mreq, 0, sizeof(mreq)); 459 mreq.imr_multiaddr = iapp->multicast; 460 mreq.imr_address.s_addr = INADDR_ANY; 461 mreq.imr_ifindex = 0; 462 if (setsockopt(iapp->udp_sock, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, 463 sizeof(mreq)) < 0) { |
464 perror("setsockopt[UDP,IP_ADD_MEMBERSHIP]"); | 464 wpa_printf(MSG_INFO, "iapp_init - setsockopt[UDP,IP_ADD_MEMBERSHIP]: %s", 465 strerror(errno)); |
465 iapp_deinit(iapp); 466 return NULL; 467 } 468 469 iapp->packet_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 470 if (iapp->packet_sock < 0) { | 466 iapp_deinit(iapp); 467 return NULL; 468 } 469 470 iapp->packet_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 471 if (iapp->packet_sock < 0) { |
471 perror("socket[PF_PACKET,SOCK_RAW]"); | 472 wpa_printf(MSG_INFO, "iapp_init - socket[PF_PACKET,SOCK_RAW]: %s", 473 strerror(errno)); |
472 iapp_deinit(iapp); 473 return NULL; 474 } 475 476 os_memset(&addr, 0, sizeof(addr)); 477 addr.sll_family = AF_PACKET; 478 addr.sll_ifindex = ifindex; 479 if (bind(iapp->packet_sock, (struct sockaddr *) &addr, 480 sizeof(addr)) < 0) { | 474 iapp_deinit(iapp); 475 return NULL; 476 } 477 478 os_memset(&addr, 0, sizeof(addr)); 479 addr.sll_family = AF_PACKET; 480 addr.sll_ifindex = ifindex; 481 if (bind(iapp->packet_sock, (struct sockaddr *) &addr, 482 sizeof(addr)) < 0) { |
481 perror("bind[PACKET]"); | 483 wpa_printf(MSG_INFO, "iapp_init - bind[PACKET]: %s", 484 strerror(errno)); |
482 iapp_deinit(iapp); 483 return NULL; 484 } 485 486 if (eloop_register_read_sock(iapp->udp_sock, iapp_receive_udp, 487 iapp, NULL)) { | 485 iapp_deinit(iapp); 486 return NULL; 487 } 488 489 if (eloop_register_read_sock(iapp->udp_sock, iapp_receive_udp, 490 iapp, NULL)) { |
488 printf("Could not register read socket for IAPP.\n"); | 491 wpa_printf(MSG_INFO, "Could not register read socket for IAPP"); |
489 iapp_deinit(iapp); 490 return NULL; 491 } 492 | 492 iapp_deinit(iapp); 493 return NULL; 494 } 495 |
493 printf("IEEE 802.11F (IAPP) using interface %s\n", iface); | 496 wpa_printf(MSG_INFO, "IEEE 802.11F (IAPP) using interface %s", iface); |
494 495 /* TODO: For levels 2 and 3: send RADIUS Initiate-Request, receive 496 * RADIUS Initiate-Accept or Initiate-Reject. IAPP port should actually 497 * be openned only after receiving Initiate-Accept. If Initiate-Reject 498 * is received, IAPP is not started. */ 499 500 return iapp; 501} --- 8 unchanged lines hidden (view full) --- 510 511 if (iapp->udp_sock >= 0) { 512 os_memset(&mreq, 0, sizeof(mreq)); 513 mreq.imr_multiaddr = iapp->multicast; 514 mreq.imr_address.s_addr = INADDR_ANY; 515 mreq.imr_ifindex = 0; 516 if (setsockopt(iapp->udp_sock, SOL_IP, IP_DROP_MEMBERSHIP, 517 &mreq, sizeof(mreq)) < 0) { | 497 498 /* TODO: For levels 2 and 3: send RADIUS Initiate-Request, receive 499 * RADIUS Initiate-Accept or Initiate-Reject. IAPP port should actually 500 * be openned only after receiving Initiate-Accept. If Initiate-Reject 501 * is received, IAPP is not started. */ 502 503 return iapp; 504} --- 8 unchanged lines hidden (view full) --- 513 514 if (iapp->udp_sock >= 0) { 515 os_memset(&mreq, 0, sizeof(mreq)); 516 mreq.imr_multiaddr = iapp->multicast; 517 mreq.imr_address.s_addr = INADDR_ANY; 518 mreq.imr_ifindex = 0; 519 if (setsockopt(iapp->udp_sock, SOL_IP, IP_DROP_MEMBERSHIP, 520 &mreq, sizeof(mreq)) < 0) { |
518 perror("setsockopt[UDP,IP_DEL_MEMBERSHIP]"); | 521 wpa_printf(MSG_INFO, "iapp_deinit - setsockopt[UDP,IP_DEL_MEMBERSHIP]: %s", 522 strerror(errno)); |
519 } 520 521 eloop_unregister_read_sock(iapp->udp_sock); 522 close(iapp->udp_sock); 523 } 524 if (iapp->packet_sock >= 0) { 525 eloop_unregister_read_sock(iapp->packet_sock); 526 close(iapp->packet_sock); 527 } 528 os_free(iapp); 529} | 523 } 524 525 eloop_unregister_read_sock(iapp->udp_sock); 526 close(iapp->udp_sock); 527 } 528 if (iapp->packet_sock >= 0) { 529 eloop_unregister_read_sock(iapp->packet_sock); 530 close(iapp->packet_sock); 531 } 532 os_free(iapp); 533} |