/*---------------------------------------------------------------------------*/ static unsigned short make_tcp_stats(void *arg) { struct uip_conn *conn; struct httpd_state *s = (struct httpd_state *)arg; uint16_t numprinted; conn = &uip_conns[s->u.count]; numprinted = snprintf((char *)uip_appdata, uip_mss(), "<tr align=\"center\"><td>%d</td><td>", htons(conn->lport)); numprinted += sprint_ip6(conn->ripaddr, uip_appdata + numprinted); numprinted += snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, "-%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\r\n", htons(conn->rport), states[conn->tcpstateflags & UIP_TS_MASK], conn->nrtx, conn->timer, (uip_outstanding(conn))? '*':' ', (uip_stopped(conn))? '!':' '); return numprinted; }
PROCESS_THREAD(border_router_process, ev, data) { PROCESS_BEGIN(); PROCESS_PAUSE(); { rpl_dag_t *dag; char buf[sizeof(dag_id)]; memcpy(buf,dag_id,sizeof(dag_id)); dag = rpl_set_root((uip_ip6addr_t *)buf); /* Assign separate addresses to the uip stack and the host network interface, but with the same prefix */ /* E.g. bbbb::ff:fe00:200 to the stack and bbbb::1 to the host *fallback* network interface */ /* Otherwise the host will trap packets intended for the stack, just as the stack will trap packets intended for the host */ /* $ifconfig usb0 -arp on Ubuntu to skip the neighbor solicitations. Add explicit neighbors on other OSs */ if(dag != NULL) { printf("Created a new RPL dag\n"); #if UIP_CONF_ROUTER_RECEIVE_RA //Contiki stack will shut down until assigned an address from the interface RA //Currently this requires changes in the core rpl-icmp6.c to pass the link-local RA broadcast #else void sprint_ip6(uip_ip6addr_t addr); int i; uip_ip6addr_t ipaddr; #ifdef HARD_CODED_ADDRESS uiplib_ipaddrconv(HARD_CODED_ADDRESS, &ipaddr); #else uip_ip6addr(&ipaddr, 0xbbbb, 0, 0, 0, 0, 0, 0, 0x1); #endif uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); rpl_set_prefix(dag, &ipaddr, 64); for (i=0;i<UIP_DS6_ADDR_NB;i++) { if (uip_ds6_if.addr_list[i].isused) { printf("IPV6 Address: ");sprint_ip6(uip_ds6_if.addr_list[i].ipaddr);printf("\n"); } } #endif } } /* The border router runs with a 100% duty cycle in order to ensure high packet reception rates. */ // NETSTACK_MAC.off(1); while(1) { PROCESS_YIELD(); /* Local and global dag repair can be done from ? */ // rpl_set_prefix(rpl_get_dag(RPL_ANY_INSTANCE), &ipaddr, 64); // rpl_repair_dag(rpl_get_dag(RPL_ANY_INSTANCE)); } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ int main(void) { #if UIP_CONF_IPV6 /* A hard coded address overrides the stack default MAC address to allow multiple instances. * uip6.c defines it as {0x00,0x06,0x98,0x00,0x02,0x32} giving an ipv6 address of [fe80::206:98ff:fe00:232] * We make it simpler, {0x02,0x00,0x00 + the last three bytes of the hard coded address (if any are nonzero). * HARD_CODED_ADDRESS can be defined in the contiki-conf.h file, or here to allow quick builds using different addresses. * If HARD_CODED_ADDRESS has a prefix it also applied, unless built as a RPL end node. * E.g. bbbb::12:3456 becomes fe80::ff:fe12:3456 and prefix bbbb::/64 if non-RPL * ::10 becomes fe80::ff:fe00:10 and prefix awaits RA or RPL formation * bbbb:: gives an address of bbbb::206:98ff:fe00:232 if non-RPL */ //#define HARD_CODED_ADDRESS "bbbb::20" #ifdef HARD_CODED_ADDRESS { uip_ipaddr_t ipaddr; uiplib_ipaddrconv(HARD_CODED_ADDRESS, &ipaddr); if ((ipaddr.u8[13]!=0) || (ipaddr.u8[14]!=0) || (ipaddr.u8[15]!=0)) { if (sizeof(uip_lladdr)==6) { //Minimal-net uses ethernet MAC uip_lladdr.addr[0]=0x02;uip_lladdr.addr[1]=0;uip_lladdr.addr[2]=0; uip_lladdr.addr[3]=ipaddr.u8[13];; uip_lladdr.addr[4]=ipaddr.u8[14]; uip_lladdr.addr[5]=ipaddr.u8[15]; } } } #endif #endif process_init(); /* procinit_init initializes RPL which sets a ctimer for the first DIS */ /* We must start etimers and ctimers,before calling it */ process_start(&etimer_process, NULL); ctimer_init(); procinit_init(); autostart_start(autostart_processes); #if RPL_BORDER_ROUTER process_start(&border_router_process, NULL); printf("Border Router Process started\n"); #elif UIP_CONF_IPV6_RPL printf("RPL enabled\n"); #endif /* Set default IP addresses if not specified */ #if !UIP_CONF_IPV6 uip_ipaddr_t addr; uip_gethostaddr(&addr); if (addr.u8[0]==0) { uip_ipaddr(&addr, 10,1,1,1); } printf("IP Address: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); uip_sethostaddr(&addr); uip_getnetmask(&addr); if (addr.u8[0]==0) { uip_ipaddr(&addr, 255,0,0,0); uip_setnetmask(&addr); } printf("Subnet Mask: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); uip_getdraddr(&addr); if (addr.u8[0]==0) { uip_ipaddr(&addr, 10,1,1,100); uip_setdraddr(&addr); } printf("Def. Router: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); #else /* UIP_CONF_IPV6 */ #if !UIP_CONF_IPV6_RPL #ifdef HARD_CODED_ADDRESS uip_ipaddr_t ipaddr; uiplib_ipaddrconv(HARD_CODED_ADDRESS, &ipaddr); if ((ipaddr.u16[0]!=0) || (ipaddr.u16[1]!=0) || (ipaddr.u16[2]!=0) || (ipaddr.u16[3]!=0)) { #if UIP_CONF_ROUTER uip_ds6_prefix_add(&ipaddr, UIP_DEFAULT_PREFIX_LEN, 0, 0, 0, 0); #else /* UIP_CONF_ROUTER */ uip_ds6_prefix_add(&ipaddr, UIP_DEFAULT_PREFIX_LEN, 0); #endif /* UIP_CONF_ROUTER */ #if !UIP_CONF_IPV6_RPL uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); #endif } #endif /* HARD_CODED_ADDRESS */ #endif #if !RPL_BORDER_ROUTER //Border router process prints addresses later { uint8_t i; for (i=0;i<UIP_DS6_ADDR_NB;i++) { if (uip_ds6_if.addr_list[i].isused) { printf("IPV6 Addresss: ");sprint_ip6(uip_ds6_if.addr_list[i].ipaddr);printf("\n"); } } } #endif #endif /* !UIP_CONF_IPV6 */ /* Make standard output unbuffered. */ setvbuf(stdout, (char *)NULL, _IONBF, 0); while(1) { fd_set fds; int n; struct timeval tv; n = process_run(); /* if(n > 0) { printf("%d processes in queue\n"); }*/ tv.tv_sec = 0; tv.tv_usec = 1; FD_ZERO(&fds); FD_SET(STDIN_FILENO, &fds); select(1, &fds, NULL, NULL, &tv); if(FD_ISSET(STDIN_FILENO, &fds)) { char c; if(read(STDIN_FILENO, &c, 1) > 0) { serial_line_input_byte(c); } } etimer_request_poll(); } return 0; }
/*---------------------------------------------------------------------------*/ int main(void) { process_init(); procinit_init(); ctimer_init(); autostart_start(autostart_processes); /* Set default IP addresses if not specified */ #if !UIP_CONF_IPV6 uip_ipaddr_t addr; uip_gethostaddr(&addr); if (addr.u8[0]==0) { uip_ipaddr(&addr, 10,1,1,1); } printf("IP Address: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); uip_sethostaddr(&addr); uip_getnetmask(&addr); if (addr.u8[0]==0) { uip_ipaddr(&addr, 255,0,0,0); uip_setnetmask(&addr); } printf("Subnet Mask: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); uip_getdraddr(&addr); if (addr.u8[0]==0) { uip_ipaddr(&addr, 10,1,1,100); uip_setdraddr(&addr); } printf("Def. Router: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); #else /* !UIP_CONF_IPV6 */ uip_ipaddr_t ipaddr; uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); uip_netif_addr_autoconf_set(&ipaddr, &uip_lladdr); uip_netif_addr_add(&ipaddr, 16, 0, TENTATIVE); printf("IP6 Address: ");sprint_ip6(ipaddr);printf("\n"); #endif /* !UIP_CONF_IPV6 */ /* Make standard output unbuffered. */ setvbuf(stdout, (char *)NULL, _IONBF, 0); while(1) { fd_set fds; int n; struct timeval tv; n = process_run(); /* if(n > 0) { printf("%d processes in queue\n"); }*/ tv.tv_sec = 0; tv.tv_usec = 1; FD_ZERO(&fds); FD_SET(STDIN_FILENO, &fds); select(1, &fds, NULL, NULL, &tv); if(FD_ISSET(STDIN_FILENO, &fds)) { char c; if(read(STDIN_FILENO, &c, 1) > 0) { serial_line_input_byte(c); } } etimer_request_poll(); } return 0; }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(border_router_process, ev, data) { rpl_dag_t *dag; PROCESS_BEGIN(); /* While waiting for the prefix to be sent through the SLIP connection, the future * border router can join an existing DAG as a parent or child, or acquire a default * router that will later take precedence over the SLIP fallback interface. * Prevent that by turning the radio off until we are initialized as a DAG root. */ prefix_set = 0; NETSTACK_MAC.off(0); PROCESS_PAUSE(); //SENSORS_ACTIVATE(button_sensor); PRINTF("RPL-Border router started\n"); #if 0 /* The border router runs with a 100% duty cycle in order to ensure high packet reception rates. Note if the MAC RDC is not turned off now, aggressive power management of the cpu will interfere with establishing the SLIP connection */ NETSTACK_MAC.off(1); #endif /* Request prefix until it has been received */ #define REQUEST_PREFIX 1 #if REQUEST_PREFIX static struct etimer et; while(!prefix_set) { etimer_set(&et, 1000); request_prefix(); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); } dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)dag_id); if(dag != NULL) { rpl_set_prefix(dag, &prefix, 64); PRINTF("created a new RPL dag\n"); } #else { char buf[sizeof(dag_id)]; memcpy(buf,dag_id,sizeof(dag_id)); dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)buf); /* Assign separate addresses to the uip stack and the host network interface, but with the same prefix E.g. bbbb::ff:fe00:200 to the stack and bbbb::1 to the host *fallback* network interface Otherwise the host will trap packets intended for the stack, just as the stack will trap packets intended for the host $ifconfig usb0 -arp on Ubuntu to skip the neighbor solicitations. Add explicit neighbors on other OSs */ if(dag != NULL) { PRINTF("Created a new RPL dag\n"); #if UIP_CONF_ROUTER_RECEIVE_RA /* Contiki stack will shut down until assigned an address from the interface RA Currently this requires changes in the core rpl-icmp6.c to pass the link-local RA broadcast. */ #else { int i; uip_ip6addr_t ipaddr; #ifdef HARD_CODED_ADDRESS uiplib_ipaddrconv(HARD_CODED_ADDRESS, &ipaddr); #else uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0x1); #endif uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); rpl_set_prefix(dag, &ipaddr, 64); for(i = 0; i < UIP_DS6_ADDR_NB; i++) { if(uip_ds6_if.addr_list[i].isused) { PRINTF("IPV6 Address: "); sprint_ip6(uip_ds6_if.addr_list[i].ipaddr); PRINTF("\n"); } } } #endif } } #endif /* Now turn the radio on, but disable radio duty cycling. * Since we are the DAG root, reception delays would constrain mesh throughbut. */ NETSTACK_MAC.off(1); #if DEBUG || 1 print_local_addresses(); #endif while(1) { PROCESS_YIELD(); if (ev == sensors_event){ PRINTF("Initiating global repair\n"); rpl_repair_root(RPL_DEFAULT_INSTANCE); } } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ int main(void) { clock_init(); #if UIP_CONF_IPV6 /* A hard coded address overrides the stack default MAC address to allow multiple instances. uip6.c defines it as {0x00,0x06,0x98,0x00,0x02,0x32} giving an ipv6 address of [fe80::206:98ff:fe00:232] We make it simpler, {0x02,0x00,0x00 + the last three bytes of the hard coded address (if any are nonzero). HARD_CODED_ADDRESS can be defined in the contiki-conf.h file, or here to allow quick builds using different addresses. If HARD_CODED_ADDRESS has a prefix it also applied, unless built as a RPL end node. E.g. bbbb::12:3456 becomes fe80::ff:fe12:3456 and prefix bbbb::/64 if non-RPL ::10 becomes fe80::ff:fe00:10 and prefix awaits RA or RPL formation bbbb:: gives an address of bbbb::206:98ff:fe00:232 if non-RPL */ #ifdef HARD_CODED_ADDRESS { uip_ipaddr_t ipaddr; uiplib_ipaddrconv(HARD_CODED_ADDRESS, &ipaddr); if((ipaddr.u8[13] != 0) || (ipaddr.u8[14] != 0) || (ipaddr.u8[15] != 0)) { if(sizeof(uip_lladdr) == 6) { /* Minimal-net uses ethernet MAC */ uip_lladdr.addr[0] = 0x02; uip_lladdr.addr[1] = 0; uip_lladdr.addr[2] = 0; uip_lladdr.addr[3] = ipaddr.u8[13]; uip_lladdr.addr[4] = ipaddr.u8[14]; uip_lladdr.addr[5] = ipaddr.u8[15]; } } } #endif /* HARD_CODED_ADDRESS */ #endif /* UIP_CONF_IPV6 */ process_init(); /* procinit_init initializes RPL which sets a ctimer for the first DIS */ /* We must start etimers and ctimers,before calling it */ process_start(&etimer_process, NULL); ctimer_init(); #if RPL_BORDER_ROUTER process_start(&border_router_process, NULL); printf("Border Router Process started\n"); #elif UIP_CONF_IPV6_RPL printf("RPL enabled\n"); #endif procinit_init(); autostart_start(autostart_processes); /* Set default IP addresses if not specified */ #if !UIP_CONF_IPV6 { uip_ipaddr_t addr; uip_gethostaddr(&addr); if(addr.u8[0] == 0) { uip_ipaddr(&addr, 172,18,0,2); } printf("IP Address: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); uip_sethostaddr(&addr); uip_getnetmask(&addr); if(addr.u8[0] == 0) { uip_ipaddr(&addr, 255,255,0,0); uip_setnetmask(&addr); } printf("Subnet Mask: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); uip_getdraddr(&addr); if(addr.u8[0] == 0) { uip_ipaddr(&addr, 172,18,0,1); uip_setdraddr(&addr); } printf("Def. Router: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); } #else /* UIP_CONF_IPV6 */ #if !UIP_CONF_IPV6_RPL { uip_ipaddr_t ipaddr; #ifdef HARD_CODED_ADDRESS uiplib_ipaddrconv(HARD_CODED_ADDRESS, &ipaddr); #else uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); #endif if((ipaddr.u16[0] != 0) || (ipaddr.u16[1] != 0) || (ipaddr.u16[2] != 0) || (ipaddr.u16[3] != 0)) { #if UIP_CONF_ROUTER if(!uip_ds6_prefix_add(&ipaddr, UIP_DEFAULT_PREFIX_LEN, 0, 0, 0, 0)) { fprintf(stderr,"uip_ds6_prefix_add() failed.\n"); exit(EXIT_FAILURE); } #else /* UIP_CONF_ROUTER */ if(!uip_ds6_prefix_add(&ipaddr, UIP_DEFAULT_PREFIX_LEN, 0)) { fprintf(stderr,"uip_ds6_prefix_add() failed.\n"); exit(EXIT_FAILURE); } #endif /* UIP_CONF_ROUTER */ uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); } } #endif /* !UIP_CONF_IPV6_RPL */ #endif /* !UIP_CONF_IPV6 */ // procinit_init(); // autostart_start(autostart_processes); /* Make standard output unbuffered. */ setvbuf(stdout, (char *)NULL, _IONBF, 0); printf("\n*******%s online*******\n",CONTIKI_VERSION_STRING); #if UIP_CONF_IPV6 && !RPL_BORDER_ROUTER /* Border router process prints addresses later */ { int i = 0; int interface_count = 0; for(i = 0; i < UIP_DS6_ADDR_NB; i++) { if(uip_ds6_if.addr_list[i].isused) { printf("IPV6 Addresss: "); sprint_ip6(uip_ds6_if.addr_list[i].ipaddr); printf("\n"); interface_count++; } } assert(0 < interface_count); } #endif while(1) { fd_set fds; int n; struct timeval tv; clock_time_t next_event; n = process_run(); next_event = etimer_next_expiration_time() - clock_time(); #if DEBUG_SLEEP if(n > 0) printf("sleep: %d events pending\n",n); else printf("sleep: next event @ T-%.03f\n",(double)next_event / (double)CLOCK_SECOND); #endif #ifdef __CYGWIN__ /* wpcap doesn't appear to support select, so * we can't idle the process on windows. */ next_event = 0; #endif if(next_event > (CLOCK_SECOND * 2)) next_event = CLOCK_SECOND * 2; tv.tv_sec = n ? 0 : (next_event / CLOCK_SECOND); tv.tv_usec = n ? 0 : ((next_event % 1000) * 1000); FD_ZERO(&fds); FD_SET(STDIN_FILENO, &fds); #ifdef __CYGWIN__ select(1, &fds, NULL, NULL, &tv); #else FD_SET(tapdev_fd(), &fds); if(0 > select(tapdev_fd() + 1, &fds, NULL, NULL, &tv)) { perror("Call to select() failed."); exit(EXIT_FAILURE); } #endif if(FD_ISSET(STDIN_FILENO, &fds)) { char c; if(read(STDIN_FILENO, &c, 1) > 0) { serial_line_input_byte(c); } } #ifdef __CYGWIN__ process_poll(&wpcap_process); #else process_poll(&tapdev_process); #endif etimer_request_poll(); } return 0; }