/*---------------------------------------------------------------------------*/ void cetic_6lbr_set_prefix(uip_ipaddr_t * prefix, unsigned len, uip_ipaddr_t * ipaddr) { #if CETIC_6LBR_SMARTBRIDGE int new_prefix = !uip_ipaddr_prefixcmp(&wsn_net_prefix, prefix, len); int new_dag_prefix = cetic_dag == NULL || !uip_ipaddr_prefixcmp(&cetic_dag->prefix_info.prefix, prefix, len); if((nvm_data.mode & CETIC_MODE_WAIT_RA_MASK) == 0) { LOG6LBR_DEBUG("Ignoring RA\n"); return; } if(new_prefix) { LOG6LBR_6ADDR(INFO, prefix, "Setting prefix : "); uip_ipaddr_copy(&wsn_ip_addr, ipaddr); uip_ipaddr_copy(&wsn_net_prefix, prefix); wsn_net_prefix_len = len; LOG6LBR_6ADDR(INFO, &wsn_ip_addr, "Tentative global IPv6 address : "); #if CONTIKI_TARGET_NATIVE cetic_6lbr_save_ip(); #endif } if(new_dag_prefix) { if((nvm_data.rpl_config & CETIC_6LBR_MODE_GLOBAL_DODAG) != 0) { cetic_dag = rpl_set_root(nvm_data.rpl_instance_id, &wsn_ip_addr); rpl_set_prefix(cetic_dag, prefix, len); LOG6LBR_6ADDR(INFO, &cetic_dag->dag_id, "Configured as DODAG Root "); } else { rpl_set_prefix(cetic_dag, prefix, len); LOG6LBR_6ADDR(INFO, prefix, "Setting DAG prefix : "); rpl_repair_root(RPL_DEFAULT_INSTANCE); } } #endif }
int node_config_allowed_node_hook(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len) { /* Test if MAC of incoming node is allowed. */ int allowed = 0; if(dag != NULL) { if(node_config_find_by_ip(prefix) == NULL) { LOG6LBR_6ADDR(INFO, prefix, "Node has been rejected : "); } else { LOG6LBR_6ADDR(DEBUG, prefix, "Node has been accepted : "); allowed = 1; } } else { if(uip_is_addr_mcast(prefix) || uip_is_addr_linklocal(prefix) || uip_ds6_is_my_addr(prefix) || uip_ds6_is_my_aaddr(prefix) || node_config_find_by_ip(prefix)) { allowed = 1; } } #if CETIC_6LBR_NODE_INFO if(dag != NULL && allowed) { //As control traffic is always allowed, set the flag only when it's coming from RPL node_info_clear_flags(prefix, NODE_INFO_REJECTED); } if(!allowed) { node_info_set_flags(prefix, NODE_INFO_REJECTED); } #endif return allowed; }
static PT_THREAD(handle_input(struct httpd_state *s)) { PSOCK_BEGIN(&s->sin); PSOCK_READTO(&s->sin, ISO_space); if(strncmp(s->inputbuf, http_get, 4) == 0) { s->request_type = REQUEST_TYPE_GET; } else if(strncmp(s->inputbuf, http_put, 4) == 0) { s->request_type = REQUEST_TYPE_PUT; } else if(strncmp(s->inputbuf, http_post, 5) == 0) { s->request_type = REQUEST_TYPE_POST; } else if(strncmp(s->inputbuf, http_delete, 7) == 0) { s->request_type = REQUEST_TYPE_DELETE; } else { PSOCK_CLOSE_EXIT(&s->sin); } PSOCK_READTO(&s->sin, ISO_space); if(s->inputbuf[0] != ISO_slash) { PSOCK_CLOSE_EXIT(&s->sin); } s->query = NULL; #if URLCONV s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; urlconv_tofilename(s->filename, &s->query, s->inputbuf, sizeof(s->filename)); if(s->filename[1] == 0) { strncpy(s->filename, http_index_html, sizeof(s->filename)); } #else /* URLCONV */ if(s->inputbuf[1] == ISO_space) { strncpy(s->filename, http_index_html, sizeof(s->filename)); } else { s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; strncpy(s->filename, s->inputbuf, sizeof(s->filename)); } #endif /* URLCONV */ if(s->query) { LOG6LBR_6ADDR(DEBUG, &uip_conn->ripaddr, "Request for '%s?%s' from ", s->filename, s->query); } else { LOG6LBR_6ADDR(DEBUG, &uip_conn->ripaddr, "Request for '%s' from ", s->filename); } s->state = STATE_OUTPUT; while(1) { PSOCK_READTO(&s->sin, ISO_nl); } PSOCK_END(&s->sin); }
static PT_THREAD(handle_output(struct httpd_state *s)) { PT_BEGIN(&s->outputpt); s->script = httpd_cgi(&s->filename[1]); if(!s->script) { httpd_cgi_command_t *cmd = httpd_cgi_command(&s->filename[1]); if(cmd) { s->script = cmd->function(s); } } if(s->script) { if((s->script->flags & HTTPD_CUSTOM_HEADER) == 0) { PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200)); } if((s->script->flags & HTTPD_CUSTOM_TOP) == 0) { PT_WAIT_THREAD(&s->outputpt, generate_top(s)); } PT_WAIT_THREAD(&s->outputpt, s->script->function(s)); if((s->script->flags & HTTPD_CUSTOM_BOTTOM) == 0) { PT_WAIT_THREAD(&s->outputpt, generate_bottom(s)); } #if CONTIKI_TARGET_NATIVE } else if (httpd_is_file(s->filename)){ PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200)); PT_WAIT_THREAD(&s->outputpt, send_file(s)); #endif } else { LOG6LBR_6ADDR(WARN, &uip_conn->ripaddr, "File '%s' not found, from ", s->filename); PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_404)); PT_WAIT_THREAD(&s->outputpt, generate_404(s)); } PSOCK_CLOSE(&s->sout); PT_END(&s->outputpt); }
void cetic_6lbr_set_prefix(uip_ipaddr_t * prefix, unsigned len, uip_ipaddr_t * ipaddr) { #if CETIC_6LBR_SMARTBRIDGE int new_prefix = cetic_dag != NULL && !uip_ipaddr_prefixcmp(&cetic_dag->prefix_info.prefix, prefix, len); if((nvm_data.mode & CETIC_MODE_WAIT_RA_MASK) == 0) { LOG6LBR_DEBUG("Ignoring RA\n"); return; } LOG6LBR_INFO("CETIC_BRIDGE : set_prefix\n"); uip_ipaddr_copy(&wsn_ip_addr, ipaddr); if(cetic_dag != NULL) { rpl_set_prefix(cetic_dag, prefix, len); uip_ipaddr_copy(&wsn_net_prefix, prefix); wsn_net_prefix_len = len; if(new_prefix) { LOG6LBR_6ADDR(INFO, prefix, "Setting DAG prefix : "); rpl_repair_root(RPL_DEFAULT_INSTANCE); } } #if CONTIKI_TARGET_NATIVE cetic_6lbr_save_ip(); #endif #endif }
void node_info_rm(node_info_t *node_info) { if(node_info != NULL) { node_info->isused = 0; LOG6LBR_6ADDR(DEBUG, &node_info->ipaddr, "Removing node "); } }
node_info_t * node_info_add(uip_ipaddr_t * ipaddr) { node_info_t *node = NULL; if(uip_ds6_list_loop ((uip_ds6_element_t *) node_info_table, UIP_DS6_ROUTE_NB, sizeof(node_info_t), ipaddr, 128, (uip_ds6_element_t **) & node) == FREESPACE) { memset(node, 0, sizeof(node_info_t)); node->isused = 1; uip_ipaddr_copy(&(node->ipaddr), ipaddr); node->stats_start = clock_time(); LOG6LBR_6ADDR(DEBUG, ipaddr, "New node created "); } else { LOG6LBR_6ADDR(ERROR, ipaddr, "Not enough memory to create node "); } return node; }
/*---------------------------------------------------------------------------*/ static void httpd_appcall(void *state) { struct httpd_state *s = (struct httpd_state *)state; if(uip_closed() || uip_aborted() || uip_timedout()) { if(s != NULL) { memb_free(&conns, s); } } else if(uip_connected()) { s = (struct httpd_state *)memb_alloc(&conns); if(s == NULL) { uip_abort(); LOG6LBR_6ADDR(DEBUG, &uip_conn->ripaddr, "reset (no memory block)"); return; } tcp_markconn(uip_conn, s); PSOCK_INIT(&s->sin, (uint8_t *) s->inputbuf, sizeof(s->inputbuf) - 1); PSOCK_INIT(&s->sout, (uint8_t *) s->inputbuf, sizeof(s->inputbuf) - 1); PT_INIT(&s->outputpt); s->state = STATE_WAITING; timer_set(&s->timer, CLOCK_SECOND * 10); handle_connection(s); } else if(s != NULL) { if(uip_poll()) { if(timer_expired(&s->timer)) { uip_abort(); memb_free(&conns, s); LOG6LBR_6ADDR(DEBUG, &uip_conn->ripaddr, "reset (timeout)"); } } else { timer_restart(&s->timer); } handle_connection(s); } else { uip_abort(); } }
void send_purge_na(uip_ipaddr_t *prefix) { if ( (nvm_data.mode & CETIC_MODE_SMART_MULTI_BR) == 0 ) { return; } LOG6LBR_6ADDR(INFO, prefix, "Sending purge NA for "); uip_ext_len = 0; UIP_IP_BUF->vtc = 0x60; UIP_IP_BUF->tcflow = 0; UIP_IP_BUF->flow = 0; UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */ UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN; UIP_IP_BUF->proto = UIP_PROTO_ICMP6; UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT; uip_create_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr); uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, prefix); UIP_ICMP_BUF->type = ICMP6_NA; UIP_ICMP_BUF->icode = 0; UIP_ND6_NA_BUF->flagsreserved = UIP_ND6_NA_FLAG_OVERRIDE; memcpy(&UIP_ND6_NA_BUF->tgtipaddr, prefix, sizeof(uip_ipaddr_t)); create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NA_LEN], UIP_ND6_OPT_TLLAO); UIP_ICMP_BUF->icmpchksum = 0; UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN; UIP_STAT(++uip_stat.nd6.sent); PRINTF("Sending Unsolicited NA to "); PRINT6ADDR(&UIP_IP_BUF->destipaddr); PRINTF(" from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF(" with target address "); PRINT6ADDR(&UIP_ND6_NA_BUF->tgtipaddr); PRINTF("\n"); tcpip_ipv6_output(); }
void cetic_6lbr_start_dodag_root(void) { #if CETIC_6LBR_DODAG_ROOT if((nvm_data.rpl_config & CETIC_6LBR_MODE_MANUAL_DODAG) != 0) { //Manual DODAG ID cetic_dag = rpl_set_root(nvm_data.rpl_instance_id, (uip_ipaddr_t*)&nvm_data.rpl_dodag_id); } else { //Automatic DODAG ID if((nvm_data.rpl_config & CETIC_6LBR_MODE_GLOBAL_DODAG) != 0) { #if CETIC_6LBR_SMARTBRIDGE if((nvm_data.mode & CETIC_MODE_WAIT_RA_MASK) == 0) { #endif //DODAGID = global address used ! cetic_dag = rpl_set_root(nvm_data.rpl_instance_id, &wsn_ip_addr); #if CETIC_6LBR_SMARTBRIDGE } else { //Not global IP yet configured cetic_dag = NULL; } #endif } else { //DODAGID = link-local address used ! cetic_dag = rpl_set_root(nvm_data.rpl_instance_id, &wsn_ip_local_addr); } } #if CETIC_6LBR_SMARTBRIDGE if((nvm_data.mode & CETIC_MODE_WAIT_RA_MASK) == 0) { rpl_set_prefix(cetic_dag, &wsn_net_prefix, nvm_data.wsn_net_prefix_len); } #else rpl_set_prefix(cetic_dag, &wsn_net_prefix, nvm_data.wsn_net_prefix_len); #endif if(cetic_dag) { LOG6LBR_6ADDR(INFO, &cetic_dag->dag_id, "Configured as DODAG Root "); } if(!uip_is_addr_unspecified(&wsn_ip_addr)) { uip_ds6_addr_add(&wsn_ip_addr, 0, ((nvm_data.mode & CETIC_MODE_WSN_AUTOCONF) != 0) ? ADDR_AUTOCONF : ADDR_MANUAL); } #endif /* CETIC_6LBR_DODAG_ROOT */ }
/** * Neighbor Advertisement Processing * * we might have to send a pkt that had been buffered while address * resolution was performed (if we support buffering, see UIP_CONF_QUEUE_PKT) * * As per RFC 4861, on link layer that have addresses, TLLAO options MUST be * included when responding to multicast solicitations, SHOULD be included in * response to unicast (here we assume it is for now) * * NA can be received after sending NS for DAD, Address resolution or NUD. Can * be unsolicited as well. * It can trigger update of the state of the neighbor in the neighbor cache, * router in the router list. * If the NS was for DAD, it means DAD failed * */ static void na_input(void) { #if CETIC_6LBR_SMARTBRIDGE uip_ds6_route_t * route; #endif uint8_t is_llchange; uint8_t is_router; uint8_t is_solicited; uint8_t is_override; PRINTF("Received NA from"); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF("to"); PRINT6ADDR(&UIP_IP_BUF->destipaddr); PRINTF("with target address"); PRINT6ADDR((uip_ipaddr_t *) (&UIP_ND6_NA_BUF->tgtipaddr)); PRINTF("\n"); UIP_STAT(++uip_stat.nd6.recv); /* * booleans. the three last one are not 0 or 1 but 0 or 0x80, 0x40, 0x20 * but it works. Be careful though, do not use tests such as is_router == 1 */ is_llchange = 0; is_router = ((UIP_ND6_NA_BUF->flagsreserved & UIP_ND6_NA_FLAG_ROUTER)); is_solicited = ((UIP_ND6_NA_BUF->flagsreserved & UIP_ND6_NA_FLAG_SOLICITED)); is_override = ((UIP_ND6_NA_BUF->flagsreserved & UIP_ND6_NA_FLAG_OVERRIDE)); #if UIP_CONF_IPV6_CHECKS if((UIP_IP_BUF->ttl != UIP_ND6_HOP_LIMIT) || (UIP_ICMP_BUF->icode != 0) || (uip_is_addr_mcast(&UIP_ND6_NA_BUF->tgtipaddr)) || (is_solicited && uip_is_addr_mcast(&UIP_IP_BUF->destipaddr))) { PRINTF("NA received is bad\n"); goto discard; } #endif /*UIP_CONF_IPV6_CHECKS */ /* Options processing: we handle TLLAO, and must ignore others */ nd6_opt_offset = UIP_ND6_NA_LEN; nd6_opt_llao = NULL; while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) { #if UIP_CONF_IPV6_CHECKS if(UIP_ND6_OPT_HDR_BUF->len == 0) { PRINTF("NA received is bad\n"); goto discard; } #endif /*UIP_CONF_IPV6_CHECKS */ switch (UIP_ND6_OPT_HDR_BUF->type) { case UIP_ND6_OPT_TLLAO: nd6_opt_llao = (uint8_t *)UIP_ND6_OPT_HDR_BUF; break; default: PRINTF("ND option not supported in NA\n"); break; } nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3); } #if CETIC_6LBR_SMARTBRIDGE /* Address Advertisement */ if ( (nvm_data.mode & CETIC_MODE_SMART_MULTI_BR) != 0 ) { if (uip_is_addr_mcast(&UIP_IP_BUF->destipaddr) && uip_is_mcast_group_id_all_nodes(&UIP_IP_BUF->destipaddr)) { LOG6LBR_6ADDR(INFO, &UIP_ND6_NA_BUF->tgtipaddr, "Received purge NA for "); #if CETIC_NODE_INFO node_info_rm_by_addr(&UIP_ND6_NA_BUF->tgtipaddr); #endif route = uip_ds6_route_lookup(&UIP_ND6_NA_BUF->tgtipaddr); if (route != NULL ) { uip_ds6_route_rm(route); } goto discard; } } #endif addr = uip_ds6_addr_lookup(&UIP_ND6_NA_BUF->tgtipaddr); /* Message processing, including TLLAO if any */ if(addr != NULL) { #if UIP_ND6_DEF_MAXDADNS > 0 if(addr->state == ADDR_TENTATIVE) { uip_ds6_dad_failed(addr); } #endif /*UIP_ND6_DEF_MAXDADNS > 0 */ PRINTF("NA received is bad\n"); goto discard; } else { uip_lladdr_t *lladdr; nbr = uip_ds6_nbr_lookup(&UIP_ND6_NA_BUF->tgtipaddr); lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); if(nbr == NULL) { goto discard; } if(nd6_opt_llao != 0) { is_llchange = memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], (void *)lladdr, UIP_LLADDR_LEN); } if(nbr->state == NBR_INCOMPLETE) { if(nd6_opt_llao == NULL) { goto discard; } memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); if(is_solicited) { nbr->state = NBR_REACHABLE; nbr->nscount = 0; /* reachable time is stored in ms */ stimer_set(&(nbr->reachable), uip_ds6_if.reachable_time / 1000); } else { nbr->state = NBR_STALE; } nbr->isrouter = is_router; } else { if(!is_override && is_llchange) { if(nbr->state == NBR_REACHABLE) { nbr->state = NBR_STALE; } goto discard; } else { if(is_override || (!is_override && nd6_opt_llao != 0 && !is_llchange) || nd6_opt_llao == 0) { if(nd6_opt_llao != 0) { memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); } if(is_solicited) { nbr->state = NBR_REACHABLE; /* reachable time is stored in ms */ stimer_set(&(nbr->reachable), uip_ds6_if.reachable_time / 1000); } else { if(nd6_opt_llao != 0 && is_llchange) { nbr->state = NBR_STALE; } } } } if(nbr->isrouter && !is_router) { defrt = uip_ds6_defrt_lookup(&UIP_IP_BUF->srcipaddr); if(defrt != NULL) { uip_ds6_defrt_rm(defrt); } } nbr->isrouter = is_router; } } #if UIP_CONF_IPV6_QUEUE_PKT /* The nbr is now reachable, check if we had buffered a pkt for it */ /*if(nbr->queue_buf_len != 0) { uip_len = nbr->queue_buf_len; memcpy(UIP_IP_BUF, nbr->queue_buf, uip_len); nbr->queue_buf_len = 0; return; }*/ if(uip_packetqueue_buflen(&nbr->packethandle) != 0) { uip_len = uip_packetqueue_buflen(&nbr->packethandle); memcpy(UIP_IP_BUF, uip_packetqueue_buf(&nbr->packethandle), uip_len); uip_packetqueue_free(&nbr->packethandle); return; } #endif /*UIP_CONF_IPV6_QUEUE_PKT */ discard: uip_clear_buf(); return; }
/*---------------------------------------------------------------------------*/ void cetic_6lbr_init(void) { uip_ds6_addr_t *local = uip_ds6_get_link_local(-1); uip_ipaddr_copy(&wsn_ip_local_addr, &local->ipaddr); LOG6LBR_6ADDR(INFO, &wsn_ip_local_addr, "Tentative local IPv6 address "); eth_mac64_addr.addr[0] = eth_mac_addr[0]; eth_mac64_addr.addr[1] = eth_mac_addr[1]; eth_mac64_addr.addr[2] = eth_mac_addr[2]; eth_mac64_addr.addr[3] = CETIC_6LBR_ETH_EXT_A; eth_mac64_addr.addr[4] = CETIC_6LBR_ETH_EXT_B; eth_mac64_addr.addr[5] = eth_mac_addr[3]; eth_mac64_addr.addr[6] = eth_mac_addr[4]; eth_mac64_addr.addr[7] = eth_mac_addr[5]; #if CETIC_6LBR_SMARTBRIDGE if((nvm_data.mode & CETIC_MODE_WAIT_RA_MASK) == 0) //Manual configuration { memcpy(wsn_net_prefix.u8, &nvm_data.wsn_net_prefix, sizeof(nvm_data.wsn_net_prefix)); wsn_net_prefix_len = nvm_data.wsn_net_prefix_len; if((nvm_data.mode & CETIC_MODE_WSN_AUTOCONF) != 0) //Address auto configuration { uip_ipaddr_copy(&wsn_ip_addr, &wsn_net_prefix); uip_ds6_set_addr_iid(&wsn_ip_addr, &uip_lladdr); uip_ds6_addr_add(&wsn_ip_addr, 0, ADDR_AUTOCONF); } else { memcpy(wsn_ip_addr.u8, &nvm_data.wsn_ip_addr, sizeof(nvm_data.wsn_ip_addr)); uip_ds6_addr_add(&wsn_ip_addr, 0, ADDR_MANUAL); } LOG6LBR_6ADDR(INFO, &wsn_ip_addr, "Tentative global IPv6 address "); memcpy(eth_dft_router.u8, &nvm_data.eth_dft_router, sizeof(nvm_data.eth_dft_router)); if ( !uip_is_addr_unspecified(ð_dft_router) ) { uip_ds6_defrt_add(ð_dft_router, 0); } uip_ipaddr_t dns; memcpy(dns.u8, &nvm_data.dns_server, sizeof(nvm_data.dns_server)); uip_nameserver_update(&dns, UIP_NAMESERVER_INFINITE_LIFETIME); } else { //End manual configuration uip_create_unspecified(&wsn_net_prefix); wsn_net_prefix_len = 0; uip_create_unspecified(&wsn_ip_addr); } #endif #if CETIC_6LBR_ROUTER //WSN network configuration memcpy(wsn_net_prefix.u8, &nvm_data.wsn_net_prefix, sizeof(nvm_data.wsn_net_prefix)); wsn_net_prefix_len = nvm_data.wsn_net_prefix_len; if((nvm_data.mode & CETIC_MODE_WSN_AUTOCONF) != 0) //Address auto configuration { uip_ipaddr_copy(&wsn_ip_addr, &wsn_net_prefix); uip_ds6_set_addr_iid(&wsn_ip_addr, &uip_lladdr); uip_ds6_addr_add(&wsn_ip_addr, 0, ADDR_AUTOCONF); } else { memcpy(wsn_ip_addr.u8, &nvm_data.wsn_ip_addr, sizeof(nvm_data.wsn_ip_addr)); uip_ds6_addr_add(&wsn_ip_addr, 0, ADDR_MANUAL); } LOG6LBR_6ADDR(INFO, &wsn_ip_addr, "Tentative global IPv6 address (WSN) "); uip_ipaddr_t dns; memcpy(dns.u8, &nvm_data.dns_server, sizeof(nvm_data.dns_server)); uip_nameserver_update(&dns, UIP_NAMESERVER_INFINITE_LIFETIME); //Ethernet network configuration memcpy(eth_net_prefix.u8, &nvm_data.eth_net_prefix, sizeof(nvm_data.eth_net_prefix)); memcpy(eth_dft_router.u8, &nvm_data.eth_dft_router, sizeof(nvm_data.eth_dft_router)); if ( !uip_is_addr_unspecified(ð_dft_router) ) { uip_ds6_defrt_add(ð_dft_router, 0); } if((nvm_data.mode & CETIC_MODE_ETH_AUTOCONF) != 0) //Address auto configuration { uip_ipaddr_copy(ð_ip_addr, ð_net_prefix); uip_ds6_set_addr_iid(ð_ip_addr, ð_mac64_addr); uip_ds6_addr_add(ð_ip_addr, 0, ADDR_AUTOCONF); } else { memcpy(eth_ip_addr.u8, &nvm_data.eth_ip_addr, sizeof(nvm_data.eth_ip_addr)); uip_ds6_addr_add(ð_ip_addr, 0, ADDR_MANUAL); } LOG6LBR_6ADDR(INFO, ð_ip_addr, "Tentative global IPv6 address (ETH) "); //Ugly hack : in order to set WSN local address as the default address //We must add it afterwards as uip_ds6_addr_add allocates addr from the end of the list uip_ds6_addr_rm(local); uip_create_linklocal_prefix(ð_ip_local_addr); uip_ds6_set_addr_iid(ð_ip_local_addr, ð_mac64_addr); uip_ds6_addr_add(ð_ip_local_addr, 0, ADDR_AUTOCONF); uip_ds6_addr_add(&wsn_ip_local_addr, 0, ADDR_AUTOCONF); //Prefix and RA configuration #if CETIC_6LBR_WITH_RPL uint8_t publish = (nvm_data.ra_prefix_flags & CETIC_6LBR_MODE_SEND_PIO) != 0; uip_ds6_prefix_add(ð_net_prefix, nvm_data.eth_net_prefix_len, publish, nvm_data.ra_prefix_flags, nvm_data.ra_prefix_vtime, nvm_data.ra_prefix_ptime); #else uip_ds6_prefix_add(ð_net_prefix, nvm_data.eth_net_prefix_len, 0, 0, 0, 0); uint8_t publish = (nvm_data.ra_prefix_flags & CETIC_6LBR_MODE_SEND_PIO) != 0; uip_ds6_prefix_add(&wsn_net_prefix, nvm_data.wsn_net_prefix_len, publish, nvm_data.ra_prefix_flags, nvm_data.ra_prefix_vtime, nvm_data.ra_prefix_ptime); #endif #if CETIC_6LBR_WITH_RPL if ((nvm_data.ra_rio_flags & CETIC_6LBR_MODE_SEND_RIO) != 0 ) { uip_ds6_route_info_add(&wsn_net_prefix, nvm_data.wsn_net_prefix_len, nvm_data.ra_rio_flags, nvm_data.ra_rio_lifetime); } #endif if ((nvm_data.mode & CETIC_MODE_ROUTER_RA_DAEMON) != 0 ) { LOG6LBR_INFO("RA Daemon enabled\n"); } else { LOG6LBR_INFO("RA Daemon disabled\n"); } #endif }
void cetic_6lbr_init(void) { uip_ds6_addr_t *local = uip_ds6_get_link_local(-1); uip_ipaddr_copy(&wsn_ip_local_addr, &local->ipaddr); LOG6LBR_6ADDR(INFO, &wsn_ip_local_addr, "Tentative local IPv6 address "); #if CETIC_6LBR_SMARTBRIDGE if((nvm_data.mode & CETIC_MODE_WAIT_RA_MASK) == 0) //Manual configuration { memcpy(wsn_net_prefix.u8, &nvm_data.wsn_net_prefix, sizeof(nvm_data.wsn_net_prefix)); if((nvm_data.mode & CETIC_MODE_WSN_AUTOCONF) != 0) //Address auto configuration { uip_ipaddr_copy(&wsn_ip_addr, &wsn_net_prefix); uip_ds6_set_addr_iid(&wsn_ip_addr, &uip_lladdr); uip_ds6_addr_add(&wsn_ip_addr, 0, ADDR_AUTOCONF); } else { memcpy(wsn_ip_addr.u8, &nvm_data.wsn_ip_addr, sizeof(nvm_data.wsn_ip_addr)); uip_ds6_addr_add(&wsn_ip_addr, 0, ADDR_MANUAL); } LOG6LBR_6ADDR(INFO, &wsn_ip_addr, "Tentative global IPv6 address "); memcpy(eth_dft_router.u8, &nvm_data.eth_dft_router, sizeof(nvm_data.eth_dft_router)); if ( !uip_is_addr_unspecified(ð_dft_router) ) { uip_ds6_defrt_add(ð_dft_router, 0); } } //End manual configuration #endif #if CETIC_6LBR_ROUTER //WSN network configuration memcpy(wsn_net_prefix.u8, &nvm_data.wsn_net_prefix, sizeof(nvm_data.wsn_net_prefix)); wsn_net_prefix_len = nvm_data.wsn_net_prefix_len; if((nvm_data.mode & CETIC_MODE_WSN_AUTOCONF) != 0) //Address auto configuration { uip_ipaddr_copy(&wsn_ip_addr, &wsn_net_prefix); uip_ds6_set_addr_iid(&wsn_ip_addr, &uip_lladdr); uip_ds6_addr_add(&wsn_ip_addr, 0, ADDR_AUTOCONF); } else { memcpy(wsn_ip_addr.u8, &nvm_data.wsn_ip_addr, sizeof(nvm_data.wsn_ip_addr)); uip_ds6_addr_add(&wsn_ip_addr, 0, ADDR_MANUAL); } LOG6LBR_6ADDR(INFO, &wsn_ip_addr, "Tentative global IPv6 address (WSN) "); //Ethernet network configuration memcpy(eth_net_prefix.u8, &nvm_data.eth_net_prefix, sizeof(nvm_data.eth_net_prefix)); memcpy(eth_dft_router.u8, &nvm_data.eth_dft_router, sizeof(nvm_data.eth_dft_router)); if ( !uip_is_addr_unspecified(ð_dft_router) ) { uip_ds6_defrt_add(ð_dft_router, 0); } eth_mac64_addr.addr[0] = eth_mac_addr[0]; eth_mac64_addr.addr[1] = eth_mac_addr[1]; eth_mac64_addr.addr[2] = eth_mac_addr[2]; eth_mac64_addr.addr[3] = CETIC_6LBR_ETH_EXT_A; eth_mac64_addr.addr[4] = CETIC_6LBR_ETH_EXT_B; eth_mac64_addr.addr[5] = eth_mac_addr[3]; eth_mac64_addr.addr[6] = eth_mac_addr[4]; eth_mac64_addr.addr[7] = eth_mac_addr[5]; if((nvm_data.mode & CETIC_MODE_ETH_AUTOCONF) != 0) //Address auto configuration { uip_ipaddr_copy(ð_ip_addr, ð_net_prefix); uip_ds6_set_addr_iid(ð_ip_addr, ð_mac64_addr); uip_ds6_addr_add(ð_ip_addr, 0, ADDR_AUTOCONF); } else { memcpy(eth_ip_addr.u8, &nvm_data.eth_ip_addr, sizeof(nvm_data.eth_ip_addr)); uip_ds6_addr_add(ð_ip_addr, 0, ADDR_MANUAL); } LOG6LBR_6ADDR(INFO, ð_ip_addr, "Tentative global IPv6 address (ETH) "); //Ugly hack : in order to set WSN local address as the default address //We must add it afterwards as uip_ds6_addr_add allocates addr from the end of the list uip_ds6_addr_rm(local); uip_create_linklocal_prefix(ð_ip_local_addr); uip_ds6_set_addr_iid(ð_ip_local_addr, ð_mac64_addr); uip_ds6_addr_add(ð_ip_local_addr, 0, ADDR_AUTOCONF); uip_ds6_addr_add(&wsn_ip_local_addr, 0, ADDR_AUTOCONF); //Prefix and RA configuration #if UIP_CONF_IPV6_RPL uint8_t publish = (nvm_data.ra_prefix_flags & CETIC_6LBR_MODE_SEND_PIO) != 0; uip_ds6_prefix_add(ð_net_prefix, nvm_data.eth_net_prefix_len, publish, nvm_data.ra_prefix_flags, nvm_data.ra_prefix_vtime, nvm_data.ra_prefix_ptime); #else uip_ds6_prefix_add(ð_net_prefix, nvm_data.eth_net_prefix_len, 0, 0, 0, 0); uint8_t publish = (nvm_data.ra_prefix_flags & CETIC_6LBR_MODE_SEND_PIO) != 0; uip_ds6_prefix_add(&wsn_net_prefix, nvm_data.wsn_net_prefix_len, publish, nvm_data.ra_prefix_flags, nvm_data.ra_prefix_vtime, nvm_data.ra_prefix_ptime); #endif #if UIP_CONF_IPV6_RPL if ((nvm_data.ra_rio_flags & CETIC_6LBR_MODE_SEND_RIO) != 0 ) { uip_ds6_route_info_add(&wsn_net_prefix, nvm_data.wsn_net_prefix_len, nvm_data.ra_rio_flags, nvm_data.ra_rio_lifetime); } #endif #endif #if UIP_CONF_IPV6_RPL && CETIC_6LBR_DODAG_ROOT //DODAGID = link-local address used ! cetic_dag = rpl_set_root(nvm_data.rpl_instance_id, &wsn_ip_local_addr); #if CETIC_6LBR_SMARTBRIDGE if((nvm_data.mode & CETIC_MODE_WAIT_RA_MASK) == 0) { rpl_set_prefix(cetic_dag, &wsn_net_prefix, nvm_data.wsn_net_prefix_len); } #else rpl_set_prefix(cetic_dag, &wsn_net_prefix, nvm_data.wsn_net_prefix_len); #endif LOG6LBR_INFO("Configured as DODAG Root\n"); #endif #if CETIC_6LBR_TRANSPARENTBRIDGE #if CETIC_6LBR_LEARN_RPL_MAC LOG6LBR_INFO("Starting as RPL Relay\n"); #else LOG6LBR_INFO("Starting as Full TRANSPARENT-BRIDGE\n"); #endif #elif CETIC_6LBR_SMARTBRIDGE LOG6LBR_INFO("Starting as SMART-BRIDGE\n"); #elif CETIC_6LBR_ROUTER #if UIP_CONF_IPV6_RPL LOG6LBR_INFO("Starting as RPL ROUTER\n"); #else LOG6LBR_INFO("Starting as NDP ROUTER\n"); #endif #elif CETIC_6LBR_6LR LOG6LBR_INFO("Starting as 6LR\n"); #else LOG6LBR_INFO("Starting in UNKNOWN mode\n"); #endif #if CONTIKI_TARGET_NATIVE if (ip_config_file_name) { char str[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, (struct sockaddr_in6 *)ð_ip_addr, str, INET6_ADDRSTRLEN); FILE *ip_config_file = fopen(ip_config_file_name, "w"); fprintf(ip_config_file, "%s\n", str); fclose(ip_config_file); } #endif }