1/* PicoTCP Test application */ 2#include <poll.h> 3#include <errno.h> 4#include <unistd.h> 5#include <signal.h> 6#include <getopt.h> 7#include <string.h> 8#include <errno.h> 9#include <fcntl.h> 10#include <libgen.h> 11#include <sys/types.h> 12#include <unistd.h> 13 14#include "utils.h" 15 16#include "pico_stack.h" 17#include "pico_config.h" 18#include "pico_dev_vde.h" 19#include "pico_ipv4.h" 20#include "pico_ipv6.h" 21#include "pico_socket.h" 22#include "pico_dev_tun.h" 23#include "pico_dev_tap.h" 24#include "pico_nat.h" 25#include "pico_icmp4.h" 26#include "pico_icmp6.h" 27#include "pico_dns_client.h" 28#include "pico_dev_loop.h" 29#include "pico_dhcp_client.h" 30#include "pico_dhcp_server.h" 31#include "pico_ipfilter.h" 32#include "pico_olsr.h" 33#include "pico_sntp_client.h" 34#include "pico_mdns.h" 35#include "pico_tftp.h" 36#include "pico_dev_radiotest.h" 37#include "pico_dev_radio_mgr.h" 38 39#include <poll.h> 40#include <errno.h> 41#include <unistd.h> 42#include <signal.h> 43#include <getopt.h> 44#include <string.h> 45#include <errno.h> 46#include <fcntl.h> 47#include <libgen.h> 48 49#ifdef FAULTY 50#include "pico_faulty.h" 51#endif 52 53void app_udpecho(char *args); 54void app_tcpecho(char *args); 55void app_udpclient(char *args); 56void app_tcpclient(char *args); 57void app_tcpbench(char *args); 58void app_natbox(char *args); 59void app_udpdnsclient(char *args); 60void app_udpnatclient(char *args); 61void app_mcastsend(char *args); 62void app_mcastreceive_ipv6(char *args); 63void app_mcastsend_ipv6(char *args); 64void app_mcastreceive(char *args); 65void app_ping(char *args); 66void app_dhcp_server(char *args); 67void app_dhcp_client(char *args); 68void app_dns_sd(char *arg, struct pico_ip4 addr); 69void app_mdns(char *arg, struct pico_ip4 addr); 70void app_sntp(char *args); 71void app_tftp(char *args); 72void app_slaacv4(char *args); 73void app_udpecho(char *args); 74void app_sendto_test(char *args); 75void app_noop(void); 76 77struct pico_ip4 ZERO_IP4 = { 78 0 79}; 80struct pico_ip_mreq ZERO_MREQ = { 81 .mcast_group_addr = {{0}}, 82 .mcast_link_addr = {{0}} 83}; 84struct pico_ip_mreq_source ZERO_MREQ_SRC = { 85 .mcast_group_addr.ip4 = {0}, 86 .mcast_link_addr.ip4 = {0}, 87 .mcast_source_addr.ip4 = {0} 88}; 89struct pico_ip6 ZERO_IP6 = { 90 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 91}; 92struct pico_ip_mreq ZERO_MREQ_IP6 = { 93 .mcast_group_addr.ip6 = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}, 94 .mcast_link_addr.ip6 = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }} 95}; 96struct pico_ip_mreq_source ZERO_MREQ_SRC_IP6 = { 97 .mcast_group_addr.ip6 = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}, 98 .mcast_link_addr.ip6 = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}, 99 .mcast_source_addr.ip6 = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }} 100}; 101 102/* #define INFINITE_TCPTEST */ 103#define picoapp_dbg(...) do {} while(0) 104/* #define picoapp_dbg printf */ 105 106/* #define PICOAPP_IPFILTER 1 */ 107 108int IPV6_MODE; 109 110 111struct pico_ip4 inaddr_any = { 112 0 113}; 114struct pico_ip6 inaddr6_any = {{0}}; 115 116char *cpy_arg(char **dst, char *str); 117 118void deferred_exit(pico_time __attribute__((unused)) now, void *arg) 119{ 120 if (arg) { 121 free(arg); 122 arg = NULL; 123 } 124 125 printf("%s: quitting\n", __FUNCTION__); 126 exit(0); 127} 128 129 130 131/** From now on, parsing the command line **/ 132#define NXT_MAC(x) ++ x[5] 133 134/* Copy a string until the separator, 135 terminate it and return the next index, 136 or NULL if it encounters a EOS */ 137char *cpy_arg(char **dst, char *str) 138{ 139 char *p, *nxt = NULL; 140 char *start = str; 141 char *end = start + strlen(start); 142 char sep = ':'; 143 144 if (IPV6_MODE) 145 sep = ','; 146 147 p = str; 148 while (p) { 149 if ((*p == sep) || (*p == '\0')) { 150 *p = (char)0; 151 nxt = p + 1; 152 if ((*nxt == 0) || (nxt >= end)) 153 nxt = 0; 154 155 printf("dup'ing %s\n", start); 156 *dst = strdup(start); 157 break; 158 } 159 160 p++; 161 } 162 return nxt; 163} 164 165static void __wakeup(uint16_t __attribute__((unused)) ev, struct pico_socket __attribute__((unused)) *s) 166{ 167 168} 169 170 171static void usage(char *arg0) 172{ 173 printf("Usage: %s [--vde name:sock:address:netmask[:gateway]] [--vde ...] [--tun name:address:netmask[:gateway]] [--tun ...] [--app name[:args]]\n\n\n", arg0); 174 printf("\tall arguments can be repeated, e.g. to run on multiple links or applications\n"); 175 printf("\t* --app arguments must be at the end *\n"); 176 exit(255); 177} 178 179#define IF_APPNAME(x) if(strcmp(x, name) == 0) 180 181int main(int argc, char **argv) 182{ 183 unsigned char macaddr[6] = { 184 0, 0, 0, 0xa, 0xb, 0x0 185 }; 186 uint16_t *macaddr_low = (uint16_t *) (macaddr + 2); 187 struct pico_device *dev = NULL; 188 struct pico_ip4 addr4 = { 189 0 190 }; 191 struct pico_ip4 bcastAddr = ZERO_IP4; 192 193 struct option long_options[] = { 194 {"help", 0, 0, 'h'}, 195 {"vde", 1, 0, 'v'}, 196 {"barevde", 1, 0, 'b'}, 197 {"tun", 1, 0, 't'}, 198 {"tap", 1, 0, 'T'}, 199 {"route", 1, 0, 'r'}, 200 {"app", 1, 0, 'a'}, 201 {"dns", 1, 0, 'd'}, 202 {"loop", 0, 0, 'l'}, 203 {0, 0, 0, 0} 204 }; 205 int option_idx = 0; 206 int c; 207 char *app = NULL, *p = argv[0]; 208 /* parse till we find the name of the executable */ 209 while (p) { 210 if (*p == '/') 211 app = p + 1; 212 else if (*p == '\0') 213 break; 214 else 215 {} /* do nothing */ 216 217 p++; 218 } 219 if (strcmp(app, "picoapp6.elf") == 0) 220 IPV6_MODE = 1; 221 222 *macaddr_low = (uint16_t)(*macaddr_low ^ (uint16_t)((uint16_t)getpid() & (uint16_t)0xFFFFU)); 223 printf("My macaddr base is: %02x %02x\n", macaddr[2], macaddr[3]); 224 printf("My macaddr is: %02x %02x %02x %02x %02x %02x\n", macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]); 225 226#ifdef PICO_SUPPORT_MM 227 pico_mem_init(128 * 1024); 228#endif 229 pico_stack_init(); 230 /* Parse args */ 231 while(1) { 232 c = getopt_long(argc, argv, "6:v:b:t:T:a:r:hl", long_options, &option_idx); 233 if (c < 0) 234 break; 235 236 switch(c) { 237 case 'h': 238 usage(argv[0]); 239 break; 240 case 'T': 241 { 242 char *nxt, *name = NULL, *addr = NULL, *nm = NULL, *gw = NULL; 243 struct pico_ip4 ipaddr, netmask, gateway, zero = ZERO_IP4; 244 do { 245 nxt = cpy_arg(&name, optarg); 246 if (!nxt) break; 247 248 nxt = cpy_arg(&addr, nxt); 249 if (!nxt) break; 250 251 nxt = cpy_arg(&nm, nxt); 252 if (!nxt) break; 253 254 cpy_arg(&gw, nxt); 255 } while(0); 256 if (!nm) { 257 fprintf(stderr, "Tun: bad configuration...\n"); 258 exit(1); 259 } 260 261 dev = pico_tap_create(name); 262 if (!dev) { 263 perror("Creating tap"); 264 exit(1); 265 } 266 267 pico_string_to_ipv4(addr, &ipaddr.addr); 268 pico_string_to_ipv4(nm, &netmask.addr); 269 pico_ipv4_link_add(dev, ipaddr, netmask); 270 bcastAddr.addr = (ipaddr.addr) | (~netmask.addr); 271 if (gw && *gw) { 272 pico_string_to_ipv4(gw, &gateway.addr); 273 printf("Adding default route via %08x\n", gateway.addr); 274 pico_ipv4_route_add(zero, zero, gateway, 1, NULL); 275 } 276 277#ifdef PICO_SUPPORT_IPV6 278 if (IPV6_MODE) { 279 struct pico_ip6 ipaddr6 = {{0}}, netmask6 = {{0}}, gateway6 = {{0}}, zero6 = {{0}}; 280 pico_string_to_ipv6(addr, ipaddr6.addr); 281 pico_string_to_ipv6(nm, netmask6.addr); 282 pico_ipv6_link_add(dev, ipaddr6, netmask6); 283 if (gw && *gw) { 284 pico_string_to_ipv6(gw, gateway6.addr); 285 pico_ipv6_route_add(zero6, zero6, gateway6, 1, NULL); 286 } 287 288 pico_ipv6_dev_routing_enable(dev); 289 } 290 291#endif 292 } 293 break; 294 case 't': 295 { 296 char *nxt, *name = NULL, *addr = NULL, *nm = NULL, *gw = NULL; 297 struct pico_ip4 ipaddr, netmask, gateway, zero = ZERO_IP4; 298 do { 299 nxt = cpy_arg(&name, optarg); 300 if (!nxt) break; 301 302 nxt = cpy_arg(&addr, nxt); 303 if (!nxt) break; 304 305 nxt = cpy_arg(&nm, nxt); 306 if (!nxt) break; 307 308 cpy_arg(&gw, nxt); 309 } while(0); 310 if (!nm) { 311 fprintf(stderr, "Tun: bad configuration...\n"); 312 exit(1); 313 } 314 315 dev = pico_tun_create(name); 316 if (!dev) { 317 perror("Creating tun"); 318 exit(1); 319 } 320 321 pico_string_to_ipv4(addr, &ipaddr.addr); 322 pico_string_to_ipv4(nm, &netmask.addr); 323 pico_ipv4_link_add(dev, ipaddr, netmask); 324 bcastAddr.addr = (ipaddr.addr) | (~netmask.addr); 325 if (gw && *gw) { 326 pico_string_to_ipv4(gw, &gateway.addr); 327 printf("Adding default route via %08x\n", gateway.addr); 328 pico_ipv4_route_add(zero, zero, gateway, 1, NULL); 329 } 330 331#ifdef PICO_SUPPORT_IPV6 332 if (IPV6_MODE) { 333 struct pico_ip6 ipaddr6 = {{0}}, netmask6 = {{0}}, gateway6 = {{0}}, zero6 = {{0}}; 334 pico_string_to_ipv6(addr, ipaddr6.addr); 335 pico_string_to_ipv6(nm, netmask6.addr); 336 pico_ipv6_link_add(dev, ipaddr6, netmask6); 337 if (gw && *gw) { 338 pico_string_to_ipv6(gw, gateway6.addr); 339 pico_ipv6_route_add(zero6, zero6, gateway6, 1, NULL); 340 } 341 342 pico_ipv6_dev_routing_enable(dev); 343 } 344 345#endif 346 } 347 break; 348 case 'v': 349 { 350 char *nxt, *name = NULL, *sock = NULL, *addr = NULL, *nm = NULL, *gw = NULL, *addr6 = NULL, *nm6 = NULL, *gw6 = NULL, *loss_in = NULL, *loss_out = NULL; 351 struct pico_ip4 ipaddr, netmask, gateway, zero = ZERO_IP4; 352 uint32_t i_pc = 0, o_pc = 0; 353 printf("+++ OPTARG %s\n", optarg); 354 do { 355 nxt = cpy_arg(&name, optarg); 356 if (!nxt) break; 357 358 nxt = cpy_arg(&sock, nxt); 359 if (!nxt) break; 360 361 if (!IPV6_MODE) { 362 nxt = cpy_arg(&addr, nxt); 363 if (!nxt) break; 364 365 nxt = cpy_arg(&nm, nxt); 366 if (!nxt) break; 367 368 nxt = cpy_arg(&gw, nxt); 369 if (!nxt) break; 370 371 nxt = cpy_arg(&loss_in, nxt); 372 if (!nxt) break; 373 374 nxt = cpy_arg(&loss_out, nxt); 375 if (!nxt) break; 376 } else { 377 nxt = cpy_arg(&addr6, nxt); 378 if (!nxt) break; 379 380 printf("addr6: %s\n", addr6); 381 382 nxt = cpy_arg(&nm6, nxt); 383 if (!nxt) break; 384 385 nxt = cpy_arg(&gw6, nxt); 386 if (!nxt) break; 387 388 nxt = cpy_arg(&loss_in, nxt); 389 if (!nxt) break; 390 391 nxt = cpy_arg(&loss_out, nxt); 392 if (!nxt) break; 393 } 394 } while(0); 395 if (!nm && !nm6) { 396 fprintf(stderr, "Vde: bad configuration...\n"); 397 exit(1); 398 } 399 400 macaddr[4] ^= (uint8_t)(getpid() >> 8); 401 macaddr[5] ^= (uint8_t) (getpid() & 0xFF); 402 dev = pico_vde_create(sock, name, macaddr); 403 NXT_MAC(macaddr); 404 if (!dev) { 405 perror("Creating vde"); 406 exit(1); 407 } 408 409 printf("Vde created.\n"); 410 411 if (!IPV6_MODE) { 412 pico_string_to_ipv4(addr, &ipaddr.addr); 413 pico_string_to_ipv4(nm, &netmask.addr); 414 pico_ipv4_link_add(dev, ipaddr, netmask); 415 addr4 = ipaddr; 416 bcastAddr.addr = (ipaddr.addr) | (~netmask.addr); 417 if (gw && *gw) { 418 pico_string_to_ipv4(gw, &gateway.addr); 419 pico_ipv4_route_add(zero, zero, gateway, 1, NULL); 420 } 421 } 422 423#ifdef PICO_SUPPORT_IPV6 424 if (IPV6_MODE) { 425 struct pico_ip6 ipaddr6 = {{0}}, netmask6 = {{0}}, gateway6 = {{0}}, zero6 = {{0}}; 426 printf("SETTING UP IPV6 ADDRESS\n"); 427 pico_string_to_ipv6(addr6, ipaddr6.addr); 428 pico_string_to_ipv6(nm6, netmask6.addr); 429 pico_ipv6_link_add(dev, ipaddr6, netmask6); 430 if (gw6 && *gw6) { 431 pico_string_to_ipv6(gw6, gateway6.addr); 432 pico_ipv6_route_add(zero6, zero6, gateway6, 1, NULL); 433 } 434 435 pico_ipv6_dev_routing_enable(dev); 436 } 437 438#endif 439 if (loss_in && (strlen(loss_in) > 0)) { 440 i_pc = (uint32_t)atoi(loss_in); 441 } 442 443 if (loss_out && (strlen(loss_out) > 0)) { 444 o_pc = (uint32_t)atoi(loss_out); 445 } 446 447 if (i_pc || o_pc) { 448 printf(" ---------- >Setting vde packet loss %u:%u\n", i_pc, o_pc); 449 pico_vde_set_packetloss(dev, i_pc, o_pc); 450 } 451 452 453 } 454 break; 455 456 case '6': 457 { 458 char *nxt, *name = NULL, *area0 = NULL, *area1 = NULL, *dump = NULL; 459 const char pan_addr[] = "2aaa:abcd::0"; 460 uint8_t n_id, n_area0, n_area1; 461 struct pico_ip6 pan; 462 463 /* Copy required command line arguments */ 464 nxt = cpy_arg(&name, optarg); 465 if (!nxt) 466 goto check; 467 nxt = cpy_arg(&area0, nxt); 468 if (!nxt) 469 goto check; 470 nxt = cpy_arg(&area1, nxt); 471 if (!nxt) 472 goto check; 473 474 /* Check required arguments */ 475check: if (!name || !area0 || !area1) { 476 fprintf(stderr, "Usage: -6,id,area\n"); 477 exit(1); 478 } 479 480 n_id = (uint8_t) atoi(name); 481 n_area0 = (uint8_t) atoi(area0); 482 n_area1 = (uint8_t) atoi(area1); 483 484 if (nxt) { 485 nxt = cpy_arg(&dump, nxt); 486 } 487 488 printf("%d:%d:%d\n", n_id, n_area0, n_area1); 489 490 if (!n_id) { 491 printf("Starting radio-network...\n"); 492 pico_radio_mgr_start(); 493 } else { 494 dev = pico_radiotest_create(n_id, n_area0, n_area1, 0, dump); 495 if (!dev) { 496 exit(1); 497 } 498 499 printf("Radiotest created.\n"); 500 501 /* Add a routable link */ 502 pico_string_to_ipv6(pan_addr, pan.addr); 503 pico_ipv6_link_add_local(dev, &pan); 504 505 /* Enable routing on first device */ 506 if (n_id == 1) { 507 pico_ipv6_dev_routing_enable(dev); 508 } 509 } 510 break; 511 } 512 case 'b': 513 { 514 char *nxt, *name = NULL, *sock = NULL; 515 printf("+++ OPTARG %s\n", optarg); 516 do { 517 nxt = cpy_arg(&name, optarg); 518 if (!nxt) break; 519 520 nxt = cpy_arg(&sock, nxt); 521 } while(0); 522 if (!sock) { 523 fprintf(stderr, "Vde: bad configuration...\n"); 524 exit(1); 525 } 526 527 macaddr[4] ^= (uint8_t)(getpid() >> 8); 528 macaddr[5] ^= (uint8_t)(getpid() & 0xFF); 529 dev = pico_vde_create(sock, name, macaddr); 530 NXT_MAC(macaddr); 531 if (!dev) { 532 if (sock) 533 free(sock); 534 535 if (name) 536 free(name); 537 538 perror("Creating vde"); 539 exit(1); 540 } 541 542 if (sock) 543 free(sock); 544 545 if (name) 546 free(name); 547 548 printf("Vde created.\n"); 549 } 550 break; 551 case 'l': 552 { 553 struct pico_ip4 ipaddr, netmask; 554 555 dev = pico_loop_create(); 556 if (!dev) { 557 perror("Creating loop"); 558 exit(1); 559 } 560 561 pico_string_to_ipv4("127.0.0.1", &ipaddr.addr); 562 pico_string_to_ipv4("255.0.0.0", &netmask.addr); 563 pico_ipv4_link_add(dev, ipaddr, netmask); 564 printf("Loopback created\n"); 565#ifdef PICO_SUPPORT_IPV6 566 if (IPV6_MODE) { 567 struct pico_ip6 ipaddr6 = {{0}}, netmask6 = {{0}}; 568 pico_string_to_ipv6("::1", ipaddr6.addr); 569 pico_string_to_ipv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", netmask6.addr); 570 pico_ipv6_link_add(dev, ipaddr6, netmask6); 571 } 572 573 pico_ipv6_dev_routing_enable(dev); 574 575#endif 576 } 577 break; 578 case 'r': 579 { 580 char *nxt, *addr, *nm, *gw; 581 struct pico_ip4 ipaddr, netmask, gateway; 582 /* XXX adjust for IPv6 */ 583 addr = NULL, nm = NULL, gw = NULL; 584 printf("+++ ROUTEOPTARG %s\n", optarg); 585 do { 586 nxt = cpy_arg(&addr, optarg); 587 if (!nxt) break; 588 589 nxt = cpy_arg(&nm, nxt); 590 if (!nxt) break; 591 592 nxt = cpy_arg(&gw, nxt); 593 } while(0); 594 if (!addr || !nm || !gw) { 595 fprintf(stderr, "--route expects addr:nm:gw:\n"); 596 usage(argv[0]); 597 } 598 599 pico_string_to_ipv4(addr, &ipaddr.addr); 600 pico_string_to_ipv4(nm, &netmask.addr); 601 pico_string_to_ipv4(gw, &gateway.addr); 602 if (pico_ipv4_route_add(ipaddr, netmask, gateway, 1, NULL) == 0) 603 fprintf(stderr, "ROUTE ADDED *** to %s via %s\n", addr, gw); 604 else 605 fprintf(stderr, "ROUTE ADD: ERROR %s \n", strerror(pico_err)); 606 607 break; 608 } 609 case 'd': 610 { 611 /* Add a DNS nameserver IP address */ 612 char *straddr; 613 struct pico_ip4 ipaddr; 614 printf("DNS nameserver address = %s\n", optarg); 615 cpy_arg(&straddr, optarg); 616 pico_string_to_ipv4(straddr, &ipaddr.addr); 617 pico_dns_client_nameserver(&ipaddr, PICO_DNS_NS_ADD); 618 break; 619 } 620 case 'a': 621 { 622 char *name = NULL, *args = NULL; 623 printf("+++ OPTARG %s\n", optarg); 624 args = cpy_arg(&name, optarg); 625 626 printf("+++ NAME: %s ARGS: %s\n", name, args); 627 IF_APPNAME("udpecho") { 628 app_udpecho(args); 629 } else IF_APPNAME("tcpecho") { 630 app_tcpecho(args); 631 } else IF_APPNAME("udpclient") { 632 app_udpclient(args); 633 } else IF_APPNAME("tcpclient") { 634 app_tcpclient(args); 635 } else IF_APPNAME("tcpbench") { 636 app_tcpbench(args); 637 } else IF_APPNAME("natbox") { 638 app_natbox(args); 639 } else IF_APPNAME("udpdnsclient") { 640 app_udpdnsclient(args); 641 } else IF_APPNAME("udpnatclient") { 642 app_udpnatclient(args); 643 } else IF_APPNAME("mcastsend") { 644#ifndef PICO_SUPPORT_MCAST 645 return 0; 646#endif 647 app_mcastsend(args); 648 } else IF_APPNAME("mcastreceive") { 649#ifndef PICO_SUPPORT_MCAST 650 return 0; 651#endif 652 app_mcastreceive(args); 653 } 654 else IF_APPNAME("mcastsend_ipv6") { 655#ifndef PICO_SUPPORT_MCAST 656 return 0; 657#endif 658 app_mcastsend_ipv6(args); 659 } else IF_APPNAME("mcastreceive_ipv6") { 660#ifndef PICO_SUPPORT_MCAST 661 return 0; 662#endif 663 app_mcastreceive_ipv6(args); 664 } 665 666#ifdef PICO_SUPPORT_PING 667 else IF_APPNAME("ping") { 668 app_ping(args); 669 } 670#endif 671 else IF_APPNAME("dhcpserver") { 672#ifndef PICO_SUPPORT_DHCPD 673 return 0; 674#else 675 app_dhcp_server(args); 676#endif 677 } else IF_APPNAME("dhcpclient") { 678#ifndef PICO_SUPPORT_DHCPC 679 return 0; 680#else 681 app_dhcp_client(args); 682#endif 683 } else IF_APPNAME("dns_sd") { 684#ifndef PICO_SUPPORT_DNS_SD 685 return 0; 686#else 687 app_dns_sd(args, addr4); 688#endif 689 } else IF_APPNAME("mdns") { 690#ifndef PICO_SUPPORT_MDNS 691 return 0; 692#else 693 app_mdns(args, addr4); 694#endif 695#ifdef PICO_SUPPORT_SNTP_CLIENT 696 } else IF_APPNAME("sntp") { 697 app_sntp(args); 698#endif 699 } else IF_APPNAME("bcast") { 700 struct pico_ip4 any = { 701 .addr = 0xFFFFFFFFu 702 }; 703 704 struct pico_socket *s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &__wakeup); 705 pico_socket_sendto(s, "abcd", 5u, &any, 1000); 706 707 pico_socket_sendto(s, "abcd", 5u, &bcastAddr, 1000); 708#ifdef PICO_SUPPORT_TFTP 709 } else IF_APPNAME("tftp") { 710 app_tftp(args); 711#endif 712 } else IF_APPNAME("noop") { 713 app_noop(); 714#ifdef PICO_SUPPORT_OLSR 715 } else IF_APPNAME("olsr") { 716 dev = pico_get_device("pic0"); 717 if(dev) { 718 pico_olsr_add(dev); 719 } 720 721 dev = pico_get_device("pic1"); 722 if(dev) { 723 pico_olsr_add(dev); 724 } 725 726 app_noop(); 727#endif 728 } else IF_APPNAME("slaacv4") { 729#ifndef PICO_SUPPORT_SLAACV4 730 return 0; 731#else 732 app_slaacv4(args); 733#endif 734 } else IF_APPNAME("udp_sendto_test") { 735 app_sendto_test(args); 736 } else { 737 fprintf(stderr, "Unknown application %s\n", name); 738 usage(argv[0]); 739 } 740 } 741 break; 742 } 743 } 744 if (!dev) { 745 printf("nodev"); 746 usage(argv[0]); 747 } 748 749#ifdef FAULTY 750 atexit(memory_stats); 751#endif 752 printf("%s: launching PicoTCP loop\n", __FUNCTION__); 753 while(1) { 754 pico_stack_tick(); 755 usleep(2000); 756 } 757} 758