1 /* 2 * test83: test bad network packets 3 */ 4 5 #define DEBUG 0 6 7 #if DEBUG 8 #define dbgprintf(...) do { \ 9 struct timeval time = { }; \ 10 gettimeofday(&time, NULL); \ 11 fprintf(stderr, "[%2d:%.2d:%.2d.%.6d p%d %s:%d] ", \ 12 (int) ((time.tv_sec / 3600) % 24), \ 13 (int) ((time.tv_sec / 60) % 60), \ 14 (int) (time.tv_sec % 60), \ 15 time.tv_usec, \ 16 getpid(), \ 17 __FUNCTION__, \ 18 __LINE__); \ 19 fprintf(stderr, __VA_ARGS__); \ 20 fflush(stderr); \ 21 } while (0) 22 #else 23 #define dbgprintf(...) 24 #endif 25 26 #include <arpa/inet.h> 27 #include <assert.h> 28 #include <fcntl.h> 29 #include <netinet/in.h> 30 #include <signal.h> 31 #include <stdarg.h> 32 #include <stdint.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <sys/ioctl.h> 37 #include <sys/socket.h> 38 #include <sys/time.h> 39 #include <sys/wait.h> 40 41 #include <net/gen/ether.h> 42 #include <net/gen/eth_io.h> 43 #include <net/gen/in.h> 44 #include <net/gen/ip_io.h> 45 46 #include "common.h" 47 48 int max_error = 100; 49 50 /* https://tools.ietf.org/html/rfc791 */ 51 struct header_ip { 52 uint8_t ver_ihl; /* Version (4 bits) + IHL (4 bits) */ 53 uint8_t tos; /* Type of Service */ 54 uint16_t len; /* Total Length */ 55 uint16_t id; /* Identification */ 56 uint16_t fl_fo; /* Flags (3 bits) + Fragment Offset (13 bits) */ 57 uint8_t ttl; /* Time to Live */ 58 uint8_t prot; /* Protocol */ 59 uint16_t cs; /* Header Checksum */ 60 uint32_t src; /* Source Address */ 61 uint32_t dst; /* Destination Address */ 62 uint8_t opt[16]; /* Options */ 63 }; 64 #define IP_FLAG_EVIL (1 << 2) 65 #define IP_FLAG_DF (1 << 1) 66 #define IP_FLAG_MF (1 << 0) 67 68 /* https://tools.ietf.org/html/rfc790 */ 69 #define IP_PROT_ICMP 1 70 #define IP_PROT_TCP 6 71 #define IP_PROT_UDP 17 72 73 /* https://tools.ietf.org/html/rfc768 */ 74 struct header_udp { 75 uint16_t src; /* Source Port */ 76 uint16_t dst; /* Destination Port */ 77 uint16_t len; /* Length */ 78 uint16_t cs; /* Checksum */ 79 }; 80 81 struct header_udp_pseudo { 82 uint32_t src; 83 uint32_t dst; 84 uint8_t zero; 85 uint8_t prot; 86 uint16_t len; 87 }; 88 89 /* https://tools.ietf.org/html/rfc793 */ 90 struct header_tcp { 91 uint16_t src; /* Source Port */ 92 uint16_t dst; /* Destination Port */ 93 uint32_t seq; /* Sequence Number */ 94 uint32_t ack; /* Acknowledgment Number */ 95 uint8_t doff; /* Data Offset */ 96 uint8_t fl; /* Flags */ 97 uint16_t win; /* Window */ 98 uint16_t cs; /* Checksum */ 99 uint16_t uptr; /* Urgent Pointer */ 100 uint8_t opt[16]; /* Options */ 101 }; 102 #define TCP_FLAG_URG (1 << 5) 103 #define TCP_FLAG_ACK (1 << 4) 104 #define TCP_FLAG_PSH (1 << 3) 105 #define TCP_FLAG_RST (1 << 2) 106 #define TCP_FLAG_SYN (1 << 1) 107 #define TCP_FLAG_FIN (1 << 0) 108 109 #define PORT_BASE 12345 110 #define PORT_COUNT_TCP 4 111 #define PORT_COUNT_UDP 2 112 #define PORT_COUNT (PORT_COUNT_TCP + PORT_COUNT_UDP) 113 114 #define PORT_BASE_SRC (PORT_BASE + PORT_COUNT) 115 #define PORT_COUNT_SRC 79 116 117 #define PAYLOADSIZE_COUNT 6 118 static const size_t payloadsizes[] = { 119 0, 120 1, 121 100, 122 1024, 123 2345, 124 65535 - sizeof(struct header_ip) - sizeof(struct header_udp), 125 }; 126 127 #define ADDR_COUNT_MAX 10 128 static size_t addr_count; 129 static uint32_t addrsrc = 0xc0000201; /* 192.0.2.1 (TEST-NET) */ 130 static uint32_t addrdst = 0x7f000001; /* 127.0.0.1 (localhost) */ 131 static uint32_t addrs[ADDR_COUNT_MAX] = { 132 0x00000000, /* 0.0.0.0 (INADDR_NONE) */ 133 0x7f000001, /* 127.0.0.1 (localhost) */ 134 0xc0000201, /* 192.0.2.1 (TEST-NET) */ 135 0xffffffff, /* 255.255.255.255 (broadcast) */ 136 /* local addresses will be added */ 137 }; 138 139 #define CLOSE(fd) do { assert(fd >= 0); if (close((fd)) != 0) efmt("close failed"); } while (0); 140 enum server_action { 141 sa_close, 142 sa_read, 143 sa_selectr, 144 sa_selectrw, 145 sa_write, 146 }; 147 static int server_done; 148 149 static void server_alarm(int seconds); 150 151 static char *sigstr_cat(char *p, const char *s) { 152 size_t slen = strlen(s); 153 memcpy(p, s, slen); 154 return p + slen; 155 } 156 157 static char *sigstr_itoa(char *p, unsigned long n) { 158 unsigned digit; 159 unsigned long factor = 1000000000UL; 160 int first = 1; 161 162 while (factor > 0) { 163 digit = (n / factor) % 10; 164 if (!first || digit || factor == 1) { 165 *(p++) = digit + '0'; 166 first = 0; 167 } 168 factor /= 10; 169 } 170 return p; 171 } 172 173 #if 0 174 static void dbgprintdata(const void *data, size_t size) { 175 size_t addr; 176 const unsigned char *p = data; 177 178 for (addr = 0; addr < size; addr++) { 179 if (addr % 16 == 0) { 180 if (addr > 0) fprintf(stderr, "\n"); 181 fprintf(stderr, "%.4zx", addr); 182 } 183 fprintf(stderr, " %.2x", p[addr]); 184 } 185 fprintf(stderr, "\n"); 186 fflush(stderr); 187 } 188 #endif 189 190 static void dbgprint_sig(const char *name) { 191 #if DEBUG 192 char buf[256]; 193 char *p = buf; 194 195 /* fprintf not used to be signal safe */ 196 p = sigstr_cat(p, "["); 197 p = sigstr_itoa(p, getpid()); 198 p = sigstr_cat(p, "] "); 199 p = sigstr_cat(p, name); 200 p = sigstr_cat(p, "\n"); 201 write(STDERR_FILENO, buf, p - buf); 202 #endif 203 } 204 205 #define SIGNAL(sig, handler) (signal_checked((sig), (handler), #sig, __FILE__, __FUNCTION__, __LINE__)) 206 207 static void signal_checked(int sig, void (* handler)(int), const char *signame, 208 const char *file, const char *func, int line) { 209 char buf[256]; 210 char *p = buf; 211 struct sigaction sa = { 212 .sa_handler = handler, 213 }; 214 215 if (sigaction(sig, &sa, NULL) == 0) return; 216 217 /* efmt not used to be signal safe */ 218 p = sigstr_cat(p, "["); 219 p = sigstr_cat(p, file); 220 p = sigstr_cat(p, ":"); 221 p = sigstr_itoa(p, line); 222 p = sigstr_cat(p, "] error: sigaction("); 223 p = sigstr_cat(p, signame); 224 p = sigstr_cat(p, ") failed in function "); 225 p = sigstr_cat(p, func); 226 p = sigstr_cat(p, ": "); 227 p = sigstr_itoa(p, errno); 228 p = sigstr_cat(p, "\n"); 229 write(STDERR_FILENO, buf, p - buf); 230 errct++; 231 } 232 233 static void server_sigusr1(int signo) { 234 dbgprint_sig("SIGUSR1"); 235 236 /* terminate on the first opportunity */ 237 server_done = 1; 238 239 /* in case signal is caught before a blocking operation, 240 * keep interrupting 241 */ 242 server_alarm(1); 243 } 244 245 static void server_stop(pid_t pid) { 246 247 if (pid < 0) return; 248 249 dbgprintf("sending SIGUSR1 to child %d\n", (int) pid); 250 if (kill(pid, SIGUSR1) != 0) efmt("kill failed"); 251 } 252 253 static void server_wait(pid_t pid) { 254 int exitcode, status; 255 pid_t r; 256 257 if (pid < 0) return; 258 259 dbgprintf("waiting for child %d\n", (int) pid); 260 r = waitpid(pid, &status, 0); 261 if (r != pid) { 262 efmt("waitpid failed"); 263 return; 264 } 265 266 if (WIFEXITED(status)) { 267 exitcode = WEXITSTATUS(status); 268 if (exitcode < 0) { 269 efmt("negative exit code from child %d\n", (int) pid); 270 } else { 271 dbgprintf("child exited exitcode=%d\n", exitcode); 272 errct += exitcode; 273 } 274 } else if (WIFSIGNALED(status)) { 275 efmt("child killed by signal %d", WTERMSIG(status)); 276 } else { 277 efmt("child has unexpected exit status 0x%x", status); 278 } 279 } 280 281 static void server_sigalrm(int signum) { 282 server_alarm(1); 283 } 284 285 static void server_alarm(int seconds) { 286 SIGNAL(SIGALRM, server_sigalrm); 287 alarm(seconds); 288 } 289 290 static void server_no_alarm(void) { 291 int errno_old = errno; 292 alarm(0); 293 SIGNAL(SIGALRM, SIG_DFL); 294 errno = errno_old; 295 } 296 297 static int server_rw(int fd, int is_write, int *success) { 298 char buf[4096]; 299 ssize_t r; 300 301 /* return 0 means close connection, *success=0 means stop server */ 302 303 if (is_write) { 304 /* ignore SIGPIPE */ 305 SIGNAL(SIGPIPE, SIG_IGN); 306 307 /* initialize buffer */ 308 memset(buf, -1, sizeof(buf)); 309 } 310 311 /* don't block for more than 1s */ 312 server_alarm(1); 313 314 /* perform read or write operation */ 315 dbgprintf("server_rw waiting is_write=%d\n", is_write); 316 r = is_write ? write(fd, buf, sizeof(buf)) : read(fd, buf, sizeof(buf)); 317 318 /* stop alarm (preserves errno) */ 319 server_no_alarm(); 320 321 /* handle read/write result */ 322 if (r >= 0) { 323 dbgprintf("server_rw done\n"); 324 *success = 1; 325 return r > 0; 326 } 327 328 switch (errno) { 329 case EINTR: 330 dbgprintf("server_rw interrupted\n"); 331 *success = 1; 332 return 0; 333 case ECONNRESET: 334 dbgprintf("server_rw connection reset\n"); 335 *success = 1; 336 return 0; 337 case EPIPE: 338 if (is_write) { 339 dbgprintf("server_rw EPIPE\n"); 340 *success = 1; 341 return 0; 342 } 343 /* fall through */ 344 default: 345 efmt("%s failed", is_write ? "write" : "read"); 346 *success = 0; 347 return 0; 348 } 349 } 350 351 static int server_select(int fd, int is_rw, int *success, 352 enum server_action *actionnext) { 353 int r; 354 fd_set readfds, writefds; 355 struct timeval timeout = { .tv_sec = 1, .tv_usec = 0 }; 356 357 /* return 0 means close connection, *success=0 means stop server */ 358 359 /* prepare fd sets */ 360 FD_ZERO(&readfds); 361 FD_SET(fd, &readfds); 362 FD_ZERO(&writefds); 363 if (is_rw) FD_SET(fd, &writefds); 364 365 /* perform select */ 366 errno = 0; 367 dbgprintf("server_select waiting\n"); 368 r = select(fd + 1, &readfds, &writefds, NULL, &timeout); 369 370 /* handle result */ 371 if (r < 0) { 372 switch (errno) { 373 case EINTR: 374 dbgprintf("server_select interrupted\n"); 375 *success = 1; 376 return 0; 377 default: 378 efmt("select failed"); 379 *success = 0; 380 return 0; 381 } 382 } 383 if (r == 0) { 384 dbgprintf("server_select nothing available\n"); 385 *success = 1; 386 return 0; 387 } 388 389 if (FD_ISSET(fd, &readfds)) { 390 dbgprintf("server_select read available\n"); 391 *actionnext = sa_read; 392 *success = 1; 393 return 1; 394 } else if (FD_ISSET(fd, &writefds)) { 395 dbgprintf("server_select write available\n"); 396 *actionnext = sa_write; 397 *success = 1; 398 return 1; 399 } 400 401 *success = 0; 402 efmt("select did not set fd"); 403 return 0; 404 } 405 406 static int server_accept(int servfd, int type, enum server_action action) { 407 enum server_action actionnext; 408 struct sockaddr addr; 409 socklen_t addrsize; 410 int connfd; 411 int success = 0; 412 413 /* if connection-oriented, accept a conmection */ 414 if (type == SOCK_DGRAM) { 415 connfd = servfd; 416 } else { 417 dbgprintf("server_accept waiting for connection\n"); 418 addrsize = sizeof(addr); 419 connfd = accept(servfd, &addr, &addrsize); 420 if (connfd < 0) { 421 switch (errno) { 422 case EINTR: 423 dbgprintf("server_accept interrupted\n"); 424 return 1; 425 default: 426 efmt("cannot accept connection"); 427 return 0; 428 } 429 } 430 dbgprintf("server_accept new connection\n"); 431 } 432 433 /* perform requested action while the connection is open */ 434 actionnext = action; 435 while (!server_done) { 436 switch (actionnext) { 437 case sa_close: 438 success = 1; 439 goto cleanup; 440 case sa_read: 441 if (!server_rw(connfd, 0, &success)) goto cleanup; 442 actionnext = action; 443 break; 444 case sa_selectr: 445 case sa_selectrw: 446 if (!server_select(connfd, actionnext == sa_selectrw, 447 &success, &actionnext)) { 448 goto cleanup; 449 } 450 break; 451 case sa_write: 452 if (!server_rw(connfd, 1, &success)) goto cleanup; 453 actionnext = action; 454 break; 455 default: 456 efmt("bad server action"); 457 success = 0; 458 goto cleanup; 459 } 460 } 461 462 /* socket connection socket */ 463 cleanup: 464 dbgprintf("server_accept done success=%d\n", success); 465 if (connfd != servfd) CLOSE(connfd); 466 return success; 467 } 468 469 static pid_t server_start(int type, int port, enum server_action action) { 470 struct sockaddr_in addr = { 471 .sin_family = AF_INET, 472 .sin_port = htons(port), 473 .sin_addr = { htonl(INADDR_ANY) }, 474 }; 475 int fd; 476 pid_t pid = -1; 477 478 dbgprintf("server_start port %d\n", port); 479 480 /* create socket */ 481 fd = socket(AF_INET, type, 0); 482 if (fd < 0) { 483 efmt("cannot create socket"); 484 goto cleanup; 485 } 486 487 /* bind socket */ 488 if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) != 0) { 489 efmt("cannot bind socket"); 490 goto cleanup; 491 } 492 493 /* make it a server socket if needed */ 494 if (type != SOCK_DGRAM) { 495 if (listen(fd, 5) != 0) { 496 efmt("cannot listen on socket"); 497 goto cleanup; 498 } 499 } 500 501 /* intercept SIGUSR1 in case parent wants the server to stop */ 502 SIGNAL(SIGUSR1, server_sigusr1); 503 504 /* fork; parent continues, child becomes server */ 505 pid = fork(); 506 if (pid < 0) { 507 efmt("cannot create socket"); 508 goto cleanup; 509 } 510 if (pid) goto cleanup; 511 512 /* server loop */ 513 dbgprintf("server_start child\n"); 514 while (!server_done && server_accept(fd, type, action)) {} 515 dbgprintf("server_start child returns\n"); 516 517 CLOSE(fd); 518 exit(errct); 519 520 cleanup: 521 dbgprintf("server_start parent returns pid=%d\n", (int) pid); 522 if (fd >= 0) CLOSE(fd); 523 return pid; 524 } 525 526 static ssize_t send_packet_raw(int fd, const void *buf, size_t size) { 527 return write(fd, buf, size); 528 } 529 530 enum settings_ip { 531 si_bad_version = (1 << 0), 532 si_bad_ihl_small = (1 << 1), 533 si_bad_ihl_big = (1 << 2), 534 si_bad_len_small = (1 << 3), 535 si_bad_len_big = (1 << 4), 536 si_bad_len_huge = (1 << 5), 537 si_bad_cs = (1 << 6), 538 si_zero_cs = (1 << 7), 539 540 si_flag_evil = (1 << 8), 541 si_flag_df = (1 << 9), 542 si_flag_mf = (1 << 10), 543 544 si_opt_end = (1 << 11), 545 si_opt_topsec = (1 << 12), 546 si_opt_nop = (1 << 13), 547 si_opt_badopt = (1 << 14), 548 si_opt_badpad = (1 << 15), 549 }; 550 551 enum settings_udp { 552 su_bad_len_small = (1 << 0), 553 su_bad_len_big = (1 << 1), 554 su_bad_len_huge = (1 << 2), 555 su_bad_cs = (1 << 3), 556 su_zero_cs = (1 << 4), 557 }; 558 559 enum fragmode_ip { 560 fi_as_needed, 561 fi_one, 562 fi_two, 563 fi_frag_tiny, 564 fi_frag_overlap, 565 fi_frag_first, 566 fi_frag_last, 567 fi_frag_repeat, 568 fi_fo_max, 569 }; 570 571 static uint16_t checksum_ip(const void *header, size_t headersize) { 572 const uint16_t *p = header; 573 uint32_t sum = 0; 574 575 while (headersize > 0) { 576 assert(headersize >= sizeof(*p)); 577 sum += ntohs(*p); 578 headersize -= sizeof(*p); 579 p++; 580 } 581 sum += sum >> 16; 582 return htons(~sum); 583 } 584 585 static void send_packet_ip_base( 586 int fd, 587 enum settings_ip ipsettings, 588 uint8_t tos, 589 uint16_t id, 590 uint16_t fo, 591 uint8_t ttl, 592 uint8_t prot, 593 uint32_t srcip, 594 uint32_t dstip, 595 const void *payload, 596 size_t payloadsize) { 597 uint8_t ver = (ipsettings & si_bad_version) ? 3 : 4; 598 uint8_t ihl, ihl_fuzzed; 599 uint16_t fl = ((ipsettings & si_flag_evil) ? IP_FLAG_EVIL : 0) | 600 ((ipsettings & si_flag_df) ? IP_FLAG_DF : 0) | 601 ((ipsettings & si_flag_mf) ? IP_FLAG_MF : 0); 602 uint16_t len; 603 int optlen; 604 struct header_ip header = { 605 .tos = tos, 606 .id = htons(id), 607 .fl_fo = htons((fl << 13) | fo), 608 .ttl = ttl, 609 .prot = prot, 610 .cs = 0, 611 .src = htonl(srcip), 612 .dst = htonl(dstip), 613 }; 614 char packet[6536]; 615 size_t packetsize; 616 ssize_t r; 617 618 dbgprintf("sending IP packet src=%d.%d.%d.%d dst=%d.%d.%d.%d " 619 "payloadsize=%zu id=0x%.4x fragoff=%d%s\n", 620 (uint8_t) (srcip >> 24), (uint8_t) (srcip >> 16), 621 (uint8_t) (srcip >> 8), (uint8_t) (srcip >> 0), 622 (uint8_t) (dstip >> 24), (uint8_t) (dstip >> 16), 623 (uint8_t) (dstip >> 8), (uint8_t) (dstip >> 0), 624 payloadsize, id, fo, (ipsettings & si_flag_mf) ? " (MF)" : ""); 625 626 optlen = 0; 627 if (ipsettings & si_opt_badpad) memset(header.opt, -1, sizeof(header.opt)); 628 if (ipsettings & si_opt_nop) header.opt[optlen++] = 0x01; 629 if (ipsettings & si_opt_topsec) { 630 header.opt[optlen++] = 0x82; 631 header.opt[optlen++] = 0x0b; 632 header.opt[optlen++] = 0x6b; /* S: top secret */ 633 header.opt[optlen++] = 0xc5; /* S: top secret */ 634 header.opt[optlen++] = 0x00; /* C */ 635 header.opt[optlen++] = 0x00; /* C */ 636 header.opt[optlen++] = 'A'; /* H */ 637 header.opt[optlen++] = 'B'; /* H */ 638 header.opt[optlen++] = 'C'; /* TCC */ 639 header.opt[optlen++] = 'D'; /* TCC */ 640 header.opt[optlen++] = 'E'; /* TCC */ 641 } 642 if (ipsettings & si_opt_badopt) header.opt[optlen++] = 0xff; 643 if (ipsettings & si_opt_end) header.opt[optlen++] = 0x00; 644 assert(optlen <= sizeof(header.opt)); 645 646 ihl = ihl_fuzzed = (20 + optlen + 3) / 4; 647 if (ipsettings & si_bad_ihl_small) ihl_fuzzed = 4; 648 if (ipsettings & si_bad_ihl_big) ihl_fuzzed = 15; 649 header.ver_ihl = (ver << 4) | ihl_fuzzed; 650 651 len = ihl * 4 + payloadsize; 652 if (ipsettings & si_bad_len_small) len = ihl * 4 - 1; 653 if (ipsettings & si_bad_len_big) len += 1; 654 if (ipsettings & si_bad_len_huge) len = 0xffff; 655 header.len = htons(len); 656 657 packetsize = ihl * 4 + payloadsize; 658 if (packetsize > sizeof(packet)) { 659 payloadsize = sizeof(packet) - ihl * 4; 660 packetsize = sizeof(packet); 661 } 662 663 header.cs = checksum_ip(&header, ihl * 4); 664 if (ipsettings & si_zero_cs) header.cs = 0; 665 if (ipsettings & si_bad_cs) header.cs += 1; 666 667 memset(packet, 0, sizeof(packet)); 668 memcpy(packet, &header, ihl * 4); 669 memcpy(packet + ihl * 4, payload, payloadsize); 670 671 errno = 0; 672 r = send_packet_raw(fd, packet, packetsize); 673 if (r == -1 && errno == EPACKSIZE && 674 (packetsize < 60 || packetsize > 1514)) { 675 return; 676 } 677 if (r != packetsize) { 678 efmt("write to network interface failed"); 679 } 680 } 681 682 static void send_packet_ip( 683 int fd, 684 enum settings_ip ipsettings, 685 uint8_t tos, 686 uint16_t id, 687 uint8_t ttl, 688 uint8_t prot, 689 uint32_t srcip, 690 uint32_t dstip, 691 enum fragmode_ip fragmode, 692 const void *payload, 693 size_t payloadsize) { 694 enum settings_ip flags; 695 size_t fragcount = 1; 696 size_t fragsize, fragsizecur; 697 size_t fragstart = 0; 698 size_t fragstep; 699 700 switch (fragmode) { 701 case fi_as_needed: 702 fragsize = fragstep = 1500; 703 fragcount = (payloadsize + fragsize - 1) / fragsize; 704 break; 705 case fi_one: 706 case fi_fo_max: 707 fragsize = fragstep = payloadsize; 708 break; 709 case fi_two: 710 fragcount = 2; 711 fragsize = fragstep = (payloadsize + 1) / 2; 712 break; 713 case fi_frag_tiny: 714 fragcount = (payloadsize >= 100) ? 100 : 715 (payloadsize < 1) ? 1 : payloadsize; 716 fragsize = fragstep = (payloadsize + fragcount - 1) / fragcount; 717 break; 718 case fi_frag_overlap: 719 fragcount = 2; 720 fragsize = (payloadsize * 2 + 2) / 3; 721 fragstep = (payloadsize + 1) / 2; 722 break; 723 case fi_frag_first: 724 fragcount = 1; 725 fragsize = fragstep = (payloadsize + 1) / 2; 726 break; 727 case fi_frag_last: 728 fragcount = 1; 729 fragsize = fragstep = (payloadsize + 1) / 2; 730 break; 731 case fi_frag_repeat: 732 fragcount = 2; 733 fragsize = payloadsize; 734 fragstep = 0; 735 break; 736 default: 737 abort(); 738 } 739 740 while (fragcount > 0) { 741 if (fragstart >= payloadsize) { 742 fragsizecur = 0; 743 } else if (payloadsize - fragstart < fragsize) { 744 fragsizecur = payloadsize - fragstart; 745 } else { 746 fragsizecur = fragsize; 747 } 748 749 flags = 0; 750 if (fragstart + fragsizecur < payloadsize) flags |= si_flag_mf; 751 send_packet_ip_base( 752 fd, 753 ipsettings | flags, 754 tos, 755 id, 756 (fragmode == fi_fo_max) ? 0x1fff : fragstart, 757 ttl, 758 prot, 759 srcip, 760 dstip, 761 (uint8_t *) payload + fragstart, 762 fragsizecur); 763 764 fragcount--; 765 fragstart += fragstep; 766 } 767 } 768 769 static uint32_t checksum_udp_sum(const void *buf, size_t size) { 770 const uint16_t *p = buf; 771 uint32_t sum = 0; 772 773 while (size > 0) { 774 assert(size >= sizeof(*p)); 775 sum += ntohs(*p); 776 size -= sizeof(*p); 777 p++; 778 } 779 return sum; 780 } 781 782 static uint16_t checksum_udp( 783 uint32_t srcip, 784 uint32_t dstip, 785 uint8_t prot, 786 const void *packet, 787 size_t packetsize) { 788 uint32_t sum = 0; 789 struct header_udp_pseudo header = { 790 .src = htonl(srcip), 791 .dst = htonl(dstip), 792 .zero = 0, 793 .prot = prot, 794 .len = htons(packetsize), 795 }; 796 797 sum = checksum_udp_sum(&header, sizeof(header)) + 798 checksum_udp_sum(packet, packetsize + packetsize % 2); 799 sum += sum >> 16; 800 return ntohs(~sum); 801 } 802 803 static void send_packet_udp( 804 int fd, 805 enum settings_ip ipsettings, 806 uint8_t tos, 807 uint16_t id, 808 uint8_t ttl, 809 uint8_t prot, 810 uint32_t srcip, 811 uint32_t dstip, 812 enum fragmode_ip fragmode, 813 enum settings_udp udpsettings, 814 uint16_t srcport, 815 uint16_t dstport, 816 const void *payload, 817 size_t payloadsize) { 818 uint16_t len; 819 struct header_udp header = { 820 .src = htons(srcport), 821 .dst = htons(dstport), 822 .cs = 0, 823 }; 824 char packet[65536]; 825 size_t packetsize; 826 827 dbgprintf("sending UDP packet srcport=%d dstport=%d payloadsize=%zu\n", 828 srcport, dstport, payloadsize); 829 830 len = sizeof(struct header_udp) + payloadsize; 831 if (udpsettings & su_bad_len_small) len = sizeof(struct header_udp) - 1; 832 if (udpsettings & su_bad_len_big) len += 1; 833 if (udpsettings & su_bad_len_huge) len = 65535 - sizeof(struct header_ip); 834 header.len = htons(len); 835 836 packetsize = sizeof(header) + payloadsize; 837 assert(packetsize <= sizeof(packet)); 838 839 memcpy(packet, &header, sizeof(header)); 840 memcpy(packet + sizeof(header), payload, payloadsize); 841 if (packetsize % 2) packet[packetsize] = 0; 842 843 header.cs = checksum_udp(srcip, dstip, prot, packet, packetsize); 844 if (udpsettings & su_zero_cs) header.cs = 0; 845 if (udpsettings & su_bad_cs) header.cs += 1; 846 847 memcpy(packet, &header, sizeof(header)); 848 send_packet_ip( 849 fd, 850 ipsettings, 851 tos, 852 id, 853 ttl, 854 prot, 855 srcip, 856 dstip, 857 fragmode, 858 packet, 859 packetsize); 860 } 861 862 struct send_packet_udp_simple_params { 863 int fd; 864 enum settings_ip ipsettings; 865 uint8_t tos; 866 uint16_t *id; 867 uint8_t ttl; 868 uint8_t prot; 869 uint32_t srcip; 870 uint32_t dstip; 871 enum fragmode_ip fragmode; 872 enum settings_udp udpsettings; 873 uint16_t srcport; 874 uint16_t dstport; 875 size_t payloadsize; 876 }; 877 878 static void send_packet_udp_simple( 879 const struct send_packet_udp_simple_params *params) { 880 int i; 881 char payload[65536]; 882 883 assert(params->payloadsize <= sizeof(payload)); 884 for (i = 0; i < params->payloadsize; i++) { 885 payload[i] = *params->id + i; 886 } 887 888 send_packet_udp( 889 params->fd, 890 params->ipsettings, 891 params->tos, 892 *params->id, 893 params->ttl, 894 params->prot, 895 params->srcip, 896 params->dstip, 897 params->fragmode, 898 params->udpsettings, 899 params->srcport, 900 params->dstport, 901 payload, 902 params->payloadsize); 903 *params->id += 5471; 904 } 905 906 static void send_packets_ip_settings( 907 const struct send_packet_udp_simple_params *paramsbase) { 908 struct send_packet_udp_simple_params params; 909 int i; 910 enum settings_ip ipsettings[] = { 911 0, 912 si_bad_version, 913 si_bad_ihl_small, 914 si_bad_ihl_big, 915 si_bad_len_small, 916 si_bad_len_big, 917 si_bad_len_huge, 918 si_bad_cs, 919 si_zero_cs, 920 si_flag_evil, 921 si_flag_df, 922 si_flag_mf, 923 si_opt_end, 924 si_opt_topsec, 925 si_opt_nop, 926 si_opt_badopt, 927 si_opt_nop | si_opt_end | si_opt_badpad, 928 }; 929 uint8_t ttls[] = { 0, 1, 127, 128, 255 }; 930 931 /* various types of flags/options/corruptions */ 932 params = *paramsbase; 933 for (i = 0; i < 17; i++) { 934 params.ipsettings = ipsettings[i]; 935 send_packet_udp_simple(¶ms); 936 } 937 938 /* various TTL settings */ 939 params = *paramsbase; 940 for (i = 0; i < 5; i++) { 941 params.ttl = ttls[i]; 942 send_packet_udp_simple(¶ms); 943 } 944 } 945 946 static void send_packets_ip(int fd) { 947 enum fragmode_ip fragmode; 948 int i, j; 949 uint16_t id = 0; 950 struct send_packet_udp_simple_params params; 951 const struct send_packet_udp_simple_params paramsbase = { 952 .fd = fd, 953 .ipsettings = 0, 954 .tos = 0, 955 .id = &id, 956 .ttl = 10, 957 .prot = IP_PROT_UDP, 958 .srcip = addrsrc, 959 .dstip = addrdst, 960 .fragmode = fi_as_needed, 961 .udpsettings = 0, 962 .srcport = PORT_BASE + 0, 963 .dstport = PORT_BASE + 1, 964 .payloadsize = 1234, 965 }; 966 967 /* send packets with various payload sizes and corruptions */ 968 params = paramsbase; 969 for (i = 0; i < PAYLOADSIZE_COUNT; i++) { 970 params.payloadsize = payloadsizes[i]; 971 send_packets_ip_settings(¶ms); 972 } 973 974 /* send packets with various addresses and corruptions */ 975 params = paramsbase; 976 for (i = 0; i < addr_count; i++) { 977 for (j = 0; j < addr_count; j++) { 978 params.srcip = addrs[i]; 979 params.dstip = addrs[j]; 980 send_packets_ip_settings(¶ms); 981 } 982 } 983 984 /* send valid packets with various fragmentation settings */ 985 params = paramsbase; 986 for (i = 0; i < PAYLOADSIZE_COUNT; i++) { 987 for (fragmode = fi_as_needed; fragmode <= fi_fo_max; fragmode++) { 988 params.payloadsize = payloadsizes[i]; 989 params.fragmode = fragmode; 990 send_packet_udp_simple(¶ms); 991 } 992 } 993 994 /* send a packet for each protocol */ 995 params = paramsbase; 996 for (i = 0; i < 256; i++) { 997 params.prot = i; 998 send_packet_udp_simple(¶ms); 999 } 1000 1001 /* send a packet for each tos */ 1002 params = paramsbase; 1003 for (i = 0; i < 256; i++) { 1004 params.tos = i; 1005 send_packet_udp_simple(¶ms); 1006 } 1007 } 1008 1009 static void send_packets_udp(int fd) { 1010 int i, j, k; 1011 uint16_t id = 0; 1012 struct send_packet_udp_simple_params params; 1013 const struct send_packet_udp_simple_params paramsbase = { 1014 .fd = fd, 1015 .ipsettings = 0, 1016 .tos = 0, 1017 .id = &id, 1018 .ttl = 10, 1019 .prot = IP_PROT_UDP, 1020 .srcip = addrsrc, 1021 .dstip = addrdst, 1022 .fragmode = fi_as_needed, 1023 .udpsettings = 0, 1024 .srcport = PORT_BASE + 0, 1025 .dstport = PORT_BASE + 1, 1026 .payloadsize = 1234, 1027 }; 1028 uint16_t ports[] = { 1029 0, 1030 PORT_BASE + 0, 1031 PORT_BASE + 1, 1032 32767, 1033 65535, 1034 }; 1035 enum settings_udp udpsettings[] = { 1036 0, 1037 su_bad_len_small, 1038 su_bad_len_big, 1039 su_bad_len_huge, 1040 su_bad_cs, 1041 su_zero_cs, 1042 }; 1043 1044 /* send packets with various corruptions */ 1045 params = paramsbase; 1046 for (i = 0; i < 6; i++) { 1047 params.udpsettings = udpsettings[i]; 1048 send_packet_udp_simple(¶ms); 1049 } 1050 1051 /* send packets with various addresses and ports */ 1052 params = paramsbase; 1053 for (i = 0; i < addr_count; i++) { 1054 for (j = 0; j < addr_count; j++) { 1055 for (k = 0; k < 5; k++) { 1056 params.srcip = addrs[i]; 1057 params.dstip = addrs[j]; 1058 params.dstport = ports[k]; 1059 send_packet_udp_simple(¶ms); 1060 } 1061 } 1062 } 1063 params = paramsbase; 1064 for (i = 0; i < addr_count; i++) { 1065 for (j = 0; j < 5; j++) { 1066 for (k = 0; k < 5; k++) { 1067 params.dstip = addrs[i]; 1068 params.srcport = ports[j]; 1069 params.dstport = ports[k]; 1070 send_packet_udp_simple(¶ms); 1071 } 1072 } 1073 } 1074 } 1075 1076 enum settings_tcp { 1077 st_bad_doff_small = (1 << 0), 1078 st_bad_doff_big = (1 << 1), 1079 st_bad_doff_huge = (1 << 2), 1080 st_bad_cs = (1 << 3), 1081 st_zero_cs = (1 << 4), 1082 st_opt_end = (1 << 5), 1083 st_opt_nop = (1 << 6), 1084 st_opt_mss_small = (1 << 7), 1085 st_opt_mss_big = (1 << 8), 1086 st_opt_mss_huge = (1 << 9), 1087 st_opt_badpad = (1 << 10), 1088 }; 1089 1090 static void send_packet_tcp( 1091 int fd, 1092 enum settings_ip ipsettings, 1093 uint8_t tos, 1094 uint16_t id, 1095 uint8_t ttl, 1096 uint8_t prot, 1097 uint32_t srcip, 1098 uint32_t dstip, 1099 enum fragmode_ip fragmode, 1100 enum settings_tcp tcpsettings, 1101 uint16_t srcport, 1102 uint16_t dstport, 1103 uint32_t seq, 1104 uint32_t ack, 1105 uint8_t fl, 1106 uint16_t win, 1107 uint16_t uptr, 1108 const void *payload, 1109 size_t payloadsize) { 1110 uint8_t doff, doff_fuzzed; 1111 int optlen; 1112 struct header_tcp header = { 1113 .src = htons(srcport), 1114 .dst = htons(dstport), 1115 .seq = htonl(seq), 1116 .ack = htonl(ack), 1117 .fl = fl, 1118 .win = htons(win), 1119 .cs = 0, 1120 .uptr = htons(uptr), 1121 }; 1122 char packet[65536]; 1123 size_t packetsize; 1124 1125 dbgprintf("sending TCP packet srcport=%d dstport=%d fl=%s%s%s%s%s%s " 1126 "payloadsize=%zu\n", srcport, dstport, 1127 (fl & TCP_FLAG_URG) ? " URG" : "", 1128 (fl & TCP_FLAG_ACK) ? " ACK" : "", 1129 (fl & TCP_FLAG_PSH) ? " PSH" : "", 1130 (fl & TCP_FLAG_RST) ? " RST" : "", 1131 (fl & TCP_FLAG_SYN) ? " SYN" : "", 1132 (fl & TCP_FLAG_FIN) ? " FIN" : "", 1133 payloadsize); 1134 1135 optlen = 0; 1136 if (tcpsettings & st_opt_badpad) memset(header.opt, -1, sizeof(header.opt)); 1137 if (tcpsettings & st_opt_nop) header.opt[optlen++] = 0x01; 1138 if (tcpsettings & st_opt_mss_small) { 1139 header.opt[optlen++] = 0x02; 1140 header.opt[optlen++] = 0x04; 1141 header.opt[optlen++] = 0x00; 1142 header.opt[optlen++] = 0x00; 1143 } 1144 if (tcpsettings & st_opt_mss_big) { 1145 header.opt[optlen++] = 0x02; 1146 header.opt[optlen++] = 0x04; 1147 header.opt[optlen++] = 0x10; 1148 header.opt[optlen++] = 0x00; 1149 } 1150 if (tcpsettings & st_opt_mss_huge) { 1151 header.opt[optlen++] = 0x02; 1152 header.opt[optlen++] = 0x04; 1153 header.opt[optlen++] = 0xff; 1154 header.opt[optlen++] = 0xff; 1155 } 1156 if (tcpsettings & st_opt_end) header.opt[optlen++] = 0x00; 1157 1158 doff = doff_fuzzed = (20 + optlen + 3) / 4; 1159 if (tcpsettings & su_bad_len_small) doff_fuzzed -= 1; 1160 if (tcpsettings & su_bad_len_big) doff_fuzzed += 1; 1161 if (tcpsettings & su_bad_len_huge) doff_fuzzed = 15; 1162 header.doff = doff_fuzzed << 4; 1163 1164 packetsize = doff * 4 + payloadsize; 1165 assert(packetsize <= sizeof(packet)); 1166 1167 memcpy(packet, &header, sizeof(header)); 1168 memcpy(packet + sizeof(header), payload, payloadsize); 1169 if (packetsize % 2) packet[packetsize] = 0; 1170 1171 header.cs = checksum_udp(srcip, dstip, prot, packet, packetsize); 1172 if (tcpsettings & su_zero_cs) header.cs = 0; 1173 if (tcpsettings & su_bad_cs) header.cs += 1; 1174 1175 memcpy(packet, &header, sizeof(header)); 1176 send_packet_ip( 1177 fd, 1178 ipsettings, 1179 tos, 1180 id, 1181 ttl, 1182 prot, 1183 srcip, 1184 dstip, 1185 fragmode, 1186 packet, 1187 packetsize); 1188 } 1189 1190 struct send_packet_tcp_simple_params { 1191 int fd; 1192 enum settings_ip ipsettings; 1193 uint8_t tos; 1194 uint16_t *id; 1195 uint8_t ttl; 1196 uint8_t prot; 1197 uint32_t srcip; 1198 uint32_t dstip; 1199 enum fragmode_ip fragmode; 1200 enum settings_tcp tcpsettings; 1201 uint16_t srcport; 1202 uint16_t dstport; 1203 uint32_t seq; 1204 uint32_t ack; 1205 uint8_t fl; 1206 uint16_t win; 1207 uint16_t uptr; 1208 size_t payloadsize; 1209 }; 1210 1211 static void send_packet_tcp_simple( 1212 const struct send_packet_tcp_simple_params *params) { 1213 int i; 1214 char payload[65536]; 1215 1216 if (!params->srcip || !params->dstip) return; /* crashes QEMU */ 1217 1218 assert(params->payloadsize <= sizeof(payload)); 1219 for (i = 0; i < params->payloadsize; i++) { 1220 payload[i] = *params->id + i; 1221 } 1222 send_packet_tcp( 1223 params->fd, 1224 params->ipsettings, 1225 params->tos, 1226 *params->id, 1227 params->ttl, 1228 params->prot, 1229 params->srcip, 1230 params->dstip, 1231 params->fragmode, 1232 params->tcpsettings, 1233 params->srcport, 1234 params->dstport, 1235 params->seq, 1236 params->ack, 1237 params->fl, 1238 params->win, 1239 params->uptr, 1240 payload, 1241 params->payloadsize); 1242 *params->id += 5471; 1243 } 1244 1245 static void send_packets_tcp(int fd) { 1246 int i, j, k; 1247 uint16_t id = 0; 1248 const struct send_packet_tcp_simple_params paramsbase = { 1249 .fd = fd, 1250 .ipsettings = 0, 1251 .tos = 0, 1252 .id = &id, 1253 .ttl = 10, 1254 .prot = IP_PROT_TCP, 1255 .srcip = addrsrc, 1256 .dstip = addrdst, 1257 .fragmode = fi_as_needed, 1258 .tcpsettings = 0, 1259 .srcport = PORT_BASE + 0, 1260 .dstport = PORT_BASE + 1, 1261 .seq = 0x12345678, 1262 .ack = 0x87654321, 1263 .fl = TCP_FLAG_SYN, 1264 .win = 4096, 1265 .uptr = 0, 1266 .payloadsize = 1234, 1267 }; 1268 uint16_t payloadsizes[] = { 1269 0, 1270 1, 1271 999, 1272 1500, 1273 1600, 1274 9999, 1275 }; 1276 uint16_t ports[] = { 1277 0, 1278 PORT_BASE + 0, 1279 PORT_BASE + 1, 1280 PORT_BASE + 2, 1281 PORT_BASE + 3, 1282 32767, 1283 65535, 1284 }; 1285 enum settings_tcp tcpsettings[] = { 1286 0, 1287 st_bad_doff_small, 1288 st_bad_doff_big, 1289 st_bad_doff_huge, 1290 st_bad_cs, 1291 st_zero_cs, 1292 st_opt_end, 1293 st_opt_nop, 1294 st_opt_mss_small, 1295 st_opt_mss_big, 1296 st_opt_mss_huge, 1297 st_opt_badpad, 1298 }; 1299 struct send_packet_tcp_simple_params params; 1300 1301 /* send packets with various corruptions */ 1302 params = paramsbase; 1303 for (i = 0; i < 12; i++) { 1304 params.tcpsettings = tcpsettings[i]; 1305 send_packet_tcp_simple(¶ms); 1306 } 1307 1308 /* send packets with various addresses and ports */ 1309 params = paramsbase; 1310 for (i = 0; i < addr_count; i++) { 1311 for (j = 0; j < addr_count; j++) { 1312 for (k = 0; k < 7; k++) { 1313 params.srcip = addrs[i]; 1314 params.dstip = addrs[j]; 1315 params.dstport = ports[k]; 1316 send_packet_tcp_simple(¶ms); 1317 } 1318 } 1319 } 1320 params = paramsbase; 1321 for (i = 0; i < addr_count; i++) { 1322 for (j = 0; j < 7; j++) { 1323 for (k = 0; k < 7; k++) { 1324 params.dstip = addrs[i]; 1325 params.srcport = ports[j]; 1326 params.dstport = ports[k]; 1327 send_packet_tcp_simple(¶ms); 1328 } 1329 } 1330 } 1331 1332 /* send packets with different sequence numbers */ 1333 params = paramsbase; 1334 for (i = 0; i < 16; i++) { 1335 params.seq = 0x1fffffff; 1336 send_packet_tcp_simple(¶ms); 1337 } 1338 1339 /* send packets with all combinations of flags */ 1340 params = paramsbase; 1341 for (i = 0; i < 256; i++) { 1342 params.fl = i; 1343 send_packet_tcp_simple(¶ms); 1344 } 1345 1346 /* send packets with different window sizes */ 1347 params = paramsbase; 1348 for (i = 0; i < 6; i++) { 1349 params.win = payloadsizes[i]; 1350 send_packet_tcp_simple(¶ms); 1351 } 1352 1353 /* send packets with different payload sizes */ 1354 params = paramsbase; 1355 for (i = 0; i < 6; i++) { 1356 params.payloadsize = payloadsizes[i]; 1357 send_packet_tcp_simple(¶ms); 1358 } 1359 } 1360 1361 static void recv_packets_nb(int fd) { 1362 char buf[4096]; 1363 int flags; 1364 ssize_t r; 1365 1366 flags = fcntl(fd, F_GETFL); 1367 if (flags < 0) { 1368 efmt("fcntl(F_GETFL) failed"); 1369 return; 1370 } 1371 1372 if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { 1373 efmt("fcntl(F_SETFL) failed"); 1374 return; 1375 } 1376 1377 for (;;) { 1378 errno = 0; 1379 r = read(fd, buf, sizeof(buf)); 1380 if (r <= 0) { 1381 if (errno != EAGAIN) efmt("nb read failed"); 1382 dbgprintf("no more packets to receive\n"); 1383 break; 1384 } 1385 dbgprintf("received packet of size %zd\n", r); 1386 } 1387 1388 if (fcntl(fd, F_SETFL, flags) == -1) { 1389 efmt("fcntl(F_SETFL) failed"); 1390 return; 1391 } 1392 } 1393 1394 static struct timeval gettimeofday_checked(void) { 1395 struct timeval time = {}; 1396 1397 if (gettimeofday(&time, NULL) != 0) { 1398 efmt("gettimeofday failed"); 1399 } 1400 return time; 1401 } 1402 1403 static int timeval_cmp(const struct timeval *x, const struct timeval *y) { 1404 if (x->tv_sec < y->tv_sec) return -1; 1405 if (x->tv_sec > y->tv_sec) return 1; 1406 if (x->tv_usec < y->tv_usec) return -1; 1407 if (x->tv_usec > y->tv_usec) return 1; 1408 return 0; 1409 } 1410 1411 static struct timeval timeval_sub(struct timeval x, struct timeval y) { 1412 struct timeval z; 1413 1414 /* no negative result allowed */ 1415 if (timeval_cmp(&x, &y) < 0) { 1416 memset(&z, 0, sizeof(z)); 1417 } else { 1418 /* no negative tv_usec allowed */ 1419 if (x.tv_usec < y.tv_usec) { 1420 x.tv_sec -= 1; 1421 x.tv_usec += 1000000; 1422 } 1423 1424 /* perform subtraction */ 1425 z.tv_sec = x.tv_sec - y.tv_sec; 1426 z.tv_usec = x.tv_usec - y.tv_usec; 1427 } 1428 return z; 1429 } 1430 1431 static size_t recv_packet_select( 1432 int fd, 1433 void *buf, 1434 size_t size, 1435 const struct timeval *deadline) { 1436 int nfds; 1437 ssize_t r; 1438 fd_set readfds; 1439 struct timeval timeout = timeval_sub(*deadline, gettimeofday_checked()); 1440 1441 FD_ZERO(&readfds); 1442 FD_SET(fd, &readfds); 1443 errno = 0; 1444 nfds = select(fd + 1, &readfds, NULL, NULL, &timeout); 1445 if (nfds < 0 || nfds > 1) { 1446 efmt("select failed"); 1447 return 0; 1448 } 1449 1450 if (nfds == 0) { 1451 if (FD_ISSET(fd, &readfds)) efmt("select spuriously set fd"); 1452 dbgprintf("no more packets to receive\n"); 1453 return 0; 1454 } 1455 1456 if (!FD_ISSET(fd, &readfds)) { 1457 efmt("select did not set fd"); 1458 return 0; 1459 } 1460 1461 r = read(fd, buf, size); 1462 if (r <= 0) { 1463 efmt("read failed"); 1464 return 0; 1465 } 1466 dbgprintf("received packet of size %zd\n", r); 1467 1468 return r; 1469 } 1470 1471 static void recv_packets_select(int fd) { 1472 char buf[4096]; 1473 struct timeval deadline = gettimeofday_checked(); 1474 1475 deadline.tv_sec++; 1476 while (recv_packet_select(fd, buf, sizeof(buf), &deadline)) { } 1477 } 1478 1479 static int open_raw_socket(int broadcast) { 1480 int fd; 1481 struct nwio_ethopt opt = { }; 1482 struct nwio_ethstat stat = { }; 1483 1484 fd = open("/dev/eth", O_RDWR); 1485 if (fd < 0) efmt("cannot open /dev/eth"); 1486 1487 /* test NWIOGETHOPT */ 1488 if (ioctl(fd, NWIOGETHOPT, &opt) != 0) { 1489 efmt("ioctl(NWIOGETHOPT) failed"); 1490 } 1491 1492 /* test NWIOGETHSTAT */ 1493 if (ioctl(fd, NWIOGETHSTAT, &stat) != 0) { 1494 efmt("ioctl(NWIOGETHSTAT) failed"); 1495 } 1496 1497 /* test invalid NWIOSETHOPT input */ 1498 opt.nweo_flags = NWEO_COPY << 16; 1499 if (ioctl(fd, NWIOSETHOPT, &opt) != -1 && errno != EBADMODE) { 1500 efmt("ioctl(NWIOSETHOPT) should have returned EBADMODE"); 1501 } 1502 1503 opt.nweo_flags = NWEO_EN_LOC | NWEO_DI_LOC; 1504 if (ioctl(fd, NWIOSETHOPT, &opt) != -1 && errno != EBADMODE) { 1505 efmt("ioctl(NWIOSETHOPT) should have returned EBADMODE"); 1506 } 1507 1508 /* test NWIOSETHOPT with defaults */ 1509 opt.nweo_flags = 0; 1510 if (ioctl(fd, NWIOSETHOPT, &opt) != 0) { 1511 efmt("ioctl(NWIOSETHOPT) failed"); 1512 } 1513 1514 /* test NWIOGETHSTAT right after reconfiguring */ 1515 opt.nweo_flags = NWEO_EN_BROAD | NWEO_EN_MULTI | NWEO_EN_PROMISC; 1516 if (ioctl(fd, NWIOSETHOPT, &opt) != 0) { 1517 efmt("ioctl(NWIOSETHOPT) failed"); 1518 } 1519 1520 opt.nweo_flags = NWEO_DI_BROAD | NWEO_DI_MULTI | NWEO_DI_PROMISC; 1521 if (ioctl(fd, NWIOSETHOPT, &opt) != 0) { 1522 efmt("ioctl(NWIOSETHOPT) failed"); 1523 } 1524 1525 if (ioctl(fd, NWIOGETHSTAT, &stat) != 0) { 1526 efmt("ioctl(NWIOGETHSTAT) failed"); 1527 } 1528 1529 /* configure /dev/eth the way we want it for the rest of the test */ 1530 opt.nweo_flags = NWEO_COPY | NWEO_EN_LOC | NWEO_EN_BROAD | 1531 NWEO_EN_MULTI | NWEO_EN_PROMISC | 1532 (broadcast ? NWEO_REMANY : NWEO_REMSPEC) | 1533 NWEO_TYPESPEC | NWEO_RWDATONLY; 1534 opt.nweo_type = htons(ETH_IP_PROTO); 1535 memcpy(&opt.nweo_rem, &stat.nwes_addr, sizeof(opt.nweo_rem)); 1536 if (ioctl(fd, NWIOSETHOPT, &opt) != 0) { 1537 efmt("ioctl(NWIOSETHOPT) failed"); 1538 } 1539 1540 return fd; 1541 } 1542 1543 static void do_packets(void) { 1544 int fd; 1545 1546 /* test IP and UDP with broadcast */ 1547 fd = open_raw_socket(1 /*broadcast*/); 1548 if (fd < 0) return; 1549 1550 send_packets_ip(fd); 1551 send_packets_udp(fd); 1552 recv_packets_nb(fd); 1553 1554 CLOSE(fd); 1555 1556 /* test TCP locally to avoid crashing QEMU */ 1557 fd = open_raw_socket(0 /*broadcast*/); 1558 if (fd < 0) return; 1559 1560 send_packets_tcp(fd); 1561 recv_packets_select(fd); 1562 1563 CLOSE(fd); 1564 } 1565 1566 static void add_local_ip(uint32_t ip) { 1567 static int first = 1; 1568 int i; 1569 1570 for (i = 0; i < addr_count; i++) { 1571 if (addrs[i] == ip) return; 1572 } 1573 dbgprintf("found local IP: %d.%d.%d.%d\n", 1574 (uint8_t) (ip >> 24), (uint8_t) (ip >> 16), 1575 (uint8_t) (ip >> 8), (uint8_t) (ip >> 0)); 1576 if (addr_count < ADDR_COUNT_MAX) { 1577 addrs[addr_count++] = ip; 1578 } 1579 if (first) { 1580 addrdst = ip; 1581 first = 0; 1582 } 1583 } 1584 1585 static void get_local_ip(void) { 1586 char device[16]; 1587 int flags; 1588 int ifno; 1589 nwio_ipconf_t ipconf; 1590 int ip_fd; 1591 1592 /* inspired by ifconfig */ 1593 for (ifno = 0; ifno < 32; ifno++) { 1594 snprintf(device, sizeof(device), "/dev/ip%d", ifno); 1595 ip_fd = open(device, O_RDWR); 1596 if (ip_fd < 0) { 1597 if (errno != ENOENT && errno != ENXIO) { 1598 efmt("cannot open %s", device); 1599 } 1600 continue; 1601 } 1602 1603 flags = fcntl(ip_fd, F_GETFL); 1604 if (flags == -1) { 1605 efmt("cannot get flags for %s", device); 1606 goto next; 1607 } 1608 if (fcntl(ip_fd, F_SETFL, flags | O_NONBLOCK) == -1) { 1609 efmt("cannot set flags for %s", device); 1610 goto next; 1611 } 1612 1613 if (ioctl(ip_fd, NWIOGIPCONF, &ipconf) == -1) { 1614 if (errno != EAGAIN) { 1615 efmt("cannot get IP address for %s", device); 1616 } 1617 goto next; 1618 } 1619 1620 if (fcntl(ip_fd, F_SETFL, flags) == -1) { 1621 efmt("cannot restore flags for %s", device); 1622 } 1623 1624 add_local_ip(ntohl(ipconf.nwic_ipaddr)); 1625 1626 next: 1627 CLOSE(ip_fd); 1628 } 1629 } 1630 1631 int main(int argc, char **argv) 1632 { 1633 int i; 1634 pid_t pids[PORT_COUNT]; 1635 1636 start(83); 1637 1638 /* start servers so we have someone to talk to */ 1639 pids[0] = server_start(SOCK_STREAM, PORT_BASE + 0, sa_close); 1640 pids[1] = server_start(SOCK_STREAM, PORT_BASE + 1, sa_read); 1641 pids[2] = server_start(SOCK_STREAM, PORT_BASE + 2, sa_selectrw); 1642 pids[3] = server_start(SOCK_STREAM, PORT_BASE + 3, sa_write); 1643 pids[4] = server_start(SOCK_DGRAM, PORT_BASE + 0, sa_read); 1644 pids[5] = server_start(SOCK_DGRAM, PORT_BASE + 1, sa_selectr); 1645 1646 /* send some bogus packets */ 1647 get_local_ip(); 1648 if (get_setting_use_network()) do_packets(); 1649 1650 /* stop the servers */ 1651 for (i = 0; i < PORT_COUNT; i++) server_stop(pids[i]); 1652 for (i = 0; i < PORT_COUNT; i++) server_wait(pids[i]); 1653 1654 quit(); 1655 return 0; 1656 } 1657