diff --git a/Makefile b/Makefile index d6744bed3c..cd5bd421c3 100644 --- a/Makefile +++ b/Makefile @@ -14,3 +14,4 @@ clean: doc: make -BC doc/doxygen + diff --git a/Makefile.dep b/Makefile.dep index b3f0f1ca11..601a08619d 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -39,4 +39,7 @@ ifneq (,$(findstring sixlowpan,$(USEMODULE))) ifeq (,$(findstring ieee802154,$(USEMODULE))) USEMODULE += ieee802154 endif + ifeq (,$(findstring net_help,$(USEMODULE))) + USEMODULE += net_help + endif endif diff --git a/sys/net/destiny/Makefile b/sys/net/destiny/Makefile index 7dce69248e..7827885383 100644 --- a/sys/net/destiny/Makefile +++ b/sys/net/destiny/Makefile @@ -1,4 +1,4 @@ MODULE:=$(shell basename $(CURDIR)) -INCLUDES = -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/sys/net +INCLUDES = -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/sys/net/destiny -I$(RIOTBASE)/sys/net/sixlowpan/include -I$(RIOTBASE)/sys/net/net_help/ include $(RIOTBASE)/Makefile.base diff --git a/sys/net/destiny/destiny.c b/sys/net/destiny/destiny.c index d23efee8f5..d5cfd44c0c 100644 --- a/sys/net/destiny/destiny.c +++ b/sys/net/destiny/destiny.c @@ -40,7 +40,7 @@ void init_transport_layer(void) int udp_thread_pid = thread_create(udp_stack_buffer, UDP_STACK_SIZE, PRIORITY_MAIN, CREATE_STACKTEST, udp_packet_handler,"udp_packet_handler"); - set_udp_packet_handler_pid(udp_thread_pid); + ipv6_register_next_header_handler(IPV6_PROTO_NUM_UDP, udp_thread_pid); /* TCP */ timex_t now; @@ -55,7 +55,7 @@ void init_transport_layer(void) int tcp_thread_pid = thread_create(tcp_stack_buffer, TCP_STACK_SIZE, PRIORITY_MAIN, CREATE_STACKTEST, tcp_packet_handler, "tcp_packet_handler"); - set_tcp_packet_handler_pid(tcp_thread_pid); + ipv6_register_next_header_handler(IPV6_PROTO_NUM_TCP, tcp_thread_pid); thread_create(tcp_timer_stack, TCP_TIMER_STACKSIZE, PRIORITY_MAIN + 1, CREATE_STACKTEST, tcp_general_timer, "tcp_general_timer"); diff --git a/sys/net/destiny/in.h b/sys/net/destiny/in.h index 0b3cf19d0d..0332da0efc 100644 --- a/sys/net/destiny/in.h +++ b/sys/net/destiny/in.h @@ -13,7 +13,8 @@ */ /* - * Protocols (RFC 1700) + * Protocols (RFC 1700) TODO: may be deleted due to some double definition + * in sys/net/sixlowpan/include/sixlowpan/ip.h */ #define IPPROTO_IP (0) /* dummy for IP */ #define IPPROTO_HOPOPTS (0) /* IP6 hop-by-hop options */ diff --git a/sys/net/destiny/socket.c b/sys/net/destiny/socket.c index 7bc674706b..6de0129e97 100644 --- a/sys/net/destiny/socket.c +++ b/sys/net/destiny/socket.c @@ -21,6 +21,7 @@ #include #include #include +#include "ipv6.h" #include "udp.h" #include "tcp.h" #include "socket.h" @@ -99,12 +100,13 @@ void print_tcp_cb(tcp_cb_t *cb) void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_t *tcp_socket) { + char addr_str[IPV6_MAX_ADDR_STR_LEN]; printf("--- %s TCP packet: ---\n", (in_or_out == INC_PACKET ? "Incoming" : "Outgoing")); - printf("IPv6 Source:"); - ipv6_print_addr(&ipv6_header->srcaddr); - printf("IPv6 Dest:"); - ipv6_print_addr(&ipv6_header->destaddr); + printf("IPv6 Source: %s\n", + ipv6_addr_to_str(addr_str, &ipv6_header->srcaddr)); + printf("IPv6 Dest: %s\n", + ipv6_addr_to_str(addr_str, &ipv6_header->destaddr)); printf("TCP Length: %x\n", ipv6_header->length - TCP_HDR_LEN); printf("Source Port: %x, Dest. Port: %x\n", NTOHS(tcp_header->src_port), NTOHS(tcp_header->dst_port)); @@ -123,12 +125,17 @@ void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header, void print_socket(socket_t *current_socket) { + char addr_str[IPV6_MAX_ADDR_STR_LEN]; printf("Domain: %i, Type: %i, Protocol: %i \n", current_socket->domain, current_socket->type, current_socket->protocol); - ipv6_print_addr(¤t_socket->local_address.sin6_addr); - ipv6_print_addr(¤t_socket->foreign_address.sin6_addr); + printf("Local address: %s\n", + ipv6_addr_to_str(addr_str, + ¤t_socket->local_address.sin6_addr)); + printf("Foreign address: %s\n", + ipv6_addr_to_str(addr_str, + ¤t_socket->foreign_address.sin6_addr)); printf("Local Port: %u, Foreign Port: %u\n", NTOHS(current_socket->local_address.sin6_port), NTOHS(current_socket->foreign_address.sin6_port)); @@ -293,11 +300,11 @@ socket_internal_t *get_udp_socket(ipv6_hdr_t *ipv6_header, udp_hdr_t *udp_header bool is_four_touple(socket_internal_t *current_socket, ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header) { - return ((ipv6_get_addr_match(¤t_socket->socket_values.local_address.sin6_addr, - &ipv6_header->destaddr) == 128) && + return (ipv6_addr_is_equal(¤t_socket->socket_values.local_address.sin6_addr, + &ipv6_header->destaddr) && (current_socket->socket_values.local_address.sin6_port == tcp_header->dst_port) && - (ipv6_get_addr_match(¤t_socket->socket_values.foreign_address.sin6_addr, - &ipv6_header->srcaddr) == 128) && + ipv6_addr_is_equal(¤t_socket->socket_values.foreign_address.sin6_addr, + &ipv6_header->srcaddr) && (current_socket->socket_values.foreign_address.sin6_port == tcp_header->src_port)); } @@ -469,15 +476,15 @@ int send_tcp(socket_internal_t *current_socket, tcp_hdr_t *current_tcp_packet, return -1; } - sixlowpan_send(¤t_tcp_socket->foreign_address.sin6_addr, - (uint8_t *)(current_tcp_packet), compressed_size, - IPPROTO_TCP); + ipv6_sendto(¤t_tcp_socket->foreign_address.sin6_addr, + IPPROTO_TCP, (uint8_t *)(current_tcp_packet), + compressed_size); return 1; #else switch_tcp_packet_byte_order(current_tcp_packet); - sixlowpan_send(¤t_tcp_socket->foreign_address.sin6_addr, - (uint8_t *)(current_tcp_packet), - header_length * 4 + payload_length, IPPROTO_TCP); + ipv6_sendto(¤t_tcp_socket->foreign_address.sin6_addr, + IPPROTO_TCP, (uint8_t *)(current_tcp_packet), + header_length * 4 + payload_length); return 1; #endif } @@ -515,7 +522,7 @@ int connect(int socket, sockaddr6_t *addr, uint32_t addrlen) current_int_tcp_socket->recv_pid = thread_getpid(); /* Local address information */ - ipv6_get_saddr(&src_addr, &addr->sin6_addr); + ipv6_iface_get_best_src_addr(&src_addr, &addr->sin6_addr); set_socket_address(¤t_tcp_socket->local_address, PF_INET6, HTONS(get_free_source_port(IPPROTO_TCP)), 0, &src_addr); @@ -978,7 +985,7 @@ int32_t sendto(int s, const void *msg, uint32_t len, int flags, uint8_t *payload = &send_buffer[IPV6_HDR_LEN + UDP_HDR_LEN]; memcpy(&(temp_ipv6_header->destaddr), &to->sin6_addr, 16); - ipv6_get_saddr(&(temp_ipv6_header->srcaddr), &(temp_ipv6_header->destaddr)); + ipv6_iface_get_best_src_addr(&(temp_ipv6_header->srcaddr), &(temp_ipv6_header->destaddr)); current_udp_packet->src_port = get_free_source_port(IPPROTO_UDP); current_udp_packet->dst_port = to->sin6_port; @@ -991,8 +998,9 @@ int32_t sendto(int s, const void *msg, uint32_t len, int flags, current_udp_packet->checksum = ~udp_csum(temp_ipv6_header, current_udp_packet); - sixlowpan_send(&to->sin6_addr, (uint8_t *)(current_udp_packet), - current_udp_packet->length, IPPROTO_UDP); + ipv6_sendto(&to->sin6_addr, IPPROTO_UDP, + (uint8_t *)(current_udp_packet), + current_udp_packet->length); return current_udp_packet->length; } else { diff --git a/sys/net/destiny/socket.h b/sys/net/destiny/socket.h index 5fb61ab541..8fee5a3b0d 100644 --- a/sys/net/destiny/socket.h +++ b/sys/net/destiny/socket.h @@ -20,10 +20,11 @@ #define SOCKET_H_ #include +#include "ipv6.h" #include "tcp.h" #include "udp.h" #include "in.h" -#include "../sixlowpan/sixlowip.h" +#include "ipv6.h" /* * POSIX compatibility diff --git a/sys/net/destiny/tcp.c b/sys/net/destiny/tcp.c index 4145e4f1cb..ca69f8e7ba 100644 --- a/sys/net/destiny/tcp.c +++ b/sys/net/destiny/tcp.c @@ -30,7 +30,7 @@ #include "socket.h" #include "../net_help/net_help.h" #include "../net_help/msg_help.h" -#include "../sixlowpan/sixlowpan.h" +#include "sixlowpan.h" void printTCPHeader(tcp_hdr_t *tcp_header) { diff --git a/sys/net/destiny/tcp.h b/sys/net/destiny/tcp.h index 6b58a29f72..3042ba692d 100644 --- a/sys/net/destiny/tcp.h +++ b/sys/net/destiny/tcp.h @@ -78,7 +78,7 @@ enum tcp_codes { #define TCP_STACK_SIZE 1024 -#include "../sixlowpan/sixlowip.h" +#include "ipv6.h" typedef struct __attribute__((packed)) tcp_mms_o_t { uint8_t kind; diff --git a/sys/net/destiny/tcp_hc.c b/sys/net/destiny/tcp_hc.c index 707b7af549..0d693ed662 100644 --- a/sys/net/destiny/tcp_hc.c +++ b/sys/net/destiny/tcp_hc.c @@ -23,7 +23,7 @@ #include "tcp_hc.h" #include "socket.h" #include "tcp.h" -#include "../sixlowpan/sixlowip.h" +#include "ipv6.h" #include "../net_help/net_help.h" #ifdef TCP_HC @@ -37,10 +37,10 @@ socket_internal_t *get_tcp_socket_by_context(ipv6_hdr_t *current_ipv6_header, temp_socket = getSocket(i); if ((temp_socket != NULL) && - (ipv6_get_addr_match(&temp_socket->socket_values.foreign_address.sin6_addr, - ¤t_ipv6_header->srcaddr) == 128) && - (ipv6_get_addr_match(&temp_socket->socket_values.local_address.sin6_addr, - ¤t_ipv6_header->destaddr) == 128) && + ipv6_addr_is_equal(&temp_socket->socket_values.foreign_address.sin6_addr, + ¤t_ipv6_header->srcaddr) && + ipv6_addr_is_equal(&temp_socket->socket_values.local_address.sin6_addr, + ¤t_ipv6_header->destaddr) && (temp_socket->socket_values.tcp_control.tcp_context.context_id == current_context)) { return temp_socket; diff --git a/sys/net/destiny/tcp_hc.h b/sys/net/destiny/tcp_hc.h index 9482d3a45b..f6b1731baa 100644 --- a/sys/net/destiny/tcp_hc.h +++ b/sys/net/destiny/tcp_hc.h @@ -9,7 +9,7 @@ #define TCP_HC_H_ #include "tcp.h" -#include "../sixlowpan/sixlowip.h" +#include "sixlowpan.h" #include "socket.h" #ifdef TCP_HC diff --git a/sys/net/destiny/tcp_timer.c b/sys/net/destiny/tcp_timer.c index c3861c8c2b..098a9f09a8 100644 --- a/sys/net/destiny/tcp_timer.c +++ b/sys/net/destiny/tcp_timer.c @@ -26,8 +26,8 @@ #include "thread.h" #include "destiny.h" #include "socket.h" -#include "net_help/msg_help.h" -#include "../sixlowpan/sixlowpan.h" +#include "../net_help/msg_help.h" +#include "sixlowpan.h" void handle_synchro_timeout(socket_internal_t *current_socket) { diff --git a/sys/net/destiny/udp.c b/sys/net/destiny/udp.c index f1c2618fdd..6ba5f868a2 100644 --- a/sys/net/destiny/udp.c +++ b/sys/net/destiny/udp.c @@ -22,8 +22,8 @@ #include "udp.h" #include "msg.h" -#include "../sixlowpan/sixlowip.h" -#include "../sixlowpan/sixlowpan.h" +#include "ipv6.h" +#include "sixlowpan.h" #include "socket.h" #include "in.h" #include "../net_help/net_help.h" diff --git a/sys/net/destiny/udp.h b/sys/net/destiny/udp.h index 23efcade94..8767c0d667 100644 --- a/sys/net/destiny/udp.h +++ b/sys/net/destiny/udp.h @@ -29,7 +29,7 @@ #define UDP_STACK_SIZE 512 -#include "../sixlowpan/sixlowip.h" +#include "ipv6.h" typedef struct __attribute__((packed)) udp_h_t { uint16_t src_port; diff --git a/sys/net/net_help/Makefile b/sys/net/net_help/Makefile index 93dfabd905..633d89730f 100644 --- a/sys/net/net_help/Makefile +++ b/sys/net/net_help/Makefile @@ -1,4 +1,4 @@ MODULE:=$(shell basename $(CURDIR)) -INCLUDES = -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include +INCLUDES = -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/sys/net/sixlowpan/include include $(RIOTBASE)/Makefile.base diff --git a/sys/net/rpl/etx_beaconing.c b/sys/net/rpl/etx_beaconing.c index b2f90f17ba..5e1c6f6802 100644 --- a/sys/net/rpl/etx_beaconing.c +++ b/sys/net/rpl/etx_beaconing.c @@ -15,11 +15,11 @@ #include #include -#include "sixlowpan/sixlowmac.h" +#include "sixlowpan.h" #include "ieee802154/ieee802154_frame.h" //prototytpes -static uint8_t etx_count_packet_tx(etx_neighbor_t * candidate); +static uint8_t etx_count_packet_tx(etx_neighbor_t *candidate); static void etx_set_packets_received(void); static bool etx_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2); @@ -89,37 +89,42 @@ transceiver_command_t tcmd; msg_t mesg; //RPL-address -static ipv6_addr_t * own_address; +static ipv6_addr_t *own_address; -static etx_probe_t * etx_get_send_buf(void) { +static etx_probe_t *etx_get_send_buf(void) +{ return ((etx_probe_t *) &(etx_send_buf[0])); } -static etx_probe_t * etx_get_rec_buf(void) { +static etx_probe_t *etx_get_rec_buf(void) +{ return ((etx_probe_t *) &(etx_rec_buf[0])); } -void show_candidates(void) { - etx_neighbor_t * candidate; +void show_candidates(void) +{ + etx_neighbor_t *candidate; etx_neighbor_t *end; for (candidate = &candidates[0], end = candidates - + ETX_MAX_CANDIDATE_NEIGHBORS; candidate < end; - candidate++) { + + ETX_MAX_CANDIDATE_NEIGHBORS; candidate < end; + candidate++) { if (candidate->used == 0) { break; } + printf("Candidates Addr:%d\n" - "\t cur_etx:%f\n" - "\t packets_rx:%d\n" - "\t packets_tx:%d\n" - "\t used:%d\n", candidate->addr.uint8[ETX_IPV6_LAST_BYTE], - candidate->cur_etx, candidate->packets_rx, - etx_count_packet_tx(candidate), - candidate->used); + "\t cur_etx:%f\n" + "\t packets_rx:%d\n" + "\t packets_tx:%d\n" + "\t used:%d\n", candidate->addr.uint8[ETX_IPV6_LAST_BYTE], + candidate->cur_etx, candidate->packets_rx, + etx_count_packet_tx(candidate), + candidate->used); } } -void etx_init_beaconing(ipv6_addr_t * address) { +void etx_init_beaconing(ipv6_addr_t *address) +{ mutex_init(&etx_mutex); own_address = address; //set code @@ -127,29 +132,30 @@ void etx_init_beaconing(ipv6_addr_t * address) { etx_send_buf[0] = ETX_PKT_OPTVAL; etx_beacon_pid = thread_create(etx_beacon_buf, ETX_BEACON_STACKSIZE, - PRIORITY_MAIN - 1, CREATE_STACKTEST, - etx_beacon, "etx_beacon"); + PRIORITY_MAIN - 1, CREATE_STACKTEST, + etx_beacon, "etx_beacon"); etx_radio_pid = thread_create(etx_radio_buf, ETX_RADIO_STACKSIZE, - PRIORITY_MAIN - 1, CREATE_STACKTEST, - etx_radio, "etx_radio"); + PRIORITY_MAIN - 1, CREATE_STACKTEST, + etx_radio, "etx_radio"); etx_clock_pid = thread_create(etx_clock_buf, ETX_CLOCK_STACKSIZE, - PRIORITY_MAIN - 1, CREATE_STACKTEST, - etx_clock, "etx_clock"); + PRIORITY_MAIN - 1, CREATE_STACKTEST, + etx_clock, "etx_clock"); //register at transceiver transceiver_register(TRANSCEIVER_CC1100, etx_radio_pid); puts("...[DONE]"); } -void etx_beacon(void) { +void etx_beacon(void) +{ /* * Sends a message every ETX_INTERVAL +/- a jitter-value (default is 10%) . * A correcting variable is needed to stay at a base interval of * ETX_INTERVAL between the wakeups. It takes the old jittervalue in account * and modifies the time to wait accordingly. */ - etx_probe_t * packet = etx_get_send_buf(); + etx_probe_t *packet = etx_get_send_buf(); uint8_t p_length = 0; /* @@ -165,47 +171,55 @@ void etx_beacon(void) { mutex_lock(&etx_mutex); //Build etx packet p_length = 0; + for (uint8_t i = 0; i < ETX_BEST_CANDIDATES; i++) { if (candidates[i].used != 0) { packet->data[i * ETX_TUPLE_SIZE] = - candidates[i].addr.uint8[ETX_IPV6_LAST_BYTE]; + candidates[i].addr.uint8[ETX_IPV6_LAST_BYTE]; packet->data[i * ETX_TUPLE_SIZE + ETX_PKT_REC_OFFSET] = - etx_count_packet_tx(&candidates[i]); + etx_count_packet_tx(&candidates[i]); p_length = p_length + ETX_PKT_HDR_LEN; } } + packet->length = p_length; send_ieee802154_frame(&empty_addr, &etx_send_buf[0], - ETX_DATA_MAXLEN+ETX_PKT_HDR_LEN, 1); + ETX_DATA_MAXLEN + ETX_PKT_HDR_LEN, 1); DEBUG("sent beacon!\n"); etx_set_packets_received(); cur_round++; + if (cur_round == ETX_WINDOW) { if (reached_window != 1) { //first round is through reached_window = 1; } + cur_round = 0; } + mutex_unlock(&etx_mutex); } } -etx_neighbor_t * etx_find_candidate(ipv6_addr_t * address) { +etx_neighbor_t *etx_find_candidate(ipv6_addr_t *address) +{ /* * find the candidate with address address and returns it, or returns NULL * if no candidate having this address was found. */ for (uint8_t i = 0; i < ETX_MAX_CANDIDATE_NEIGHBORS; i++) { if (candidates[i].used - && (etx_equal_id(&candidates[i].addr, address))) { + && (etx_equal_id(&candidates[i].addr, address))) { return &candidates[i]; } } + return NULL ; } -void etx_clock(void) { +void etx_clock(void) +{ /* * Manages the etx_beacon thread to wake up every full second +- jitter */ @@ -217,7 +231,7 @@ void etx_clock(void) { * That is why they are multiplied by 1000 when used for hwtimer_wait. */ uint8_t jittercorrection = ETX_DEF_JIT_CORRECT; - uint8_t jitter = (uint8_t) (rand() % ETX_JITTER_MOD); + uint8_t jitter = (uint8_t)(rand() % ETX_JITTER_MOD); while (true) { thread_wakeup(etx_beacon_pid); @@ -227,32 +241,37 @@ void etx_clock(void) { * for now. */ vtimer_usleep( - ((ETX_INTERVAL - ETX_MAX_JITTER)*MS)+ jittercorrection*MS + jitter*MS - ETX_CLOCK_ADJUST); + ((ETX_INTERVAL - ETX_MAX_JITTER)*MS) + jittercorrection * MS + jitter * MS - ETX_CLOCK_ADJUST); //hwtimer_wait( // HWTIMER_TICKS(((ETX_INTERVAL - ETX_MAX_JITTER)*MS) + jittercorrection*MS + jitter*MS - ETX_CLOCK_ADJUST)); jittercorrection = (ETX_MAX_JITTER) - jitter; - jitter = (uint8_t) (rand() % ETX_JITTER_MOD); + jitter = (uint8_t)(rand() % ETX_JITTER_MOD); } } -double etx_get_metric(ipv6_addr_t * address) { - etx_neighbor_t * candidate = etx_find_candidate(address); - if (candidate != NULL ) { +double etx_get_metric(ipv6_addr_t *address) +{ + etx_neighbor_t *candidate = etx_find_candidate(address); + + if (candidate != NULL) { if (etx_count_packet_tx(candidate) > 0) { //this means the current etx_value is not outdated return candidate->cur_etx; - } else { + } + else { //The last time I received a packet is too long ago to give a //good estimate of the etx value return 0; } } + return 0; } -etx_neighbor_t * etx_add_candidate(ipv6_addr_t * address) { +etx_neighbor_t *etx_add_candidate(ipv6_addr_t *address) +{ DEBUG("add candidate\n"); /* * Pre-Condition: etx_add_candidate should only be called when the @@ -275,16 +294,17 @@ etx_neighbor_t * etx_add_candidate(ipv6_addr_t * address) { * Returns the pointer to the candidate if it was added, or a NULL-pointer * otherwise. */ - etx_neighbor_t * candidate; - etx_neighbor_t * end; + etx_neighbor_t *candidate; + etx_neighbor_t *end; for (candidate = &candidates[0], end = candidates - + ETX_MAX_CANDIDATE_NEIGHBORS; candidate < end; - candidate++) { + + ETX_MAX_CANDIDATE_NEIGHBORS; candidate < end; + candidate++) { if (candidate->used) { //skip continue; - } else { + } + else { //We still have a free place add the new candidate memset(candidate, 0, sizeof(*candidate)); candidate->addr = *address; @@ -294,27 +314,31 @@ etx_neighbor_t * etx_add_candidate(ipv6_addr_t * address) { return candidate; } } + return NULL ; } -void etx_handle_beacon(ipv6_addr_t * candidate_address) { +void etx_handle_beacon(ipv6_addr_t *candidate_address) +{ /* * Handle the ETX probe that has been received and update all infos. * If the candidate address is unknown, try to add it to my struct. */ DEBUG( - "ETX beacon package received with following values:\n" - "\tPackage Option:%x\n" - "\t Data Length:%u\n" - "\tSource Address:%d\n\n", etx_rec_buf[ETX_PKT_OPT], etx_rec_buf[ETX_PKT_LEN], - candidate_address->uint8[ETX_IPV6_LAST_BYTE]); + "ETX beacon package received with following values:\n" + "\tPackage Option:%x\n" + "\t Data Length:%u\n" + "\tSource Address:%d\n\n", etx_rec_buf[ETX_PKT_OPT], etx_rec_buf[ETX_PKT_LEN], + candidate_address->uint8[ETX_IPV6_LAST_BYTE]); - etx_neighbor_t* candidate = etx_find_candidate(candidate_address); - if (candidate == NULL ) { + etx_neighbor_t *candidate = etx_find_candidate(candidate_address); + + if (candidate == NULL) { //Candidate was not found in my list, I should add it candidate = etx_add_candidate(candidate_address); - if (candidate == NULL ) { + + if (candidate == NULL) { puts("[ERROR] Candidate could not get added"); puts("Increase the constant ETX_MAX_CANDIDATE_NEIHGBORS"); return; @@ -327,18 +351,18 @@ void etx_handle_beacon(ipv6_addr_t * candidate_address) { // If i find my address in this probe, update the packet_rx value for // this candidate. - etx_probe_t * rec_pkt = etx_get_rec_buf(); + etx_probe_t *rec_pkt = etx_get_rec_buf(); for (uint8_t i = 0; i < rec_pkt->length / ETX_TUPLE_SIZE; i++) { DEBUG("\tIPv6 short Addr:%u\n" - "\tPackets f. Addr:%u\n\n", rec_pkt->data[i * ETX_TUPLE_SIZE], - rec_pkt->data[i * ETX_TUPLE_SIZE + ETX_PKT_REC_OFFSET]); + "\tPackets f. Addr:%u\n\n", rec_pkt->data[i * ETX_TUPLE_SIZE], + rec_pkt->data[i * ETX_TUPLE_SIZE + ETX_PKT_REC_OFFSET]); if (rec_pkt->data[i * ETX_TUPLE_SIZE] - == own_address->uint8[ETX_IPV6_LAST_BYTE]) { + == own_address->uint8[ETX_IPV6_LAST_BYTE]) { candidate->packets_rx = rec_pkt->data[i * ETX_TUPLE_SIZE - + ETX_PKT_REC_OFFSET]; + + ETX_PKT_REC_OFFSET]; } } @@ -346,7 +370,8 @@ void etx_handle_beacon(ipv6_addr_t * candidate_address) { etx_update(candidate); } -void etx_radio(void) { +void etx_radio(void) +{ msg_t m; radio_packet_t *p; @@ -357,13 +382,14 @@ void etx_radio(void) { ipv6_addr_t ll_address; ipv6_addr_t candidate_addr; - ipv6_set_ll_prefix(&ll_address); - ipv6_get_saddr(&candidate_addr, &ll_address); + ipv6_addr_set_link_local_prefix(&ll_address); + ipv6_iface_get_best_src_addr(&candidate_addr, &ll_address); while (1) { msg_receive(&m); + if (m.type == PKT_PENDING) { - p = (radio_packet_t*) m.content.ptr; + p = (radio_packet_t *) m.content.ptr; read_802154_frame(p->data, &frame, p->length); @@ -392,7 +418,8 @@ void etx_radio(void) { } } -void etx_update(etx_neighbor_t * candidate) { +void etx_update(etx_neighbor_t *candidate) +{ DEBUG("update!\n"); /* * Update the current ETX value of a candidate @@ -400,7 +427,7 @@ void etx_update(etx_neighbor_t * candidate) { double d_f; double d_r; - if (reached_window != 1 || candidate == NULL ) { + if (reached_window != 1 || candidate == NULL) { //We will wait at least ETX_WINDOW beacons until we decide to //calculate an ETX value, so that we have a good estimate return; @@ -419,24 +446,26 @@ void etx_update(etx_neighbor_t * candidate) { /* * Calculate the current ETX value for my link to this candidate. */ - if (d_f * d_r != 0) { + if (d_f *d_r != 0) { candidate->cur_etx = 1 / (d_f * d_r); - } else { + } + else { candidate->cur_etx = 0; } DEBUG( - "Estimated ETX Metric is %f for candidate w/ addr %d\n" - "Estimated PDR_forward is %f\n" - "Estimated PDR_backwrd is %f\n" - "\n" - "Received Packets: %d\n" - "Sent Packets : %d\n\n", - candidate->cur_etx, candidate->addr.uint8[ETX_IPV6_LAST_BYTE], - d_f, d_r, candidate->packets_rx, etx_count_packet_tx(candidate)); + "Estimated ETX Metric is %f for candidate w/ addr %d\n" + "Estimated PDR_forward is %f\n" + "Estimated PDR_backwrd is %f\n" + "\n" + "Received Packets: %d\n" + "Sent Packets : %d\n\n", + candidate->cur_etx, candidate->addr.uint8[ETX_IPV6_LAST_BYTE], + d_f, d_r, candidate->packets_rx, etx_count_packet_tx(candidate)); } -static uint8_t etx_count_packet_tx(etx_neighbor_t * candidate) { +static uint8_t etx_count_packet_tx(etx_neighbor_t *candidate) +{ /* * Counts the number of packets that were received for this candidate * in the last ETX_WINDOW intervals. @@ -444,38 +473,46 @@ static uint8_t etx_count_packet_tx(etx_neighbor_t * candidate) { DEBUG("counting packets"); uint8_t pkt_count = 0; DEBUG("["); + for (uint8_t i = 0; i < ETX_WINDOW; i++) { if (i != cur_round) { pkt_count = pkt_count + candidate->packets_tx[i]; - DEBUG("%d",candidate->packets_tx[i]); + DEBUG("%d", candidate->packets_tx[i]); + if (i < ETX_WINDOW - 1) { DEBUG(","); } - } else { + } + else { //Check if I received something for the current round if (candidate->tx_cur_round == 0) { //Didn't receive a packet, zero the field and don't add candidate->packets_tx[i] = 0; - DEBUG("%d!",candidate->packets_tx[i]); + DEBUG("%d!", candidate->packets_tx[i]); + if (i < ETX_WINDOW - 1) { DEBUG(","); } - } else { + } + else { //Add 1 and set field pkt_count = pkt_count + 1; candidate->packets_tx[i] = 1; - DEBUG("%d!",candidate->packets_tx[i]); + DEBUG("%d!", candidate->packets_tx[i]); + if (i < ETX_WINDOW - 1) { DEBUG(","); } } } } + DEBUG("]\n"); return pkt_count; } -static void etx_set_packets_received(void) { +static void etx_set_packets_received(void) +{ /* * Set for all candidates if they received a packet this round or not */ @@ -489,12 +526,14 @@ static void etx_set_packets_received(void) { } } -bool etx_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2){ - for(uint8_t i=0;i<4;i++){ - if(id1->uint32[i] != id2->uint32[i]){ +bool etx_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2) +{ + for (uint8_t i = 0; i < 4; i++) { + if (id1->uint32[i] != id2->uint32[i]) { return false; } } + return true; } diff --git a/sys/net/rpl/etx_beaconing.h b/sys/net/rpl/etx_beaconing.h index 4cdf762a3d..de353bb9d3 100644 --- a/sys/net/rpl/etx_beaconing.h +++ b/sys/net/rpl/etx_beaconing.h @@ -9,20 +9,20 @@ #ifndef ETX_BEACONING_H_ #define ETX_BEACONING_H_ -#include "sys/net/sixlowpan/sixlowip.h" +#include "ipv6.h" //For debugging purposes #define ENABLE_DEBUG (0) #include #if ENABLE_DEBUG - #define ETX_BEACON_STACKSIZE (4500) - #define ETX_RADIO_STACKSIZE (4500) - #define ETX_CLOCK_STACKSIZE (500) +#define ETX_BEACON_STACKSIZE (4500) +#define ETX_RADIO_STACKSIZE (4500) +#define ETX_CLOCK_STACKSIZE (500) #else - #define ETX_BEACON_STACKSIZE (2500) //TODO optimize, maybe 2000 is enough - #define ETX_RADIO_STACKSIZE (2500) //TODO optimize, maybe 2000 is enough - #define ETX_CLOCK_STACKSIZE (500) //TODO optimize, maybe 250 is enough +#define ETX_BEACON_STACKSIZE (2500) //TODO optimize, maybe 2000 is enough +#define ETX_RADIO_STACKSIZE (2500) //TODO optimize, maybe 2000 is enough +#define ETX_CLOCK_STACKSIZE (500) //TODO optimize, maybe 250 is enough #endif //[option|length|ipaddr.|packetcount] with up to 15 ipaddr|packetcount pairs @@ -36,9 +36,9 @@ * In my tests, the maximum count of neighbors was around 30-something */ #if ENABLE_DEBUG - #define ETX_MAX_CANDIDATE_NEIGHBORS (15) //Stacksizes are huge in debug mode, so memory is rare +#define ETX_MAX_CANDIDATE_NEIGHBORS (15) //Stacksizes are huge in debug mode, so memory is rare #else - #define ETX_MAX_CANDIDATE_NEIGHBORS (40) +#define ETX_MAX_CANDIDATE_NEIGHBORS (40) #endif //ETX Interval parameters #define MS (1000) @@ -86,7 +86,7 @@ * information. * The information processed shall not exceed the value set in Option Length. */ -typedef struct __attribute__((packed)) etx_probe_t{ +typedef struct __attribute__((packed)) etx_probe_t { uint8_t code; uint8_t length; uint8_t data[30]; @@ -102,11 +102,11 @@ typedef struct etx_neighbor_t { } etx_neighbor_t; //prototypes -void etx_init_beaconing(ipv6_addr_t * address); +void etx_init_beaconing(ipv6_addr_t *address); void etx_beacon(void); void etx_clock(void); -double etx_get_metric(ipv6_addr_t * address); -void etx_update(etx_neighbor_t * neighbor); +double etx_get_metric(ipv6_addr_t *address); +void etx_update(etx_neighbor_t *neighbor); void etx_radio(void); #define ETX_PKT_OPT (0) //Position of Option-Type-Byte diff --git a/sys/net/rpl/of0.c b/sys/net/rpl/of0.c index 2890bf22c4..3cca85e196 100644 --- a/sys/net/rpl/of0.c +++ b/sys/net/rpl/of0.c @@ -1,5 +1,5 @@ /** - * Objective function 0 for RPL implementation + * Objective function 0 for RPL implementation * * Copyright (C) 2013 INRIA. * @@ -7,10 +7,10 @@ * Public License. See the file LICENSE in the top level directory for more * details. * - * @ingroup rpl + * @ingroup rpl * @{ - * @file of0.c - * @brief RPL objective function 0 + * @file of0.c + * @brief RPL objective function 0 * @author Eric Engel * @} */ diff --git a/sys/net/rpl/of_mrhof.c b/sys/net/rpl/of_mrhof.c index 66f04f7c6a..8c6fec2b74 100644 --- a/sys/net/rpl/of_mrhof.c +++ b/sys/net/rpl/of_mrhof.c @@ -9,33 +9,37 @@ static uint16_t calc_rank(rpl_parent_t *, uint16_t); static rpl_parent_t *which_parent(rpl_parent_t *, rpl_parent_t *); static rpl_dodag_t *which_dodag(rpl_dodag_t *, rpl_dodag_t *); static void reset(rpl_dodag_t *); -static uint16_t calc_path_cost(rpl_parent_t * parent); +static uint16_t calc_path_cost(rpl_parent_t *parent); uint16_t cur_min_path_cost = MAX_PATH_COST; -rpl_parent_t * cur_preferred_parent = NULL; +rpl_parent_t *cur_preferred_parent = NULL; rpl_of_t rpl_of_mrhof = { - 0x1, - calc_rank, - which_parent, - which_dodag, - reset, - NULL - }; + 0x1, + calc_rank, + which_parent, + which_dodag, + reset, + NULL +}; -rpl_of_t * rpl_get_of_mrhof(void) { +rpl_of_t *rpl_get_of_mrhof(void) +{ return &rpl_of_mrhof; } -void reset(rpl_dodag_t *dodag) { +void reset(rpl_dodag_t *dodag) +{ } -static uint16_t calc_path_cost(rpl_parent_t * parent) { +static uint16_t calc_path_cost(rpl_parent_t *parent) +{ puts("calc_pathcost"); + /* * Calculates the path cost through the parent, for now, only for ETX */ - if (parent == NULL ) { + if (parent == NULL) { // Shouldn't ever happen since this function is supposed to be always // run with a parent. If it does happen, we can assume a root called it. puts("[WARNING] calc_path_cost called without parent!"); @@ -44,6 +48,7 @@ static uint16_t calc_path_cost(rpl_parent_t * parent) { double etx_value = etx_get_metric(&(parent->addr)); printf("Metric for parent returned: %f", etx_value); + if (etx_value != 0) { /* * (ETX_for_link_to_neighbor * 128) + Rank_of_that_neighbor @@ -60,14 +65,16 @@ static uint16_t calc_path_cost(rpl_parent_t * parent) { } if (etx_value * ETX_RANK_MULTIPLIER + parent->rank - < parent->rank) { + < parent->rank) { //Overflow return MAX_PATH_COST; } + //TODO runden return etx_value * ETX_RANK_MULTIPLIER - + parent->rank; - } else { + + parent->rank; + } + else { // IMPLEMENT HANDLING OF OTHER METRICS HERE // if it is 0, it hasn't been computed, thus we cannot compute a path // cost @@ -75,8 +82,10 @@ static uint16_t calc_path_cost(rpl_parent_t * parent) { } } -static uint16_t calc_rank(rpl_parent_t * parent, uint16_t base_rank) { +static uint16_t calc_rank(rpl_parent_t *parent, uint16_t base_rank) +{ puts("calc_rank"); + /* * Return the rank for this node. * @@ -84,7 +93,7 @@ static uint16_t calc_rank(rpl_parent_t * parent, uint16_t base_rank) { * putation will always be assumed to be done for the ETX metric. * Baserank is pretty much only used to find out if a node is a root or not. */ - if (parent == NULL ) { + if (parent == NULL) { if (base_rank == 0) { //No parent, no rank, a root node would have a rank != 0 return INFINITE_RANK; @@ -97,7 +106,8 @@ static uint16_t calc_rank(rpl_parent_t * parent, uint16_t base_rank) { * (see rpl.c, function global_repair), we can assume this node is root. */ return DEFAULT_MIN_HOP_RANK_INCREASE; - } else { + } + else { /* * We have a parent and are a non-root node, calculate the path cost for * the parent and choose the maximum of that value and the advertised @@ -107,19 +117,22 @@ static uint16_t calc_rank(rpl_parent_t * parent, uint16_t base_rank) { if (calculated_pcost < MAX_PATH_COST) { if ((parent->rank + parent->dodag->minhoprankincrease) - > calculated_pcost) { + > calculated_pcost) { return parent->rank + parent->dodag->minhoprankincrease; - } else { + } + else { return calculated_pcost; } - } else { + } + else { //Path costs are greater than allowed return INFINITE_RANK; } } } -static rpl_parent_t * which_parent(rpl_parent_t * p1, rpl_parent_t * p2) { +static rpl_parent_t *which_parent(rpl_parent_t *p1, rpl_parent_t *p2) +{ puts("which_parent"); /* * Return the parent with the lowest path cost. @@ -130,12 +143,12 @@ static rpl_parent_t * which_parent(rpl_parent_t * p1, rpl_parent_t * p2) { uint16_t path_p1 = calc_path_cost(p1); uint16_t path_p2 = calc_path_cost(p2); - if(cur_preferred_parent != NULL){ + if (cur_preferred_parent != NULL) { //test if the parent from which we got this path is still active - if(cur_preferred_parent->used != 0){ + if (cur_preferred_parent->used != 0) { // Test, if the current best path is better than both parents given - if(cur_min_path_cost < path_p1 + PARENT_SWITCH_THRESHOLD - && cur_min_path_cost < path_p2 + PARENT_SWITCH_THRESHOLD){ + if (cur_min_path_cost < path_p1 + PARENT_SWITCH_THRESHOLD + && cur_min_path_cost < path_p2 + PARENT_SWITCH_THRESHOLD) { return cur_preferred_parent; } } @@ -149,12 +162,14 @@ static rpl_parent_t * which_parent(rpl_parent_t * p1, rpl_parent_t * p2) { cur_preferred_parent = p1; return p1; } + cur_min_path_cost = path_p2; cur_preferred_parent = p2; return p2; } //Not used yet, as the implementation only makes use of one dodag for now. -static rpl_dodag_t * which_dodag(rpl_dodag_t *d1, rpl_dodag_t *d2) { +static rpl_dodag_t *which_dodag(rpl_dodag_t *d1, rpl_dodag_t *d2) +{ return d1; } diff --git a/sys/net/rpl/rpl.c b/sys/net/rpl/rpl.c index d3b425e957..203db70cb1 100644 --- a/sys/net/rpl/rpl.c +++ b/sys/net/rpl/rpl.c @@ -1,5 +1,5 @@ /** - * RPL implementation + * RPL implementation * * Copyright (C) 2013 INRIA. * @@ -7,10 +7,10 @@ * Public License. See the file LICENSE in the top level directory for more * details. * - * @ingroup rpl + * @ingroup rpl * @{ - * @file rpl.c - * @brief basic RPL functions + * @file rpl.c + * @brief basic RPL functions * @author Eric Engel * @} */ @@ -19,6 +19,7 @@ #include #include #include + #include "msg.h" #include "rpl.h" #include "etx_beaconing.h" @@ -26,11 +27,8 @@ #include "of_mrhof.h" #include "trickle.h" -#include "sys/net/sixlowpan/sixlowmac.h" -#include "sys/net/sixlowpan/sixlowip.h" -#include "sys/net/sixlowpan/sixlowpan.h" -#include "sys/net/sixlowpan/sixlownd.h" -#include "sys/net/sixlowpan/sixlowerror.h" +#include "sixlowpan.h" +#include "ipv6.h" char rpl_process_buf[RPL_PROCESS_STACKSIZE]; /* global variables */ @@ -74,7 +72,7 @@ static rpl_opt_transit_t *rpl_opt_transit_buf; /* SEND BUFFERS */ static ipv6_hdr_t *get_rpl_send_ipv6_buf(void) { - return ((ipv6_hdr_t *)&(rpl_send_buffer[0])); + return ((ipv6_hdr_t *) &(rpl_send_buffer[0])); } static uint8_t *get_rpl_send_payload_buf(uint8_t ext_len) @@ -82,95 +80,86 @@ static uint8_t *get_rpl_send_payload_buf(uint8_t ext_len) return &(rpl_send_buffer[IPV6_HDR_LEN + ext_len]); } -static struct icmpv6_hdr_t *get_rpl_send_icmpv6_buf(uint8_t ext_len) -{ - return ((struct icmpv6_hdr_t *)&(rpl_send_buffer[IPV6_HDR_LEN + ext_len])); +static struct icmpv6_hdr_t *get_rpl_send_icmpv6_buf(uint8_t ext_len) { + return ((struct icmpv6_hdr_t *) &(rpl_send_buffer[IPV6_HDR_LEN + ext_len])); } -static struct rpl_dio_t *get_rpl_send_dio_buf(void) -{ - return ((struct rpl_dio_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); +static struct rpl_dio_t *get_rpl_send_dio_buf(void) { + return ((struct rpl_dio_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); } -static struct rpl_dao_t *get_rpl_send_dao_buf(void) -{ - return ((struct rpl_dao_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); +static struct rpl_dao_t *get_rpl_send_dao_buf(void) { + return ((struct rpl_dao_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); } -static struct rpl_dao_ack_t *get_rpl_send_dao_ack_buf(void) -{ - return ((struct rpl_dao_ack_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); +static struct rpl_dao_ack_t *get_rpl_send_dao_ack_buf(void) { + return ((struct rpl_dao_ack_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); } -static struct rpl_dis_t *get_rpl_send_dis_buf(void) -{ - return ((struct rpl_dis_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); +static struct rpl_dis_t *get_rpl_send_dis_buf(void) { + return ((struct rpl_dis_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN])); } static rpl_opt_dodag_conf_t *get_rpl_send_opt_dodag_conf_buf(uint8_t rpl_msg_len) { - return ((rpl_opt_dodag_conf_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); + return ((rpl_opt_dodag_conf_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); } static rpl_opt_target_t *get_rpl_send_opt_target_buf(uint8_t rpl_msg_len) { - return ((rpl_opt_target_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); + return ((rpl_opt_target_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); } static rpl_opt_transit_t *get_rpl_send_opt_transit_buf(uint8_t rpl_msg_len) { - return ((rpl_opt_transit_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); + return ((rpl_opt_transit_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); } /* RECEIVE BUFFERS */ static ipv6_hdr_t *get_rpl_ipv6_buf(void) { - return ((ipv6_hdr_t *)&(rpl_buffer[0])); + return ((ipv6_hdr_t *) &(rpl_buffer[0])); } -static struct rpl_dio_t *get_rpl_dio_buf(void) -{ - return ((struct rpl_dio_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN])); +static struct rpl_dio_t *get_rpl_dio_buf(void) { + return ((struct rpl_dio_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN])); } -static struct rpl_dao_t *get_rpl_dao_buf(void) -{ - return ((struct rpl_dao_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN])); +static struct rpl_dao_t *get_rpl_dao_buf(void) { + return ((struct rpl_dao_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN])); } -static struct rpl_dao_ack_t *get_rpl_dao_ack_buf(void) -{ - return ((struct rpl_dao_ack_t *)&(buffer[LLHDR_ICMPV6HDR_LEN])); +static struct rpl_dao_ack_t *get_rpl_dao_ack_buf(void) { + return ((struct rpl_dao_ack_t *) &(buffer[LLHDR_ICMPV6HDR_LEN])); } -static struct rpl_dis_t *get_rpl_dis_buf(void) -{ - return ((struct rpl_dis_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN])); +static struct rpl_dis_t *get_rpl_dis_buf(void) { + return ((struct rpl_dis_t *) & (rpl_buffer[IPV6HDR_ICMPV6HDR_LEN])); } static rpl_opt_t *get_rpl_opt_buf(uint8_t rpl_msg_len) { - return ((rpl_opt_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); + return ((rpl_opt_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); } static rpl_opt_dodag_conf_t *get_rpl_opt_dodag_conf_buf(uint8_t rpl_msg_len) { - return ((rpl_opt_dodag_conf_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); + return ((rpl_opt_dodag_conf_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); } static rpl_opt_solicited_t *get_rpl_opt_solicited_buf(uint8_t rpl_msg_len) { - return ((rpl_opt_solicited_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); + return ((rpl_opt_solicited_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); } static rpl_opt_target_t *get_rpl_opt_target_buf(uint8_t rpl_msg_len) { - return ((rpl_opt_target_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); + return ((rpl_opt_target_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); } static rpl_opt_transit_t *get_rpl_opt_transit_buf(uint8_t rpl_msg_len) { - return ((rpl_opt_transit_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); + return ((rpl_opt_transit_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len])); } /* find implemented OF via objective code point */ @@ -205,15 +194,15 @@ uint8_t rpl_init(transceiver_type_t trans, uint16_t rpl_address) objective_functions[0] = rpl_get_of0(); /* objective_functions[1] = rpl_get_of_ETX() */ - sixlowpan_init(trans, rpl_address, 0); + sixlowpan_lowpan_init(trans, rpl_address, 0); /* need link local prefix to query _our_ corresponding address */ ipv6_addr_t ll_address; - ipv6_set_ll_prefix(&ll_address); - ipv6_get_saddr(&my_address, &ll_address); - set_rpl_process_pid(rpl_process_pid); + ipv6_addr_set_link_local_prefix(&ll_address); + ipv6_iface_get_best_src_addr(&my_address, &ll_address); + ipv6_register_rpl_handler(rpl_process_pid); /* initialize ETX-calculation if needed */ - if(RPL_DEFAULT_OCP == 1){ + if (RPL_DEFAULT_OCP == 1) { DEBUG("INIT ETX BEACONING\n"); etx_init_beaconing(&my_address); } @@ -239,7 +228,7 @@ void rpl_init_root(void) dodag = rpl_new_dodag(RPL_DEFAULT_INSTANCE, &my_address); if (dodag != NULL) { - dodag->of = (struct rpl_of_t*) rpl_get_of_for_ocp(RPL_DEFAULT_OCP); + dodag->of = (struct rpl_of_t *) rpl_get_of_for_ocp(RPL_DEFAULT_OCP); dodag->instance = inst; dodag->mop = RPL_DEFAULT_MOP; dodag->dtsn = 1; @@ -284,9 +273,9 @@ void send_DIO(ipv6_addr_t *destination) return; } - icmp_send_buf->type = ICMP_RPL_CONTROL; + icmp_send_buf->type = ICMPV6_TYPE_RPL_CONTROL; icmp_send_buf->code = ICMP_CODE_DIO; - icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); + icmp_send_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6); rpl_send_dio_buf = get_rpl_send_dio_buf(); memset(rpl_send_dio_buf, 0, sizeof(*rpl_send_dio_buf)); @@ -320,7 +309,7 @@ void send_DIO(ipv6_addr_t *destination) uint16_t plen = ICMPV6_HDR_LEN + DIO_BASE_LEN + opt_hdr_len; - rpl_send(destination, (uint8_t *)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL); + rpl_send(destination, (uint8_t *)icmp_send_buf, plen, IPV6_PROTO_NUM_ICMPV6, NULL); mutex_unlock(&rpl_send_mutex); } @@ -329,14 +318,14 @@ void send_DIS(ipv6_addr_t *destination) mutex_lock(&rpl_send_mutex); icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); - icmp_send_buf->type = ICMP_RPL_CONTROL; + icmp_send_buf->type = ICMPV6_TYPE_RPL_CONTROL; icmp_send_buf->code = ICMP_CODE_DIS; - icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); + icmp_send_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6); rpl_send_dis_buf = get_rpl_send_dis_buf(); uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN; - rpl_send(destination, (uint8_t *)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL); + rpl_send(destination, (uint8_t *)icmp_send_buf, plen, IPV6_PROTO_NUM_ICMPV6, NULL); mutex_unlock(&rpl_send_mutex); } @@ -361,9 +350,9 @@ void send_DAO(ipv6_addr_t *destination, uint8_t lifetime, bool default_lifetime, icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); - icmp_send_buf->type = ICMP_RPL_CONTROL; + icmp_send_buf->type = ICMPV6_TYPE_RPL_CONTROL; icmp_send_buf->code = ICMP_CODE_DAO; - icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); + icmp_send_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6); if (my_dodag == NULL) { mutex_unlock(&rpl_send_mutex); @@ -427,7 +416,7 @@ void send_DAO(ipv6_addr_t *destination, uint8_t lifetime, bool default_lifetime, opt_len += RPL_OPT_TRANSIT_LEN + 2; uint16_t plen = ICMPV6_HDR_LEN + DAO_BASE_LEN + opt_len; - rpl_send(destination, (uint8_t *)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL); + rpl_send(destination, (uint8_t *)icmp_send_buf, plen, IPV6_PROTO_NUM_ICMPV6, NULL); mutex_unlock(&rpl_send_mutex); if (continue_index > 1) { @@ -437,7 +426,8 @@ void send_DAO(ipv6_addr_t *destination, uint8_t lifetime, bool default_lifetime, void send_DAO_ACK(ipv6_addr_t *destination) { - ipv6_print_addr(destination); + char addr_str[IPV6_MAX_ADDR_STR_LEN]; + printf("%s\n", ipv6_addr_to_str(addr_str, destination)); rpl_dodag_t *my_dodag; my_dodag = rpl_get_my_dodag(); @@ -448,9 +438,9 @@ void send_DAO_ACK(ipv6_addr_t *destination) mutex_lock(&rpl_send_mutex); icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); - icmp_send_buf->type = ICMP_RPL_CONTROL; + icmp_send_buf->type = ICMPV6_TYPE_RPL_CONTROL; icmp_send_buf->code = ICMP_CODE_DAO_ACK; - icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); + icmp_send_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6); rpl_send_dao_ack_buf = get_rpl_send_dao_ack_buf(); rpl_send_dao_ack_buf->rpl_instanceid = my_dodag->instance->id; @@ -459,7 +449,7 @@ void send_DAO_ACK(ipv6_addr_t *destination) rpl_send_dao_ack_buf->status = 0; uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN; - rpl_send(destination, (uint8_t *)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL); + rpl_send(destination, (uint8_t *)icmp_send_buf, plen, IPV6_PROTO_NUM_ICMPV6, NULL); mutex_unlock(&rpl_send_mutex); } @@ -474,10 +464,10 @@ void rpl_process(void) uint8_t *code; code = ((uint8_t *)m_recv.content.ptr); /* differentiate packet types */ - ipv6_buf = get_ipv6_buf(); + ipv6_buf = ipv6_get_buf(); memcpy(&rpl_buffer, ipv6_buf, ipv6_buf->length + IPV6_HDR_LEN); - switch(*code) { + switch (*code) { case (ICMP_CODE_DIS): { recv_rpl_dis(); mutex_unlock(&rpl_recv_mutex); @@ -533,11 +523,11 @@ void recv_rpl_dio(void) } } else if (my_inst->id != dio_inst->id) { - /* TODO: Add support support for several instances. */ + /* TODO: Add support support for several instances. */ - /* At the moment, nodes can only join one instance, this is - * the instance they join first. - * Instances cannot be switched later on. */ + /* At the moment, nodes can only join one instance, this is + * the instance they join first. + * Instances cannot be switched later on. */ DEBUG("Ignoring instance - we are %d and got %d\n", my_inst->id, dio_inst->id); return; @@ -556,14 +546,14 @@ void recv_rpl_dio(void) uint8_t has_dodag_conf_opt = 0; - /* Parse until all options are consumed. - * ipv6_buf->length contains the packet length minus ipv6 and - * icmpv6 header, so only ICMPV6_HDR_LEN remains to be - * subtracted. */ + /* Parse until all options are consumed. + * ipv6_buf->length contains the packet length minus ipv6 and + * icmpv6 header, so only ICMPV6_HDR_LEN remains to be + * subtracted. */ while (len < (ipv6_buf->length - ICMPV6_HDR_LEN)) { rpl_opt_buf = get_rpl_opt_buf(len); - switch(rpl_opt_buf->type) { + switch (rpl_opt_buf->type) { case (RPL_OPT_PAD1): { len += 1; @@ -601,7 +591,7 @@ void recv_rpl_dio(void) dio_dodag.minhoprankincrease = rpl_opt_dodag_conf_buf->MinHopRankIncrease; dio_dodag.default_lifetime = rpl_opt_dodag_conf_buf->default_lifetime; dio_dodag.lifetime_unit = rpl_opt_dodag_conf_buf->lifetime_unit; - dio_dodag.of = (struct rpl_of_t*) rpl_get_of_for_ocp(rpl_opt_dodag_conf_buf->ocp); + dio_dodag.of = (struct rpl_of_t *) rpl_get_of_for_ocp(rpl_opt_dodag_conf_buf->ocp); len += RPL_OPT_DODAG_CONF_LEN + 2; break; } @@ -648,8 +638,9 @@ void recv_rpl_dio(void) } if (rpl_dio_buf->rank != INFINITE_RANK) { + char addr_str[IPV6_MAX_ADDR_STR_LEN]; DEBUG("Will join DODAG\n"); - ipv6_print_addr(&dio_dodag.dodag_id); + printf("%s", ipv6_addr_to_str(addr_str, &dio_dodag.dodag_id)); rpl_join_dodag(&dio_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank); } else { @@ -685,7 +676,7 @@ void recv_rpl_dio(void) reset_trickletimer(); } - /* We are root, all done! */ + /* We are root, all done! */ if (my_dodag->my_rank == ROOT_RANK) { if (rpl_dio_buf->rank != INFINITE_RANK) { trickle_increment_counter(); @@ -739,7 +730,7 @@ void recv_rpl_dis(void) while (len < (ipv6_buf->length - ICMPV6_HDR_LEN)) { rpl_opt_buf = get_rpl_opt_buf(len); - switch(rpl_opt_buf->type) { + switch (rpl_opt_buf->type) { case (RPL_OPT_PAD1): { len += 1; break; @@ -808,7 +799,7 @@ void recv_rpl_dao(void) while (len < (ipv6_buf->length - ICMPV6_HDR_LEN)) { rpl_opt_buf = get_rpl_opt_buf(len); - switch(rpl_opt_buf->type) { + switch (rpl_opt_buf->type) { case (RPL_OPT_PAD1): { len += 1; @@ -899,7 +890,7 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_ uint8_t *p_ptr; ipv6_send_buf = get_rpl_send_ipv6_buf(); p_ptr = get_rpl_send_payload_buf(ipv6_ext_hdr_len); - packet_length = 0; + uint16_t packet_length = 0; ipv6_send_buf->version_trafficclass = IPV6_VER; ipv6_send_buf->trafficclass_flowlabel = 0; @@ -909,7 +900,7 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_ ipv6_send_buf->length = p_len; memcpy(&(ipv6_send_buf->destaddr), destination, 16); - ipv6_get_saddr(&(ipv6_send_buf->srcaddr), &(ipv6_send_buf->destaddr)); + ipv6_iface_get_best_src_addr(&(ipv6_send_buf->srcaddr), &(ipv6_send_buf->destaddr)); /* The packet was "assembled" in rpl.c. Therefore rpl_send_buf was used. * Therefore memcpy is not needed because the payload is at the @@ -921,8 +912,10 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_ packet_length = IPV6_HDR_LEN + p_len; - if (ipv6_prefix_mcast_match(&ipv6_send_buf->destaddr)) { - lowpan_init((ieee_802154_long_t *)&(ipv6_send_buf->destaddr.uint16[4]), (uint8_t *)ipv6_send_buf); + if (ipv6_addr_is_multicast(&ipv6_send_buf->destaddr)) { + sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_send_buf->destaddr.uint16[4]), + (uint8_t *)ipv6_send_buf, + packet_length); } else { /* find appropriate next hop before sending */ @@ -943,7 +936,9 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_ } } - lowpan_init((ieee_802154_long_t *)&(next_hop->uint16[4]), (uint8_t *)ipv6_send_buf); + sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(next_hop->uint16[4]), + (uint8_t *)ipv6_send_buf, + packet_length); } } diff --git a/sys/net/rpl/rpl.h b/sys/net/rpl/rpl.h index c38a2bf2ea..67f14877b2 100644 --- a/sys/net/rpl/rpl.h +++ b/sys/net/rpl/rpl.h @@ -1,5 +1,5 @@ /** - * RPL constants and prototypes + * RPL constants and prototypes * * Copyright (C) 2013 INRIA. * @@ -7,7 +7,7 @@ * Public License. See the file LICENSE in the top level directory for more * details. * - * @ingroup rpl + * @ingroup rpl * @{ * @file rpl.h * @brief RPL header @@ -20,7 +20,7 @@ #include #include #include -#include "sixlowpan/sixlowip.h" +#include "ipv6.h" #include "rpl_dodag.h" #define CC1100_RADIO_MODE CC1100_MODE_WOR diff --git a/sys/net/rpl/rpl_dodag.c b/sys/net/rpl/rpl_dodag.c index d80e9fb941..fb254272ba 100644 --- a/sys/net/rpl/rpl_dodag.c +++ b/sys/net/rpl/rpl_dodag.c @@ -1,5 +1,5 @@ /** - * RPL dodag implementation + * RPL dodag implementation * * Copyright (C) 2013 INRIA. * @@ -7,10 +7,10 @@ * Public License. See the file LICENSE in the top level directory for more * details. * - * @ingroup rpl + * @ingroup rpl * @{ * @file rpl_dodag.c - * @brief RPL dodag functions + * @brief RPL dodag functions * @author Eric Engel * @} */ @@ -179,7 +179,7 @@ void rpl_delete_parent(rpl_parent_t *parent) rpl_dodag_t *my_dodag = rpl_get_my_dodag(); if ((my_dodag != NULL) && rpl_equal_id(&my_dodag->my_preferred_parent->addr, - &parent->addr)) { + &parent->addr)) { my_dodag->my_preferred_parent = NULL; } @@ -275,7 +275,7 @@ void rpl_parent_update(rpl_parent_t *parent) } if (rpl_calc_rank(old_rank, my_dodag->minhoprankincrease) != - rpl_calc_rank(my_dodag->my_rank, my_dodag->minhoprankincrease)) { + rpl_calc_rank(my_dodag->my_rank, my_dodag->minhoprankincrease)) { if (my_dodag->my_rank < my_dodag->min_rank) { my_dodag->min_rank = my_dodag->my_rank; } @@ -348,7 +348,7 @@ void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t *p_addr, uint16_t rank) else { /* Calc new Rank */ my_dodag->my_rank = my_dodag->of->calc_rank(my_dodag->my_preferred_parent, - my_dodag->my_rank); + my_dodag->my_rank); my_dodag->min_rank = my_dodag->my_rank; reset_trickletimer(); delay_dao(); diff --git a/sys/net/rpl/rpl_dodag.h b/sys/net/rpl/rpl_dodag.h index a4ad7e0ace..014a0b51a2 100644 --- a/sys/net/rpl/rpl_dodag.h +++ b/sys/net/rpl/rpl_dodag.h @@ -1,5 +1,5 @@ /** - * RPL dodag prototypes + * RPL dodag prototypes * * Copyright (C) 2013 INRIA. * @@ -7,15 +7,16 @@ * Public License. See the file LICENSE in the top level directory for more * details. * - * @ingroup rpl + * @ingroup rpl * @{ * @file rpl_dodag.h - * @brief RPL dodag header + * @brief RPL dodag header * @author Eric Engel * @} */ #include +#include "ipv6.h" #include "rpl_structs.h" rpl_instance_t *rpl_new_instance(uint8_t instanceid); diff --git a/sys/net/rpl/rpl_structs.h b/sys/net/rpl/rpl_structs.h index b03c0d2bd7..80e374fe33 100644 --- a/sys/net/rpl/rpl_structs.h +++ b/sys/net/rpl/rpl_structs.h @@ -1,5 +1,5 @@ /** - * RPL data structs + * RPL data structs * * Copyright (C) 2013 INRIA. * @@ -7,7 +7,7 @@ * Public License. See the file LICENSE in the top level directory for more * details. * - * @ingroup rpl + * @ingroup rpl * @{ * @file rpl_structs.h * @brief RPL data structs @@ -16,7 +16,7 @@ */ #include -#include "sixlowpan/sixlowip.h" +#include "ipv6.h" #ifndef RPL_STRUCTS_H_INCLUDED #define RPL_STRUCTS_H_INCLUDED @@ -219,12 +219,12 @@ struct rpl_dodag_t; typedef struct { ipv6_addr_t addr; uint16_t rank; - uint8_t dtsn; + uint8_t dtsn; struct rpl_dodag_t *dodag; - uint16_t lifetime; - double link_metric; - uint8_t link_metric_type; - uint8_t used; + uint16_t lifetime; + double link_metric; + uint8_t link_metric_type; + uint8_t used; } rpl_parent_t; struct rpl_of_t; @@ -264,13 +264,13 @@ typedef struct rpl_dodag_t { typedef struct rpl_of_t { uint16_t ocp; - uint16_t (*calc_rank)(rpl_parent_t * parent, uint16_t base_rank); + uint16_t (*calc_rank)(rpl_parent_t *parent, uint16_t base_rank); rpl_parent_t *(*which_parent)(rpl_parent_t *, rpl_parent_t *); rpl_dodag_t *(*which_dodag)(rpl_dodag_t *, rpl_dodag_t *); void (*reset)(rpl_dodag_t *); void (*parent_state_callback)(rpl_parent_t *, int, int); - void (*init) (void); //OF specific init function - void (*process_dio) (void); //DIO processing callback (acc. to OF0 spec, chpt 5) + void (*init)(void); //OF specific init function + void (*process_dio)(); //DIO processing callback (acc. to OF0 spec, chpt 5) } rpl_of_t; typedef struct { diff --git a/sys/net/rpl/trickle.c b/sys/net/rpl/trickle.c index 69473445ab..c090733459 100644 --- a/sys/net/rpl/trickle.c +++ b/sys/net/rpl/trickle.c @@ -7,7 +7,7 @@ * Public License. See the file LICENSE in the top level directory for more * details. * - * @ingroup rpl + * @ingroup rpl * @{ * @file trickle.c * @brief Trickle implementation @@ -25,9 +25,9 @@ #include "rpl/rpl.h" //TODO in pointer umwandeln, speicher mit malloc holen -char * timer_over_buf; -char * interval_over_buf; -char * dao_delay_over_buf; +char *timer_over_buf; +char *interval_over_buf; +char *dao_delay_over_buf; char routing_table_buf[RT_STACKSIZE]; int timer_over_pid; int interval_over_pid; @@ -71,18 +71,23 @@ void reset_trickletimer(void) void init_trickle(void) { - timer_over_buf = calloc(TRICKLE_TIMER_STACKSIZE,sizeof(char)); - if(timer_over_buf == NULL){ + timer_over_buf = calloc(TRICKLE_TIMER_STACKSIZE, sizeof(char)); + + if (timer_over_buf == NULL) { puts("[ERROR] Could not allocate enough memory for timer_over_buf!"); return; } - interval_over_buf = calloc(TRICKLE_INTERVAL_STACKSIZE,sizeof(char)); - if(interval_over_buf == NULL){ + + interval_over_buf = calloc(TRICKLE_INTERVAL_STACKSIZE, sizeof(char)); + + if (interval_over_buf == NULL) { puts("[ERROR] Could not allocate enough memory for interval_over_buf!"); return; } - dao_delay_over_buf = calloc(DAO_DELAY_STACKSIZE,sizeof(char)); - if(dao_delay_over_buf == NULL){ + + dao_delay_over_buf = calloc(DAO_DELAY_STACKSIZE, sizeof(char)); + + if (dao_delay_over_buf == NULL) { puts("[ERROR] Could not allocate enough memory for interval_over_buf!"); return; } @@ -135,7 +140,7 @@ void trickle_increment_counter(void) void trickle_timer_over(void) { ipv6_addr_t mcast; - ipv6_set_all_nds_mcast_addr(&mcast); + ipv6_addr_set_all_nodes_addr(&mcast); while (1) { thread_sleep(); diff --git a/sys/net/rpl/trickle.h b/sys/net/rpl/trickle.h index 72ec98dfc0..5f21720042 100644 --- a/sys/net/rpl/trickle.h +++ b/sys/net/rpl/trickle.h @@ -7,10 +7,10 @@ * Public License. See the file LICENSE in the top level directory for more * details. * - * @ingroup rpl + * @ingroup rpl * @{ * @file trickle.h - * @brief Trickle + * @brief Trickle * @author Eric Engel * @} */ diff --git a/sys/net/sixlowpan/Makefile b/sys/net/sixlowpan/Makefile index c5dac39f00..4e0b8e4cc2 100644 --- a/sys/net/sixlowpan/Makefile +++ b/sys/net/sixlowpan/Makefile @@ -1,4 +1,4 @@ MODULE:=$(shell basename $(CURDIR)) -INCLUDES = -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/sys/net -I$(RIOTBASE)/cpu/arm_common/include/ +INCLUDES = -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/sixlowpan/include/ include $(RIOTBASE)/Makefile.base diff --git a/sys/net/sixlowpan/sixlowborder.c b/sys/net/sixlowpan/border.c similarity index 75% rename from sys/net/sixlowpan/sixlowborder.c rename to sys/net/sixlowpan/border.c index 51d41c5ed1..dc4e619d34 100644 --- a/sys/net/sixlowpan/sixlowborder.c +++ b/sys/net/sixlowpan/border.c @@ -1,5 +1,5 @@ /** - * 6lowpan border router implementation + * 6lowpan border router implementation * * Copyright (C) 2013 INRIA. * @@ -10,7 +10,7 @@ * @ingroup sixlowpan * @{ * @file sixlowborder.c - * @brief constraint node implementation for a 6lowpan border router + * @brief constraint node implementation for a 6lowpan border router * @author Martin Lenders * @author Oliver Hahm * @} @@ -19,24 +19,25 @@ #include #include #include -#include -#include -#include -#include -#include +#include "mutex.h" +#include "thread.h" +#include "msg.h" +#include "posix_io.h" +#include "board_uart0.h" +#include "sixlowpan/error.h" #include "bordermultiplex.h" -#include "ieee802154/ieee802154_frame.h" #include "flowcontrol.h" -#include "sixlowborder.h" -#include "sixlowip.h" -#include "sixlownd.h" +#include "border.h" +#include "ip.h" +#include "icmp.h" #include "serialnumber.h" -#include "sixlowerror.h" + +#include "sys/net/ieee802154/ieee802154_frame.h" #include "sys/net/net_help/net_help.h" -#define READER_STACK_SIZE 512 +#define READER_STACK_SIZE (KERNEL_CONF_STACKSIZE_DEFAULT) ipv6_addr_t abr_addr; @@ -86,7 +87,7 @@ void serial_reader_f(void) bytes = readpacket(get_serial_in_buffer(0), BORDER_BUFFER_SIZE); if (bytes < 0) { - switch(bytes) { + switch (bytes) { case (-SIXLOWERROR_ARRAYFULL): { printf("ERROR: Array was full\n"); break; @@ -119,7 +120,8 @@ void serial_reader_f(void) } } -uint8_t border_initialize(transceiver_type_t trans, ipv6_addr_t *border_router_addr) +uint8_t sixlowpan_lowpan_border_init(transceiver_type_t trans, + const ipv6_addr_t *border_router_addr) { ipv6_addr_t addr; @@ -139,9 +141,9 @@ uint8_t border_initialize(transceiver_type_t trans, ipv6_addr_t *border_router_a * -- for now */ if (border_router_addr->uint16[4] != HTONS(IEEE_802154_PAN_ID ^ 0x0200) || - border_router_addr->uint16[5] != HTONS(0x00FF) || - border_router_addr->uint16[6] != HTONS(0xFE00) - ) { + border_router_addr->uint16[5] != HTONS(0x00FF) || + border_router_addr->uint16[6] != HTONS(0xFE00) + ) { return SIXLOWERROR_ADDRESS; } @@ -152,26 +154,13 @@ uint8_t border_initialize(transceiver_type_t trans, ipv6_addr_t *border_router_a memcpy(&(abr_addr.uint8[0]), &(border_router_addr->uint8[0]), 16); - sixlowpan_init(trans, border_router_addr->uint8[15], 1); + sixlowpan_lowpan_init(trans, border_router_addr->uint8[15], 1); ipv6_init_iface_as_router(); return SUCCESS; } -void border_send_ipv6_over_lowpan(ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t sixco_flag) -{ - uint16_t offset = IPV6_HDR_LEN + HTONS(packet->length); - - packet->flowlabel = HTONS(packet->flowlabel); - packet->length = HTONS(packet->length); - - memset(buffer, 0, BUFFER_SIZE); - memcpy(buffer + LL_HDR_LEN, packet, offset); - - lowpan_init((ieee_802154_long_t *)&(packet->destaddr.uint16[4]), (uint8_t *)packet); -} - void border_process_lowpan(void) { msg_t m; @@ -181,10 +170,10 @@ void border_process_lowpan(void) msg_receive(&m); ipv6_buf = (ipv6_hdr_t *)m.content.ptr; - if (ipv6_buf->nextheader == PROTO_NUM_ICMPV6) { - struct icmpv6_hdr_t *icmp_buf = (struct icmpv6_hdr_t *)(((uint8_t *)ipv6_buf) + IPV6_HDR_LEN); + if (ipv6_buf->nextheader == IPV6_PROTO_NUM_ICMPV6) { + icmpv6_hdr_t *icmp_buf = (icmpv6_hdr_t *)(((uint8_t *)ipv6_buf) + IPV6_HDR_LEN); - if (icmp_buf->type == ICMP_REDIRECT) { + if (icmp_buf->type == ICMPV6_TYPE_REDIRECT) { continue; } diff --git a/sys/net/sixlowpan/sixlowborder.h b/sys/net/sixlowpan/border.h similarity index 65% rename from sys/net/sixlowpan/sixlowborder.h rename to sys/net/sixlowpan/border.h index 4d0729e35d..6ee70b8dc4 100644 --- a/sys/net/sixlowpan/sixlowborder.h +++ b/sys/net/sixlowpan/border.h @@ -10,7 +10,7 @@ * @ingroup sixlowpan * @{ * @file sixlowborder.h - * @brief header for 6lowpan border router + * @brief header for 6lowpan border router * @author Martin Lenders * @author Oliver Hahm * @} @@ -18,14 +18,15 @@ /* 6LoWPAN Border Router header file */ -#ifndef SIXLOWBORDER_H -#define SIXLOWBORDER_H +#ifndef _SIXLOWPAN_BORDER_H +#define _SIXLOWPAN_BORDER_H #include -#include -#include -#include "sixlowip.h" +#include "mutex.h" +#include "transceiver.h" + +#include "ip.h" #include "semaphore.h" extern ipv6_addr_t abr_addr; @@ -35,8 +36,6 @@ uint16_t border_get_serial_reader(void); uint8_t *get_serial_out_buffer(int offset); uint8_t *get_serial_in_buffer(int offset); -uint8_t border_initialize(transceiver_type_t trans, ipv6_addr_t *border_router_addr); -void border_send_ipv6_over_lowpan(ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t sixco_flag); void border_process_lowpan(void); -#endif /* SIXLOWBORDER_H*/ +#endif /* _SIXLOWPAN_BORDER_H*/ diff --git a/sys/net/sixlowpan/bordermultiplex.c b/sys/net/sixlowpan/bordermultiplex.c index af10ebdfb5..b2aefc6133 100644 --- a/sys/net/sixlowpan/bordermultiplex.c +++ b/sys/net/sixlowpan/bordermultiplex.c @@ -19,24 +19,24 @@ #include #include -#include +#include "board_uart0.h" +#include "sixlowpan/error.h" #include "flowcontrol.h" -#include "sixlowpan.h" -#include "sixlownd.h" -#include "sixlowborder.h" -#include "sixlowerror.h" +#include "lowpan.h" +#include "icmp.h" +#include "border.h" #include "bordermultiplex.h" -#define END 0xC0 -#define ESC 0xDB -#define END_ESC 0xDC -#define ESC_ESC 0xDD +#define END (0xC0) +#define ESC (0xDB) +#define END_ESC (0xDC) +#define ESC_ESC (0xDD) void demultiplex(border_packet_t *packet, int len) { - switch(packet->type) { + switch (packet->type) { case (BORDER_PACKET_RAW_TYPE): { fputs(((char *)packet) + sizeof(border_packet_t), stdin); break; @@ -45,10 +45,10 @@ void demultiplex(border_packet_t *packet, int len) case (BORDER_PACKET_L3_TYPE): { border_l3_header_t *l3_header_buf = (border_l3_header_t *)packet; - switch(l3_header_buf->ethertype) { + switch (l3_header_buf->ethertype) { case (BORDER_ETHERTYPE_IPV6): { ipv6_hdr_t *ipv6_buf = (ipv6_hdr_t *)(((unsigned char *)packet) + sizeof(border_l3_header_t)); - border_send_ipv6_over_lowpan(ipv6_buf, 1, 1); + ipv6_send_bytes(ipv6_buf); break; } @@ -63,11 +63,11 @@ void demultiplex(border_packet_t *packet, int len) case (BORDER_PACKET_CONF_TYPE): { border_conf_header_t *conf_header_buf = (border_conf_header_t *)packet; - switch(conf_header_buf->conftype) { + switch (conf_header_buf->conftype) { case (BORDER_CONF_CONTEXT): { border_context_packet_t *context = (border_context_packet_t *)packet; ipv6_addr_t target_addr; - ipv6_set_all_nds_mcast_addr(&target_addr); + ipv6_addr_set_all_nodes_addr(&target_addr); mutex_lock(&lowpan_context_mutex); lowpan_context_update( context->context.cid, @@ -148,7 +148,7 @@ int readpacket(uint8_t *packet_buf, size_t size) if (esc) { esc = 0; - switch(byte) { + switch (byte) { case (END_ESC): { *line_buf_ptr++ = END; continue; @@ -184,7 +184,7 @@ int writepacket(uint8_t *packet_buf, size_t size) return -1; } - switch(*byte_ptr) { + switch (*byte_ptr) { case (END): { *byte_ptr = END_ESC; uart0_putc(ESC); diff --git a/sys/net/sixlowpan/bordermultiplex.h b/sys/net/sixlowpan/bordermultiplex.h index 4d00f0c4e1..ff67d9980b 100644 --- a/sys/net/sixlowpan/bordermultiplex.h +++ b/sys/net/sixlowpan/bordermultiplex.h @@ -1,5 +1,5 @@ /** - * 6lowpan border router multiplexer + * 6lowpan border router multiplexer * * Copyright (C) 2013 INRIA. * @@ -9,32 +9,32 @@ * * @ingroup sixlowpan * @{ - * @file bordermultiplex.h + * @file bordermultiplex.h * @brief data structs for border router multiplexing * @author Martin Lenders * @author Oliver Hahm * @} */ -#ifndef BORDERMULTIPLEX_H -#define BORDERMULTIPLEX_H +#ifndef _SIXLOWPAN_BORDERMULTIPLEX_H +#define _SIXLOWPAN_BORDERMULTIPLEX_H #include #include -#include "sixlowip.h" +#include "ip.h" /* packet types of uart-packets */ -#define BORDER_PACKET_RAW_TYPE 0 -#define BORDER_PACKET_CONF_TYPE 2 -#define BORDER_PACKET_L3_TYPE 3 +#define BORDER_PACKET_RAW_TYPE (0) +#define BORDER_PACKET_CONF_TYPE (2) +#define BORDER_PACKET_L3_TYPE (3) /* configuration types */ -#define BORDER_CONF_CONTEXT 2 -#define BORDER_CONF_IPADDR 3 +#define BORDER_CONF_CONTEXT (2) +#define BORDER_CONF_IPADDR (3) /* ethertypes for L3 packets */ -#define BORDER_ETHERTYPE_IPV6 0x86DD +#define BORDER_ETHERTYPE_IPV6 (0x86DD) typedef struct __attribute__((packed)) { uint8_t empty; @@ -80,7 +80,7 @@ typedef struct __attribute__((packed)) { } context; } border_context_packet_t; -#define BORDER_BUFFER_SIZE (sizeof(border_l3_header_t) + MTU) +#define BORDER_BUFFER_SIZE (sizeof(border_l3_header_t) + IPV6_MTU) void demultiplex(border_packet_t *packet, int len); void multiplex_send_ipv6_over_uart(ipv6_hdr_t *packet); @@ -89,4 +89,4 @@ void multiplex_send_addr_over_uart(ipv6_addr_t *addr); int readpacket(uint8_t *packet_buf, size_t size); int writepacket(uint8_t *packet_buf, size_t size); -#endif /* BORDERMULTIPLEX_H*/ +#endif /* _SIXLOWPAN_BORDERMULTIPLEX_H*/ diff --git a/sys/net/sixlowpan/flowcontrol.c b/sys/net/sixlowpan/flowcontrol.c index 38ef216969..eab60b4102 100644 --- a/sys/net/sixlowpan/flowcontrol.c +++ b/sys/net/sixlowpan/flowcontrol.c @@ -1,5 +1,5 @@ /** - * 6lowpan border router flow control + * 6lowpan border router flow control * * Copyright (C) 2013 INRIA. * @@ -10,7 +10,7 @@ * @ingroup sixlowpan * @{ * @file flowcontrol.c - * @brief flowcontrol for constraint node border router implementation + * @brief flowcontrol for constraint node border router implementation * @author Martin Lenders * @author Oliver Hahm * @} @@ -125,7 +125,7 @@ static int in_window(uint8_t seq_num, uint8_t min, uint8_t max) { uint8_t pos = seq_num - min; uint8_t maxpos = max - min + 1; - return pos < maxpos; + return (pos < maxpos); } void flowcontrol_send_over_uart(border_packet_t *packet, int len) @@ -181,8 +181,8 @@ void flowcontrol_deliver_from_uart(border_packet_t *packet, int len) slot = &(slwin_stat.recv_win[packet->seq_num % BORDER_RWS]); if (!in_window(packet->seq_num, - slwin_stat.next_exp, - slwin_stat.next_exp + BORDER_RWS - 1)) { + slwin_stat.next_exp, + slwin_stat.next_exp + BORDER_RWS - 1)) { return; } diff --git a/sys/net/sixlowpan/flowcontrol.h b/sys/net/sixlowpan/flowcontrol.h index 61c1842afb..b14b7387bf 100644 --- a/sys/net/sixlowpan/flowcontrol.h +++ b/sys/net/sixlowpan/flowcontrol.h @@ -1,5 +1,5 @@ /** - * 6lowpan border router flow control + * 6lowpan border router flow control * * Copyright (C) 2013 INRIA. * @@ -16,29 +16,30 @@ * @} */ -#ifndef FLOWCONTROL_H -#define FLOWCONTROL_H +#ifndef _SIXLOWPAN_FLOWCONTROL_H +#define _SIXLOWPAN_FLOWCONTROL_H #include -#include + +#include "vtimer.h" #include "semaphore.h" -#include "sixlowip.h" -#include "sixlowborder.h" +#include "ip.h" +#include "border.h" #include "bordermultiplex.h" /* packet types for flowcontrol */ -#define BORDER_PACKET_ACK_TYPE 1 +#define BORDER_PACKET_ACK_TYPE (1) /* configuration types for flowcontrol */ -#define BORDER_CONF_SYN 0 -#define BORDER_CONF_SYNACK 1 +#define BORDER_CONF_SYN (0) +#define BORDER_CONF_SYNACK (1) -#define BORDER_SWS 1 -#define BORDER_RWS 1 -#define BORDER_SL_TIMEOUT 500 // microseconds, maybe smaller +#define BORDER_SWS (1) +#define BORDER_RWS (1) +#define BORDER_SL_TIMEOUT (500) // microseconds, maybe smaller -#define SENDING_SLOT_STACK_SIZE (256) +#define SENDING_SLOT_STACK_SIZE (MINIMUM_STACK_SIZE + 256) typedef struct { /* Sender state */ @@ -73,4 +74,4 @@ ipv6_addr_t flowcontrol_init(void); void flowcontrol_send_over_uart(border_packet_t *packet, int len); void flowcontrol_deliver_from_uart(border_packet_t *packet, int len); -#endif /* FLOWCONTROL_H*/ +#endif /* _SIXLOWPAN_FLOWCONTROL_H*/ diff --git a/sys/net/sixlowpan/sixlownd.c b/sys/net/sixlowpan/icmp.c similarity index 51% rename from sys/net/sixlowpan/sixlownd.c rename to sys/net/sixlowpan/icmp.c index 32abce272e..8ce346dbec 100644 --- a/sys/net/sixlowpan/sixlownd.c +++ b/sys/net/sixlowpan/icmp.c @@ -1,5 +1,5 @@ /* - * 6lowpan neighbor discovery + * 6lowpan neighbor discovery * * Copyright (C) 2013 INRIA. * @@ -10,7 +10,7 @@ * @ingroup sixlowpan * @{ * @file sixlownd.c - * @brief 6lowpan neighbor discovery functions + * @brief 6lowpan neighbor discovery functions * @author Stephan Zeisberg * @author Martin Lenders * @author Oliver Gesch @@ -20,21 +20,79 @@ #include #include #include -#include "sixlowip.h" -#include "sixlownd.h" -#include "sixlowmac.h" -#include "sixlowpan.h" -#include "sixlowerror.h" -#include "serialnumber.h" -#include "sys/net/net_help/net_help.h" + #include "vtimer.h" #include "mutex.h" +#include "sixlowpan/error.h" +#include "sixlowpan/mac.h" + +#include "ip.h" +#include "icmp.h" +#include "lowpan.h" +#include "serialnumber.h" +#include "sys/net/net_help/net_help.h" #define ENABLE_DEBUG (0) #include "debug.h" +#define LLHDR_ICMPV6HDR_LEN (LL_HDR_LEN + IPV6_HDR_LEN + ICMPV6_HDR_LEN) +#define IPV6HDR_ICMPV6HDR_LEN (IPV6_HDR_LEN + ipv6_ext_hdr_len + ICMPV6_HDR_LEN) +#define ND_HOPLIMIT (0xFF) + +/* parameter problem [rfc4443] */ +#define PARA_PROB_LEN (8) +/* echo request */ +#define ECHO_REQ_LEN (4) +/* echo reply */ +#define ECHO_REPL_LEN (4) +/* router solicitation */ +#define RTR_SOL_LEN (4) +#define RTR_SOL_INTERVAL (4) +#define RTR_SOL_MAX (3) +/* router advertisment */ +#define RTR_ADV_MAX (3) +#define RTR_ADV_MAX_INTERVAL (600) +#define RTR_ADV_LEN (12) +/* neighbour solicitation */ +#define NBR_SOL_LEN (20) +/* neighbour advertisement */ +#define NBR_ADV_LEN (20) +/* stllao option rfc4861 4.6.1 */ +#define OPT_STLLAO_MIN_LEN (8) +#define OPT_STLLAO_MAX_LEN (16) +/* prefix info option rfc 4.6.2 */ +#define OPT_PI_LIST_LEN (5) //TODO: initalwert suchen +#define OPT_PI_TYPE (3) +#define OPT_PI_LEN (4) +#define OPT_PI_HDR_LEN (32) +/* mtu option rfc4861 4.6.4 */ +#define OPT_MTU_TYPE (5) +#define OPT_MTU_LEN (1) +#define OPT_MTU_HDR_LEN (8) +/* aro - address registration option rfc6775 4.1 */ +#define OPT_ARO_TYPE (31) /* TBD1 */ +#define OPT_ARO_LEN (2) +#define OPT_ARO_HDR_LEN (16) +#define OPT_ARO_LTIME (300) /* TODO: geeigneten wert finden */ +/* 6lowpan context option */ +#define OPT_6CO_TYPE (32) +#define OPT_6CO_MIN_LEN (2) +#define OPT_6CO_MAX_LEN (3) +#define OPT_6CO_HDR_LEN (8) +#define OPT_6CO_LTIME (5) /* TODO geeigneten Wert finden */ +/* authoritative border router option */ +#define OPT_ABRO_TYPE (33) +#define OPT_ABRO_LEN (3) +#define OPT_ABRO_HDR_LEN (24) +/* authoritive border router cache size */ +#define ABR_CACHE_SIZE (2) +/* neighbor cache size */ +#define NBR_CACHE_SIZE (8) +#define NBR_CACHE_LTIME_TEN (20) +/* default router list size */ +#define DEF_RTR_LST_SIZE (3) /* geeigneten wert finden */ + /* extern variables */ -uint8_t opt_hdr_len = 0; uint8_t ipv6_ext_hdr_len = 0; /* counter */ @@ -45,42 +103,59 @@ uint8_t rtr_sol_count = 0; uint8_t prefix_count = 0; /* datastructures */ -abr_cache_t abr_cache[ABR_CACHE_SIZE]; -nbr_cache_t nbr_cache[NBR_CACHE_SIZE]; -def_rtr_lst_t def_rtr_lst[DEF_RTR_LST_SIZE]; -plist_t plist[OPT_PI_LIST_LEN]; +ndp_a6br_cache_t abr_cache[ABR_CACHE_SIZE]; +ndp_neighbor_cache_t nbr_cache[NBR_CACHE_SIZE]; +ndp_default_router_list_t def_rtr_lst[DEF_RTR_LST_SIZE]; +ndp_prefix_list_t plist[OPT_PI_LIST_LEN]; /* pointer */ static uint8_t *llao; addr_list_t *addr_list_ptr; static ipv6_hdr_t *ipv6_buf; -static struct icmpv6_hdr_t *icmp_buf; -static struct rtr_adv_t *rtr_adv_buf; -static struct nbr_sol_t *nbr_sol_buf; -static struct nbr_adv_t *nbr_adv_buf; -static opt_buf_t *opt_buf; -static opt_stllao_t *opt_stllao_buf; -static opt_mtu_t *opt_mtu_buf; -static opt_abro_t *opt_abro_buf; -static opt_6co_hdr_t *opt_6co_hdr_buf; +static icmpv6_hdr_t *icmp_buf; +static icmpv6_router_adv_hdr_t *rtr_adv_buf; +static icmpv6_neighbor_sol_hdr_t *nbr_sol_buf; +static icmpv6_neighbor_adv_hdr_t *nbr_adv_buf; +static icmpv6_ndp_opt_hdr_t *opt_buf; +static icmpv6_ndp_opt_stllao_t *opt_stllao_buf; +static icmpv6_ndp_opt_mtu_t *opt_mtu_buf; +static icmpv6_ndp_opt_abro_t *opt_abro_buf; +static icmpv6_ndp_opt_6co_hdr_t *opt_6co_hdr_buf; static uint8_t *opt_6co_prefix_buf; -static opt_pi_t *opt_pi_buf; -static opt_aro_t *opt_aro_buf; +static icmpv6_ndp_opt_pi_t *opt_pi_buf; +static icmpv6_ndp_opt_aro_t *opt_aro_buf; -nbr_cache_t *nbr_entry; -def_rtr_lst_t *def_rtr_entry; +ndp_neighbor_cache_t *nbr_entry; +ndp_default_router_list_t *def_rtr_entry; /* elements */ //ipv6_addr_t tmpaddr; -uint8_t recvd_cids[LOWPAN_CONTEXT_MAX]; +uint8_t recvd_cids[NDP_6LOWPAN_CONTEXT_MAX]; +uint8_t icmpv6_opt_hdr_len = 0; uint8_t recvd_cids_len = 0; -plist_t *recvd_prefixes[OPT_PI_LIST_LEN]; +ndp_prefix_list_t *recvd_prefixes[OPT_PI_LIST_LEN]; uint8_t recvd_pref_len = 0; -static abr_cache_t *abr_get_most_current(void); -static abr_cache_t *abr_get_oldest(void); +void def_rtr_lst_add(ipv6_addr_t *ipaddr, uint32_t rtr_ltime); +void def_rtr_lst_rem(ndp_default_router_list_t *entry); +uint8_t nbr_cache_add(ipv6_addr_t *ipaddr, ieee_802154_long_t *laddr, + uint8_t isrouter, ndp_nce_state_t state, + ndp_nce_type_t type, uint16_t ltime, + ieee_802154_short_t *saddr); +void nbr_cache_rem(ipv6_addr_t *addr); + +/** + * @brief Set Source link-layer address option according to interface + * configuration. + * + * @param[out] sllao The SLLAO to set. + * @param[in] type The value for the type field of the SLLAO. + * @param[in] length The value for the length field of the SLLAO + */ +void icmpv6_ndp_set_sllao(icmpv6_ndp_opt_stllao_t *sllao, uint8_t type, + uint8_t length); int min(int a, int b) { @@ -92,101 +167,193 @@ int min(int a, int b) } } -static struct para_prob_t *get_para_prob_buf(uint8_t ext_len) +static icmpv6_parameter_prob_hdr_t *get_para_prob_buf(uint8_t ext_len) { - return ((struct para_prob_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); + return ((icmpv6_parameter_prob_hdr_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); } -static struct rtr_adv_t *get_rtr_adv_buf(uint8_t ext_len) +static icmpv6_echo_request_hdr_t *get_echo_req_buf(uint8_t ext_len) { - return ((struct rtr_adv_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); + return ((icmpv6_echo_request_hdr_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); } -static struct nbr_sol_t *get_nbr_sol_buf(uint8_t ext_len) +static icmpv6_echo_reply_hdr_t *get_echo_repl_buf(uint8_t ext_len) { - return ((struct nbr_sol_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); + return ((icmpv6_echo_reply_hdr_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); } -static struct nbr_adv_t *get_nbr_adv_buf(uint8_t ext_len) +static icmpv6_router_adv_hdr_t *get_rtr_adv_buf(uint8_t ext_len) { - return ((struct nbr_adv_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); + return ((icmpv6_router_adv_hdr_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); } -static opt_buf_t *get_opt_buf(uint8_t ext_len, uint8_t opt_len) +static icmpv6_neighbor_sol_hdr_t *get_nbr_sol_buf(uint8_t ext_len) { - return ((opt_buf_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + - ext_len + opt_len])); + return ((icmpv6_neighbor_sol_hdr_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); } -static opt_stllao_t *get_opt_stllao_buf(uint8_t ext_len, uint8_t opt_len) +static icmpv6_neighbor_adv_hdr_t *get_nbr_adv_buf(uint8_t ext_len) { - return ((opt_stllao_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + + return ((icmpv6_neighbor_adv_hdr_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + ext_len])); +} + +static icmpv6_ndp_opt_hdr_t *get_opt_buf(uint8_t ext_len, uint8_t opt_len) +{ + return ((icmpv6_ndp_opt_hdr_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + ext_len + opt_len])); } -static opt_mtu_t *get_opt_mtu_buf(uint8_t ext_len, uint8_t opt_len) +static icmpv6_ndp_opt_stllao_t *get_opt_stllao_buf(uint8_t ext_len, uint8_t opt_len) { - return ((opt_mtu_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + - ext_len + opt_len])); + return ((icmpv6_ndp_opt_stllao_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + + ext_len + opt_len])); } -static opt_abro_t *get_opt_abro_buf(uint8_t ext_len, uint8_t opt_len) +static icmpv6_ndp_opt_mtu_t *get_opt_mtu_buf(uint8_t ext_len, uint8_t opt_len) { - return ((opt_abro_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + - ext_len + opt_len])); -} - -static opt_6co_hdr_t *get_opt_6co_hdr_buf(uint8_t ext_len, uint8_t opt_len) -{ - return ((opt_6co_hdr_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + + return ((icmpv6_ndp_opt_mtu_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + ext_len + opt_len])); } +static icmpv6_ndp_opt_abro_t *get_opt_abro_buf(uint8_t ext_len, uint8_t opt_len) +{ + return ((icmpv6_ndp_opt_abro_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + + ext_len + opt_len])); +} + +static icmpv6_ndp_opt_6co_hdr_t *get_opt_6co_hdr_buf(uint8_t ext_len, uint8_t opt_len) +{ + return ((icmpv6_ndp_opt_6co_hdr_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + + ext_len + opt_len])); +} + static uint8_t *get_opt_6co_prefix_buf(uint8_t ext_len, uint8_t opt_len) { - return ((uint8_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len + opt_len])); + return ((uint8_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + ext_len + opt_len])); } -static opt_pi_t *get_opt_pi_buf(uint8_t ext_len, uint8_t opt_len) +static icmpv6_ndp_opt_pi_t *get_opt_pi_buf(uint8_t ext_len, uint8_t opt_len) { - return ((opt_pi_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len + - opt_len])); + return ((icmpv6_ndp_opt_pi_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + ext_len + + opt_len])); } -static opt_aro_t *get_opt_aro_buf(uint8_t ext_len, uint8_t opt_len) +static icmpv6_ndp_opt_aro_t *get_opt_aro_buf(uint8_t ext_len, uint8_t opt_len) { - return ((opt_aro_t *)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len + - opt_len])); + return ((icmpv6_ndp_opt_aro_t *) &(buffer[LLHDR_ICMPV6HDR_LEN + ext_len + + opt_len])); } -/* send router solicitation message - RFC4861 section 4.1 */ -void init_rtr_sol(uint8_t sllao) +void icmpv6_send_echo_request(ipv6_addr_t *destaddr, uint16_t id, uint16_t seq, char *data, size_t data_len) { - ipv6_buf = get_ipv6_buf(); + uint16_t packet_length; + + ipv6_buf = ipv6_get_buf(); icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); + icmpv6_echo_request_hdr_t *echo_buf = get_echo_req_buf(ipv6_ext_hdr_len); + char *echo_data_buf = ((char *)echo_buf) + sizeof(icmpv6_echo_request_hdr_t); - packet_length = 0; - - icmp_buf->type = ICMP_RTR_SOL; + icmp_buf->type = ICMPV6_TYPE_ECHO_REQUEST; icmp_buf->code = 0; ipv6_buf->version_trafficclass = IPV6_VER; ipv6_buf->trafficclass_flowlabel = 0; ipv6_buf->flowlabel = 0; - ipv6_buf->nextheader = PROTO_NUM_ICMPV6; + ipv6_buf->nextheader = IPV6_PROTO_NUM_ICMPV6; + ipv6_buf->hoplimit = 0xff; + + memcpy(&ipv6_buf->destaddr, destaddr, sizeof(ipv6_addr_t)); + ipv6_iface_get_best_src_addr(&ipv6_buf->srcaddr, &ipv6_buf->destaddr); + echo_buf->id = id; + echo_buf->seq = seq; + + memcpy(echo_data_buf, data, data_len); + packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + ipv6_ext_hdr_len + + ECHO_REQ_LEN + data_len; + + ipv6_buf->length = packet_length - IPV6_HDR_LEN; + + icmp_buf->checksum = 0; + icmp_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6); + +#ifdef ENABLE_DEBUG + char addr_str[IPV6_MAX_ADDR_STR_LEN]; + printf("INFO: send echo request to: %s\n", + ipv6_addr_to_str(addr_str, &ipv6_buf->destaddr)); +#endif + sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_buf->destaddr.uint16[4]), + (uint8_t *)ipv6_buf, + packet_length); +} + +void icmpv6_send_echo_reply(ipv6_addr_t *destaddr, uint16_t id, uint16_t seq, char *data, size_t data_len) +{ + uint16_t packet_length; + + ipv6_buf = ipv6_get_buf(); + icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); + icmpv6_echo_reply_hdr_t *echo_buf = get_echo_repl_buf(ipv6_ext_hdr_len); + char *echo_data_buf = ((char *)echo_buf) + sizeof(icmpv6_echo_reply_hdr_t); + + icmp_buf->type = ICMPV6_TYPE_ECHO_REPLY; + icmp_buf->code = 0; + ipv6_buf->version_trafficclass = IPV6_VER; + ipv6_buf->trafficclass_flowlabel = 0; + ipv6_buf->flowlabel = 0; + ipv6_buf->nextheader = IPV6_PROTO_NUM_ICMPV6; + ipv6_buf->hoplimit = 0xff; + + memcpy(&ipv6_buf->destaddr, destaddr, sizeof(ipv6_addr_t)); + ipv6_iface_get_best_src_addr(&ipv6_buf->srcaddr, &ipv6_buf->destaddr); + echo_buf->id = id; + echo_buf->seq = seq; + + memcpy(echo_data_buf, data, data_len); + packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + ipv6_ext_hdr_len + + ECHO_REPL_LEN + data_len; + + ipv6_buf->length = packet_length - IPV6_HDR_LEN; + + icmp_buf->checksum = 0; + icmp_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6); + +#ifdef ENABLE_DEBUG + char addr_str[IPV6_MAX_ADDR_STR_LEN]; + printf("INFO: send echo request to: %s\n", + ipv6_addr_to_str(addr_str, &ipv6_buf->destaddr)); +#endif + sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_buf->destaddr.uint16[4]), + (uint8_t *)ipv6_buf, + packet_length); +} + +/* send router solicitation message - RFC4861 section 4.1 */ +void icmpv6_send_router_sol(uint8_t sllao) +{ + uint16_t packet_length; + + ipv6_buf = ipv6_get_buf(); + icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); + + icmp_buf->type = ICMPV6_TYPE_ROUTER_SOL; + icmp_buf->code = 0; + ipv6_buf->version_trafficclass = IPV6_VER; + ipv6_buf->trafficclass_flowlabel = 0; + ipv6_buf->flowlabel = 0; + ipv6_buf->nextheader = IPV6_PROTO_NUM_ICMPV6; ipv6_buf->hoplimit = ND_HOPLIMIT; - ipv6_set_all_rtrs_mcast_addr(&ipv6_buf->destaddr); - //iface_find_src_ipaddr(&ipv6_buf->srcaddr, ADDR_STATE_PREFERRED, - /* ADDR_TYPE_MULTICAST); */ + ipv6_addr_set_all_routers_addr(&ipv6_buf->destaddr); + //iface_find_src_ipaddr(&ipv6_buf->srcaddr, NDP_ADDR_STATE_PREFERRED, + /* IPV6_ADDR_TYPE_MULTICAST); */ - ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); + ipv6_iface_get_best_src_addr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); - opt_hdr_len = RTR_SOL_LEN; + icmpv6_opt_hdr_len = RTR_SOL_LEN; ipv6_buf->length = HTONS(ICMPV6_HDR_LEN + RTR_SOL_LEN + OPT_STLLAO_MAX_LEN); if (sllao == OPT_SLLAO) { - opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len); - set_llao(opt_stllao_buf, OPT_SLLAO_TYPE, 2); + opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); + icmpv6_ndp_set_sllao(opt_stllao_buf, NDP_OPT_SLLAO_TYPE, 2); packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + ipv6_ext_hdr_len + RTR_SOL_LEN + OPT_STLLAO_MAX_LEN; } @@ -196,30 +363,84 @@ void init_rtr_sol(uint8_t sllao) } icmp_buf->checksum = 0; - icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); + icmp_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6); #if ENABLE_DEBUG - printf("INFO: send router solicitation to: "); - ipv6_print_addr(&ipv6_buf->destaddr); + char addr_str[IPV6_MAX_ADDR_STR_LEN]; + printf("INFO: send router solicitation to: %s\n", + ipv6_addr_to_str(addr_str, &ipv6_buf->destaddr)); +#endif + sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_buf->destaddr.uint16[4]), + (uint8_t *)ipv6_buf, + packet_length); +} + +void recv_echo_req(void) +{ + ipv6_buf = ipv6_get_buf(); + icmpv6_echo_request_hdr_t *echo_buf = get_echo_req_buf(ipv6_ext_hdr_len); + char *echo_data_buf = ((char *)echo_buf) + sizeof(icmpv6_echo_reply_hdr_t); + size_t data_len = ipv6_buf->length - (IPV6_HDR_LEN + ICMPV6_HDR_LEN + + ipv6_ext_hdr_len + ECHO_REQ_LEN); +#ifdef ENABLE_DEBUG + char addr_str[IPV6_MAX_ADDR_STR_LEN]; + printf("INFO: received echo request from: %s\n", + ipv6_addr_to_str(addr_str, &ipv6_buf->srcaddr)); + printf("\n"); + printf("id = 0x%04x, seq = %d\n", echo_buf->id, echo_buf->seq); + + for (int i = 0; i < data_len; i++) { + printf("%02x ", echo_data_buf[i]); + + if ((i + 1) % 16 || i == data_len - 1) { + printf("\n"); + } + } + +#endif + icmpv6_send_echo_reply(&ipv6_buf->srcaddr, echo_buf->id, echo_buf->seq, + echo_data_buf, data_len); +} + +void recv_echo_repl(void) +{ + ipv6_buf = ipv6_get_buf(); + icmpv6_echo_reply_hdr_t *echo_buf = get_echo_repl_buf(ipv6_ext_hdr_len); + char *echo_data_buf = ((char *)echo_buf) + sizeof(icmpv6_echo_reply_hdr_t); + size_t data_len = ipv6_buf->length - (IPV6_HDR_LEN + ICMPV6_HDR_LEN + + ipv6_ext_hdr_len + ECHO_REPL_LEN); +#ifdef ENABLE_DEBUG + char addr_str[IPV6_MAX_ADDR_STR_LEN]; + printf("INFO: received echo reply from: %s\n", + ipv6_addr_to_str(addr_str, &ipv6_buf->srcaddr)); + printf("\n"); + printf("id = 0x%04x, seq = %d\n", echo_buf->id, echo_buf->seq); + + for (int i = 0; i < data_len; i++) { + printf("%02x ", echo_data_buf[i]); + + if ((i + 1) % 16 || i == data_len - 1) { + printf("\n"); + } + } + #endif - lowpan_init((ieee_802154_long_t *)&(ipv6_buf->destaddr.uint16[4]), - (uint8_t *)ipv6_buf); } void recv_rtr_sol(void) { - opt_hdr_len = RTR_SOL_LEN; - ipv6_buf = get_ipv6_buf(); + icmpv6_opt_hdr_len = RTR_SOL_LEN; + ipv6_buf = ipv6_get_buf(); /* check if source option is set*/ - if (opt_stllao_buf->type == OPT_SLLAO_TYPE) { - opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len); + if (opt_stllao_buf->type == NDP_OPT_SLLAO_TYPE) { + opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); llao = (uint8_t *)opt_stllao_buf; - opt_hdr_len += (opt_stllao_buf->length) << 3; + icmpv6_opt_hdr_len += (opt_stllao_buf->length) << 3; } if (llao != NULL) { - nbr_entry = nbr_cache_search(&ipv6_buf->srcaddr); + nbr_entry = ndp_neighbor_cache_search(&ipv6_buf->srcaddr); if (nbr_entry != NULL) { /* found neighbor in cache, update values and check long addr */ @@ -229,32 +450,34 @@ void recv_rtr_sol(void) else { /* new long addr found, update */ memcpy(&nbr_entry->laddr, &llao[2], 8); - nbr_entry->state = NBR_STATUS_STALE; + nbr_entry->state = NDP_NCE_STATUS_STALE; nbr_entry->isrouter = 0; } } else { /* nothing found, add neigbor into cache*/ nbr_cache_add(&ipv6_buf->srcaddr, (ieee_802154_long_t *)&llao[2], - 0, NBR_STATUS_STALE, NBR_CACHE_TYPE_TEN, + 0, NDP_NCE_STATUS_STALE, NDP_NCE_TYPE_TENTATIVE, NBR_CACHE_LTIME_TEN, NULL); } } /* send solicited router advertisment */ if (abr_count > 0) { - init_rtr_adv(&ipv6_buf->srcaddr, 0, 0, OPT_PI, OPT_6CO, OPT_ABRO); + icmpv6_send_router_adv(&ipv6_buf->srcaddr, 0, 0, OPT_PI, OPT_6CO, OPT_ABRO); } else { - init_rtr_adv(&ipv6_buf->srcaddr, 0, 0, OPT_PI, 0, 0); + icmpv6_send_router_adv(&ipv6_buf->srcaddr, 0, 0, OPT_PI, 0, 0); } #if ENABLE_DEBUG - printf("INFO: send router advertisment to: "); - ipv6_print_addr(&ipv6_buf->destaddr); + char addr_str[IPV6_MAX_ADDR_STR_LEN]; + printf("INFO: send router advertisment to: %s\n", + ipv6_addr_to_str(addr_str, &ipv6_buf->destaddr)); #endif - lowpan_init((ieee_802154_long_t *)&(ipv6_buf->destaddr.uint16[4]), - (uint8_t *)ipv6_buf); + sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_buf->destaddr.uint16[4]), + (uint8_t *)ipv6_buf, + IPV6_HDR_LEN + NTOHS(ipv6_buf->length)); } @@ -263,51 +486,52 @@ uint8_t set_opt_6co_flags(uint8_t compression_flag, uint8_t cid) uint8_t flags; if (compression_flag) { - flags = OPT_6CO_FLAG_C; + flags = ICMPV6_NDP_OPT_6CO_FLAG_CCOMPR; } else { flags = 0; } - flags |= cid & OPT_6CO_FLAG_CID; + flags |= cid & ICMPV6_NDP_OPT_6CO_FLAG_CID; return flags; } void get_opt_6co_flags(uint8_t *compression_flag, uint8_t *cid, uint8_t flags) { - compression_flag[0] = flags & OPT_6CO_FLAG_CID; + compression_flag[0] = flags & ICMPV6_NDP_OPT_6CO_FLAG_CID; compression_flag[0] = compression_flag[0] != 0; - cid[0] = flags & OPT_6CO_FLAG_CID; + cid[0] = flags & ICMPV6_NDP_OPT_6CO_FLAG_CID; } -lowpan_context_t *abr_get_context(abr_cache_t *abr, uint8_t cid); +lowpan_context_t *abr_get_context(ndp_a6br_cache_t *abr, uint8_t cid); -void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, - uint8_t sixco, uint8_t abro) +void icmpv6_send_router_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, + uint8_t sixco, uint8_t abro) { + uint16_t packet_length; lowpan_context_t *contexts = NULL; - abr_cache_t *msg_abr = NULL; - ipv6_buf = get_ipv6_buf(); + ndp_a6br_cache_t *msg_abr = NULL; + ipv6_buf = ipv6_get_buf(); icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); ipv6_buf->version_trafficclass = IPV6_VER; ipv6_buf->trafficclass_flowlabel = 0; ipv6_buf->flowlabel = 0; - ipv6_buf->nextheader = PROTO_NUM_ICMPV6; + ipv6_buf->nextheader = IPV6_PROTO_NUM_ICMPV6; ipv6_buf->hoplimit = ND_HOPLIMIT; if (addr == NULL) { /* not solicited */ - ipv6_set_all_nds_mcast_addr(&ipv6_buf->destaddr); + ipv6_addr_set_all_nodes_addr(&ipv6_buf->destaddr); } else { memcpy(&ipv6_buf->destaddr, addr, 16); } - ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); + ipv6_iface_get_best_src_addr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); - icmp_buf->type = ICMP_RTR_ADV; + icmp_buf->type = ICMPV6_TYPE_ROUTER_ADV; icmp_buf->code = 0; //TODO: gethoplimit func, set current ttl @@ -315,30 +539,30 @@ void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, rtr_adv_buf = get_rtr_adv_buf(ipv6_ext_hdr_len); rtr_adv_buf->hoplimit = MULTIHOP_HOPLIMIT; /* set M and O flag, last 6 bits are zero */ - rtr_adv_buf->autoconfig_flags = (RTR_ADV_M_FLAG << 7) | (RTR_ADV_O_FLAG << 6); + rtr_adv_buf->autoconfig_flags = ICMPV6_ROUTER_ADV_FLAG_MANAGED | ICMPV6_ROUTER_ADV_FLAG_OTHER; rtr_adv_buf->router_lifetime = HTONS(RTR_ADV_MAX_INTERVAL * RTR_ADV_MAX); rtr_adv_buf->reachable_time = 0; rtr_adv_buf->retrans_timer = 0; - opt_hdr_len = RTR_ADV_LEN; + icmpv6_opt_hdr_len = RTR_ADV_LEN; packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + RTR_ADV_LEN; if (sllao == OPT_SLLAO) { /* set link layer address option */ - opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len); - set_llao(opt_stllao_buf, OPT_SLLAO_TYPE, 2); - opt_hdr_len += OPT_STLLAO_MAX_LEN; + opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); + icmpv6_ndp_set_sllao(opt_stllao_buf, NDP_OPT_SLLAO_TYPE, 2); + icmpv6_opt_hdr_len += OPT_STLLAO_MAX_LEN; packet_length += OPT_STLLAO_MAX_LEN; } if (mtu == OPT_MTU) { /* set MTU options */ - opt_mtu_buf = get_opt_mtu_buf(ipv6_ext_hdr_len, opt_hdr_len); + opt_mtu_buf = get_opt_mtu_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); opt_mtu_buf->type = OPT_MTU_TYPE; opt_mtu_buf->length = OPT_MTU_LEN; opt_mtu_buf->reserved = 0; opt_mtu_buf->mtu = HTONL(1500); - opt_hdr_len += OPT_MTU_HDR_LEN; + icmpv6_opt_hdr_len += OPT_MTU_HDR_LEN; packet_length += OPT_MTU_HDR_LEN; } @@ -347,8 +571,8 @@ void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, if (abro == OPT_ABRO) { /* set authoritive border router option */ if (abr_count > 0) { - msg_abr = abr_get_most_current(); - opt_abro_buf = get_opt_abro_buf(ipv6_ext_hdr_len, opt_hdr_len); + msg_abr = ndp_a6br_cache_get_most_current(); + opt_abro_buf = get_opt_abro_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); opt_abro_buf->type = OPT_ABRO_TYPE; opt_abro_buf->length = OPT_ABRO_LEN; opt_abro_buf->version = HTONS(msg_abr->version); @@ -367,11 +591,11 @@ void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, contexts_len = lowpan_context_len(); } else { - lowpan_context_t c_tmp[LOWPAN_CONTEXT_MAX]; + lowpan_context_t c_tmp[NDP_6LOWPAN_CONTEXT_MAX]; contexts_len = 0; - for (int i = 0; i < LOWPAN_CONTEXT_MAX; i++) { + for (int i = 0; i < NDP_6LOWPAN_CONTEXT_MAX; i++) { lowpan_context_t *ctx = abr_get_context(msg_abr, i); if (ctx != NULL) { @@ -384,7 +608,7 @@ void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, } for (int i = 0; i < contexts_len; i++) { - opt_6co_hdr_buf = get_opt_6co_hdr_buf(ipv6_ext_hdr_len, opt_hdr_len); + opt_6co_hdr_buf = get_opt_6co_hdr_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); opt_6co_hdr_buf->type = OPT_6CO_TYPE; if (contexts[i].length > 64) { @@ -399,21 +623,21 @@ void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, opt_6co_hdr_buf->reserved = 0; opt_6co_hdr_buf->val_ltime = HTONS(contexts[i].lifetime); - opt_hdr_len += OPT_6CO_HDR_LEN; + icmpv6_opt_hdr_len += OPT_6CO_HDR_LEN; packet_length += OPT_6CO_HDR_LEN; /* attach prefixes */ - opt_6co_prefix_buf = get_opt_6co_prefix_buf(ipv6_ext_hdr_len, opt_hdr_len); + opt_6co_prefix_buf = get_opt_6co_prefix_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); if (opt_6co_hdr_buf->c_length > 64) { memset((void *)opt_6co_prefix_buf, 0, 16); - memcpy((void *)opt_6co_prefix_buf, (void *) & (contexts[i].prefix.uint8[0]), opt_6co_hdr_buf->c_length / 8); - opt_hdr_len += 16; + memcpy((void *)opt_6co_prefix_buf, (void *) &(contexts[i].prefix.uint8[0]), opt_6co_hdr_buf->c_length / 8); + icmpv6_opt_hdr_len += 16; packet_length += 16; } else { memset((void *)opt_6co_prefix_buf, 0, 8); - memcpy((void *)opt_6co_prefix_buf, (void *) & (contexts[i].prefix.uint8[0]), opt_6co_hdr_buf->c_length / 8); - opt_hdr_len += 8; + memcpy((void *)opt_6co_prefix_buf, (void *) &(contexts[i].prefix.uint8[0]), opt_6co_hdr_buf->c_length / 8); + icmpv6_opt_hdr_len += 8; packet_length += 8; } @@ -430,7 +654,7 @@ void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, /* set prefix option */ for (int i = 0; i < OPT_PI_LIST_LEN; i++) { if (plist[i].inuse && plist[i].adv) { - opt_pi_buf = get_opt_pi_buf(ipv6_ext_hdr_len, opt_hdr_len); + opt_pi_buf = get_opt_pi_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); memcpy(&(opt_pi_buf->addr.uint8[0]), &(plist[i].addr.uint8[0]), 16); opt_pi_buf->type = OPT_PI_TYPE; opt_pi_buf->length = OPT_PI_LEN; @@ -440,7 +664,7 @@ void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, opt_pi_buf->pref_ltime = HTONL(plist[i].pref_ltime); opt_pi_buf->reserved2 = 0; packet_length += OPT_PI_HDR_LEN; - opt_hdr_len += OPT_PI_HDR_LEN; + icmpv6_opt_hdr_len += OPT_PI_HDR_LEN; } } } @@ -449,7 +673,7 @@ void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, /* calculate checksum */ icmp_buf->checksum = 0; - icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); + icmp_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6); } void recv_rtr_adv(void) @@ -457,10 +681,12 @@ void recv_rtr_adv(void) int8_t trigger_ns = -1; int8_t abro_found = 0; int16_t abro_version = 0; /* later replaced, just to supress warnings */ + uint16_t packet_length; ipv6_addr_t abro_addr; - ipv6_buf = get_ipv6_buf(); - opt_hdr_len = RTR_ADV_LEN; + ipv6_buf = ipv6_get_buf(); + packet_length = IPV6_HDR_LEN + ipv6_buf->length; + icmpv6_opt_hdr_len = RTR_ADV_LEN; rtr_adv_buf = get_rtr_adv_buf(ipv6_ext_hdr_len); ipv6_addr_t newaddr; recvd_cids_len = 0; @@ -474,7 +700,7 @@ void recv_rtr_adv(void) iface.adv_retrans_timer = HTONL(rtr_adv_buf->retrans_timer); } - def_rtr_entry = def_rtr_lst_search(&ipv6_buf->srcaddr); + def_rtr_entry = ndp_default_router_list_search(&ipv6_buf->srcaddr); if (rtr_adv_buf->router_lifetime != 0) { if (def_rtr_entry != NULL) { @@ -495,11 +721,11 @@ void recv_rtr_adv(void) mutex_lock(&lowpan_context_mutex); /* read options */ - while (packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len) { - opt_buf = get_opt_buf(ipv6_ext_hdr_len, opt_hdr_len); + while (packet_length > IPV6HDR_ICMPV6HDR_LEN + icmpv6_opt_hdr_len) { + opt_buf = get_opt_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); - switch(opt_buf->type) { - case (OPT_SLLAO_TYPE): { + switch (opt_buf->type) { + case (NDP_OPT_SLLAO_TYPE): { break; } @@ -509,37 +735,38 @@ void recv_rtr_adv(void) /* rfc 4862 section 5.5.3 */ case (OPT_PI_TYPE): { - opt_pi_buf = get_opt_pi_buf(ipv6_ext_hdr_len, opt_hdr_len); + opt_pi_buf = get_opt_pi_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); /* crazy condition, read 5.5.3a-b-c for further information */ - if (ipv6_prefix_ll_match(&opt_pi_buf->addr) || - (HTONL(opt_pi_buf->pref_ltime) > - HTONL(opt_pi_buf->val_ltime))) { + if (ipv6_addr_is_link_local(&opt_pi_buf->addr) || + (HTONL(opt_pi_buf->pref_ltime) > + HTONL(opt_pi_buf->val_ltime))) { break; } else { /* check if on-link flag is set */ - if (opt_pi_buf->l_a_reserved1 & OPT_PI_FLAG_L) { + if (opt_pi_buf->l_a_reserved1 & ICMPV6_NDP_OPT_PI_FLAG_ON_LINK) { /* TODO: do on-link pi handling */ } - if (opt_pi_buf->l_a_reserved1 & OPT_PI_FLAG_A) { + if (opt_pi_buf->l_a_reserved1 & ICMPV6_NDP_OPT_PI_FLAG_AUTONOM) { addr_list_ptr = ipv6_iface_addr_prefix_eq(&opt_pi_buf->addr); if (addr_list_ptr == NULL) { /* 5.5.3d */ if (opt_pi_buf->val_ltime != 0) { /* iid will also be added here */ - ipv6_init_addr_prefix(&newaddr, &opt_pi_buf->addr); + ipv6_addr_set_by_eui64(&newaddr, + &opt_pi_buf->addr); /* add into address list * TODO: duplicate address detection is not * implementet yet, so all new addresse will * be added with state PREFFERED */ ipv6_iface_add_addr(&newaddr, - ADDR_STATE_PREFERRED, + IPV6_ADDR_TYPE_UNICAST, + NDP_ADDR_STATE_PREFERRED, opt_pi_buf->val_ltime, - opt_pi_buf->pref_ltime, - ADDR_CONFIGURED_AUTO); + opt_pi_buf->pref_ltime); printf("INFO: added address to interface\n"); trigger_ns = 1; } @@ -550,8 +777,8 @@ void recv_rtr_adv(void) /* 7200 = 2hours in seconds */ if (HTONL(opt_pi_buf->val_ltime) > 7200 || - HTONL(opt_pi_buf->val_ltime) > - get_remaining_time(&(addr_list_ptr->val_ltime))) { + HTONL(opt_pi_buf->val_ltime) > + get_remaining_time(&(addr_list_ptr->val_ltime))) { set_remaining_time(&(addr_list_ptr->val_ltime), HTONL(opt_pi_buf->val_ltime)); } else { @@ -570,14 +797,14 @@ void recv_rtr_adv(void) uint8_t comp; uint8_t num; - opt_6co_hdr_buf = get_opt_6co_hdr_buf(ipv6_ext_hdr_len, opt_hdr_len); + opt_6co_hdr_buf = get_opt_6co_hdr_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); get_opt_6co_flags(&comp, &num, opt_6co_hdr_buf->c_flags); ipv6_addr_t prefix; memset(&prefix, 0, 16); - opt_6co_prefix_buf = get_opt_6co_prefix_buf(ipv6_ext_hdr_len, opt_hdr_len + OPT_6CO_HDR_LEN); + opt_6co_prefix_buf = get_opt_6co_prefix_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len + OPT_6CO_HDR_LEN); memcpy(&prefix, opt_6co_prefix_buf, opt_6co_hdr_buf->c_length); @@ -589,12 +816,12 @@ void recv_rtr_adv(void) HTONS(opt_6co_hdr_buf->val_ltime) ); recvd_cids[recvd_cids_len] = num; - recvd_cids_len = (recvd_cids_len + 1) % LOWPAN_CONTEXT_MAX; + recvd_cids_len = (recvd_cids_len + 1) % NDP_6LOWPAN_CONTEXT_MAX; break; } case (OPT_ABRO_TYPE): { - opt_abro_buf = get_opt_abro_buf(ipv6_ext_hdr_len, opt_hdr_len); + opt_abro_buf = get_opt_abro_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); abro_found = 1; abro_version = HTONS(opt_abro_buf->version); memcpy(&(abro_addr), &(opt_abro_buf->addr), sizeof(ipv6_addr_t)); @@ -606,7 +833,7 @@ void recv_rtr_adv(void) } /* multiplied with 8 because options length is in units of 8 bytes */ - opt_hdr_len += (opt_buf->length * 8); + icmpv6_opt_hdr_len += (opt_buf->length * 8); } if (abro_found) { @@ -628,27 +855,32 @@ void recv_rtr_adv(void) * containing its tentative global IPv6 address to register * * if new address was configured, set src to newaddr(gp16) */ - init_nbr_sol(&newaddr, &(ipv6_buf->srcaddr), &(ipv6_buf->srcaddr), OPT_SLLAO, OPT_ARO); + icmpv6_send_neighbor_sol(&newaddr, &(ipv6_buf->srcaddr), &(ipv6_buf->srcaddr), OPT_SLLAO, OPT_ARO); #if ENABLE_DEBUG - printf("INFO: send neighbor solicitation to: "); - ipv6_print_addr(&(ipv6_buf->destaddr)); + char addr_str[IPV6_MAX_ADDR_STR_LEN]; + printf("INFO: send neighbor solicitation to: %s\n", + ipv6_addr_to_str(addr_str, &(ipv6_buf->destaddr))); #endif - lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]), (uint8_t *)ipv6_buf); + sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_buf->destaddr.uint16[4]), + (uint8_t *)ipv6_buf, + packet_length); } } -void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ, - uint8_t sllao, uint8_t aro) +void icmpv6_send_neighbor_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ, + uint8_t sllao, uint8_t aro) { - ipv6_buf = get_ipv6_buf(); + uint16_t packet_length; + + ipv6_buf = ipv6_get_buf(); ipv6_buf->version_trafficclass = IPV6_VER; ipv6_buf->trafficclass_flowlabel = 0; ipv6_buf->flowlabel = 0; - ipv6_buf->nextheader = PROTO_NUM_ICMPV6; + ipv6_buf->nextheader = IPV6_PROTO_NUM_ICMPV6; ipv6_buf->hoplimit = ND_HOPLIMIT; if (dest == NULL) { - ipv6_set_sol_node_mcast_addr(targ, &(ipv6_buf->destaddr)); + ipv6_addr_set_solicited_node_addr(&(ipv6_buf->destaddr), targ); } else { memcpy(&(ipv6_buf->destaddr.uint8[0]), &(dest->uint8[0]), 16); @@ -656,19 +888,19 @@ void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ, ipv6_ext_hdr_len = 0; icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); - icmp_buf->type = ICMP_NBR_SOL; + icmp_buf->type = ICMPV6_TYPE_NEIGHBOR_SOL; icmp_buf->code = 0; nbr_sol_buf = get_nbr_sol_buf(ipv6_ext_hdr_len); nbr_sol_buf->reserved = 0; - memcpy(&(nbr_sol_buf->tgtaddr), targ, 16); - opt_hdr_len = NBR_SOL_LEN; + memcpy(&(nbr_sol_buf->target_addr), targ, 16); + icmpv6_opt_hdr_len = NBR_SOL_LEN; packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + NBR_SOL_LEN; if (ipv6_iface_addr_match(targ) == NULL) { if (src == NULL) { - ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); + ipv6_iface_get_best_src_addr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); } else { memcpy(&(ipv6_buf->srcaddr), src, 16); @@ -676,9 +908,9 @@ void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ, if (sllao == OPT_SLLAO) { /* set sllao option */ - opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len); - set_llao(opt_stllao_buf, OPT_SLLAO_TYPE, 1); - opt_hdr_len += OPT_STLLAO_MIN_LEN; + opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); + icmpv6_ndp_set_sllao(opt_stllao_buf, NDP_OPT_SLLAO_TYPE, 1); + icmpv6_opt_hdr_len += OPT_STLLAO_MIN_LEN; packet_length += OPT_STLLAO_MIN_LEN; } @@ -686,14 +918,14 @@ void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ, if (aro == OPT_ARO) { /* set aro option */ - opt_aro_buf = get_opt_aro_buf(ipv6_ext_hdr_len, opt_hdr_len); + opt_aro_buf = get_opt_aro_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); opt_aro_buf->type = OPT_ARO_TYPE; opt_aro_buf->length = OPT_ARO_LEN; opt_aro_buf->status = 0; opt_aro_buf->reserved1 = 0; opt_aro_buf->reserved2 = 0; - memcpy(&(opt_aro_buf->eui64), mac_get_eui(src), 8); - opt_hdr_len += OPT_ARO_HDR_LEN; + memcpy(&(opt_aro_buf->eui64), sixlowpan_mac_get_eui64(src), 8); + icmpv6_opt_hdr_len += OPT_ARO_HDR_LEN; packet_length += OPT_ARO_HDR_LEN; } @@ -701,57 +933,58 @@ void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ, ipv6_buf->length = HTONS(packet_length - IPV6_HDR_LEN); icmp_buf->checksum = 0; - icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); + icmp_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6); } void recv_nbr_sol(void) { - ipv6_buf = get_ipv6_buf(); + ipv6_buf = ipv6_get_buf(); llao = NULL; - opt_hdr_len = NBR_SOL_LEN; + icmpv6_opt_hdr_len = NBR_SOL_LEN; uint8_t send_na = 0; uint8_t sllao_set = 0; - uint8_t aro_state = OPT_ARO_STATE_SUCCESS; + uint8_t aro_state = NDP_OPT_ARO_STATE_SUCCESS; + uint16_t packet_length = IPV6_HDR_LEN + ipv6_buf->length; /* check whick options are set, we need that because an aro * option condition is that a sllao option is set. thus that we don't * know which option comes first we need to this here */ - while (packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len) { - opt_buf = get_opt_buf(ipv6_ext_hdr_len, opt_hdr_len); + while (packet_length > IPV6HDR_ICMPV6HDR_LEN + icmpv6_opt_hdr_len) { + opt_buf = get_opt_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); - if (opt_buf->type == OPT_SLLAO_TYPE) { + if (opt_buf->type == NDP_OPT_SLLAO_TYPE) { sllao_set = 1; } - opt_hdr_len += (opt_buf->length * 8); + icmpv6_opt_hdr_len += (opt_buf->length * 8); } - opt_hdr_len = NBR_SOL_LEN; + icmpv6_opt_hdr_len = NBR_SOL_LEN; - while (packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len) { - opt_buf = get_opt_buf(ipv6_ext_hdr_len, opt_hdr_len); + while (packet_length > IPV6HDR_ICMPV6HDR_LEN + icmpv6_opt_hdr_len) { + opt_buf = get_opt_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); - switch(opt_buf->type) { - case (OPT_SLLAO_TYPE): { + switch (opt_buf->type) { + case (NDP_OPT_SLLAO_TYPE): { opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, - opt_hdr_len); + icmpv6_opt_hdr_len); llao = (uint8_t *)opt_stllao_buf; if (llao != NULL && - !(ipv6_addr_unspec_match(&ipv6_buf->srcaddr))) { - nbr_entry = nbr_cache_search(&(ipv6_buf->srcaddr)); + !(ipv6_addr_is_unspecified(&ipv6_buf->srcaddr))) { + nbr_entry = ndp_neighbor_cache_search(&(ipv6_buf->srcaddr)); if (nbr_entry != NULL) { - switch(opt_stllao_buf->length) { + switch (opt_stllao_buf->length) { case (1): { if (memcmp(&llao[2], &(nbr_entry->saddr), 2) == 0) { nbr_entry->isrouter = 0; } else { memcpy(&nbr_entry->saddr, &llao[2], 2); - nbr_entry->state = NBR_STATUS_STALE; + nbr_entry->state = NDP_NCE_STATUS_STALE; nbr_entry->isrouter = 0; } @@ -764,7 +997,7 @@ void recv_nbr_sol(void) } else { memcpy(&nbr_entry->laddr, &llao[2], 8); - nbr_entry->state = NBR_STATUS_STALE; + nbr_entry->state = NDP_NCE_STATUS_STALE; nbr_entry->isrouter = 0; } @@ -776,11 +1009,11 @@ void recv_nbr_sol(void) } } else { - switch(opt_stllao_buf->length) { + switch (opt_stllao_buf->length) { case (1): { nbr_cache_add(&ipv6_buf->srcaddr, - NULL , 0, NBR_STATUS_STALE, - NBR_CACHE_TYPE_TEN, + NULL , 0, NDP_NCE_STATUS_STALE, + NDP_NCE_TYPE_TENTATIVE, NBR_CACHE_LTIME_TEN, (ieee_802154_short_t *)&llao[2]); @@ -790,8 +1023,8 @@ void recv_nbr_sol(void) case (2): { nbr_cache_add(&ipv6_buf->srcaddr, (ieee_802154_long_t *)&llao[2], 0, - NBR_STATUS_STALE, - NBR_CACHE_TYPE_TEN, + NDP_NCE_STATUS_STALE, + NDP_NCE_TYPE_TENTATIVE, NBR_CACHE_LTIME_TEN, NULL); break; } @@ -808,26 +1041,26 @@ void recv_nbr_sol(void) case (OPT_ARO_TYPE): { /* check if sllao option is set, and if address src address * isn't unspecified - draft-ietf-6lowpan-nd-15#section-6.5 */ - if (!(ipv6_addr_unspec_match(&ipv6_buf->srcaddr)) && - sllao_set == 1) { + if (!(ipv6_addr_is_unspecified(&ipv6_buf->srcaddr)) && + sllao_set == 1) { opt_aro_buf = get_opt_aro_buf(ipv6_ext_hdr_len, - opt_hdr_len); + icmpv6_opt_hdr_len); if ((opt_aro_buf->length == 2) && - (opt_aro_buf->status == 0)) { + (opt_aro_buf->status == 0)) { /* check neighbor cache for duplicates */ - nbr_entry = nbr_cache_search(&(ipv6_buf->srcaddr)); + nbr_entry = ndp_neighbor_cache_search(&(ipv6_buf->srcaddr)); if (nbr_entry == NULL) { /* create neighbor cache */ aro_state = nbr_cache_add(&ipv6_buf->srcaddr, &(opt_aro_buf->eui64), 0, - NBR_STATUS_STALE, NBR_CACHE_TYPE_TEN, + NDP_NCE_STATUS_STALE, NDP_NCE_TYPE_TENTATIVE, opt_aro_buf->reg_ltime, NULL); } else { if (memcmp(&(nbr_entry->addr.uint16[4]), - &(opt_aro_buf->eui64.uint16[0]), 8) == 0) { + &(opt_aro_buf->eui64.uint16[0]), 8) == 0) { /* update neighbor cache entry */ if (opt_aro_buf->reg_ltime == 0) { /* delete neighbor cache entry */ @@ -835,17 +1068,17 @@ void recv_nbr_sol(void) } else { set_remaining_time(&(nbr_entry->ltime), (uint32_t)opt_aro_buf->reg_ltime); - nbr_entry->state = NBR_STATUS_STALE; + nbr_entry->state = NDP_NCE_STATUS_STALE; nbr_entry->isrouter = 0; memcpy(&(nbr_entry->addr.uint8[0]), &(ipv6_buf->srcaddr.uint8[0]), 16); } - aro_state = OPT_ARO_STATE_SUCCESS; + aro_state = NDP_OPT_ARO_STATE_SUCCESS; } else { /* duplicate found */ - aro_state = OPT_ARO_STATE_DUP_ADDR; + aro_state = NDP_OPT_ARO_STATE_DUP_ADDR; } } } @@ -858,53 +1091,58 @@ void recv_nbr_sol(void) break; } - opt_hdr_len += (opt_buf->length * 8); + icmpv6_opt_hdr_len += (opt_buf->length * 8); } addr_list_t *alist_targ, *alist_dest; nbr_sol_buf = get_nbr_sol_buf(ipv6_ext_hdr_len); - alist_targ = ipv6_iface_addr_match(&(nbr_sol_buf->tgtaddr)); + alist_targ = ipv6_iface_addr_match(&(nbr_sol_buf->target_addr)); if (alist_targ != NULL) { alist_dest = ipv6_iface_addr_match(&(ipv6_buf->destaddr)); if ((memcmp(&(alist_targ->addr), &(alist_dest->addr), 16) == 0) || - ipv6_addr_sol_node_mcast_match(&ipv6_buf->destaddr)) { + ipv6_addr_is_solicited_node(&ipv6_buf->destaddr)) { memcpy(&(ipv6_buf->destaddr.uint8[0]), &(ipv6_buf->srcaddr.uint8[0]), 16); memcpy(&(ipv6_buf->srcaddr.uint8[0]), - &(nbr_sol_buf->tgtaddr.uint8[0]), 16); + &(nbr_sol_buf->target_addr.uint8[0]), 16); send_na = 1; } } if (send_na) { /* solicited na */ - uint8_t flags = (NBR_ADV_FLAG_O | NBR_ADV_FLAG_S); - init_nbr_adv(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr), - &(alist_targ->addr), flags, 0, OPT_ARO, aro_state); + uint8_t flags = (ICMPV6_NEIGHBOR_ADV_FLAG_OVERRIDE | ICMPV6_NEIGHBOR_ADV_FLAG_SOLICITED); + icmpv6_send_neighbor_adv(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr), + &(alist_targ->addr), flags, 0, OPT_ARO); #if ENABLE_DEBUG - printf("INFO: send neighbor advertisment to: "); - ipv6_print_addr(&ipv6_buf->destaddr); + char addr_str[IPV6_MAX_ADDR_STR_LEN]; + printf("INFO: send neighbor advertisment to: %s\n", + ipv6_addr_to_str(addr_str, &ipv6_buf->destaddr)); #endif - lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]), (uint8_t *)ipv6_buf); + sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_buf->destaddr.uint16[4]), + (uint8_t *)ipv6_buf, + packet_length); } } -void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt, - uint8_t rso, uint8_t sllao, uint8_t aro, uint8_t aro_state) +void icmpv6_send_neighbor_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt, + uint8_t rso, uint8_t sllao, uint8_t aro) { - ipv6_buf = get_ipv6_buf(); + uint16_t packet_length; + + ipv6_buf = ipv6_get_buf(); ipv6_buf->version_trafficclass = IPV6_VER; ipv6_buf->trafficclass_flowlabel = 0; ipv6_buf->flowlabel = 0; - ipv6_buf->nextheader = PROTO_NUM_ICMPV6; + ipv6_buf->nextheader = IPV6_PROTO_NUM_ICMPV6; ipv6_buf->hoplimit = ND_HOPLIMIT; ipv6_ext_hdr_len = 0; icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); - icmp_buf->type = ICMP_NBR_ADV; + icmp_buf->type = ICMPV6_TYPE_NEIGHBOR_ADV; icmp_buf->code = 0; memcpy(&(ipv6_buf->destaddr.uint8[0]), &(dst->uint8[0]), 16); @@ -914,29 +1152,29 @@ void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt, nbr_adv_buf->rso = rso; memset(&(nbr_adv_buf->reserved[0]), 0, 3); - memcpy(&(nbr_adv_buf->tgtaddr.uint8[0]), &(tgt->uint8[0]), 16); + memcpy(&(nbr_adv_buf->target_addr.uint8[0]), &(tgt->uint8[0]), 16); packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + NBR_ADV_LEN; if (sllao == OPT_SLLAO) { /* set sllao option */ - opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len); - set_llao(opt_stllao_buf, OPT_SLLAO_TYPE, 1); - opt_hdr_len += OPT_STLLAO_MIN_LEN; + opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); + icmpv6_ndp_set_sllao(opt_stllao_buf, NDP_OPT_SLLAO_TYPE, 1); + icmpv6_opt_hdr_len += OPT_STLLAO_MIN_LEN; packet_length += OPT_STLLAO_MIN_LEN; } if (aro == OPT_ARO) { /* set aro option */ - opt_aro_buf = get_opt_aro_buf(ipv6_ext_hdr_len, opt_hdr_len); + opt_aro_buf = get_opt_aro_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); opt_aro_buf->type = OPT_ARO_TYPE; opt_aro_buf->length = OPT_ARO_LEN; opt_aro_buf->status = 0; /* TODO */ opt_aro_buf->reserved1 = 0; opt_aro_buf->reserved2 = 0; - memcpy(&(opt_aro_buf->eui64), mac_get_eui(dst), 8); - opt_hdr_len += OPT_ARO_HDR_LEN; + memcpy(&(opt_aro_buf->eui64), sixlowpan_mac_get_eui64(dst), 8); + icmpv6_opt_hdr_len += OPT_ARO_HDR_LEN; packet_length += OPT_ARO_HDR_LEN; } @@ -944,25 +1182,27 @@ void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt, ipv6_buf->length = HTONS(packet_length - IPV6_HDR_LEN); icmp_buf->checksum = 0; - icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); + icmp_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6); } void recv_nbr_adv(void) { - opt_hdr_len = NBR_ADV_LEN; + ipv6_buf = ipv6_get_buf(); + uint16_t packet_length = IPV6_HDR_LEN + ipv6_buf->length; + icmpv6_opt_hdr_len = NBR_ADV_LEN; llao = NULL; nbr_entry = NULL; int8_t new_ll = -1; nbr_adv_buf = get_nbr_adv_buf(ipv6_ext_hdr_len); /* check if options are present */ - while (packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len) { - opt_buf = get_opt_buf(ipv6_ext_hdr_len, opt_hdr_len); + while (packet_length > IPV6HDR_ICMPV6HDR_LEN + icmpv6_opt_hdr_len) { + opt_buf = get_opt_buf(ipv6_ext_hdr_len, icmpv6_opt_hdr_len); - switch(opt_buf->type) { - case (OPT_TLLAO_TYPE): { + switch (opt_buf->type) { + case (NDP_OPT_TLLAO_TYPE): { llao = (uint8_t *)get_opt_stllao_buf(ipv6_ext_hdr_len, - opt_hdr_len); + icmpv6_opt_hdr_len); break; } @@ -971,14 +1211,14 @@ void recv_nbr_adv(void) } } - opt_hdr_len += (opt_buf->length * 8); + icmpv6_opt_hdr_len += (opt_buf->length * 8); } addr_list_t *addr; - addr = ipv6_iface_addr_match(&nbr_adv_buf->tgtaddr); + addr = ipv6_iface_addr_match(&nbr_adv_buf->target_addr); if (addr == NULL) { - nbr_entry = nbr_cache_search(&nbr_adv_buf->tgtaddr); + nbr_entry = ndp_neighbor_cache_search(&nbr_adv_buf->target_addr); if (nbr_entry != NULL) { if (llao != 0) { @@ -986,7 +1226,7 @@ void recv_nbr_adv(void) new_ll = memcmp(&llao[2], &(nbr_entry->laddr), 8); } - if (nbr_entry->state == NBR_STATUS_INCOMPLETE) { + if (nbr_entry->state == NDP_NCE_STATUS_INCOMPLETE) { if (llao == NULL) { return; } @@ -994,39 +1234,39 @@ void recv_nbr_adv(void) /* TODO: untersheiden zwischen short und long stllao option */ memcpy(&nbr_entry->laddr, &llao[2], 8); - if (nbr_adv_buf->rso & NBR_ADV_FLAG_S) { - nbr_entry->state = NBR_STATUS_REACHABLE; + if (nbr_adv_buf->rso & ICMPV6_NEIGHBOR_ADV_FLAG_SOLICITED) { + nbr_entry->state = NDP_NCE_STATUS_REACHABLE; /* TODO: set rechability */ } else { - nbr_entry->state = NBR_STATUS_STALE; + nbr_entry->state = NDP_NCE_STATUS_STALE; } - nbr_entry->isrouter = nbr_adv_buf->rso & NBR_ADV_FLAG_R; + nbr_entry->isrouter = nbr_adv_buf->rso & ICMPV6_NEIGHBOR_ADV_FLAG_ROUTER; } else { - if (new_ll && !(nbr_adv_buf->rso & NBR_ADV_FLAG_O)) { - if (nbr_entry->state == NBR_STATUS_REACHABLE) { - nbr_entry->state = NBR_STATUS_STALE; + if (new_ll && !(nbr_adv_buf->rso & ICMPV6_NEIGHBOR_ADV_FLAG_OVERRIDE)) { + if (nbr_entry->state == NDP_NCE_STATUS_REACHABLE) { + nbr_entry->state = NDP_NCE_STATUS_STALE; } return; } else { - if ((nbr_adv_buf->rso & NBR_ADV_FLAG_O) || - (!(nbr_adv_buf->rso & NBR_ADV_FLAG_O) && llao != 0 && - !new_ll)) { + if ((nbr_adv_buf->rso & ICMPV6_NEIGHBOR_ADV_FLAG_OVERRIDE) || + (!(nbr_adv_buf->rso & ICMPV6_NEIGHBOR_ADV_FLAG_OVERRIDE) && llao != 0 && + !new_ll)) { if (llao != 0) { memcpy(&nbr_entry->laddr, &llao[2], 8); } - if (nbr_adv_buf->rso & NBR_ADV_FLAG_S) { - nbr_entry->state = NBR_STATUS_REACHABLE; + if (nbr_adv_buf->rso & ICMPV6_NEIGHBOR_ADV_FLAG_SOLICITED) { + nbr_entry->state = NDP_NCE_STATUS_REACHABLE; /* TODO: set rechablility */ } else { if (llao != 0 && new_ll) { - nbr_entry->state = NBR_STATUS_STALE; + nbr_entry->state = NDP_NCE_STATUS_STALE; } } } @@ -1037,7 +1277,7 @@ void recv_nbr_adv(void) } /* link-layer address option - RFC4861 section 4.6.1/ RFC4944 8. */ -void set_llao(opt_stllao_t *sllao, uint8_t type, uint8_t length) +void icmpv6_ndp_set_sllao(icmpv6_ndp_opt_stllao_t *sllao, uint8_t type, uint8_t length) { sllao->type = type; sllao->length = length; @@ -1045,7 +1285,7 @@ void set_llao(opt_stllao_t *sllao, uint8_t type, uint8_t length) uint8_t *llao = (uint8_t *)sllao; /* get link layer address */ - switch(length) { + switch (length) { case (1): { memcpy(&llao[2], &(iface.saddr), 2); memset(&llao[4], 0, 4); @@ -1067,7 +1307,7 @@ void set_llao(opt_stllao_t *sllao, uint8_t type, uint8_t length) uint16_t icmpv6_csum(uint8_t proto) { - ipv6_buf = get_ipv6_buf(); + ipv6_buf = ipv6_get_buf(); uint16_t sum; uint16_t len = NTOHS(ipv6_buf->length); sum = len + proto; @@ -1079,25 +1319,25 @@ uint16_t icmpv6_csum(uint8_t proto) } -void init_para_prob(ipv6_addr_t *src, ipv6_addr_t *dest, uint8_t code, uint32_t pointer, uint8_t *packet, uint8_t packet_len) +void icmpv6_send_parameter_prob(ipv6_addr_t *src, ipv6_addr_t *dest, + uint8_t code, uint32_t pointer, + uint8_t *packet, uint8_t packet_len) { - struct para_prob_t *para_prob_buf; + uint16_t packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + PARA_PROB_LEN; + icmpv6_parameter_prob_hdr_t *para_prob_buf; + memcpy(&(ipv6_buf[packet_length]), packet, min(IPV6_MTU - packet_length, packet_len)); - packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + PARA_PROB_LEN; - - memcpy(&(ipv6_buf[packet_length]), packet, min(MTU - packet_length, packet_len)); - - ipv6_buf = get_ipv6_buf(); + ipv6_buf = ipv6_get_buf(); ipv6_buf->version_trafficclass = IPV6_VER; ipv6_buf->trafficclass_flowlabel = 0; ipv6_buf->flowlabel = 0; - ipv6_buf->nextheader = PROTO_NUM_ICMPV6; + ipv6_buf->nextheader = IPV6_PROTO_NUM_ICMPV6; ipv6_buf->hoplimit = ND_HOPLIMIT; ipv6_ext_hdr_len = 0; icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); - icmp_buf->type = ICMP_PARA_PROB; + icmp_buf->type = ICMPV6_TYPE_PARAMETER_PROB; icmp_buf->code = code; memcpy(&(ipv6_buf->destaddr.uint8[0]), &(dest->uint8[0]), 16); @@ -1107,18 +1347,18 @@ void init_para_prob(ipv6_addr_t *src, ipv6_addr_t *dest, uint8_t code, uint32_t para_prob_buf->pointer = pointer; - packet_length += min(MTU - packet_length, packet_len); + packet_length += min(IPV6_MTU - packet_length, packet_len); ipv6_buf->length = HTONS(packet_length - IPV6_HDR_LEN); icmp_buf->checksum = 0; - icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6); + icmp_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6); } //------------------------------------------------------------------------------ /* neighbor cache functions */ -nbr_cache_t *nbr_cache_search(ipv6_addr_t *ipaddr) +ndp_neighbor_cache_t *ndp_neighbor_cache_search(ipv6_addr_t *ipaddr) { int i; @@ -1132,12 +1372,13 @@ nbr_cache_t *nbr_cache_search(ipv6_addr_t *ipaddr) } uint8_t nbr_cache_add(ipv6_addr_t *ipaddr, ieee_802154_long_t *laddr, - uint8_t isrouter, uint8_t state, uint8_t type, - uint16_t ltime, ieee_802154_short_t *saddr) + uint8_t isrouter, ndp_nce_state_t state, + ndp_nce_type_t type, uint16_t ltime, + ieee_802154_short_t *saddr) { if (nbr_count == NBR_CACHE_SIZE) { printf("ERROR: neighbor cache full\n"); - return OPT_ARO_STATE_NBR_CACHE_FULL; + return NDP_OPT_ARO_STATE_NBR_CACHE_FULL; } memcpy(&(nbr_cache[nbr_count].addr), ipaddr, 16); @@ -1151,7 +1392,7 @@ uint8_t nbr_cache_add(ipv6_addr_t *ipaddr, ieee_802154_long_t *laddr, nbr_count++; - return OPT_ARO_STATE_SUCCESS; + return NDP_OPT_ARO_STATE_SUCCESS; } void nbr_cache_auto_rem(void) @@ -1160,10 +1401,10 @@ void nbr_cache_auto_rem(void) for (i = 0; i < NBR_CACHE_SIZE; i++) { if (get_remaining_time(&(nbr_cache[i].ltime)) == 0 && - nbr_cache[i].type == NBR_CACHE_TYPE_TEN) { + nbr_cache[i].type == NDP_NCE_TYPE_TENTATIVE) { memmove(&(nbr_cache[i]), &(nbr_cache[nbr_count]), - sizeof(nbr_cache_t)); - memset(&(nbr_cache[nbr_count]), 0, sizeof(nbr_cache_t)); + sizeof(ndp_neighbor_cache_t)); + memset(&(nbr_cache[nbr_count]), 0, sizeof(ndp_neighbor_cache_t)); nbr_count--; } } @@ -1176,8 +1417,8 @@ void nbr_cache_rem(ipv6_addr_t *addr) for (i = 0; i < NBR_CACHE_SIZE; i++) { if (memcmp(&(nbr_cache[i].addr.uint8[0]), &(addr->uint8[0]), 16) == 0) { memmove(&(nbr_cache[i]), &(nbr_cache[nbr_count]), - sizeof(nbr_cache_t)); - memset(&(nbr_cache[nbr_count]), 0, sizeof(nbr_cache_t)); + sizeof(ndp_neighbor_cache_t)); + memset(&(nbr_cache[nbr_count]), 0, sizeof(ndp_neighbor_cache_t)); nbr_count--; } } @@ -1192,9 +1433,9 @@ void nbr_cache_rem(ipv6_addr_t *addr) * @return The most current authoritive border router information, NULL * if no such information is given. */ -static abr_cache_t *abr_get_most_current(void) +ndp_a6br_cache_t *ndp_a6br_cache_get_most_current(void) { - abr_cache_t *abr = NULL; + ndp_a6br_cache_t *abr = NULL; int i; int version = abr_cache[0].version; @@ -1208,9 +1449,9 @@ static abr_cache_t *abr_get_most_current(void) return abr; } -static abr_cache_t *abr_get_oldest(void) +ndp_a6br_cache_t *ndp_a6br_cache_get_oldest(void) { - abr_cache_t *abr = NULL; + ndp_a6br_cache_t *abr = NULL; int i; int version = abr_cache[0].version; @@ -1224,15 +1465,15 @@ static abr_cache_t *abr_get_oldest(void) return abr; } -abr_cache_t *abr_get_version(uint16_t version, ipv6_addr_t *abr_addr) +ndp_a6br_cache_t *abr_get_version(uint16_t version, ipv6_addr_t *abr_addr) { int i = 0; for (i = 0; i < ABR_CACHE_SIZE; i++) { if (abr_cache[i].version == version && - memcmp(&(abr_cache[i].abr_addr.uint8[0]), - &(abr_addr->uint8[0]), 16 - ) == 0) { + memcmp(&(abr_cache[i].abr_addr.uint8[0]), + &(abr_addr->uint8[0]), 16 + ) == 0) { return &(abr_cache[i]); } } @@ -1240,7 +1481,7 @@ abr_cache_t *abr_get_version(uint16_t version, ipv6_addr_t *abr_addr) return NULL; } -lowpan_context_t *abr_get_context(abr_cache_t *abr, uint8_t cid) +lowpan_context_t *abr_get_context(ndp_a6br_cache_t *abr, uint8_t cid) { if (abr->cids[cid] != cid) { return NULL; @@ -1249,14 +1490,14 @@ lowpan_context_t *abr_get_context(abr_cache_t *abr, uint8_t cid) return lowpan_context_num_lookup(abr->cids[cid]); } -abr_cache_t *abr_add_context(uint16_t version, ipv6_addr_t *abr_addr, - uint8_t cid) +ndp_a6br_cache_t *abr_add_context(uint16_t version, ipv6_addr_t *abr_addr, + uint8_t cid) { - abr_cache_t *abr = abr_get_version(version, abr_addr); + ndp_a6br_cache_t *abr = abr_get_version(version, abr_addr); if (abr == NULL) { if (abr_count == ABR_CACHE_SIZE) { - abr = abr_get_oldest(); + abr = ndp_a6br_cache_get_oldest(); } else { abr = &(abr_cache[abr_count++]); @@ -1264,7 +1505,7 @@ abr_cache_t *abr_add_context(uint16_t version, ipv6_addr_t *abr_addr, abr->version = version; memcpy(&(abr->abr_addr), abr_addr, sizeof(ipv6_addr_t)); - memset(abr->cids, 0xFF, LOWPAN_CONTEXT_MAX); + memset(abr->cids, 0xFF, NDP_6LOWPAN_CONTEXT_MAX); } abr->cids[cid] = cid; @@ -1284,13 +1525,13 @@ void abr_remove_context(uint8_t cid) //------------------------------------------------------------------------------ /* default router list functions */ -def_rtr_lst_t *def_rtr_lst_search(ipv6_addr_t *ipaddr) +ndp_default_router_list_t *ndp_default_router_list_search(ipv6_addr_t *ipaddr) { int i; for (i = 0; i < DEF_RTR_LST_SIZE; i++) { if (memcmp(&def_rtr_lst[i].addr.uint8[0], - &(ipaddr->uint8[0]), 16) == 0) { + &(ipaddr->uint8[0]), 16) == 0) { return &def_rtr_lst[i]; } } @@ -1315,7 +1556,7 @@ void def_rtr_lst_add(ipv6_addr_t *ipaddr, uint32_t rtr_ltime) } } -void def_rtr_lst_rem(def_rtr_lst_t *entry) +void def_rtr_lst_rem(ndp_default_router_list_t *entry) { int i; @@ -1323,8 +1564,8 @@ void def_rtr_lst_rem(def_rtr_lst_t *entry) if (&def_rtr_lst[i] == entry) { /* search the to deleted item, then memmove the last item to its * position, and decrement array count */ - memmove(entry, &def_rtr_lst[def_rtr_count], sizeof(def_rtr_lst_t)); - memset(&def_rtr_lst[def_rtr_count], 0, sizeof(def_rtr_lst_t)); + memmove(entry, &def_rtr_lst[def_rtr_count], sizeof(ndp_default_router_list_t)); + memset(&def_rtr_lst[def_rtr_count], 0, sizeof(ndp_default_router_list_t)); def_rtr_count--; } } diff --git a/sys/net/sixlowpan/icmp.h b/sys/net/sixlowpan/icmp.h new file mode 100644 index 0000000000..37babfe86b --- /dev/null +++ b/sys/net/sixlowpan/icmp.h @@ -0,0 +1,64 @@ +/* + * 6lowpan neighbor discovery + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlownd.h + * @brief 6lowpan neighbor discovery constants, data structs, and prototypes + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Oliver Gesch + * @} + */ + +#ifndef _SIXLOWPAN_ICMP_H +#define _SIXLOWPAN_ICMP_H + +#include + +#include "vtimer.h" +#include "sixlowpan/icmp.h" +#include "sixlowpan/ndp.h" +#include "sixlowpan/types.h" + +#include "lowpan.h" +#include "ip.h" + +enum option_types_t { + OPT_SLLAO = 1, + OPT_TLLAO, + OPT_PI, + OPT_MTU, + OPT_ARO, + OPT_6CO, + OPT_ABRO, + OPT_DAR, + OPT_DAC, +}; + +extern unsigned int nd_nbr_cache_rem_pid; + + +void recv_echo_req(void); +void recv_echo_repl(void); +void recv_rtr_sol(void); +void recv_rtr_adv(void); +void recv_nbr_adv(void); +void recv_nbr_sol(void); + +void nbr_cache_auto_rem(void); +int8_t plist_add(ipv6_addr_t *addr, uint8_t size, uint32_t val_ltime, + uint32_t pref_ltime, uint8_t adv_opt, uint8_t l_a_reserved1); + +ndp_a6br_cache_t *abr_add_context(uint16_t version, ipv6_addr_t *abr_addr, + uint8_t cid); +void abr_remove_context(uint8_t cid); + +uint16_t icmpv6_csum(uint8_t proto); +#endif /* _SIXLOWPAN_ICMP_H*/ diff --git a/sys/net/sixlowpan/include/ipv6.h b/sys/net/sixlowpan/include/ipv6.h index e69de29bb2..4334b4533d 100644 --- a/sys/net/sixlowpan/include/ipv6.h +++ b/sys/net/sixlowpan/include/ipv6.h @@ -0,0 +1,31 @@ +/** + * ipv6.h - Wraps all API types, constants and functions of + * 6LoWPAN in layer 3. + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file + * @brief IPv6 and ICMP functions + * @author Martin Lenders + */ +#ifndef IPV6_H +#define IPV6_H + +#include "sixlowpan/error.h" +#include "sixlowpan/types.h" +#include "sixlowpan/ip.h" +#include "sixlowpan/icmp.h" +#include "sixlowpan/ndp.h" + +#include "../icmp.h" /* TODO: remove if not needed anymore */ + +/** + * @} + */ +#endif /* IPV6_H */ diff --git a/sys/net/sixlowpan/include/sixlowpan.h b/sys/net/sixlowpan/include/sixlowpan.h index e69de29bb2..f7a5e6df8b 100644 --- a/sys/net/sixlowpan/include/sixlowpan.h +++ b/sys/net/sixlowpan/include/sixlowpan.h @@ -0,0 +1,52 @@ +/** + * sixlowpan.h - Wraps all API types, constants and functions + * of 6LoWPAN concerning layers under 3. + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @defgroup sixlowpan 6LoWPAN + * @ingroup net + * @brief 6LoWPAN module implements (parts of) the 6LoWPAN adaption layer + * for IPv6 over Low Power Wireless Personal Area Networks + * (6LoWPANs) + * @see + * RFC 4919 - IPv6 over Low-Power Wireless Personal Area + * Networks (6LoWPANs): Overview, Assumptions, Problem + * Statement, and Goals + * + * @see + * RFC 4944 - Transmission of IPv6 Packets over + * IEEE 802.15.4 Networks + * + * @see + * RFC 6282 - Compression Format for IPv6 Datagrams over + * IEEE 802.15.4-Based Networks + * + * @see + * RFC 6775 - Neighbor Discovery Optimization for IPv6 + * over Low-Power Wireless Personal Area Networks + * (6LoWPANs) + * + * @{ + * @file + * @brief 6lowpan link layer and lowpan functions + * @author Martin Lenders + */ +#ifndef SIXLOWPAN_H +#define SIXLOWPAN_H + +#include "sixlowpan/error.h" +#include "sixlowpan/types.h" +#include "sixlowpan/lowpan.h" +#include "sixlowpan/mac.h" + +/** + * @} + */ +#endif /* SIXLOWPAN_H */ diff --git a/sys/net/sixlowpan/include/sixlowpan/error.h b/sys/net/sixlowpan/include/sixlowpan/error.h new file mode 100644 index 0000000000..863f845adf --- /dev/null +++ b/sys/net/sixlowpan/include/sixlowpan/error.h @@ -0,0 +1,102 @@ +/** + * sixlowpan/error.h - 6LoWPAN error codes + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file + * @brief 6LoWPAN error codes + * @author Martin Lenders + * @} + */ + +#ifndef SIXLOWPAN_ERROR_H +#define SIXLOWPAN_ERROR_H + +#ifndef SUCCESS +/** + * Functions return this if call was success. Only defined if not + * already defined by other header. + */ +#define SUCCESS (0) +#endif + +/** + * Error code that signals that array is full. + */ +#define SIXLOWERROR_ARRAYFULL (132) + +/** + * Error code that signals a NULL pointer error. + */ +#define SIXLOWERROR_NULLPTR (133) + +/** + * Error code that signals an illegal value. + */ +#define SIXLOWERROR_VALUE (134) + +/** + * Error code that signals an illegal address. + */ +#define SIXLOWERROR_ADDRESS (135) + +/** + * Error code that signals an unknown 6LoWPAN dispatch + * @see + * RFC 4944, Section 5: LoWPAN Adaptation Layer and Frame Format + * + */ +#define SIXLOWERROR_DISPATCH (136) + +/** + * Error code that signals that the first 6LoWPAN fragment was + * not received + * @see + * RFC 4944, Section 5.3: Fragmentation Type and Header + * + */ +#define SIXLOWERROR_FSTFRAG (137) + +/** + * Error code that signals that an invalid 6LoWPAN fragment was + * received. + * @see + * RFC 4944, Section 5.3: Fragmentation Type and Header + * + */ +#define SIXLOWERROR_INVFRAG (138) + +/** + * Error code that signals that the source context identifier was not + * found. + * @see + * RFC 6282, Section 3.1: LOWPAN_IPHC Encoding format + * + */ +#define SIXLOWERROR_SCI (139) + +/** + * Error code that signals that the destination context identifier was + * not found. + * @see + * RFC 6282, Section 3.1: LOWPAN_IPHC Encoding format + * + */ +#define SIXLOWERROR_DCI (140) + +/** + * Error code that signals that the destination context identifier was + * not found. + */ +#define SIXLOWERROR_CSUM (141) + +/** + * @} + */ +#endif /* SIXLOWPAN_ERROR_H */ diff --git a/sys/net/sixlowpan/include/sixlowpan/icmp.h b/sys/net/sixlowpan/include/sixlowpan/icmp.h new file mode 100644 index 0000000000..a5e9b8e9e2 --- /dev/null +++ b/sys/net/sixlowpan/include/sixlowpan/icmp.h @@ -0,0 +1,236 @@ +/** + * sixlowpan/icmp.h - 6LoWPAN constants, data structs, and prototypes + * related to ICMP + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file + * @brief 6LoWPAN ICMP related header + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Eric Engel + * @author Oliver Gesch + */ + +#ifndef SIXLOWPAN_ICMP_H +#define SIXLOWPAN_ICMP_H + +#include + +#include "sixlowpan/types.h" + +/** + * @brief ICMPv6 packet type for parameter problem message. + * @see + * RFC 4443, section 3.4 + * + */ +#define ICMPV6_TYPE_PARAMETER_PROB (4) + +/** + * @brief ICMPv6 packet type for an echo request. + * @see + * RFC 4443, section 4.1 + * + */ +#define ICMPV6_TYPE_ECHO_REQUEST (128) + +/** + * @brief ICMPv6 packet type for an echo reply. + * @see + * RFC 4443, section 4.2 + * + */ +#define ICMPV6_TYPE_ECHO_REPLY (129) + +/** + * @brief ICMPv6 packet type for a router solicitation. + * @see + * RFC 4861, section 4.1 + * + */ +#define ICMPV6_TYPE_ROUTER_SOL (133) + +/** + * @brief ICMPv6 packet type for a router advertisement. + * @see + * RFC 4861, section 4.2 + * + */ +#define ICMPV6_TYPE_ROUTER_ADV (134) + +/** + * @brief ICMPv6 packet type for a neighbor solicitation. + * @see + * RFC 4861, section 4.3 + * + */ +#define ICMPV6_TYPE_NEIGHBOR_SOL (135) + +/** + * @brief ICMPv6 packet type for a neighbor advertisement. + * @see + * RFC 4861, section 4.4 + * + */ +#define ICMPV6_TYPE_NEIGHBOR_ADV (136) + +/** + * @brief ICMPv6 packet type for a redirect message. + * @see + * RFC 4861, section 4.5 + * + */ +#define ICMPV6_TYPE_REDIRECT (137) + +/** + * @brief ICMPv6 packet type for a rpl control message. + * @note TODO: not RFC conform. + */ +#define ICMPV6_TYPE_RPL_CONTROL (155) + +/** + * @brief ICMPv6 parameter problem message code for + * "Erroneous header field encountered". + * @see + * RFC 4443, section 3.4 + * + */ +#define ICMPV6_PARAMETER_PROB_CODE_ERR (0) + +/** + * @brief ICMPv6 parameter problem message code for + * "Unrecognized Next Header type encountered". + * @see + * RFC 4443, section 3.4 + * + */ +#define ICMPV6_PARAMETER_PROB_CODE_NXT_HDR_UNREC (1) + +/** + * @brief ICMPv6 parameter problem message code for + * "Unrecognized IPv6 option encountered". + * @see + * RFC 4443, section 3.4 + * + */ +#define ICMPV6_PARAMETER_PROB_CODE_IPV6_OPT_UNREC (2) + +/** + * @brief Send ICMPv6 parameter problem message. + * + * @param[in] src Source address for IPv6 header. + * @param[in] dest Destination address for IPv6 header. + * @param[in] code Value for code field of parameter problem + * message. + * @param[in] pointer Value for pointer field of parameter problem + * message. + * @param[in] packet Data payload for echo request. + * @param[in] packet_len Length of data payload. + */ +void icmpv6_send_parameter_prob(ipv6_addr_t *src, ipv6_addr_t *dest, + uint8_t code, uint32_t pointer, + uint8_t *packet, uint8_t packet_len); + +/** + * @brief Send ICMPv6 echo request. + * + * @param[in] destaddr Destination address for IPv6 header. + * @param[in] id Value for identifier field of echo request. + * @param[in] seq Value for sequence number field of echo request. + * @param[in] data Data payload for echo request. + * @param[in] data_len Length of data payload. + */ +void icmpv6_send_echo_request(ipv6_addr_t *destaddr, uint16_t id, + uint16_t seq, char *data, + size_t data_len); + +/** + * @brief Send ICMPv6 echo reply. + * + * @param[in] destaddr Destination address for IPv6 header. + * @param[in] id Value for identifier field of echo reply. + * @param[in] seq Value for sequence number field of echo reply. + * @param[in] data Data payload for echo reply. + * @param[in] data_len Length of data payload. + */ +void icmpv6_send_echo_reply(ipv6_addr_t *destaddr, uint16_t id, + uint16_t seq, char *data, size_t data_len); + +/** + * @brief Send ICMPv6 router solicitation. + * + * @param[in] sllao Flag to include source link-layer address + * option. If *sllao* == OPT_SLLAO add it, else + * not. + */ +void icmpv6_send_router_sol(uint8_t sllao); + +/** + * @brief Send ICMPv6 router advertisement. + * + * @param[in] addr Address of node to advertise router to. If + * NULL *addr* is set to the all nodes multicast + * address. + * @param[in] sllao Flag to include source link-layer address + * option. If *sllao* == OPT_SLLAO add it, else + * not. + * @param[in] mtu Flag to include MTU option. If *mtu* == OPT_MTU + * add it, else not. + * @param[in] pi Flag to include prefix information option. If + * *pi* == OPT_PI add it, else not. + * @param[in] sixco Flag to include 6LoWPAN context option. If + * *sixco* == OPT_6CO add it, else not. + * @param[in] abro Flag to include 6LoWPAN authoritive border + * router option. If *abro* == OPT_ABRO add it, + * else not. + */ +void icmpv6_send_router_adv(ipv6_addr_t *addr, uint8_t sllao, + uint8_t mtu, uint8_t pi, uint8_t sixco, + uint8_t abro); + +/** + * @brief Send ICMPv6 neighbor solicitation. + * + * @param[in] src Source address for IPv6 header. + * @param[in] dest Destination address for IPv6 header. + * @param[in] targ Value for target address field of neighbor + * solicitation. + * @param[in] sllao Flag to include source link-layer address + * option. If *sllao* == OPT_SLLAO add it, else + * not. + * @param[in] aro Flag to include address registration option. If + * *aro* == OPT_ARO add it, else not. + */ +void icmpv6_send_neighbor_sol(ipv6_addr_t *src, ipv6_addr_t *dest, + ipv6_addr_t *targ, uint8_t slloa, + uint8_t aro); + +/** + * @brief Send ICMPv6 neighbor advertisement. + * + * @param[in] src Source address for IPv6 header. + * @param[in] dest Destination address for IPv6 header. + * @param[in] targ Value for target address field of neighbor + * advertisement. + * @param[in] rso Value for flags field of neighbor advertisement. + * @param[in] sllao Flag to include source link-layer address + * option. If *sllao* == OPT_SLLAO add it, else + * not. + * @param[in] aro Flag to include address registration option. If + * *aro* == OPT_ARO add it, else not. + */ +void icmpv6_send_neighbor_adv(ipv6_addr_t *src, ipv6_addr_t *dst, + ipv6_addr_t *tgt, uint8_t rso, + uint8_t sllao, uint8_t aro); + +/** + * @} + */ +#endif /* SIXLOWPAN_ICMP_H */ diff --git a/sys/net/sixlowpan/include/sixlowpan/ip.h b/sys/net/sixlowpan/include/sixlowpan/ip.h new file mode 100644 index 0000000000..e486e103a0 --- /dev/null +++ b/sys/net/sixlowpan/include/sixlowpan/ip.h @@ -0,0 +1,355 @@ +/** + * sixlowpan/ip.h - 6LoWPAN constants, data structs, and prototypes + * for network layer + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file + * @brief 6LoWPAN network layer header + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Eric Engel + * @author Oliver Gesch + */ + +#ifndef SIXLOWPAN_IP_H +#define SIXLOWPAN_IP_H + +#include + +#include "sixlowpan/types.h" + +/** + * @brief IPv6 maximum transmission unit. + */ +#define IPV6_MTU (256) + +/** + * @brief Maximum length of a IPv6 address represented as string. + */ +#define IPV6_MAX_ADDR_STR_LEN (40) + +/** + * @brief L4 protocol number for TCP. + */ +#define IPV6_PROTO_NUM_TCP (6) + +/** + * @brief L4 protocol number for UDP. + */ +#define IPV6_PROTO_NUM_UDP (17) + +/** + * @brief L4 protocol number for ICMPv6. + */ +#define IPV6_PROTO_NUM_ICMPV6 (58) + +/** + * @brief L4 protocol number for no L4 protocol in IPv6. + */ +#define IPV6_PROTO_NUM_NONE (59) + +/** + * @brief L4 protocol number for IPv6 destination options. + */ +#define IPV6_PROTO_NUM_IPV6_OPTS (60) + +/** + * @brief Get IPv6 send/receive buffer. + * + * @return Pointer to IPv6 header in send/receive bouffer. + * @note To be deleted in later releases. Here only because it is + * used by the rpl module. + */ +ipv6_hdr_t *ipv6_get_buf(void); + +/** + * @brief Send IPv6 packet to dest. + * + * @param[in] dest Destination of this packet. + * @param[in] next_header Next header ID of payload. + * @param[in] payload Payload of the packet. + * @param[in] payload_length Length of payload. + */ +void ipv6_sendto(const ipv6_addr_t *dest, uint8_t next_header, + const uint8_t *payload, uint16_t payload_length); + +/** + * @brief Determines if node is a router. + * + * @return 1 if node is router, 0 otherwise. + */ +uint8_t ipv6_is_router(void); + +/** + * @brief Registers a handler thread for incoming IP packets. + * + * @param[in] pid PID of handler thread. + * + * @return 0 on success, ENOMEN if maximum number of registrable + * threads is exceeded. + */ +uint8_t ipv6_register_packet_handler(int pid); + +/** + * @brief Registers a handler thread for L4 protocol. + * + * @param[in] next_header Next header ID of the L4 protocol. + * @param[in] pid PID of the handler thread + */ +void ipv6_register_next_header_handler(uint8_t next_header, int pid); + +/** + * @brief Registers a handler thread for RPL options + * + * @param[in] pid PID of the handler thread. + */ +void ipv6_register_rpl_handler(int pid); + +/** + * @brief Sets the first 64 bit of *ipv6_addr* to link local prefix. + * + * @param[in,out] ipv6_addr The address to set. + */ +void ipv6_addr_set_link_local_prefix(ipv6_addr_t *ipv6_addr); + +/** + * @brief Sets IPv6 address *out* according to the remaining + * parameters. + * + * @param[out] out The resulting address. + * @param[in] addr0 The first 16 bit of the new address. + * @param[in] addr1 The second 16 bit of the new address. + * @param[in] addr2 The third 16 bit of the new address. + * @param[in] addr3 The fourth 16 bit of the new address. + * @param[in] addr4 The fifth 16 bit of the new address. + * @param[in] addr5 The sixth 16 bit of the new address. + * @param[in] addr6 The seventh 16 bit of the new address. + * @param[in] addr7 The eighth 16 bit of the new address. + */ +void ipv6_addr_init(ipv6_addr_t *out, uint16_t addr0, uint16_t addr1, + uint16_t addr2, uint16_t addr3, uint16_t addr4, + uint16_t addr5, uint16_t addr6, uint16_t addr7); + +/** + * @brief Sets IPv6 address *out* using the given *prefix* and this + * nodes EUI-64 (i. e. interface must be initialized). + * + * @param[out] out Address to be set. + * @param[in] prefix 64-bit network prefix to be used for *out* + * (only the first 64 bit of the ipv6_addr_t type + * are copied to *out*) + */ +void ipv6_addr_set_by_eui64(ipv6_addr_t *out, + const ipv6_addr_t *prefix); + +/** + * @brief Sets IPv6 address *out* with the first *bits* bit taken + * from *prefix* and the remaining bits to 0. + * + * @param[out] out Prefix to be set. + * @param[in] prefix Address to take prefix from. + * @param[in] bits Bits to be copied from *prefix* to *out* + * (set to 128 when greater than 128). + */ +void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix, + uint8_t bits); + +/** + * @brief Set *ipv6_addr* to the loopback address. + * + * @see + * RFC 4291 + * + * + * @param[out] ipv6_addr Is set to the loopback address. + */ +void ipv6_addr_set_loopback_addr(ipv6_addr_t *ipv6_addr); + +/** + * @brief Set *ipv6_addr* to a link-local all routers multicast + * address (ff02::/16 prefix). + * + * @see + * RFC 4291 + * + * + * @param[out] ipv6_addr Is set to a link-local all routers multicast + * address. + */ +void ipv6_addr_set_all_routers_addr(ipv6_addr_t *ipv6_addr); + +/** + * @brief Set *ipv6_addr* to a link-local all nodes multicast address + * (ff02::/16 prefix). + * + * @see + * RFC 4291 + * + * + * @param[out] ipv6_addr Is set to a link-local all nodes multicast + * address. + */ +void ipv6_addr_set_all_nodes_addr(ipv6_addr_t *ipv6_addr); + +/** + * @brief Set *ipv6_addr_out* to the solicited-node multicast address + * computed from *ipv6_addr_in*. + * + * @see + * RFC 4291 + * + * + * @param[out] ipv6_addr_out Is set to solicited-node address of + * this node. + * @param[in] ipv6_addr_in The IPv6 address the solicited-node + * address. + */ +void ipv6_addr_set_solicited_node_addr(ipv6_addr_t *ipv6_addr_out, + const ipv6_addr_t *ipv6_addr_in); + +/** + * @brief Converts IPv6 address into string (unabbrivated notation). + * Note that addr_str must allocate at least + * IPV6_MAX_ADDR_STR_LEN byte (40 byte). + * + * @param[out] addr_str The IPv6 address as string. Must allocate + * at least IPV6_MAX_ADDR_STR_LEN byte (40 + * byte). + * @param[in] ipv6_addr IPv6 address to be converted. + * + * @return Pointer to addr_str. + */ +char *ipv6_addr_to_str(char *addr_str, const ipv6_addr_t *ipv6_addr); + +/** + * @brief Checks if two IPv6 addresses are equal. + * + * @param[in] a An IPv6 address. + * @param[in] b Another IPv6 address. + * + * @return 1 if *a* and *b* are equal, 0 otherwise. + */ +int ipv6_addr_is_equal(const ipv6_addr_t *a, const ipv6_addr_t *b); + +/** + * @brief Checks if *ipv6_addr* is unspecified (all zero). + * + * @see + * RFC 4291 + * + * + * @param[in] ipv6_addr An IPv6 address. + * + * @return 1 if *ipv6_addr* is unspecified address, 0 otherwise. + */ +int ipv6_addr_is_unspecified(const ipv6_addr_t *ipv6_addr); + +/** + * @brief Check if *ipv6_addr* is a link-local address. + * + * @see + * RFC 4291 + * + * + * @param[in] ipv6_addr An IPv6 address. + * + * @return 1 if *ipv6_addr* is link-local address, 0 otherwise. + */ +int ipv6_addr_is_link_local(const ipv6_addr_t *ipv6_addr); + +/** + * @brief Check if *ipv6_addr* is unique local unicast address. + * + * @see + * RFC 4193 + * + * + * @param[in] ipv6_addr An IPv6 address. + * + * @return 1 if *ipv6_addr* is unique local unicast address, + * 0 otherwise. + */ +int ipv6_addr_is_unique_local_unicast(const ipv6_addr_t *addr); + +/** + * @brief Check if *ipv6_addr* is a multicast address. + * + * @see + * RFC 4291 + * + * + * @param[in] ipv6_addr An IPv6 address. + * + * @return 1 if *ipv6_addr* is multicast address, 0 otherwise. + */ +int ipv6_addr_is_multicast(const ipv6_addr_t *ipv6_addr); + +/** + * @brief Check if *ipv6_addr* is solicited-node multicast address. + * + * @see + * RFC 4291 + * + * + * @param[in] ipv6_addr An IPv6 address. + * + * @return 1 if *ipv6_addr* is solicited-node multicast address, + * 0 otherwise. + */ +int ipv6_addr_is_solicited_node(const ipv6_addr_t *ipv6_addr); + +/* + * TODO to wrap sixlowpan initialisations + * int ipv6_iface_init(transceiver_type_t trans, ..); + */ + +/** + * @brief Add an IPv6 address to this nodes interface. + * + * @see + * RFC 4862 + * + * + * @param[in] addr Address to be added to the interface. + * @param[in] type Type of this address. + * @param[in] state Initial state of the address. + * @param[in] val_ltime Valid lifetime of this address in seconds. + * @param[in] pref_ltime Preferred lifetime of this address in + * seconds. + */ +void ipv6_iface_add_addr(const ipv6_addr_t *addr, ipv6_addr_type_t type, + ndp_addr_state_t state, uint32_t val_ltime, + uint32_t pref_ltime); + +/** + * @brief Tries to determine best suitable source address attached to + * the interface of this node based on the given destination + * address. The use-case for this function is to find a + * suitable address for the source address field of an IPv6 + * address upon sending. *src* may be empty (all zero) if there + * is no suitable address attached to the interface. + * + * @param[out] src The best source address for this node (may be + * all zero if ther is none). + * @param[in] dest The destination address for a packet we search + * the source address for. + */ +void ipv6_iface_get_best_src_addr(ipv6_addr_t *src, + const ipv6_addr_t *dest); + +/** + * @brief Print all addresses attached to the interface to stdout. + */ +void ipv6_iface_print_addrs(void); + +/** + * @} + */ +#endif /* SIXLOWPAN_IP_H */ diff --git a/sys/net/sixlowpan/include/sixlowpan/lowpan.h b/sys/net/sixlowpan/include/sixlowpan/lowpan.h new file mode 100644 index 0000000000..3743268e94 --- /dev/null +++ b/sys/net/sixlowpan/include/sixlowpan/lowpan.h @@ -0,0 +1,273 @@ +/** + * sixlowpan/lowpan.h - 6LoWPAN constants, data structs, and + * prototypes for 6LoWPAN layer + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file + * @brief 6LoWPAN LoWPAN layer header + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Eric Engel + * @author Oliver Gesch + */ + +#ifndef SIXLOWPAN_LOWPAN_H +#define SIXLOWPAN_LOWPAN_H + +#include + +#include "transceiver.h" +#include "sixlowpan/types.h" + +/** + * @brief 6LoWPAN dispatch value for uncompressed IPv6 packets. + * @see + * RFC 4944, section 5.1 + * + */ +#define SIXLOWPAN_IPV6_DISPATCH (0x41) + +/** + * @brief 6LoWPAN dispatch value for IPv6 header compression (part of + * first byte of LOWPAN_IPHC). + * @see + * RFC 4944, section 3.1.1 + * + */ +#define SIXLOWPAN_IPHC1_DISPATCH (0x60) + +/** + * @brief Flag for Flow Label elision (part of first byte of + * LOWPAN_IPHC). + * @see + * RFC 6282, section 3.1.1 + * + */ +#define SIXLOWPAN_IPHC1_FL_C (0x10) + +/** + * @brief Flag for Traffic Class elision (part of first byte of + * LOWPAN_IPHC). + * @see + * RFC 6282, section 3.1.1 + * + */ +#define SIXLOWPAN_IPHC1_TC_C (0x08) + +/** + * @brief Flag for Next Header Compression (part of first byte of + * LOWPAN_IPHC). + * @see + * RFC 6282, section 3.1.1 + * + */ +#define SIXLOWPAN_IPHC1_NH (0x04) + +/** + * @brief Flag for Context Identifier Extention (part of second byte + * of LOWPAN_IPHC). + * @see + * RFC 6282, section 3.1.1 + * + */ +#define SIXLOWPAN_IPHC2_CID (0x80) + +/** + * @brief Flag for Source Address Compression (part of second byte + * of LOWPAN_IPHC). + * @see + * RFC 6282, section 3.1.1 + * + */ +#define SIXLOWPAN_IPHC2_SAC (0x40) + +/** + * @brief Bits for Source Address Mode (part of second byte of + * LOWPAN_IPHC). + * @see + * RFC 6282, section 3.1.1 + * + */ +#define SIXLOWPAN_IPHC2_SAM (0x30) + +/** + * @brief Flag for Destination Address Compression (part of second + * byte of LOWPAN_IPHC). + * @see + * RFC 6282, section 3.1.1 + * + */ +#define SIXLOWPAN_IPHC2_DAC (0x04) + +/** + * @brief Bits for Destination Address Mode (part of second byte of + * LOWPAN_IPHC). + * @see + * RFC 6282, section 3.1.1 + * + */ +#define SIXLOWPAN_IPHC2_DAM (0x03) + +/** + * @brief Flag for Multicast Compression (part of second byte of + * LOWPAN_IPHC). + * @see + * RFC 6282, section 3.1.1 + * + */ +#define SIXLOWPAN_IPHC2_M (0x08) + + +/** + * 6LoWPAN dispatch value for fragmentation header (first fragment) + * @see + * RFC 4944, section 5.1 + * + */ +#define SIXLOWPAN_FRAG1_DISPATCH (0xc0) + +/** + * 6LoWPAN dispatch value for fragmentation header (subsequent fragment) + * @see + * RFC 4944, section 5.1 + * + */ +#define SIXLOWPAN_FRAGN_DISPATCH (0xe0) + + +/** + * 6LoWPAN fragmentation header length (first fragment) + */ +#define SIXLOWPAN_FRAG1_HDR_LEN (4) + +/** + * 6LoWPAN fragmentation header length (subsequent fragment) + */ +#define SIXLOWPAN_FRAGN_HDR_LEN (5) + + +/** + * @brief Data type to configure 6LoWPAN IPv6 header compression. + */ +typedef enum __attribute__((packed)) +{ + LOWPAN_IPHC_DISABLE = 0, ///< header compression disabled + LOWPAN_IPHC_ENABLE = 1 ///< header compression enabled +} + sixlowpan_lowpan_iphc_status_t; + +/** + * @brief Data type to represent an 6LoWPAN frame as byte stream. + */ +typedef struct __attribute__((packed)) { + uint8_t length; ///< length of the byte stream. + uint8_t *data; ///< the byte stream representing the 6LoWPAN frame. +} sixlowpan_lowpan_frame_t; + + +/** + * @brief Initializes 6LoWPAN. + * + * @param[in] trans Transceiver to use with 6LoWPAN. + * @param[in] r_addr PHY layer address. + * @param[in] as_border 1 if node should act as border router, + * 0 otherwise. + */ +void sixlowpan_lowpan_init(transceiver_type_t trans, uint8_t r_addr, + int as_border); + +/** + * @brief Initializes a 6LoWPAN router with address prefix + * + * @param[in] trans transceiver to use with 6LoWPAN. + * @param[in] prefix the address prefix to advertise. + * @param[in] r_addr PHY layer address. + */ +void sixlowpan_lowpan_adhoc_init(transceiver_type_t trans, + const ipv6_addr_t *prefix, + uint8_t r_addr); + +/** + * @brief Initializes a 6LoWPAN border router with an address + * + * @note Currently only working with addresses generated from + * IEEE 802.15.4 16-bit short addresses. + * + * @param[in] trans transceiver to use with 6LoWPAN. + * @param[in] border_router_addr Address of this border router. + * + * @return SUCCESS on success, otherwise SIXLOWERROR_ADDRESS if + * address was not generated from IEEE 802.15.4 16-bit short + * address. + */ +uint8_t sixlowpan_lowpan_border_init(transceiver_type_t trans, + const ipv6_addr_t *border_router_addr); + +/** + * @brief Send data via 6LoWPAN to destination node dest. + * + * @param[in] dest EUI-64 of destination node. + * @param[in] data Data to send to destination node (may be + * manipulated). + * @param[in] data_len Length of data. + */ +void sixlowpan_lowpan_sendto(const ieee_802154_long_t *dest, + uint8_t *data, uint16_t data_len); + +/** + * @brief Set header compression status for 6LoWPAN. + * + * @param[in] status Header compression status to set to. + */ +void sixlowpan_lowpan_set_iphc_status( + sixlowpan_lowpan_iphc_status_t status); + +/** + * @brief Initialize 6LoWPAN neighbor discovery (i.e. send + * router advertisement with Source Link-Layer Address Option) + * + * @see + * RFC 4861 + * , + * RFC 6775 + * + * + */ +void sixlowpan_lowpan_bootstrapping(void); + +/** + * @brief Registers a thread to read received 6LoWPAN frames. The + * 6LoWPAN frames are delivered as sixlowpan_lowpan_frame_t + * structs. + * + * @param[in] pid The PID of the receiver thread. + * + * @return 1 on success, ENOMEM if maximum number of registrable + * threads is exceeded. + */ +uint8_t sixlowpan_lowpan_register(int pid); + +#if ENABLE_DEBUG +/** + * @brief Print current buffer of assembled (i. e. not fragmented) + * 6LoWPAN packages. + */ +void sixlowpan_lowpan_print_fifo_buffers(void); + +/** + * @brief Print current buffer for 6LoWPAN fragmentation reassembly. + */ +void sixlowpan_lowpan_print_reassembly_buffers(void); +#endif + +/** + * @} + */ +#endif /* SIXLOWPAN_LOWPAN_H */ diff --git a/sys/net/sixlowpan/include/sixlowpan/mac.h b/sys/net/sixlowpan/include/sixlowpan/mac.h index e69de29bb2..d5abd3f56e 100644 --- a/sys/net/sixlowpan/include/sixlowpan/mac.h +++ b/sys/net/sixlowpan/include/sixlowpan/mac.h @@ -0,0 +1,92 @@ +/** + * sixlowpan/mac.h - 6LoWPAN data structs, and prototypes for MAC layer + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file + * @brief 6LoWPAN MAC layer header + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Eric Engel + * @author Oliver Gesch + */ + +#ifndef SIXLOWPAN_MAC_H +#define SIXLOWPAN_MAC_H + +#include + +#include "transceiver.h" + +#include "sixlowpan/types.h" + +/** + * @brief Gets current radio transmitter address. + * + * @return Current radio address as 8-bit value. + */ +uint8_t sixlowpan_mac_get_radio_address(void); + +/** + * @brief Sets radio transmitter address. + * + * @param[in] addr 8-bit radio address. + */ +void sixlowpan_mac_set_radio_address(uint8_t addr); + +/** + * @brief Generates EUI-64 from IEEE 802.15.4 PAN ID and + * radio transceiver address. + * + * @param[out] laddr The EUI-64 address of this node. + */ +void sixlowpan_mac_init_802154_long_addr(ieee_802154_long_t *laddr); + +/** + * @brief Generates IEEE 802.15.4 16-bit short address from radio + * transceiver address. + * + * @param[out] saddr The IEEE 802.15.4 16-bit short address of this + * node. + */ +void sixlowpan_mac_init_802154_short_addr(ieee_802154_short_t *saddr); + +/** + * @brief Get pointer to potential EUI-64 bit of the IPv6 address. + * + * @param[in] ipaddr An IPv6 address of this node. + * + * @return The EUI-64 address of this node. + */ +ieee_802154_long_t *sixlowpan_mac_get_eui64(const ipv6_addr_t *ipaddr); + +/** + * @brief Send an IEEE 802.15.4 frame. + * + * @param[in] addr The destination address of the frame. + * @param[in] payload The payload of the frame. + * @param[in] length The length of the payload. + * @param[in] mcast send frame as multicast frame (identical to + * give a destination address of 0). + */ +void sixlowpan_mac_send_ieee802154_frame(const ieee_802154_long_t *addr, + const uint8_t *payload, + uint8_t length, uint8_t mcast); + +/** + * @brief Initialise 6LoWPAN MAC interface + * + * @param[in] type Type of transceiver. + */ +void sixlowpan_mac_init(transceiver_type_t type); + +/** + * @} + */ +#endif /* SIXLOWPAN_MAC_H */ diff --git a/sys/net/sixlowpan/include/sixlowpan/ndp.h b/sys/net/sixlowpan/include/sixlowpan/ndp.h new file mode 100644 index 0000000000..5789f7624a --- /dev/null +++ b/sys/net/sixlowpan/include/sixlowpan/ndp.h @@ -0,0 +1,129 @@ +/** + * sixlowpan/ndp.h - 6LoWPAN constants, data structs, and prototypes + * related to NDP + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file + * @brief 6LoWPAN NDP related header + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Eric Engel + * @author Oliver Gesch + */ + +#ifndef SIXLOWPAN_NDP_H +#define SIXLOWPAN_NDP_H + +#include + +#include "timex.h" +#include "sixlowpan/types.h" + +#define NDP_6LOWPAN_CONTEXT_MAX (16) + +#define NDP_OPT_SLLAO_TYPE (1) +#define NDP_OPT_TLLAO_TYPE (2) +#define NDP_OPT_PI_VLIFETIME_INFINITE (0xffffffff) +#define NDP_OPT_ARO_STATE_SUCCESS (0) +#define NDP_OPT_ARO_STATE_DUP_ADDR (1) +#define NDP_OPT_ARO_STATE_NBR_CACHE_FULL (2) + +/** + * @brief Neighbor cache entry state according to + * + * RFC 4861, section 7.3.2 + * . + */ +typedef enum __attribute__((packed)) { + NDP_NCE_STATUS_INCOMPLETE, + NDP_NCE_STATUS_REACHABLE, + NDP_NCE_STATUS_STALE, + NDP_NCE_STATUS_DELAY, + NDP_NCE_STATUS_PROBE, +} ndp_nce_state_t; + +/** + * @brief Neighbor cache entry type according to + * + * RFC 6775, section 3.5 + * . + */ +typedef enum __attribute__((packed)) { + NDP_NCE_TYPE_GC = 1, ///< Garbage-collectible. + NDP_NCE_TYPE_REGISTERED, ///< Registered. + NDP_NCE_TYPE_TENTATIVE ///< Tentetive. +} ndp_nce_type_t; + +/** + * @brief Prefix list type to store information spread by prefix + * information option. + */ +typedef struct __attribute__((packed)) { + uint8_t inuse; ///< Prefix is in in use. + uint8_t adv; + ipv6_addr_t addr; ///< The Prefix. + uint8_t length; ///< Length of the prefix. + uint8_t l_a_reserved1; ///< L and A flag of prefix information option + uint32_t val_ltime; ///< valid lifetime + uint32_t pref_ltime; ///< preferred lifetime + uint8_t infinite; ///< flag to set to infinite lifetime +} ndp_prefix_list_t; + +/** + * @brief Default router list to store information spread by + * router advertisement. + */ +typedef struct __attribute__((packed)) { + ipv6_addr_t addr; ///< Address of router. + timex_t inval_time; ///< remaining time until this entry is + ///< invalid. +} ndp_default_router_list_t; + +/** + * @brief Neighbor cache as defined in + * + * RFC 4861, section 5.1 + * . + */ +typedef struct __attribute__((packed)) { + ndp_nce_type_t type; ///< Type of neighbor cache entry. + ndp_nce_state_t state; ///< State of neighbor cache entry. + uint8_t isrouter; ///< Flag to signify that this neighbor + ///< is a router. + ipv6_addr_t addr; ///< IPv6 address of the neighbor. + ieee_802154_long_t laddr; ///< EUI-64 of neighbor + ieee_802154_short_t saddr; ///< IEEE 802.15.4 16-bit short address + ///< of neighbor. + timex_t ltime; ///< lifetime of entry. +} ndp_neighbor_cache_t; + +/** + * @brief Authoritive border router cache as defined in + * + * RFC 6775 + * . + */ +typedef struct __attribute__((packed)) { + uint16_t version; ///< version of entry. + ipv6_addr_t abr_addr; ///< Addres of ABR. + uint8_t cids[NDP_6LOWPAN_CONTEXT_MAX]; ///< context IDs. +} ndp_a6br_cache_t; + +ndp_default_router_list_t *ndp_default_router_list_search(ipv6_addr_t *ipaddr); +ndp_neighbor_cache_t *ndp_neighbor_cache_search(ipv6_addr_t *ipaddr); +/*TODO: to implement*/ +uint8_t ndp_prefix_list_search(ipv6_addr_t *addr); +ndp_a6br_cache_t *ndp_a6br_cache_get_most_current(void); +ndp_a6br_cache_t *ndp_a6br_cache_get_oldest(void); + +/** + * @} + */ +#endif /* SIXLOWPAN_NDP_H */ diff --git a/sys/net/sixlowpan/include/sixlowpan/types.h b/sys/net/sixlowpan/include/sixlowpan/types.h new file mode 100644 index 0000000000..8fc1ab7596 --- /dev/null +++ b/sys/net/sixlowpan/include/sixlowpan/types.h @@ -0,0 +1,404 @@ +/** + * 6LoWPAN data types + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlowpan/types.h + * @brief 6LoWPAN data types + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Eric Engel + * @author Oliver Gesch + */ + +#ifndef SIXLOWPAN_TYPES_H +#define SIXLOWPAN_TYPES_H + +#include + +/** + * @brief Data type to represent an EUI-64. + */ +typedef union __attribute__((packed)) { + uint8_t uint8[8]; ///< devided by 8 8-bit words. + uint16_t uint16[4]; ///< devided by 4 16-bit words. +} ieee_802154_long_t; + +/** + * @brief Data type to represent IEEE 802.15.4 short address. + */ +typedef union __attribute__((packed)) { + uint8_t uint8[2]; ///< devided by 2 8-bit words. + uint16_t uint16[1]; ///< as a 16-bit value. +} ieee_802154_short_t; + +/** + * @brief Data type to represent an IPv6 address. + */ +typedef union __attribute__((packed)) { + uint8_t uint8[16]; ///< devided by 16 8-bit words. + uint16_t uint16[8]; ///< devided by 8 16-bit words. + uint32_t uint32[4]; ///< devided by 4 32-bit words. +} ipv6_addr_t; + +/** + * @brief Data type to represent IPv6 address types. + * + * @see + * RFC 4291 + * + */ +typedef enum __attribute__((packed)) +{ + IPV6_ADDR_TYPE_NONE, ///< address has no type/is invalid. + IPV6_ADDR_TYPE_UNICAST, ///< address is an unicast address. + IPV6_ADDR_TYPE_MULTICAST, ///< address is a multicast address. + IPV6_ADDR_TYPE_ANYCAST, ///< address is an anycast address. + IPV6_ADDR_TYPE_SOLICITED_NODE, ///< address is a solicitated node + ///< multicast address. + IPV6_ADDR_TYPE_LOOPBACK, ///< address is a loopback address. + IPV6_ADDR_TYPE_LINK_LOCAL, ///< address is a link-local address. + IPV6_ADDR_TYPE_GLOBAL ///< address is a global address. +} +ipv6_addr_type_t; + +/** + * @brief Data type to represent an IPv6 packet header + * + * @see + * RFC 2460 + * + */ +typedef struct __attribute__((packed)) { + uint8_t version_trafficclass; ///< Version field + first 4 bit of Traffic Class. + uint8_t trafficclass_flowlabel; ///< last 4 bit of Traffic Class + ///< and first 4 bit of Flow Label. + uint16_t flowlabel; ///< last 16 bit of Flow Label. + uint16_t length; ///< payload length of this packet. + uint8_t nextheader; ///< type of next header in this packet. + uint8_t hoplimit; ///< hop limit for this packet. + ipv6_addr_t srcaddr; ///< source address of this packet. + ipv6_addr_t destaddr; ///< destination address of this packet. +} ipv6_hdr_t; + +/** + * @brief Data type to represent an ICMPv6 packet header. + * + * @see + * RFC 4443 + * + */ +typedef struct __attribute__((packed)) { + uint8_t type; ///< type field. + uint8_t code; ///< code field. + uint16_t checksum; ///< checksum field. +} icmpv6_hdr_t; + +/** + * @brief Data type to represent the relevant sub-part of an + * ICMPv6 Parameter Problem Message. + * + * @see + * RFC 4443, section 3.4 + * + */ +typedef struct __attribute__((packed)) { + uint8_t pointer; +} icmpv6_parameter_prob_hdr_t; + +/** + * @brief Data type to represent the relevant sub-part of an + * ICMPv6 Echo Request. + * + * @see + * RFC 4443, section 4.1 + * + */ +typedef struct __attribute__((packed)) { + uint16_t id; ///< identifier field. + uint16_t seq; ///< sequence number field. +} icmpv6_echo_request_hdr_t; + +/** + * @brief Data type to represent the relevant sub-part of an + * ICMPv6 Echo Reply. + * + * @see + * RFC 4443, section 4.2 + * + */ +typedef struct __attribute__((packed)) { + uint16_t id; ///< identifier field. + uint16_t seq; ///< sequence number field. +} icmpv6_echo_reply_hdr_t; + +/* + * ICMPv6 Router Solicitation has no fields but reserved fields + * and is thus elided. + */ + +/** + * @brief Data type to represent the relevant sub-part of an + * ICMPv6 Router Advertisement. + * + * @see ICMPV6_ROUTER_ADV_FLAG_MANAGED + * @see ICMPV6_ROUTER_ADV_FLAG_OTHER + * @see + * RFC 4861, section 4.2 + * + */ +typedef struct __attribute__((packed)) { + uint8_t hoplimit; ///< hop limit field. + uint8_t autoconfig_flags; ///< (M)anaged and (Other) flag. + uint16_t router_lifetime; ///< router lifetime field. + uint32_t reachable_time; ///< reachable time field. + uint32_t retrans_timer; ///< retrans timer field. +} icmpv6_router_adv_hdr_t; + +/** + * @brief Bit for (M)anaged flag in Router Advertisement + * @see icmpv6_router_adv_hdr_t + * @see + * RFC 4861, section 4.2 + * + */ +#define ICMPV6_ROUTER_ADV_FLAG_MANAGED (0x80) + +/** + * @brief Bit for (O)ther flag in Router Advertisement + * @see icmpv6_router_adv_hdr_t + * @see + * RFC 4861, section 4.2 + * + */ +#define ICMPV6_ROUTER_ADV_FLAG_OTHER (0x40) + +/** + * @brief Data type to represent the relevant sub-part of an + * ICMPv6 Neighbor Solicitation. + * + * @see + * RFC 4861, section 4.3 + * + */ +typedef struct __attribute__((packed)) { + uint32_t reserved; ///< reserved field. + ipv6_addr_t target_addr; ///< target address field. +} icmpv6_neighbor_sol_hdr_t; + +/** + * @brief Data type to represent the relevant sub-part of an + * ICMPv6 Neighbor Solicitation. + * + * @see ICMPV6_NEIGHBOR_ADV_FLAG_ROUTER + * @see ICMPV6_NEIGHBOR_ADV_FLAG_SOLICITED + * @see ICMPV6_NEIGHBOR_ADV_FLAG_OVERRIDE + * @see + * RFC 4861, section 4.4 + * + */ +typedef struct __attribute__((packed)) { + uint8_t rso; ///< flags + first 5 bits of reserved field. + uint8_t reserved[3]; ///< rest of reserved field. + ipv6_addr_t target_addr; ///< target address field. +} icmpv6_neighbor_adv_hdr_t; + +/** + * @brief Bit for (R)outer flag in Neighbor Advertisement + * @see icmpv6_neighbor_adv_hdr_t + * @see + * RFC 4861, section 4.4 + * + */ +#define ICMPV6_NEIGHBOR_ADV_FLAG_ROUTER (0x80) + +/** + * @brief Bit for (S)olicited flag in Neighbor Advertisement + * @see icmpv6_neighbor_adv_hdr_t + * @see + * RFC 4861, section 4.4 + * + */ +#define ICMPV6_NEIGHBOR_ADV_FLAG_SOLICITED (0x40) + +/** + * @brief Bit for (O)verride flag in Neighbor Advertisement + * @see icmpv6_neighbor_adv_hdr_t + * @see + * RFC 4861, section 4.4 + * + */ +#define ICMPV6_NEIGHBOR_ADV_FLAG_OVERRIDE (0x20) + +/** + * @brief Data type to represent an IPv6 Neighbor Discover Option + * header. + * + * @see + * RFC 4861, section 4.6 + * + */ +typedef struct __attribute__((packed)) { + uint8_t type; ///< type field. + uint8_t length; ///< length field. +} icmpv6_ndp_opt_hdr_t; + +/** + * @brief Data type to represent a Source/Target Link-layer Option + * Address option. Link-layer address may be added in payload. + * + * @see + * RFC 4861, section 4.6.1 + * + */ +typedef struct __attribute__((packed)) { + uint8_t type; ///< type field. + uint8_t length; ///< length field. +} icmpv6_ndp_opt_stllao_t; + +/** + * @brief Data type to represent a Prefix Information option. + * + * @see ICMPV6_NDP_OPT_PI_FLAG_ON_LINK + * @see ICMPV6_NDP_OPT_PI_FLAG_AUTONOM + * @see + * RFC 4861, section 4.6.2 + * + */ +typedef struct __attribute__((packed)) { + uint8_t type; ///< type field. + uint8_t length; ///< length field. + uint8_t prefix_length; ///< prefix length field. + uint8_t l_a_reserved1; ///< flags + reserved1 field. + uint32_t val_ltime; ///< valid lifetime field. + uint32_t pref_ltime; ///< preferred lifetime field. + uint32_t reserved2; ///< reserved2 field. + ipv6_addr_t addr; ///< prefix field. +} icmpv6_ndp_opt_pi_t; + +/** + * @brief Bit for on-(L)ink flag in Prefix Information option. + * @see icmpv6_ndp_opt_pi_t + * @see + * RFC 4861, section 4.6.2 + * + */ +#define ICMPV6_NDP_OPT_PI_FLAG_ON_LINK (0x80) + +/** + * @brief Bit for (A)utonoums address-configuration flag in Prefix + * Information option. + * @see icmpv6_ndp_opt_pi_t + * @see + * RFC 4861, section 4.6.2 + * + */ +#define ICMPV6_NDP_OPT_PI_FLAG_AUTONOM (0x40) + +/** + * @brief Data type to represent a MTU option. + * + * @see + * RFC 4861, section 4.6.4 + * + */ +typedef struct __attribute__((packed)) { + uint8_t type; ///< type field. + uint8_t length; ///< length field. + uint16_t reserved; ///< reserved field. + uint32_t mtu; ///< MTU field. +} icmpv6_ndp_opt_mtu_t; + +/** + * @brief Data type to represent an Address Registration Option. + * + * @see + * RFC 6775, section 4.1 + * + */ +typedef struct __attribute__((packed)) { + uint8_t type; ///< type field. + uint8_t length; ///< length field. + uint8_t status; ///< status field. + uint8_t reserved1; ///< reserved1 field. + uint16_t reserved2; ///< reserved2 field. + uint16_t reg_ltime; ///< registration lifetem field. + ieee_802154_long_t eui64; ///< EUI-64 field. +} icmpv6_ndp_opt_aro_t; + +/** + * @brief Data type to represent an 6LoWPAN Context Option. + * + * @see ICMPV6_NDP_OPT_6CO_FLAG_CCOMPR + * @see ICMPV6_NDP_OPT_6CO_FLAG_CID + * @see + * RFC 6775, section 4.2 + * + */ +typedef struct __attribute__((packed)) { + uint8_t type; ///< type field. + uint8_t length; ///< length field. + uint8_t c_length; ///< context length field. + uint8_t c_flags; ///< Res(erved) field + C flag + CID field. + uint16_t reserved; ///< reserved field. + uint16_t val_ltime; ///< valid lifetime field. +} icmpv6_ndp_opt_6co_hdr_t; + +/** + * @brief Bit for context (C)ompression flag in 6LoWPAN Context + * Option. + * @see icmpv6_ndp_opt_6co_hdr_t + * @see + * RFC 6775, section 4.2 + * + */ +#define ICMPV6_NDP_OPT_6CO_FLAG_CCOMPR (0x10) + +/** + * @brief Bitmask for Context Identifier in 6LoWPAN Context Option. + * @see icmpv6_ndp_opt_6co_hdr_t + * @see + * RFC 6775, section 4.2 + * + */ +#define ICMPV6_NDP_OPT_6CO_FLAG_CID (0x0F) + +/** + * @brief Data type to represent an Authoritative Border Router Option. + * @note TODO not according to RFC. + * + * @see + * RFC 6775, section 4.3 + * + */ +typedef struct __attribute__((packed)) { + uint8_t type; ///< type field. + uint8_t length; ///< length field. + uint16_t version; ///< version field. + uint32_t reserved; ///< reseverd field. + ipv6_addr_t addr; ///< 6LBR address field. +} icmpv6_ndp_opt_abro_t; + +/** + * @brief Data type to represent address types according to + * RFC 4862. + */ +typedef enum __attribute__((packed)) +{ + NDP_ADDR_STATE_TENTATIVE, ///< tentative address, uniqueness to be verified. + NDP_ADDR_STATE_PREFERRED, ///< preferred address, for unrestricted use. + NDP_ADDR_STATE_DEPRECATED, ///< deprecated address, use discouraged. + NDP_ADDR_STATE_ANY ///< addresses of this state are always permitted. +} +ndp_addr_state_t; + +/** + * @} + */ +#endif /* SIXLOWPAN_TYPES_H */ diff --git a/sys/net/sixlowpan/ip.c b/sys/net/sixlowpan/ip.c new file mode 100644 index 0000000000..87f9271282 --- /dev/null +++ b/sys/net/sixlowpan/ip.c @@ -0,0 +1,671 @@ +/** + * IPv6 implementation + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlowip.c + * @brief 6lowpan IP layer functions + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Eric Engel + * @author Oliver Gesch + * @} + */ + +#include +#include +#include + +#include "vtimer.h" +#include "mutex.h" +#include "msg.h" +#include "sixlowpan/mac.h" + +#include "ip.h" +#include "icmp.h" +#include "lowpan.h" + +#include "sys/net/destiny/socket.h" +#include "sys/net/net_help/net_help.h" +#include "sys/net/net_help/msg_help.h" + +#define IP_PKT_RECV_BUF_SIZE (64) +#define LLHDR_IPV6HDR_LEN (LL_HDR_LEN + IPV6_HDR_LEN) + +uint8_t ip_send_buffer[BUFFER_SIZE]; +uint8_t buffer[BUFFER_SIZE]; +msg_t msg_queue[IP_PKT_RECV_BUF_SIZE]; +ipv6_hdr_t *ipv6_buf; +icmpv6_hdr_t *icmp_buf; +uint8_t *nextheader; + +uint8_t iface_addr_list_count = 0; +int udp_packet_handler_pid = 0; +int tcp_packet_handler_pid = 0; +int rpl_process_pid = 0; + +/* registered upper layer threads */ +int sixlowip_reg[SIXLOWIP_MAX_REGISTERED]; + +void ipv6_send_bytes(ipv6_hdr_t *bytes) +{ + uint16_t offset = IPV6_HDR_LEN + HTONS(bytes->length); + + bytes->flowlabel = HTONS(bytes->flowlabel); + bytes->length = HTONS(bytes->length); + + memset(bytes, 0, BUFFER_SIZE); + memcpy(bytes + LL_HDR_LEN, bytes, offset); + + sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(bytes->destaddr.uint16[4]), + (uint8_t *)bytes, + offset); +} + +ipv6_hdr_t *ipv6_get_buf_send(void) +{ + return ((ipv6_hdr_t *) &(ip_send_buffer[LL_HDR_LEN])); +} + +uint8_t *get_payload_buf_send(uint8_t ext_len) +{ + return &(ip_send_buffer[LLHDR_IPV6HDR_LEN + ext_len]); +} + +ipv6_hdr_t *ipv6_get_buf(void) +{ + return ((ipv6_hdr_t *) &(buffer[LL_HDR_LEN])); +} + +icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len) +{ + return ((icmpv6_hdr_t *) &(buffer[LLHDR_IPV6HDR_LEN + ext_len])); +} + +uint8_t *get_payload_buf(uint8_t ext_len) +{ + return &(buffer[LLHDR_IPV6HDR_LEN + ext_len]); +} + +void ipv6_sendto(const ipv6_addr_t *dest, uint8_t next_header, + const uint8_t *payload, uint16_t payload_length) +{ + uint8_t *p_ptr; + uint16_t packet_length; + + if (next_header == IPV6_PROTO_NUM_TCP) { + p_ptr = get_payload_buf_send(ipv6_ext_hdr_len); + ipv6_buf = ipv6_get_buf_send(); + } + else { + ipv6_buf = ipv6_get_buf(); + p_ptr = get_payload_buf(ipv6_ext_hdr_len); + } + + ipv6_buf->version_trafficclass = IPV6_VER; + ipv6_buf->trafficclass_flowlabel = 0; + ipv6_buf->flowlabel = 0; + ipv6_buf->nextheader = next_header; + ipv6_buf->hoplimit = MULTIHOP_HOPLIMIT; + ipv6_buf->length = payload_length; + + memcpy(&(ipv6_buf->destaddr), dest, 16); + ipv6_iface_get_best_src_addr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); + + memcpy(p_ptr, payload, payload_length); + + packet_length = IPV6_HDR_LEN + payload_length; + + sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_buf->destaddr.uint16[4]), + (uint8_t *)ipv6_buf, packet_length); +} + +/* Register an upper layer thread */ +uint8_t ipv6_register_packet_handler(int pid) +{ + uint8_t i; + + for (i = 0; ((sixlowip_reg[i] != pid) && (i < SIXLOWIP_MAX_REGISTERED) && + (sixlowip_reg[i] != 0)); i++) { + ; + } + + if (i >= SIXLOWIP_MAX_REGISTERED) { + return ENOMEM; + } + else { + sixlowip_reg[i] = pid; + return 1; + } +} + +int icmpv6_demultiplex(const icmpv6_hdr_t *hdr) +{ + switch (hdr->type) { + case (ICMPV6_TYPE_ECHO_REQUEST): { + puts("INFO: packet type: icmp echo request"); + /* processing echo request */ + recv_echo_req(); + break; + } + + case (ICMPV6_TYPE_ECHO_REPLY): { + puts("INFO: packet type: icmp echo reply"); + /* processing echo reply */ + recv_echo_repl(); + break; + } + + case (ICMPV6_TYPE_ROUTER_SOL): { + puts("INFO: packet type: icmp router solicitation"); + /* processing router solicitation */ + recv_rtr_sol(); + /* init solicited router advertisment*/ + break; + } + + case (ICMPV6_TYPE_ROUTER_ADV): { + puts("INFO: packet type: icmp router advertisment"); + /* processing router advertisment */ + recv_rtr_adv(); + /* init neighbor solicitation */ + break; + } + + case (ICMPV6_TYPE_NEIGHBOR_SOL): { + puts("INFO: packet type: icmp neighbor solicitation"); + recv_nbr_sol(); + break; + } + + case (ICMPV6_TYPE_NEIGHBOR_ADV): { + puts("INFO: packet type: icmp neighbor advertisment"); + recv_nbr_adv(); + break; + } + + case (ICMPV6_TYPE_RPL_CONTROL): { + puts("INFO: packet type: RPL message"); + + if (rpl_process_pid != 0) { + msg_t m_send; + m_send.content.ptr = (char *) &hdr->code; + msg_send(&m_send, rpl_process_pid, 1); + } + else { + puts("INFO: no RPL handler registered"); + } + + break; + } + + default: + return -1; + } + + return 0; +} + +uint8_t ipv6_get_addr_match(const ipv6_addr_t *src, + const ipv6_addr_t *dst) +{ + uint8_t val = 0, xor; + + for (int i = 0; i < 16; i++) { + /* if bytes are equal add 8 */ + if (src->uint8[i] == dst->uint8[i]) { + val += 8; + } + else { + xor = src->uint8[i] ^ dst->uint8[i]; + + /* while bits from byte equal add 1 */ + for (int j = 0; j < 8; j++) { + if ((xor & 0x80) == 0) { + val++; + xor = xor << 1; + } + else { + break; + } + } + } + } + + return val; +} + +void ipv6_process(void) +{ + msg_t m_recv_lowpan, m_send_lowpan; + msg_t m_recv, m_send; + ipv6_addr_t myaddr; + uint8_t i; + uint16_t packet_length; + + ipv6_addr_init(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00, + sixlowpan_mac_get_radio_address()); + + while (1) { + msg_receive(&m_recv_lowpan); + + ipv6_buf = (ipv6_hdr_t *)m_recv_lowpan.content.ptr; + + /* identifiy packet */ + nextheader = &ipv6_buf->nextheader; + + if ((ipv6_get_addr_match(&myaddr, &ipv6_buf->destaddr) >= 112) && + (ipv6_buf->destaddr.uint8[15] != myaddr.uint8[15])) { + packet_length = IPV6_HDR_LEN + ipv6_buf->length; + memcpy(ipv6_get_buf_send(), ipv6_get_buf(), packet_length); + sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_buf->destaddr.uint16[4]), + (uint8_t *)ipv6_get_buf_send(), + packet_length); + } + else { + for (i = 0; i < SIXLOWIP_MAX_REGISTERED; i++) { + if (sixlowip_reg[i]) { + msg_t m_send; + m_send.content.ptr = (char *) &ipv6_buf; + msg_send(&m_send, sixlowip_reg[i], 1); + } + } + + switch (*nextheader) { + case (IPV6_PROTO_NUM_ICMPV6): { + /* checksum test*/ + if (icmpv6_csum(IPV6_PROTO_NUM_ICMPV6) != 0xffff) { + printf("ERROR: wrong checksum\n"); + } + + icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); + icmpv6_demultiplex(icmp_buf); + break; + } + + case (IPV6_PROTO_NUM_TCP): { + if (tcp_packet_handler_pid != 0) { + m_send.content.ptr = (char *) ipv6_buf; + msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid); + } + else { + printf("INFO: No TCP handler registered.\n"); + } + + break; + } + + case (IPV6_PROTO_NUM_UDP): { + if (udp_packet_handler_pid != 0) { + m_send.content.ptr = (char *) ipv6_buf; + msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid); + } + else { + printf("INFO: No UDP handler registered.\n"); + } + + break; + } + + case (IPV6_PROTO_NUM_NONE): { + printf("INFO: Packet with no Header following the IPv6 Header received.\n"); + break; + } + + default: + break; + } + } + + msg_reply(&m_recv_lowpan, &m_send_lowpan); + } +} + +void ipv6_iface_add_addr(const ipv6_addr_t *addr, ipv6_addr_type_t type, + ndp_addr_state_t state, uint32_t val_ltime, + uint32_t pref_ltime) +{ + if (ipv6_addr_is_unspecified(addr) == 128) { + printf("ERROR: unspecified address (::) can't be assigned to interface.\n"); + return; + } + + if (ipv6_iface_addr_match(addr) != 0) { + return; + } + + if (iface_addr_list_count < IFACE_ADDR_LIST_LEN) { + memcpy(&(iface.addr_list[iface_addr_list_count].addr.uint8[0]), + &(addr->uint8[0]), 16); + iface.addr_list[iface_addr_list_count].state = state; + timex_t valtime = {val_ltime, 0}; + timex_t preftime = {pref_ltime, 0}; + timex_t now; + vtimer_now(&now); + iface.addr_list[iface_addr_list_count].val_ltime = timex_add(now, valtime); + iface.addr_list[iface_addr_list_count].pref_ltime = timex_add(now, preftime); + iface.addr_list[iface_addr_list_count].type = type; + iface_addr_list_count++; + + /* Register to Solicited-Node multicast address according to RFC 4291 */ + if (type == IPV6_ADDR_TYPE_ANYCAST || type == IPV6_ADDR_TYPE_LINK_LOCAL || + type == IPV6_ADDR_TYPE_GLOBAL || type == IPV6_ADDR_TYPE_UNICAST) { + ipv6_addr_t sol_node_mcast_addr; + ipv6_addr_set_solicited_node_addr(&sol_node_mcast_addr, addr); + + if (ipv6_iface_addr_match(&sol_node_mcast_addr) == NULL) { + ipv6_iface_add_addr(&sol_node_mcast_addr, + IPV6_ADDR_TYPE_SOLICITED_NODE, + state, val_ltime, pref_ltime); + } + } + } +} + +addr_list_t *ipv6_iface_addr_match(const ipv6_addr_t *addr) +{ + int i; + + for (i = 0; i < iface_addr_list_count; i++) { + if (memcmp(&(iface.addr_list[i].addr.uint8[0]), + &(addr->uint8[0]), 16) == 0) { + return &(iface.addr_list[i]); + } + } + + return NULL; +} + +addr_list_t *ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr) +{ + int i; + + for (i = 0; i < iface_addr_list_count; i++) { + if (memcmp(&(iface.addr_list[i].addr.uint8[0]), + &(addr->uint8[0]), 8) == 0) { + return &(iface.addr_list[i]); + } + } + + return NULL; +} + +void ipv6_iface_print_addrs(void) +{ + for (int i = 0; i < iface_addr_list_count; i++) { + char addr_str[IPV6_MAX_ADDR_STR_LEN]; + printf("%s\n", ipv6_addr_to_str(addr_str, + &(iface.addr_list[i].addr))); + } +} + +void ipv6_addr_set_by_eui64(ipv6_addr_t *out, const ipv6_addr_t *prefix) +{ + out->uint16[0] = prefix->uint16[0]; + out->uint16[1] = prefix->uint16[1]; + out->uint16[2] = prefix->uint16[2]; + out->uint16[3] = prefix->uint16[3]; + + memcpy(&(out->uint8[8]), &(iface.laddr.uint8[0]), 8); +} + +void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix, + uint8_t bits) +{ + if (bits > 128) { + bits = 128; + } + + uint8_t bytes = bits / 8, mask; + + if (bits % 8) { + mask = 0xff << (bits - (bytes * 8)); + } + else { + mask = 0x00; + } + + bytes++; + memset(out, 0, 16); + memcpy(out, prefix, bytes); + out->uint8[bytes] = prefix->uint8[bytes] & mask; +} + +void ipv6_addr_set_all_routers_addr(ipv6_addr_t *ipv6_addr) +{ + ipv6_addr->uint16[0] = HTONS(0xff02); + ipv6_addr->uint16[1] = 0; + ipv6_addr->uint16[2] = 0; + ipv6_addr->uint16[3] = 0; + ipv6_addr->uint16[4] = 0; + ipv6_addr->uint16[5] = 0; + ipv6_addr->uint16[6] = 0; + ipv6_addr->uint16[7] = HTONS(0x0002); +} + +void ipv6_addr_set_all_nodes_addr(ipv6_addr_t *ipv6_addr) +{ + ipv6_addr->uint16[0] = HTONS(0xff02); + ipv6_addr->uint16[1] = 0; + ipv6_addr->uint16[2] = 0; + ipv6_addr->uint16[3] = 0; + ipv6_addr->uint16[4] = 0; + ipv6_addr->uint16[5] = 0; + ipv6_addr->uint16[6] = 0; + ipv6_addr->uint16[7] = HTONS(0x0001); +} + +void ipv6_addr_set_loopback_addr(ipv6_addr_t *ipv6_addr) +{ + ipv6_addr->uint16[0] = 0; + ipv6_addr->uint16[1] = 0; + ipv6_addr->uint16[2] = 0; + ipv6_addr->uint16[3] = 0; + ipv6_addr->uint16[4] = 0; + ipv6_addr->uint16[5] = 0; + ipv6_addr->uint16[6] = 0; + ipv6_addr->uint16[7] = HTONS(0x0001); +} + +void ipv6_iface_get_best_src_addr(ipv6_addr_t *src, const ipv6_addr_t *dest) +{ + /* try to find best match if dest is not mcast or link local */ + int8_t itmp = -1; + uint8_t tmp = 0; + uint8_t bmatch = 0; + + if (!(ipv6_addr_is_link_local(dest)) && !(ipv6_addr_is_multicast(dest))) { + for (int i = 0; i < IFACE_ADDR_LIST_LEN; i++) { + if (iface.addr_list[i].state == NDP_ADDR_STATE_PREFERRED) { + if (!ipv6_addr_is_link_local(&(iface.addr_list[i].addr)) && + !ipv6_addr_is_multicast(&(iface.addr_list[i].addr)) && + !ipv6_addr_is_unique_local_unicast(&(iface.addr_list[i].addr))) { + tmp = ipv6_get_addr_match(dest, &(iface.addr_list[i].addr)); + + if (tmp >= bmatch) { + bmatch = tmp; + itmp = i; + } + } + } + } + } + else { + for (int j = 0; j < IFACE_ADDR_LIST_LEN; j++) { + if ((iface.addr_list[j].state == NDP_ADDR_STATE_PREFERRED) && + ipv6_addr_is_link_local(&(iface.addr_list[j].addr)) && + !ipv6_addr_is_multicast(&(iface.addr_list[j].addr))) { + itmp = j; + } + } + } + + if (itmp == -1) { + memset(src, 0, 16); + } + else { + memcpy(src, &(iface.addr_list[itmp].addr), 16); + } +} + +int ipv6_addr_is_equal(const ipv6_addr_t *a, const ipv6_addr_t *b) +{ + return (ipv6_get_addr_match(a, b) == 128); +} + +void ipv6_addr_set_link_local_prefix(ipv6_addr_t *ipv6_addr) +{ + ipv6_addr->uint16[0] = HTONS(0xfe80); + ipv6_addr->uint16[1] = 0; + ipv6_addr->uint16[2] = 0; + ipv6_addr->uint16[3] = 0; +} + +void ipv6_addr_init(ipv6_addr_t *out, uint16_t addr0, uint16_t addr1, + uint16_t addr2, uint16_t addr3, uint16_t addr4, + uint16_t addr5, uint16_t addr6, uint16_t addr7) +{ + out->uint16[0] = HTONS(addr0); + out->uint16[1] = HTONS(addr1); + out->uint16[2] = HTONS(addr2); + out->uint16[3] = HTONS(addr3); + out->uint16[4] = HTONS(addr4); + out->uint16[5] = HTONS(addr5); + out->uint16[6] = HTONS(addr6); + out->uint16[7] = HTONS(addr7); +} + +int ipv6_addr_is_link_local(const ipv6_addr_t *addr) +{ + return (addr->uint8[0] == 0xfe && addr->uint8[0] == 0x80); +} + +int ipv6_addr_is_unique_local_unicast(const ipv6_addr_t *addr) +{ + return (addr->uint8[0] == 0xfc || addr->uint8[0] == 0xfd); +} + +int ipv6_addr_is_multicast(const ipv6_addr_t *addr) +{ + return (addr->uint8[0] == 0xff); +} + +int ipv6_addr_is_unspecified(const ipv6_addr_t *ipv6_addr) +{ + return (ipv6_addr->uint32[0] == 0) && (ipv6_addr->uint32[1] == 0) && + (ipv6_addr->uint32[2] == 0) && (ipv6_addr->uint32[3] == 0); +} + +int ipv6_addr_is_solicited_node(const ipv6_addr_t *ipv6_addr) +{ + return (ipv6_addr->uint8[0] == 0xFF) && + (ipv6_addr->uint8[1] == 0x02) && + (ipv6_addr->uint16[1] == 0x00) && + (ipv6_addr->uint16[2] == 0x00) && + (ipv6_addr->uint16[3] == 0x00) && + (ipv6_addr->uint16[4] == 0x00) && + (ipv6_addr->uint8[10] == 0x00) && + (ipv6_addr->uint8[11] == 0x01) && + (ipv6_addr->uint8[12] == 0xFF); +} + +void ipv6_addr_set_solicited_node_addr(ipv6_addr_t *ipv6_addr_out, + const ipv6_addr_t *ipv6_addr_in) +{ + /* copy only the last 24-bit of the ip-address that is beeing resolved */ + ipv6_addr_out->uint16[0] = HTONS(0xff02); + ipv6_addr_out->uint16[1] = 0; + ipv6_addr_out->uint16[2] = 0; + ipv6_addr_out->uint16[3] = 0; + ipv6_addr_out->uint16[4] = 0; + ipv6_addr_out->uint16[5] = HTONS(0x0001); + ipv6_addr_out->uint8[12] = 0xff; + ipv6_addr_out->uint8[13] = ipv6_addr_in->uint8[13]; + ipv6_addr_out->uint16[7] = ipv6_addr_in->uint16[7]; +} + +char *ipv6_addr_to_str(char *addr_str, const ipv6_addr_t *ipv6_addr) +{ + sprintf(addr_str, + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", + ipv6_addr->uint16[0], ipv6_addr->uint16[1], + ipv6_addr->uint16[2], ipv6_addr->uint16[3], + ipv6_addr->uint16[4], ipv6_addr->uint16[5], + ipv6_addr->uint16[6], ipv6_addr->uint16[7]); + return addr_str; +} + +uint32_t get_remaining_time(timex_t *t) +{ + timex_t now; + vtimer_now(&now); + + return (timex_sub(*t, now).seconds); +} + +void set_remaining_time(timex_t *t, uint32_t time) +{ + timex_t tmp = {time, 0}; + + timex_t now; + vtimer_now(&now); + *t = timex_add(now, tmp); +} + +void ipv6_init_iface_as_router(void) +{ + ipv6_addr_t addr; + + ipv6_addr_set_all_routers_addr(&addr); + ipv6_iface_add_addr(&addr, NDP_ADDR_STATE_PREFERRED, 0, 0, IPV6_ADDR_TYPE_MULTICAST); +} + + +uint8_t ipv6_is_router(void) +{ + ipv6_addr_t addr; + + ipv6_addr_set_all_routers_addr(&addr); + + if (ipv6_iface_addr_match(&addr) != NULL) { + return 1; + } + + return 0; +} + +void set_tcp_packet_handler_pid(int pid) +{ + tcp_packet_handler_pid = pid; +} + +void set_udp_packet_handler_pid(int pid) +{ + udp_packet_handler_pid = pid; +} + +void ipv6_register_next_header_handler(uint8_t next_header, int pid) +{ + switch (next_header) { + case (IPV6_PROTO_NUM_TCP): + set_tcp_packet_handler_pid(pid); + break; + case (IPV6_PROTO_NUM_UDP): + set_udp_packet_handler_pid(pid); + break; + default: + /* TODO */ + break; + } +} + +void ipv6_register_rpl_handler(int pid) +{ + rpl_process_pid = pid; +} diff --git a/sys/net/sixlowpan/ip.h b/sys/net/sixlowpan/ip.h new file mode 100644 index 0000000000..9258005e7b --- /dev/null +++ b/sys/net/sixlowpan/ip.h @@ -0,0 +1,91 @@ +/** + * IPv6 constants, data structs, and prototypes + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlowip.h + * @brief 6lowpan IP layer header + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Eric Engel + * @author Oliver Gesch + * @} + */ + +/* 6LoWPAN IP header file */ + +#ifndef _SIXLOWPAN_IP_H +#define _SIXLOWPAN_IP_H + +#include + +#include "timex.h" +#include "mutex.h" + +#include "sixlowpan/ip.h" +#include "sixlowpan/types.h" + +/* IPv6 field values */ +#define IPV6_VER (0x60) +/* size of global buffer */ +#define BUFFER_SIZE (LL_HDR_LEN + IPV6_MTU) + +#define MULTIHOP_HOPLIMIT (64) + +#define SIXLOWIP_MAX_REGISTERED (4) + +/* extern variables */ +extern uint8_t ipv6_ext_hdr_len; + +/* base header lengths */ +#define LL_HDR_LEN (0x4) +#define ICMPV6_HDR_LEN (0x4) +#define IPV6_HDR_LEN (0x28) + +#define IFACE_ADDR_LIST_LEN (10) // maybe to much + +/* buffer */ +extern uint8_t buffer[BUFFER_SIZE]; + +extern int sixlowip_reg[SIXLOWIP_MAX_REGISTERED]; + +typedef struct __attribute__((packed)) { + ipv6_addr_t addr; + ipv6_addr_type_t type; + ndp_addr_state_t state; + timex_t val_ltime; + timex_t pref_ltime; +} addr_list_t; + +typedef struct __attribute__((packed)) { + ieee_802154_short_t saddr; + ieee_802154_long_t laddr; + addr_list_t addr_list[IFACE_ADDR_LIST_LEN]; + uint8_t adv_cur_hop_limit; + uint32_t adv_reachable_time; + uint32_t adv_retrans_timer; +} iface_t; + +extern iface_t iface; + +/* function prototypes */ +void ipv6_send_bytes(ipv6_hdr_t *bytes); +icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len); +uint8_t *get_payload_buf(uint8_t ext_len); +uint8_t *get_payload_buf_send(uint8_t ext_len); + +int icmpv6_demultiplex(const icmpv6_hdr_t *hdr); +void ipv6_init_iface_as_router(void); +void ipv6_process(void); +addr_list_t *ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr); +addr_list_t *ipv6_iface_addr_match(const ipv6_addr_t *addr); +uint32_t get_remaining_time(timex_t *t); +void set_remaining_time(timex_t *t, uint32_t time); + +#endif /* _SIXLOWPAN_IP_H*/ diff --git a/sys/net/sixlowpan/sixlowpan.c b/sys/net/sixlowpan/lowpan.c similarity index 77% rename from sys/net/sixlowpan/sixlowpan.c rename to sys/net/sixlowpan/lowpan.c index 7c6ac128e2..61b0f858c4 100644 --- a/sys/net/sixlowpan/sixlowpan.c +++ b/sys/net/sixlowpan/lowpan.c @@ -10,7 +10,7 @@ * @ingroup sixlowpan * @{ * @file sixlowpan.c - * @brief 6lowpan functions + * @brief 6lowpan functions * @author Stephan Zeisberg * @author Martin Lenders * @author Oliver Gesch @@ -18,11 +18,11 @@ * @} */ -#include "sixlowip.h" #include #include #include #include +#include #include "vtimer.h" #include "timex.h" @@ -31,18 +31,61 @@ #include "mutex.h" #include "hwtimer.h" #include "msg.h" -#include "sixlowmac.h" -#include "sixlowpan.h" -#include "sixlowborder.h" -#include "sixlowip.h" -#include "sixlownd.h" #include "transceiver.h" -#include "ieee802154/ieee802154_frame.h" +#include "sixlowpan/mac.h" +#include "sixlowpan/ndp.h" + +#include "lowpan.h" +#include "border.h" +#include "ip.h" +#include "icmp.h" + +#include "sys/net/ieee802154/ieee802154_frame.h" #include "sys/net/destiny/in.h" #include "sys/net/net_help/net_help.h" -uint16_t packet_length; -uint8_t packet_dispatch; +#define IP_PROCESS_STACKSIZE (KERNEL_CONF_STACKSIZE_DEFAULT * 6) +#define NC_STACKSIZE (KERNEL_CONF_STACKSIZE_DEFAULT) +#define CON_STACKSIZE (KERNEL_CONF_STACKSIZE_DEFAULT) +#define LOWPAN_TRANSFER_BUF_STACKSIZE (KERNEL_CONF_STACKSIZE_DEFAULT) + +#define SIXLOWPAN_MAX_REGISTERED (4) + +#define LOWPAN_REAS_BUF_TIMEOUT (15 * 1000 * 1000) +/* TODO: Set back to 3 * 1000 * (1000) */ + +#define IPV6_LL_ADDR_LEN (8) + +#define SIXLOWPAN_FRAG_HDR_MASK (0xf8) + +typedef struct lowpan_interval_list_t { + uint8_t start; + uint8_t end; + struct lowpan_interval_list_t *next; +} lowpan_interval_list_t; + +typedef struct lowpan_reas_buf_t { + /* Source Address */ + ieee_802154_long_t s_laddr; + /* Destination Address */ + ieee_802154_long_t d_laddr; + /* Identification Number */ + uint16_t ident_no; + /* Timestamp of last packet fragment */ + long timestamp; + /* Size of reassembled packet with possible IPHC header */ + uint16_t packet_size; + /* Additive size of currently already received fragments */ + uint16_t current_packet_size; + /* Pointer to allocated memory for reassembled packet + 6LoWPAN Dispatch Byte */ + uint8_t *packet; + /* Pointer to list of intervals of received packet fragments (if any) */ + lowpan_interval_list_t *interval_list_head; + /* Pointer to next reassembly buffer (if any) */ + struct lowpan_reas_buf_t *next; +} lowpan_reas_buf_t; + +extern mutex_t lowpan_context_mutex; uint16_t tag; uint8_t header_size = 0; uint8_t max_frame = 0; @@ -50,7 +93,11 @@ uint8_t max_frag_initial = 0; uint8_t position; uint8_t max_frag; +static uint16_t packet_length; +static sixlowpan_lowpan_iphc_status_t iphc_status = LOWPAN_IPHC_ENABLE; static ipv6_hdr_t *ipv6_buf; +static lowpan_reas_buf_t *head = NULL; +static lowpan_reas_buf_t *packet_fifo = NULL; /* length of compressed packet */ uint16_t comp_len; @@ -59,8 +106,6 @@ uint8_t reas_buf[512]; uint8_t comp_buf[512]; uint8_t byte_offset; uint8_t first_frag = 0; -lowpan_reas_buf_t *head = NULL; -lowpan_reas_buf_t *packet_fifo = NULL; mutex_t fifo_mutex; unsigned int ip_process_pid; @@ -71,36 +116,59 @@ unsigned int transfer_pid = 0; iface_t iface; ipv6_addr_t lladdr; ieee_802154_long_t laddr; -mutex_t buf_mutex; mutex_t lowpan_context_mutex; +/* registered upper layer threads */ +int sixlowpan_reg[SIXLOWPAN_MAX_REGISTERED]; + char ip_process_buf[IP_PROCESS_STACKSIZE]; char nc_buf[NC_STACKSIZE]; char con_buf[CON_STACKSIZE]; char lowpan_transfer_buf[LOWPAN_TRANSFER_BUF_STACKSIZE]; -lowpan_context_t contexts[LOWPAN_CONTEXT_MAX]; +lowpan_context_t contexts[NDP_6LOWPAN_CONTEXT_MAX]; uint8_t context_len = 0; uint16_t local_address = 0; void lowpan_context_auto_remove(void); +void lowpan_iphc_encoding(ieee_802154_long_t *dest, + ipv6_hdr_t *ipv6_buf_extra, uint8_t *ptr); +void lowpan_iphc_decoding(uint8_t *data, uint8_t length, + ieee_802154_long_t *s_laddr, + ieee_802154_long_t *d_laddr); +void add_fifo_packet(lowpan_reas_buf_t *current_packet); +lowpan_reas_buf_t *collect_garbage_fifo(lowpan_reas_buf_t *current_buf); +lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf); +void init_reas_bufs(lowpan_reas_buf_t *buf); +void check_timeout(void); + +lowpan_context_t *lowpan_context_lookup(ipv6_addr_t *addr); + +void lowpan_ipv6_set_dispatch(uint8_t *data); /* deliver packet to mac*/ -void lowpan_init(ieee_802154_long_t *addr, uint8_t *data) +void sixlowpan_lowpan_sendto(const ieee_802154_long_t *dest, + uint8_t *data, uint16_t data_len) { uint8_t mcast = 0; ipv6_buf = (ipv6_hdr_t *) data; + packet_length = data_len; - memcpy(&laddr.uint8[0], &addr->uint8[0], 8); + memcpy(&laddr.uint8[0], &dest->uint8[0], 8); - if (ipv6_prefix_mcast_match(&ipv6_buf->destaddr)) { + if (ipv6_addr_is_multicast(&ipv6_buf->destaddr)) { /* send broadcast */ mcast = 1; } - lowpan_iphc_encoding(&laddr, ipv6_buf, data); - data = &comp_buf[0]; - packet_length = comp_len; + if (iphc_status == LOWPAN_IPHC_ENABLE) { + lowpan_iphc_encoding(&laddr, ipv6_buf, data); + data = &comp_buf[0]; + packet_length = comp_len; + } + else { + lowpan_ipv6_set_dispatch(data); + } /* check if packet needs to be fragmented */ if (packet_length + header_size > PAYLOAD_SIZE - IEEE_802154_MAX_HDR_LEN) { @@ -113,13 +181,15 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data) memcpy(fragbuf + 4, data, max_frag_initial); - fragbuf[0] = (((0xc0 << 8) | packet_length) >> 8) & 0xff; - fragbuf[1] = ((0xc0 << 8) | packet_length) & 0xff; - fragbuf[2] = (tag >> 8) & 0xff; - fragbuf[3] = tag & 0xff; + fragbuf[0] = ((SIXLOWPAN_FRAG1_DISPATCH << 8) | packet_length) >> 8; + fragbuf[1] = (SIXLOWPAN_FRAG1_DISPATCH << 8) | packet_length; + fragbuf[2] = tag >> 8; + fragbuf[3] = tag; - send_ieee802154_frame(&laddr, (uint8_t *)&fragbuf, - max_frag_initial + header_size + 4, mcast); + sixlowpan_mac_send_ieee802154_frame(&laddr, + (uint8_t *)&fragbuf, + max_frag_initial + header_size + 4, + mcast); /* subsequent fragments */ position = max_frag_initial; max_frag = ((max_frame - 5) / 8) * 8; @@ -130,14 +200,15 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data) memset(&fragbuf, 0, packet_length + header_size); memcpy(fragbuf + 5, data, max_frag); - fragbuf[0] = (((0xe0 << 8) | packet_length) >> 8) & 0xff; - fragbuf[1] = ((0xe0 << 8) | packet_length) & 0xff; - fragbuf[2] = (tag >> 8) & 0xff; - fragbuf[3] = tag & 0xff; + fragbuf[0] = ((SIXLOWPAN_FRAGN_DISPATCH << 8) | packet_length) >> 8; + fragbuf[1] = (SIXLOWPAN_FRAGN_DISPATCH << 8) | packet_length; + fragbuf[2] = tag >> 8; + fragbuf[3] = tag; fragbuf[4] = position / 8; - send_ieee802154_frame(&laddr, (uint8_t *)&fragbuf, max_frag + 5, - mcast); + sixlowpan_mac_send_ieee802154_frame(&laddr, + (uint8_t *)&fragbuf, + max_frag + 5, mcast); data += max_frag; position += max_frag; @@ -149,22 +220,32 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data) memset(&fragbuf, 0, packet_length + header_size); memcpy(fragbuf + 5, data, remaining); - fragbuf[0] = (((0xe0 << 8) | packet_length) >> 8) & 0xff; - fragbuf[1] = ((0xe0 << 8) | packet_length) & 0xff; - fragbuf[2] = (tag >> 8) & 0xff; - fragbuf[3] = tag & 0xff; + fragbuf[0] = ((SIXLOWPAN_FRAGN_DISPATCH << 8) | packet_length) >> 8; + fragbuf[1] = (SIXLOWPAN_FRAGN_DISPATCH << 8) | packet_length; + fragbuf[2] = tag >> 8; + fragbuf[3] = tag; fragbuf[4] = position / 8; - send_ieee802154_frame(&laddr, (uint8_t *)&fragbuf, remaining + 5, mcast); + sixlowpan_mac_send_ieee802154_frame(&laddr, + (uint8_t *)&fragbuf, + remaining + 5, mcast); } else { - send_ieee802154_frame(&laddr, data, packet_length, mcast); + sixlowpan_mac_send_ieee802154_frame(&laddr, data, + packet_length, mcast); } tag++; } -void printLongLocalAddr(ieee_802154_long_t *saddr) +void sixlowpan_lowpan_set_iphc_status( + sixlowpan_lowpan_iphc_status_t status) +{ + iphc_status = status; +} + +#if ENABLE_DEBUG +void print_long_local_addr(ieee_802154_long_t *saddr) { printf("%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", ((uint8_t *)saddr)[0], ((uint8_t *)saddr)[1], ((uint8_t *)saddr)[2], @@ -172,7 +253,7 @@ void printLongLocalAddr(ieee_802154_long_t *saddr) ((uint8_t *)saddr)[6], ((uint8_t *)saddr)[7]); } -void printReasBuffers(void) +void sixlowpan_lowpan_print_reassembly_buffers(void) { lowpan_reas_buf_t *temp_buffer; lowpan_interval_list_t *temp_interval; @@ -181,7 +262,7 @@ void printReasBuffers(void) printf("\n\n--- Reassembly Buffers ---\n"); while (temp_buffer != NULL) { - printLongLocalAddr(&temp_buffer->s_laddr); + print_long_local_addr(&temp_buffer->s_laddr); printf("Ident.: %i, Packet Size: %i/%i, Timestamp: %li\n", temp_buffer->ident_no, temp_buffer->current_packet_size, temp_buffer->packet_size, temp_buffer->timestamp); @@ -196,7 +277,7 @@ void printReasBuffers(void) } } -void printFIFOBuffers(void) +void sixlowpan_lowpan_print_fifo_buffers(void) { lowpan_reas_buf_t *temp_buffer; lowpan_interval_list_t *temp_interval; @@ -205,9 +286,9 @@ void printFIFOBuffers(void) printf("\n\n--- Reassembly Buffers ---\n"); while (temp_buffer != NULL) { - printLongLocalAddr(&temp_buffer->s_laddr); + print_long_local_addr(&temp_buffer->s_laddr); printf("Ident.: %i, Packet Size: %i/%i, Timestamp: %li\n", - temp_buffer->ident_no, temp_buffer->current_packet_size, + temp_buffer->ident_no, temp_buffer->current_packet_size, temp_buffer->packet_size, temp_buffer->timestamp); temp_interval = temp_buffer->interval_list_head; @@ -219,6 +300,7 @@ void printFIFOBuffers(void) temp_buffer = temp_buffer->next; } } +#endif void lowpan_transfer(void) { @@ -236,20 +318,20 @@ void lowpan_transfer(void) if (current_buf != NULL) { mutex_unlock(&fifo_mutex); - if ((current_buf->packet)[0] == LOWPAN_IPV6_DISPATCH) { - ipv6_buf = get_ipv6_buf(); + if ((current_buf->packet)[0] == SIXLOWPAN_IPV6_DISPATCH) { + ipv6_buf = ipv6_get_buf(); memcpy(ipv6_buf, (current_buf->packet) + 1, current_buf->packet_size - 1); m_send.content.ptr = (char *)ipv6_buf; packet_length = current_buf->packet_size - 1; msg_send_receive(&m_send, &m_recv, ip_process_pid); } - else if (((current_buf->packet)[0] & 0xe0) == LOWPAN_IPHC_DISPATCH) { + else if (((current_buf->packet)[0] & 0xe0) == SIXLOWPAN_IPHC1_DISPATCH) { lowpan_iphc_decoding(current_buf->packet, current_buf->packet_size, &(current_buf->s_laddr), &(current_buf->d_laddr)); - ipv6_buf = get_ipv6_buf(); + ipv6_buf = ipv6_get_buf(); m_send.content.ptr = (char *) ipv6_buf; msg_send_receive(&m_send, &m_recv, ip_process_pid); } @@ -315,8 +397,8 @@ lowpan_reas_buf_t *new_packet_buffer(uint16_t datagram_size, new_buf->packet = malloc(datagram_size); if (new_buf->packet != NULL) { - memcpy(&new_buf->s_laddr, s_laddr, SIXLOWPAN_IPV6_LL_ADDR_LEN); - memcpy(&new_buf->d_laddr, d_laddr, SIXLOWPAN_IPV6_LL_ADDR_LEN); + memcpy(&new_buf->s_laddr, s_laddr, IPV6_LL_ADDR_LEN); + memcpy(&new_buf->d_laddr, d_laddr, IPV6_LL_ADDR_LEN); new_buf->ident_no = datagram_tag; new_buf->packet_size = datagram_size; @@ -353,10 +435,10 @@ lowpan_reas_buf_t *get_packet_frag_buf(uint16_t datagram_size, while (current_buf != NULL) { if (((ll_get_addr_match(¤t_buf->s_laddr, s_laddr)) == 64) && - ((ll_get_addr_match(¤t_buf->d_laddr, d_laddr)) == 64) && - (current_buf->packet_size == datagram_size) && - (current_buf->ident_no == datagram_tag) && - current_buf->interval_list_head != NULL) { + ((ll_get_addr_match(¤t_buf->d_laddr, d_laddr)) == 64) && + (current_buf->packet_size == datagram_size) && + (current_buf->ident_no == datagram_tag) && + current_buf->interval_list_head != NULL) { /* Found buffer for current packet fragment */ timex_t now; vtimer_now(&now); @@ -372,14 +454,14 @@ lowpan_reas_buf_t *get_packet_frag_buf(uint16_t datagram_size, current_buf, temp_buf); } -uint8_t isInInterval(uint8_t start1, uint8_t end1, uint8_t start2, uint8_t end2) +uint8_t is_in_interval(uint8_t start1, uint8_t end1, uint8_t start2, uint8_t end2) { /* 1: Interval 1 and 2 are the same or overlapping */ /* 0: Interval 1 and 2 are not overlapping or the same */ if (((start1 < start2) && (start2 <= end1)) || - ((start2 < start1) && (start1 <= end2)) || - ((start1 == start2) && (end1 == end2))) { + ((start2 < start1) && (start1 <= end2)) || + ((start1 == start2) && (end1 == end2))) { return 1; } else { @@ -396,7 +478,7 @@ uint8_t handle_packet_frag_interval(lowpan_reas_buf_t *current_buf, current_interval = current_buf->interval_list_head; while (current_interval != NULL) { - if (isInInterval(current_interval->start, current_interval->end, datagram_offset, datagram_offset + frag_size) == 1) { + if (is_in_interval(current_interval->start, current_interval->end, datagram_offset, datagram_offset + frag_size) == 1) { /* Interval is overlapping or the same as one of a previous fragment, discard fragment */ return 0; } @@ -505,7 +587,7 @@ lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf) return return_buf; } -void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset, +void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset, uint16_t datagram_size, uint16_t datagram_tag, ieee_802154_long_t *s_laddr, ieee_802154_long_t *d_laddr, uint8_t hdr_length, @@ -516,8 +598,8 @@ void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset, current_buf = get_packet_frag_buf(datagram_size, datagram_tag, s_laddr, d_laddr); if ((current_buf != NULL) && (handle_packet_frag_interval(current_buf, - datagram_offset, - frag_size) == 1)) { + datagram_offset, + frag_size) == 1)) { /* Copy fragment bytes into corresponding packet space area */ memcpy(current_buf->packet + datagram_offset, data + hdr_length, frag_size); current_buf->current_packet_size += frag_size; @@ -614,6 +696,25 @@ void add_fifo_packet(lowpan_reas_buf_t *current_packet) current_packet->next = NULL; } +/* Register an upper layer thread */ +uint8_t sixlowpan_lowpan_register(int pid) +{ + uint8_t i; + + for (i = 0; ((sixlowpan_reg[i] != pid) && (i < SIXLOWPAN_MAX_REGISTERED) && + (sixlowpan_reg[i] != 0)); i++) { + ; + } + + if (i >= SIXLOWPAN_MAX_REGISTERED) { + return ENOMEM; + } + else { + sixlowpan_reg[i] = pid; + return 1; + } +} + void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr, ieee_802154_long_t *d_laddr) { @@ -622,27 +723,40 @@ void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr, uint8_t datagram_offset = 0; uint16_t datagram_size = 0; uint16_t datagram_tag = 0; + short i; + sixlowpan_lowpan_frame_t current_frame; check_timeout(); + for (i = 0; i < SIXLOWPAN_MAX_REGISTERED; i++) { + if (sixlowpan_reg[i]) { + msg_t m_send; + current_frame.length = length; + current_frame.data = data; + m_send.content.ptr = (char *) ¤t_frame; + msg_send(&m_send, sixlowpan_reg[i], 1); + } + } + /* Fragmented Packet */ - if (((data[0] & 0xf8) == (0xc0)) || ((data[0] & 0xf8) == (0xe0))) { + if (((data[0] & SIXLOWPAN_FRAG_HDR_MASK) == SIXLOWPAN_FRAG1_DISPATCH) || + ((data[0] & SIXLOWPAN_FRAG_HDR_MASK) == SIXLOWPAN_FRAGN_DISPATCH)) { /* get 11-bit from first 2 byte*/ datagram_size = (((uint16_t)(data[0] << 8)) | data[1]) & 0x07ff; /* get 16-bit datagram tag */ datagram_tag = (((uint16_t)(data[2] << 8)) | data[3]); - switch(data[0] & 0xf8) { + switch (data[0] & SIXLOWPAN_FRAG_HDR_MASK) { /* First Fragment */ - case (0xc0): { + case (SIXLOWPAN_FRAG1_DISPATCH): { datagram_offset = 0; hdr_length += 4; break; } /* Subsequent Fragment */ - case (0xe0): { + case (SIXLOWPAN_FRAGN_DISPATCH): { datagram_offset = data[4]; hdr_length += 5; break; @@ -665,7 +779,7 @@ void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr, /* Regular Packet */ else { lowpan_reas_buf_t *current_buf = get_packet_frag_buf(length, 0, s_laddr, - d_laddr); + d_laddr); /* Copy packet bytes into corresponding packet space area */ memcpy(current_buf->packet, data, length); current_buf->current_packet_size += length; @@ -681,7 +795,7 @@ void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr, void lowpan_ipv6_set_dispatch(uint8_t *data) { memmove(data + 1, data, packet_length); - data[0] = LOWPAN_IPV6_DISPATCH; + data[0] = SIXLOWPAN_IPV6_DISPATCH; packet_length++; } @@ -701,7 +815,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, memset(&lowpan_iphc, 0, 2); /* set iphc dispatch */ - lowpan_iphc[0] = LOWPAN_IPHC_DISPATCH; + lowpan_iphc[0] = SIXLOWPAN_IPHC1_DISPATCH; /* TF: Traffic Class, Flow Label: * first we need to change DSCP and ECN because in 6lowpan-nd-13 these @@ -711,14 +825,14 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, tc = (tc >> 2) | (tc << 6); if ((ipv6_buf->flowlabel == 0) && - (ipv6_buf->trafficclass_flowlabel & 0x0f) == 0) { + (ipv6_buf->trafficclass_flowlabel & 0x0f) == 0) { /* flowlabel is elided */ - lowpan_iphc[0] |= LOWPAN_IPHC_FL_C; + lowpan_iphc[0] |= SIXLOWPAN_IPHC1_FL_C; if (((ipv6_buf->version_trafficclass & 0x0f) == 0) && - ((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)) { + ((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)) { /* traffic class is elided */ - lowpan_iphc[0] |= LOWPAN_IPHC_TC_C; + lowpan_iphc[0] |= SIXLOWPAN_IPHC1_TC_C; } else { /* ECN + DSCP (1 byte), Flow Label is elided */ @@ -729,9 +843,9 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, else { /* flowlabel not compressible */ if (((ipv6_buf->version_trafficclass & 0x0f) == 0) && - ((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)) { + ((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)) { /* traffic class is elided */ - lowpan_iphc[0] |= LOWPAN_IPHC_TC_C; + lowpan_iphc[0] |= SIXLOWPAN_IPHC1_TC_C; /* ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided */ ipv6_hdr_fields[hdr_pos] = ((tc & 0xc0) | (ipv6_buf->trafficclass_flowlabel & 0x0f)); @@ -752,7 +866,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, hdr_pos++; /* HLIM: Hop Limit: */ - switch(ipv6_buf->hoplimit) { + switch (ipv6_buf->hoplimit) { case (1): { /* 01: The Hop Limit field is compressed and the hop limit is 1. */ lowpan_iphc[0] |= 0x01; @@ -782,21 +896,21 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, /* CID: Context Identifier Extension: */ if ((lowpan_context_lookup(&ipv6_buf->srcaddr) != NULL) || - (lowpan_context_lookup(&ipv6_buf->destaddr) != NULL)) { - lowpan_iphc[1] |= LOWPAN_IPHC_CID; + (lowpan_context_lookup(&ipv6_buf->destaddr) != NULL)) { + lowpan_iphc[1] |= SIXLOWPAN_IPHC2_CID; memmove(&ipv6_hdr_fields[1], &ipv6_hdr_fields[0], hdr_pos); hdr_pos++; } /* SAC: Source Address Compression */ - if (ipv6_addr_unspec_match(&(ipv6_buf->srcaddr))) { + if (ipv6_addr_is_unspecified(&(ipv6_buf->srcaddr))) { /* SAC = 1 and SAM = 00 */ - lowpan_iphc[1] |= LOWPAN_IPHC_SAC; + lowpan_iphc[1] |= SIXLOWPAN_IPHC2_SAC; } else if ((con = lowpan_context_lookup(&ipv6_buf->srcaddr)) != NULL) { /* 1: Source address compression uses stateful, context-based * compression. */ - lowpan_iphc[1] |= LOWPAN_IPHC_SAC; + lowpan_iphc[1] |= SIXLOWPAN_IPHC2_SAC; ipv6_hdr_fields[0] |= (con->num << 4); if (memcmp(&(ipv6_buf->srcaddr.uint8[8]), &(iface.laddr.uint8[0]), 8) == 0) { @@ -805,9 +919,9 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, lowpan_iphc[1] |= 0x30; } else if ((ipv6_buf->srcaddr.uint16[4] == 0) && - (ipv6_buf->srcaddr.uint16[5] == 0) && - (ipv6_buf->srcaddr.uint16[6] == 0) && - ((ipv6_buf->srcaddr.uint8[14]) & 0x80) == 0) { + (ipv6_buf->srcaddr.uint16[5] == 0) && + (ipv6_buf->srcaddr.uint16[6] == 0) && + ((ipv6_buf->srcaddr.uint8[14]) & 0x80) == 0) { /* 49-bit of interface identifier are 0, so we can compress * source address-iid to 16-bit */ memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->srcaddr.uint16[7], 2); @@ -824,7 +938,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, lowpan_iphc[1] |= 0x10; } } - else if (ipv6_prefix_ll_match(&ipv6_buf->srcaddr)) { + else if (ipv6_addr_is_link_local(&ipv6_buf->srcaddr)) { /* 0: Source address compression uses stateless compression.*/ if (memcmp(&(ipv6_buf->srcaddr.uint8[8]), &(iface.laddr.uint8[0]), 8) == 0) { /* 0 bits. The address is derived using context information @@ -832,9 +946,9 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, lowpan_iphc[1] |= 0x30; } else if ((ipv6_buf->srcaddr.uint16[4] == 0) && - (ipv6_buf->srcaddr.uint16[5] == 0) && - (ipv6_buf->srcaddr.uint16[6] == 0) && - ((ipv6_buf->srcaddr.uint8[14]) & 0x80) == 0) { + (ipv6_buf->srcaddr.uint16[5] == 0) && + (ipv6_buf->srcaddr.uint16[6] == 0) && + ((ipv6_buf->srcaddr.uint8[14]) & 0x80) == 0) { /* 49-bit of interface identifier are 0, so we can compress * source address-iid to 16-bit */ memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->srcaddr.uint16[7], 2); @@ -858,30 +972,30 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, } /* M: Multicast Compression */ - if (ipv6_prefix_mcast_match(&ipv6_buf->destaddr)) { + if (ipv6_addr_is_multicast(&ipv6_buf->destaddr)) { /* 1: Destination address is a multicast address. */ - lowpan_iphc[1] |= LOWPAN_IPHC_M; + lowpan_iphc[1] |= SIXLOWPAN_IPHC2_M; /* just another cool if condition */ if ((ipv6_buf->destaddr.uint8[1] == 2) && - (ipv6_buf->destaddr.uint16[1] == 0) && - (ipv6_buf->destaddr.uint16[2] == 0) && - (ipv6_buf->destaddr.uint16[3] == 0) && - (ipv6_buf->destaddr.uint16[4] == 0) && - (ipv6_buf->destaddr.uint16[5] == 0) && - (ipv6_buf->destaddr.uint16[6] == 0) && - (ipv6_buf->destaddr.uint8[14] == 0)) { + (ipv6_buf->destaddr.uint16[1] == 0) && + (ipv6_buf->destaddr.uint16[2] == 0) && + (ipv6_buf->destaddr.uint16[3] == 0) && + (ipv6_buf->destaddr.uint16[4] == 0) && + (ipv6_buf->destaddr.uint16[5] == 0) && + (ipv6_buf->destaddr.uint16[6] == 0) && + (ipv6_buf->destaddr.uint8[14] == 0)) { /* 11: 8 bits. The address takes the form FF02::00XX. */ lowpan_iphc[1] |= 0x03; ipv6_hdr_fields[hdr_pos] = ipv6_buf->destaddr.uint8[15]; hdr_pos++; } else if ((ipv6_buf->destaddr.uint16[1] == 0) && - (ipv6_buf->destaddr.uint16[2] == 0) && - (ipv6_buf->destaddr.uint16[3] == 0) && - (ipv6_buf->destaddr.uint16[4] == 0) && - (ipv6_buf->destaddr.uint16[5] == 0) && - (ipv6_buf->destaddr.uint8[12] == 0)) { + (ipv6_buf->destaddr.uint16[2] == 0) && + (ipv6_buf->destaddr.uint16[3] == 0) && + (ipv6_buf->destaddr.uint16[4] == 0) && + (ipv6_buf->destaddr.uint16[5] == 0) && + (ipv6_buf->destaddr.uint8[12] == 0)) { /* 10: 32 bits. The address takes the form FFXX::00XX:XXXX. */ lowpan_iphc[1] |= 0x02; /* copy second and last 3 byte */ @@ -891,10 +1005,10 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, hdr_pos += 3; } else if ((ipv6_buf->destaddr.uint16[1] == 0) && - (ipv6_buf->destaddr.uint16[2] == 0) && - (ipv6_buf->destaddr.uint16[3] == 0) && - (ipv6_buf->destaddr.uint16[4] == 0) && - (ipv6_buf->destaddr.uint8[10] == 0)) { + (ipv6_buf->destaddr.uint16[2] == 0) && + (ipv6_buf->destaddr.uint16[3] == 0) && + (ipv6_buf->destaddr.uint16[4] == 0) && + (ipv6_buf->destaddr.uint8[10] == 0)) { /* 01: 48 bits. The address takes the form FFXX::00XX:XXXX:XXXX */ lowpan_iphc[1] |= 0x01; /* copy second and last 5 byte */ @@ -913,7 +1027,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, if ((con = lowpan_context_lookup(&ipv6_buf->destaddr)) != NULL) { /* 1: Destination address compression uses stateful, context-based * compression. */ - lowpan_iphc[1] |= LOWPAN_IPHC_DAC; + lowpan_iphc[1] |= SIXLOWPAN_IPHC2_DAC; ipv6_hdr_fields[0] = con->num; if (memcmp(&(ipv6_buf->destaddr.uint8[8]), &(dest->uint8[0]), 8) == 0) { @@ -922,9 +1036,9 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, lowpan_iphc[1] |= 0x03; } else if ((ipv6_buf->destaddr.uint16[4] == 0) && - (ipv6_buf->destaddr.uint16[5] == 0) && - (ipv6_buf->destaddr.uint16[6] == 0) && - ((ipv6_buf->destaddr.uint8[14]) & 0x80) == 0) { + (ipv6_buf->destaddr.uint16[5] == 0) && + (ipv6_buf->destaddr.uint16[6] == 0) && + ((ipv6_buf->destaddr.uint8[14]) & 0x80) == 0) { /* 49-bit of interface identifier are 0, so we can compress * source address-iid to 16-bit */ memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->destaddr.uint16[7], 2); @@ -941,16 +1055,16 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, lowpan_iphc[1] |= 0x01; } } - else if (ipv6_prefix_ll_match(&ipv6_buf->destaddr)) { + else if (ipv6_addr_is_link_local(&ipv6_buf->destaddr)) { if (memcmp(&(ipv6_buf->destaddr.uint8[8]), &(dest->uint8[0]), 8) == 0) { /* 0 bits. The address is derived using context information * and possibly the link-layer addresses.*/ lowpan_iphc[1] |= 0x03; } else if ((ipv6_buf->destaddr.uint16[4] == 0) && - (ipv6_buf->destaddr.uint16[5] == 0) && - (ipv6_buf->destaddr.uint16[6] == 0) && - ((ipv6_buf->destaddr.uint8[14]) & 0x80) == 0) { + (ipv6_buf->destaddr.uint16[5] == 0) && + (ipv6_buf->destaddr.uint16[6] == 0) && + ((ipv6_buf->destaddr.uint8[14]) & 0x80) == 0) { /* 49-bit of interface identifier are 0, so we can compress * source address-iid to 16-bit */ memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->destaddr.uint16[7], 2); @@ -979,7 +1093,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, comp_buf[1] = lowpan_iphc[1]; /*uint8_t *ptr; - if (ipv6_buf->nextheader == IPPROTO_TCP) + if (ipv6_buf->nextheader == IPV6_PROTO_NUM_TCP) { ptr = get_payload_buf_send(ipv6_ext_hdr_len); } @@ -1008,22 +1122,22 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, uint8_t m_prefix[2] = {0xff, 0x02}; lowpan_context_t *con = NULL; - ipv6_buf = get_ipv6_buf(); + ipv6_buf = ipv6_get_buf(); lowpan_iphc[0] = ipv6_hdr_fields[0]; lowpan_iphc[1] = ipv6_hdr_fields[1]; hdr_pos += 2; /* first check if CID flag is set */ - if (lowpan_iphc[1] & LOWPAN_IPHC_CID) { + if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_CID) { hdr_pos++; cid = 1; } /* TF: Traffic Class, Flow Label: */ - if (lowpan_iphc[0] & LOWPAN_IPHC_FL_C) { + if (lowpan_iphc[0] & SIXLOWPAN_IPHC1_FL_C) { /* flowlabel is elided */ - if (lowpan_iphc[0] & LOWPAN_IPHC_TC_C) { + if (lowpan_iphc[0] & SIXLOWPAN_IPHC1_TC_C) { /* traffic class is elided */ ipv6_buf->version_trafficclass = 0x60; ipv6_buf->trafficclass_flowlabel = 0; @@ -1041,7 +1155,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, } else { /* flowlabel carried inline */ - if (lowpan_iphc[0] & LOWPAN_IPHC_TC_C) { + if (lowpan_iphc[0] & SIXLOWPAN_IPHC1_TC_C) { /* traffic class is elided */ ipv6_buf->version_trafficclass = 0x60; /* ecn + 4 bit flowlabel*/ @@ -1066,7 +1180,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, } /* NH: Next Header: */ - if (lowpan_iphc[0] & LOWPAN_IPHC_NH) { + if (lowpan_iphc[0] & SIXLOWPAN_IPHC1_NH) { // TODO: next header decompression } else { @@ -1076,7 +1190,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, /* HLIM: Hop Limit: */ if (lowpan_iphc[0] & 0x03) { - switch(lowpan_iphc[0] & 0x03) { + switch (lowpan_iphc[0] & 0x03) { case (0x01): { ipv6_buf->hoplimit = 1; break; @@ -1102,7 +1216,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, } /* CID: Context Identifier Extension: + SAC: Source Address Compression */ - if (lowpan_iphc[1] & LOWPAN_IPHC_SAC) { + if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_SAC) { /* 1: Source address compression uses stateful, context-based * compression.*/ if (cid) { @@ -1112,7 +1226,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, mutex_lock(&lowpan_context_mutex); /* check context number */ - if (((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03) { + if (((lowpan_iphc[1] & SIXLOWPAN_IPHC2_SAM) >> 4) & 0x03) { con = lowpan_context_num_lookup(sci); } @@ -1121,7 +1235,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, return; } - switch(((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03) { + switch (((lowpan_iphc[1] & SIXLOWPAN_IPHC2_SAM) >> 4) & 0x03) { case (0x01): { /* 64-bits */ memcpy(&(ipv6_buf->srcaddr.uint8[8]), &ipv6_hdr_fields[hdr_pos], 8); @@ -1163,7 +1277,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, mutex_unlock(&lowpan_context_mutex); } else { - switch(((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03) { + switch (((lowpan_iphc[1] & SIXLOWPAN_IPHC2_SAM) >> 4) & 0x03) { case (0x01): { /* 64-bits */ memcpy(&(ipv6_buf->srcaddr.uint8[0]), &ll_prefix[0], 2); @@ -1201,9 +1315,9 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, } /* M: Multicast Compression + DAC: Destination Address Compression */ - if (lowpan_iphc[1] & LOWPAN_IPHC_M) { + if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_M) { /* 1: Destination address is a multicast address. */ - if (lowpan_iphc[1] & LOWPAN_IPHC_DAC) { + if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAC) { /* 1: Destination address compression uses stateful, context-based * compression. * If M=1 and DAC=1: */ @@ -1213,7 +1327,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, mutex_lock(&lowpan_context_mutex); - if ((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) { + if ((lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAM) & 0x03) { con = lowpan_context_num_lookup(dci); } @@ -1227,7 +1341,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, } else { /* If M=1 and DAC=0: */ - switch(lowpan_iphc[1] & 0x03) { + switch (lowpan_iphc[1] & 0x03) { case (0x01): { m_prefix[1] = ipv6_hdr_fields[hdr_pos]; hdr_pos++; @@ -1244,7 +1358,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, break; } - switch(lowpan_iphc[1] & 0x03) { + switch (lowpan_iphc[1] & 0x03) { case (0x01): { memcpy(&(ipv6_buf->destaddr.uint8[0]), &m_prefix[0], 2); memset(&(ipv6_buf->destaddr.uint8[2]), 0, 9); @@ -1277,7 +1391,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, } } else { - if (lowpan_iphc[1] & LOWPAN_IPHC_DAC) { + if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAC) { /* 1: Destination address compression uses stateful, context-based * compression. * If M=1 and DAC=1: */ @@ -1287,7 +1401,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, mutex_lock(&lowpan_context_mutex); - if ((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) { + if ((lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAM) & 0x03) { con = lowpan_context_num_lookup(dci); } @@ -1296,7 +1410,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, return; } - switch((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) { + switch ((lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAM) & 0x03) { case (0x01): { memcpy(&(ipv6_buf->destaddr.uint8[8]), &ipv6_hdr_fields[hdr_pos], 8); /* By draft-ietf-6lowpan-hc-15 3.1.1. Bits covered by context information are always used. */ @@ -1329,7 +1443,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length, mutex_unlock(&lowpan_context_mutex); } else { - switch((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) { + switch ((lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAM) & 0x03) { case (0x01): { memcpy(&(ipv6_buf->destaddr.uint8[0]), &ll_prefix[0], 2); memset(&(ipv6_buf->destaddr.uint8[2]), 0, 6); @@ -1383,7 +1497,7 @@ void lowpan_context_remove(uint8_t num) { int i, j; - for (i = 0; i < LOWPAN_CONTEXT_MAX; i++) { + for (i = 0; i < NDP_6LOWPAN_CONTEXT_MAX; i++) { if (contexts[i].num == num) { context_len--; break; @@ -1392,7 +1506,7 @@ void lowpan_context_remove(uint8_t num) abr_remove_context(num); - for (j = i; j < LOWPAN_CONTEXT_MAX; j++) { + for (j = i; j < NDP_6LOWPAN_CONTEXT_MAX; j++) { contexts[j] = contexts[j + 1]; } } @@ -1408,7 +1522,7 @@ lowpan_context_t *lowpan_context_update(uint8_t num, const ipv6_addr_t *prefix, return NULL; } - if (context_len == LOWPAN_CONTEXT_MAX) { + if (context_len == NDP_6LOWPAN_CONTEXT_MAX) { return NULL; } @@ -1441,7 +1555,7 @@ lowpan_context_t *lowpan_context_lookup(ipv6_addr_t *addr) for (i = 0; i < lowpan_context_len(); i++) { if (contexts[i].length > 0 && memcmp((void *)addr, &(contexts[i].prefix), - contexts[i].length) == 0) { + contexts[i].length) == 0) { /* longer prefixes are always prefered */ if (context == NULL || context->length < contexts[i].length) { context = &contexts[i]; @@ -1469,7 +1583,7 @@ void lowpan_context_auto_remove(void) { timex_t minute = timex_set(60, 0); int i; - int8_t to_remove[LOWPAN_CONTEXT_MAX]; + int8_t to_remove[NDP_6LOWPAN_CONTEXT_MAX]; int8_t to_remove_size; while (1) { @@ -1493,8 +1607,8 @@ void lowpan_context_auto_remove(void) void init_reas_bufs(lowpan_reas_buf_t *buf) { - memset(&buf->s_laddr, 0, SIXLOWPAN_IPV6_LL_ADDR_LEN); - memset(&buf->d_laddr, 0, SIXLOWPAN_IPV6_LL_ADDR_LEN); + memset(&buf->s_laddr, 0, IPV6_LL_ADDR_LEN); + memset(&buf->d_laddr, 0, IPV6_LL_ADDR_LEN); buf->ident_no = 0; buf->timestamp = 0; buf->packet_size = 0; @@ -1504,19 +1618,20 @@ void init_reas_bufs(lowpan_reas_buf_t *buf) buf->next = NULL; } -void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border) +void sixlowpan_lowpan_init(transceiver_type_t trans, uint8_t r_addr, + int as_border) { ipv6_addr_t tmp; + short i; + /* init mac-layer and radio transceiver */ - sixlowmac_init(trans); + sixlowpan_mac_init(trans); /* init interface addresses */ memset(&iface, 0, sizeof(iface_t)); - set_radio_address(r_addr); - init_802154_short_addr(&(iface.saddr)); - init_802154_long_addr(&(iface.laddr)); - /* init global buffer mutex */ - mutex_init(&buf_mutex); + sixlowpan_mac_set_radio_address(r_addr); + sixlowpan_mac_init_802154_short_addr(&(iface.saddr)); + sixlowpan_mac_init_802154_long_addr(&(iface.laddr)); /* init lowpan context mutex */ mutex_init(&lowpan_context_mutex); @@ -1527,20 +1642,20 @@ void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border) local_address = r_addr; /* init link-local address */ - ipv6_set_ll_prefix(&lladdr); + ipv6_addr_set_link_local_prefix(&lladdr); memcpy(&(lladdr.uint8[8]), &(iface.laddr.uint8[0]), 8); - ipv6_iface_add_addr(&lladdr, ADDR_STATE_PREFERRED, 0, 0, - ADDR_TYPE_LINK_LOCAL); - ipv6_set_loaddr(&tmp); - ipv6_iface_add_addr(&tmp, ADDR_STATE_PREFERRED, 0, 0, - ADDR_TYPE_LOOPBACK); - ipv6_set_all_nds_mcast_addr(&tmp); - ipv6_iface_add_addr(&tmp, ADDR_STATE_PREFERRED, 0, 0, - ADDR_TYPE_LOOPBACK); + ipv6_iface_add_addr(&lladdr, IPV6_ADDR_TYPE_LINK_LOCAL, + NDP_ADDR_STATE_PREFERRED, 0, 0); + ipv6_addr_set_loopback_addr(&tmp); + ipv6_iface_add_addr(&tmp, IPV6_ADDR_TYPE_LOOPBACK, + NDP_ADDR_STATE_PREFERRED, 0, 0); + ipv6_addr_set_all_nodes_addr(&tmp); + ipv6_iface_add_addr(&tmp, IPV6_ADDR_TYPE_LOOPBACK, + NDP_ADDR_STATE_PREFERRED, 0, 0); - ipv6_iface_add_addr(&lladdr, ADDR_STATE_PREFERRED, 0, 0, - ADDR_CONFIGURED_AUTO); + ipv6_iface_add_addr(&lladdr, IPV6_ADDR_TYPE_LINK_LOCAL, + NDP_ADDR_STATE_PREFERRED, 0, 0); if (as_border) { ip_process_pid = thread_create(ip_process_buf, IP_PROCESS_STACKSIZE, @@ -1563,14 +1678,29 @@ void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border) transfer_pid = thread_create(lowpan_transfer_buf, LOWPAN_TRANSFER_BUF_STACKSIZE, PRIORITY_MAIN - 1, CREATE_STACKTEST, lowpan_transfer, "lowpan_transfer"); + + for (i = 0; i < SIXLOWIP_MAX_REGISTERED; i++) { + sixlowip_reg[i] = 0; + } + } -void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix, - uint8_t r_addr) +void sixlowpan_lowpan_adhoc_init(transceiver_type_t trans, + const ipv6_addr_t *prefix, + uint8_t r_addr) { /* init network prefix */ - ipv6_set_prefix(prefix, prefix); - plist_add(prefix, 64, OPT_PI_VLIFETIME_INFINITE, 0, 1, OPT_PI_FLAG_A); + ipv6_addr_t save_prefix; + ipv6_addr_init_prefix(&save_prefix, prefix, 64); + plist_add(&save_prefix, 64, NDP_OPT_PI_VLIFETIME_INFINITE, 0, 1, + ICMPV6_NDP_OPT_PI_FLAG_AUTONOM); ipv6_init_iface_as_router(); - sixlowpan_init(trans, r_addr, 0); + sixlowpan_lowpan_init(trans, r_addr, 0); } + +void sixlowpan_lowpan_bootstrapping(void) +{ + + icmpv6_send_router_sol(OPT_SLLAO); +} + diff --git a/sys/net/sixlowpan/lowpan.h b/sys/net/sixlowpan/lowpan.h new file mode 100644 index 0000000000..770913875a --- /dev/null +++ b/sys/net/sixlowpan/lowpan.h @@ -0,0 +1,53 @@ +/* + * 6LoWPAN constants, data structs, and prototypes + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sixlowpan + * @{ + * @file sixlowpan.h + * @brief 6lowpan header + * @author Stephan Zeisberg + * @author Martin Lenders + * @author Oliver Gesch + * @author Eric Engel + */ + +#ifndef _SIXLOWPAN_LOWPAN_H +#define _SIXLOWPAN_LOWPAN_H + +#include "mutex.h" +#include "vtimer.h" + +#include "sixlowpan/lowpan.h" + +typedef struct { + uint8_t num; + ipv6_addr_t prefix; + uint8_t length; + uint8_t comp; + uint16_t lifetime; +} lowpan_context_t; + +extern uint16_t local_address; +extern mutex_t lowpan_context_mutex; + +void lowpan_read(uint8_t *data, uint8_t length, + ieee_802154_long_t *s_laddr, + ieee_802154_long_t *d_laddr); +uint8_t lowpan_context_len(void); +lowpan_context_t *lowpan_context_update(uint8_t num, + const ipv6_addr_t *prefix, + uint8_t length, uint8_t comp, + uint16_t lifetime); +lowpan_context_t *lowpan_context_get(void); +lowpan_context_t *lowpan_context_num_lookup(uint8_t num); + +/** + * @} + */ +#endif /* _SIXLOWPAN_LOWPAN_H */ diff --git a/sys/net/sixlowpan/sixlowmac.c b/sys/net/sixlowpan/mac.c similarity index 81% rename from sys/net/sixlowpan/sixlowmac.c rename to sys/net/sixlowpan/mac.c index 40615dfda1..c72b8ec85e 100644 --- a/sys/net/sixlowpan/sixlowmac.c +++ b/sys/net/sixlowpan/mac.c @@ -9,8 +9,8 @@ * * @ingroup sixlowpan * @{ - * @file sixlowmac.c - * @brief 6lowpan link layer functions + * @file sixlowmac.c + * @brief 6lowpan link layer functions * @author Stephan Zeisberg * @author Martin Lenders * @author Eric Engel @@ -21,26 +21,31 @@ #include +#include #include -#include -#include "sixlowmac.h" -#include "sixlowip.h" -#include "sixlownd.h" -#include "sixlowpan.h" -#include -#include +#include "ltc4150.h" +#include "hwtimer.h" #include "thread.h" #include "msg.h" #include "radio/radio.h" #include "transceiver.h" #include "vtimer.h" -#include "ieee802154/ieee802154_frame.h" -#include "net_help/net_help.h" +#include "sixlowpan/mac.h" + +#include "ip.h" +#include "icmp.h" +#include "lowpan.h" +#include "sys/net/ieee802154/ieee802154_frame.h" +#include "sys/net/net_help/net_help.h" #define ENABLE_DEBUG (0) #include "debug.h" +#define RADIO_STACK_SIZE (MINIMUM_STACK_SIZE + 256) +#define RADIO_RCV_BUF_SIZE (64) +#define RADIO_SENDING_DELAY (1000) + char radio_stack_buffer[RADIO_STACK_SIZE]; msg_t msg_q[RADIO_RCV_BUF_SIZE]; @@ -52,9 +57,8 @@ static radio_packet_t p; static msg_t mesg; int transceiver_type; static transceiver_command_t tcmd; -uint16_t fragmentcounter = 0; -uint8_t get_radio_address(void) +uint8_t sixlowpan_mac_get_radio_address(void) { int16_t address; @@ -67,7 +71,7 @@ uint8_t get_radio_address(void) return (uint8_t)address; } -void set_radio_address(uint8_t addr) +void sixlowpan_mac_set_radio_address(uint8_t addr) { int16_t address = (int16_t)addr; @@ -97,18 +101,18 @@ void switch_to_rx(void) msg_send(&mesg, transceiver_pid, 1); } -void init_802154_short_addr(ieee_802154_short_t *saddr) +void sixlowpan_mac_init_802154_short_addr(ieee_802154_short_t *saddr) { saddr->uint8[0] = 0; - saddr->uint8[1] = get_radio_address(); + saddr->uint8[1] = sixlowpan_mac_get_radio_address(); } -ieee_802154_long_t *mac_get_eui(ipv6_addr_t *ipaddr) +ieee_802154_long_t *sixlowpan_mac_get_eui64(const ipv6_addr_t *ipaddr) { - return ((ieee_802154_long_t *) & (ipaddr->uint8[8])); + return ((ieee_802154_long_t *) &(ipaddr->uint8[8])); } -void init_802154_long_addr(ieee_802154_long_t *laddr) +void sixlowpan_mac_init_802154_long_addr(ieee_802154_long_t *laddr) { // 16bit Pan-ID:16-zero-bits:16-bit-short-addr = 48bit laddr->uint16[0] = IEEE_802154_PAN_ID; @@ -120,7 +124,7 @@ void init_802154_long_addr(ieee_802154_long_t *laddr) laddr->uint8[4] = 0xFE; laddr->uint8[5] = 0; laddr->uint8[6] = 0; - laddr->uint8[7] = get_radio_address(); + laddr->uint8[7] = sixlowpan_mac_get_radio_address(); } void recv_ieee802154_frame(void) @@ -142,7 +146,6 @@ void recv_ieee802154_frame(void) length = p->length - hdrlen; /* deliver packet to network(6lowpan)-layer */ - fragmentcounter++; lowpan_read(frame.payload, length, (ieee_802154_long_t *)&frame.src_addr, (ieee_802154_long_t *)&frame.dest_addr); @@ -180,8 +183,9 @@ void set_ieee802154_frame_values(ieee802154_frame_t *frame) macdsn++; } -void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload, - uint8_t length, uint8_t mcast) +void sixlowpan_mac_send_ieee802154_frame(const ieee_802154_long_t *addr, + const uint8_t *payload, + uint8_t length, uint8_t mcast) { uint16_t daddr; /* TODO: check if dedicated response struct is necessary */ @@ -204,7 +208,7 @@ void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload, memcpy(&(frame.src_addr[0]), &(iface.laddr.uint8[0]), 8); daddr = HTONS(addr->uint16[3]); - frame.payload = payload; + frame.payload = (uint8_t *)payload; // payload won't be changed so cast is legal. frame.payload_len = length; uint8_t hdrlen = get_802154_hdr_len(&frame); @@ -213,9 +217,6 @@ void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload, memcpy(&buf[hdrlen], frame.payload, frame.payload_len); DEBUG("IEEE802.15.4 frame - FCF: %02X %02X DPID: %02X SPID: %02X DSN: %02X\n", buf[0], buf[1], frame->dest_pan_id, frame->src_pan_id, frame->seq_nr); - /* mutex unlock */ - mutex_unlock(&buf_mutex); - p.length = hdrlen + frame.payload_len; if (mcast == 0) { @@ -231,7 +232,7 @@ void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload, hwtimer_wait(5000); } -void sixlowmac_init(transceiver_type_t type) +void sixlowpan_mac_init(transceiver_type_t type) { int recv_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE, PRIORITY_MAIN - 2, CREATE_STACKTEST, recv_ieee802154_frame , "radio"); diff --git a/sys/net/sixlowpan/semaphore.c b/sys/net/sixlowpan/semaphore.c index 67ac13ca1d..6e2e837d53 100644 --- a/sys/net/sixlowpan/semaphore.c +++ b/sys/net/sixlowpan/semaphore.c @@ -1,5 +1,5 @@ /** - * Semaphore implemenation + * Semaphore implemenation * * Copyright (C) 2013 INRIA. * @@ -16,8 +16,6 @@ * @} */ -#include - #include "semaphore.h" void sem_init(sem_t *sem, int8_t value) diff --git a/sys/net/sixlowpan/semaphore.h b/sys/net/sixlowpan/semaphore.h index b30b0e4d03..3acb650b47 100644 --- a/sys/net/sixlowpan/semaphore.h +++ b/sys/net/sixlowpan/semaphore.h @@ -16,11 +16,12 @@ * @} */ -#ifndef SEMAPHORE_H -#define SEMAPHORE_H +#ifndef _SIXLOWPAN_SEMAPHORE_H +#define _SIXLOWPAN_SEMAPHORE_H #include -#include + +#include "mutex.h" typedef struct sem_t { int8_t value; @@ -32,4 +33,4 @@ void sem_init(sem_t *sem, int8_t value); int sem_wait(sem_t *sem); int sem_signal(sem_t *sem); -#endif /* SEMAPHORE_H*/ +#endif /* _SIXLOWPAN_SEMAPHORE_H*/ diff --git a/sys/net/sixlowpan/serialnumber.c b/sys/net/sixlowpan/serialnumber.c index b1fad78016..f774b76627 100644 --- a/sys/net/sixlowpan/serialnumber.c +++ b/sys/net/sixlowpan/serialnumber.c @@ -1,5 +1,5 @@ /** - * serial number arithmetics (corresponding RFC1982) for version field in ABRO + * serial number arithmetics (corresponding RFC1982) for version field in ABRO * * Copyright (C) 2013 INRIA. * @@ -10,7 +10,7 @@ * @ingroup sixlowpan * @{ * @file serialnumber.c - * @brief serial number arithmetics (corresponding RFC1982) for version field in ABRO + * @brief serial number arithmetics (corresponding RFC1982) for version field in ABRO * @author Martin Lenders * @author Oliver Hahm * @} diff --git a/sys/net/sixlowpan/serialnumber.h b/sys/net/sixlowpan/serialnumber.h index 66cc40502f..d9bbc8ca0f 100644 --- a/sys/net/sixlowpan/serialnumber.h +++ b/sys/net/sixlowpan/serialnumber.h @@ -2,8 +2,8 @@ * Header file for serial number arithmetics [RFC1982] */ -#ifndef SERIALNUMBER_H -#define SERIALNUMBER_H +#ifndef _SIXLOWPAN_SERIALNUMBER_H +#define _SIXLOWPAN_SERIALNUMBER_H #include typedef enum serial_comp_res_t { @@ -79,4 +79,4 @@ serial_comp_res_t serial_comp16(uint16_t s1, uint16_t s2); **/ serial_comp_res_t serial_comp32(uint32_t s1, uint32_t s2); -#endif /* SERIALNUMBER_H*/ +#endif /* _SIXLOWPAN_SERIALNUMBER_H*/ diff --git a/sys/net/sixlowpan/sixlowerror.h b/sys/net/sixlowpan/sixlowerror.h deleted file mode 100644 index 90c2c4a5da..0000000000 --- a/sys/net/sixlowpan/sixlowerror.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef SIXLOWERROR_H -#define SIXLOWERROR_H - -#define SUCCESS 0 -#define SIXLOWERROR_ARRAYFULL 132 // array is full -#define SIXLOWERROR_NULLPTR 133 // null pointer error -#define SIXLOWERROR_VALUE 134 // illegal value -#define SIXLOWERROR_ADDRESS 135 // illegal address -#define SIXLOWERROR_DISPATCH 136 // lowpan dispatch unknown -#define SIXLOWERROR_FSTFRAG 137 // first lowpan fragment not received -#define SIXLOWERROR_INVFRAG 138 // invalid fragment received -#define SIXLOWERROR_SCI 139 // source context not found -#define SIXLOWERROR_DCI 140 // destination context not found -#define SIXLOWERROR_CSUM 141 // wrong checksum - -#endif /* SIXLOWERROR_H*/ diff --git a/sys/net/sixlowpan/sixlowip.c b/sys/net/sixlowpan/sixlowip.c deleted file mode 100644 index 0eb67e744c..0000000000 --- a/sys/net/sixlowpan/sixlowip.c +++ /dev/null @@ -1,586 +0,0 @@ -/** - * IPv6 implementation - * - * Copyright (C) 2013 INRIA. - * - * This file subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more - * details. - * - * @ingroup sixlowpan - * @{ - * @file sixlowip.c - * @brief 6lowpan IP layer functions - * @author Stephan Zeisberg - * @author Martin Lenders - * @author Eric Engel - * @author Oliver Gesch - * @} - */ - -#include -#include -#include -#include -#include "msg.h" -#include "sixlowip.h" -#include "sixlowmac.h" -#include "sixlownd.h" -#include "sixlowpan.h" -#include "sys/net/destiny/in.h" -#include "sys/net/destiny/socket.h" -#include "sys/net/net_help/net_help.h" -#include "sys/net/net_help/msg_help.h" - -uint8_t ip_send_buffer[BUFFER_SIZE]; -uint8_t buffer[BUFFER_SIZE]; -msg_t msg_queue[IP_PKT_RECV_BUF_SIZE]; -ipv6_hdr_t *ipv6_buf; -struct icmpv6_hdr_t *icmp_buf; -uint8_t *nextheader; -uint8_t iface_addr_list_count = 0; -int udp_packet_handler_pid = 0; -int tcp_packet_handler_pid = 0; -int rpl_process_pid = 0; - -ipv6_hdr_t *get_ipv6_buf_send(void) -{ - return ((ipv6_hdr_t *) & (ip_send_buffer[LL_HDR_LEN])); -} - -uint8_t *get_payload_buf_send(uint8_t ext_len) -{ - return &(ip_send_buffer[LLHDR_IPV6HDR_LEN + ext_len]); -} - -ipv6_hdr_t *get_ipv6_buf(void) -{ - return ((ipv6_hdr_t *)&(buffer[LL_HDR_LEN])); -} - -struct icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len) -{ - return ((struct icmpv6_hdr_t *) & (buffer[LLHDR_IPV6HDR_LEN + ext_len])); -} - -uint8_t *get_payload_buf(uint8_t ext_len) -{ - return &(buffer[LLHDR_IPV6HDR_LEN + ext_len]); -} - -void sixlowpan_bootstrapping(void) -{ - - init_rtr_sol(OPT_SLLAO); -} - -void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len, - uint8_t next_header) -{ - uint8_t *p_ptr; - - if (next_header == IPPROTO_TCP) { - p_ptr = get_payload_buf_send(ipv6_ext_hdr_len); - ipv6_buf = get_ipv6_buf_send(); - } - else { - ipv6_buf = get_ipv6_buf(); - p_ptr = get_payload_buf(ipv6_ext_hdr_len); - } - - icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); - packet_length = 0; - - ipv6_buf->version_trafficclass = IPV6_VER; - ipv6_buf->trafficclass_flowlabel = 0; - ipv6_buf->flowlabel = 0; - ipv6_buf->nextheader = next_header; - ipv6_buf->hoplimit = MULTIHOP_HOPLIMIT; - ipv6_buf->length = p_len; - - memcpy(&(ipv6_buf->destaddr), addr, 16); - ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); - - memcpy(p_ptr, payload, p_len); - - packet_length = IPV6_HDR_LEN + p_len; - - lowpan_init((ieee_802154_long_t *)&(ipv6_buf->destaddr.uint16[4]), - (uint8_t *)ipv6_buf); -} - -int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr) -{ - switch(hdr->type) { - case (ICMP_RTR_SOL): { - puts("INFO: packet type: icmp router solicitation"); - /* processing router solicitation */ - recv_rtr_sol(); - /* init solicited router advertisment*/ - break; - } - - case (ICMP_RTR_ADV): { - puts("INFO: packet type: icmp router advertisment"); - /* processing router advertisment */ - recv_rtr_adv(); - /* init neighbor solicitation */ - break; - } - - case (ICMP_NBR_SOL): { - puts("INFO: packet type: icmp neighbor solicitation"); - recv_nbr_sol(); - break; - } - - case (ICMP_NBR_ADV): { - puts("INFO: packet type: icmp neighbor advertisment"); - recv_nbr_adv(); - break; - } - - case (ICMP_RPL_CONTROL): { - puts("INFO: packet type: RPL message"); - - if (rpl_process_pid != 0) { - msg_t m_send; - m_send.content.ptr = (char *) &hdr->code; - msg_send(&m_send, rpl_process_pid, 1); - } - else { - puts("INFO: no RPL handler registered"); - } - - break; - } - - default: - return -1; - } - - return 0; -} - -void ipv6_process(void) -{ - msg_t m_recv_lowpan, m_send_lowpan; - msg_t m_recv, m_send; - ipv6_addr_t myaddr; - ipv6_init_address(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00, - get_radio_address()); - - while (1) { - msg_receive(&m_recv_lowpan); - - ipv6_buf = (ipv6_hdr_t *)m_recv_lowpan.content.ptr; - - /* identifiy packet */ - nextheader = &ipv6_buf->nextheader; - - if ((ipv6_get_addr_match(&myaddr, &ipv6_buf->destaddr) >= 112) && - (ipv6_buf->destaddr.uint8[15] != myaddr.uint8[15])) { - memcpy(get_ipv6_buf_send(), get_ipv6_buf(), - IPV6_HDR_LEN + ipv6_buf->length); - lowpan_init((ieee_802154_long_t *)&(ipv6_buf->destaddr.uint16[4]), - (uint8_t *)get_ipv6_buf_send()); - } - else { - switch(*nextheader) { - case (PROTO_NUM_ICMPV6): { - /* checksum test*/ - if (icmpv6_csum(PROTO_NUM_ICMPV6) != 0xffff) { - printf("ERROR: wrong checksum\n"); - } - - icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); - icmpv6_demultiplex(icmp_buf); - break; - } - - case (IPPROTO_TCP): { - if (tcp_packet_handler_pid != 0) { - m_send.content.ptr = (char *) ipv6_buf; - msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid); - } - else { - printf("INFO: No TCP handler registered.\n"); - } - - break; - } - - case (IPPROTO_UDP): { - if (udp_packet_handler_pid != 0) { - m_send.content.ptr = (char *) ipv6_buf; - msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid); - } - else { - printf("INFO: No UDP handler registered.\n"); - } - - break; - } - - case (PROTO_NUM_NONE): { - printf("INFO: Packet with no Header following the IPv6 Header received.\n"); - break; - } - - default: - break; - } - } - - msg_reply(&m_recv_lowpan, &m_send_lowpan); - } -} - -void ipv6_iface_add_addr(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime, - uint32_t pref_ltime, uint8_t type) -{ - if (ipv6_addr_unspec_match(addr) == 128) { - printf("ERROR: unspecified address (::) can't be assigned to interface.\n"); - return; - } - - if (ipv6_iface_addr_match(addr) != 0) { - return; - } - - if (iface_addr_list_count < IFACE_ADDR_LIST_LEN) { - memcpy(&(iface.addr_list[iface_addr_list_count].addr.uint8[0]), - &(addr->uint8[0]), 16); - iface.addr_list[iface_addr_list_count].state = state; - timex_t valtime = {val_ltime, 0}; - timex_t preftime = {pref_ltime, 0}; - timex_t now; - vtimer_now(&now); - iface.addr_list[iface_addr_list_count].val_ltime = timex_add(now, valtime); - iface.addr_list[iface_addr_list_count].pref_ltime = timex_add(now, preftime); - iface.addr_list[iface_addr_list_count].type = type; - iface_addr_list_count++; - - /* Register to Solicited-Node multicast address according to RFC 4291 */ - if (type == ADDR_TYPE_ANYCAST || type == ADDR_TYPE_LINK_LOCAL || - type == ADDR_TYPE_GLOBAL || type == ADDR_TYPE_UNICAST) { - ipv6_addr_t sol_node_mcast_addr; - ipv6_set_sol_node_mcast_addr(addr, &sol_node_mcast_addr); - - if (ipv6_iface_addr_match(&sol_node_mcast_addr) == NULL) { - ipv6_iface_add_addr(&sol_node_mcast_addr, state, val_ltime, pref_ltime, ADDR_TYPE_SOL_NODE_MCAST); - } - } - } -} - -addr_list_t *ipv6_iface_addr_match(ipv6_addr_t *addr) -{ - int i; - - for (i = 0; i < iface_addr_list_count; i++) { - if (memcmp(&(iface.addr_list[i].addr.uint8[0]), - &(addr->uint8[0]), 16) == 0) { - return &(iface.addr_list[i]); - } - } - - return NULL; -} - -addr_list_t *ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr) -{ - int i; - - for (i = 0; i < iface_addr_list_count; i++) { - if (memcmp(&(iface.addr_list[i].addr.uint8[0]), - &(addr->uint8[0]), 8) == 0) { - return &(iface.addr_list[i]); - } - } - - return NULL; -} - -void ipv6_iface_print_addrs(void) -{ - for (int i = 0; i < iface_addr_list_count; i++) { - ipv6_print_addr(&(iface.addr_list[i].addr)); - } -} - -void ipv6_init_addr_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix) -{ - inout->uint16[0] = prefix->uint16[0]; - inout->uint16[1] = prefix->uint16[1]; - inout->uint16[2] = prefix->uint16[2]; - inout->uint16[3] = prefix->uint16[3]; - - memcpy(&(inout->uint8[8]), &(iface.laddr.uint8[0]), 8); -} - -void ipv6_set_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix) -{ - inout->uint16[0] = prefix->uint16[0]; - inout->uint16[1] = prefix->uint16[1]; - inout->uint16[2] = prefix->uint16[2]; - inout->uint16[3] = prefix->uint16[3]; - inout->uint16[4] = 0; - inout->uint16[5] = 0; - inout->uint16[6] = 0; - inout->uint16[7] = 0; -} - -void ipv6_set_all_rtrs_mcast_addr(ipv6_addr_t *ipaddr) -{ - ipaddr->uint16[0] = HTONS(0xff02); - ipaddr->uint16[1] = 0; - ipaddr->uint16[2] = 0; - ipaddr->uint16[3] = 0; - ipaddr->uint16[4] = 0; - ipaddr->uint16[5] = 0; - ipaddr->uint16[6] = 0; - ipaddr->uint16[7] = HTONS(0x0002); -} - -void ipv6_set_all_nds_mcast_addr(ipv6_addr_t *ipaddr) -{ - ipaddr->uint16[0] = HTONS(0xff02); - ipaddr->uint16[1] = 0; - ipaddr->uint16[2] = 0; - ipaddr->uint16[3] = 0; - ipaddr->uint16[4] = 0; - ipaddr->uint16[5] = 0; - ipaddr->uint16[6] = 0; - ipaddr->uint16[7] = HTONS(0x0001); -} - -void ipv6_set_loaddr(ipv6_addr_t *ipaddr) -{ - ipaddr->uint16[0] = 0; - ipaddr->uint16[1] = 0; - ipaddr->uint16[2] = 0; - ipaddr->uint16[3] = 0; - ipaddr->uint16[4] = 0; - ipaddr->uint16[5] = 0; - ipaddr->uint16[6] = 0; - ipaddr->uint16[7] = HTONS(0x0001); -} - -void ipv6_get_saddr(ipv6_addr_t *src, ipv6_addr_t *dst) -{ - /* try to find best match if dest is not mcast or link local */ - int8_t itmp = -1; - uint8_t tmp = 0; - uint8_t bmatch = 0; - - if (!(ipv6_prefix_ll_match(dst)) && !(ipv6_prefix_mcast_match(dst))) { - for (int i = 0; i < IFACE_ADDR_LIST_LEN; i++) { - if (iface.addr_list[i].state == ADDR_STATE_PREFERRED) { - if (!(ipv6_prefix_ll_match(&(iface.addr_list[i].addr)))) { - tmp = ipv6_get_addr_match(dst, &(iface.addr_list[i].addr)); - - if (tmp >= bmatch) { - bmatch = tmp; - itmp = i; - } - } - } - } - } - else { - for (int j = 0; j < IFACE_ADDR_LIST_LEN; j++) { - if ((iface.addr_list[j].state == ADDR_STATE_PREFERRED) && - ipv6_prefix_ll_match(&(iface.addr_list[j].addr))) { - itmp = j; - } - } - } - - if (itmp == -1) { - memset(src, 0, 16); - } - else { - memcpy(src, &(iface.addr_list[itmp].addr), 16); - } -} - -uint8_t ipv6_get_addr_match(ipv6_addr_t *src, ipv6_addr_t *dst) -{ - uint8_t val = 0, xor; - - for (int i = 0; i < 16; i++) { - /* if bytes are equal add 8 */ - if (src->uint8[i] == dst->uint8[i]) { - val += 8; - } - else { - xor = src->uint8[i] ^ dst->uint8[i]; - - /* while bits from byte equal add 1 */ - for (int j = 0; j < 8; j++) { - if ((xor & 0x80) == 0) { - val++; - xor = xor << 1; - } - else { - break; - } - } - } - } - - return val; -} - -void ipv6_set_ll_prefix(ipv6_addr_t *ipaddr) -{ - ipaddr->uint16[0] = HTONS(0xfe80); - ipaddr->uint16[1] = 0; - ipaddr->uint16[2] = 0; - ipaddr->uint16[3] = 0; -} - -void ipv6_init_address(ipv6_addr_t *addr, uint16_t addr0, uint16_t addr1, - uint16_t addr2, uint16_t addr3, uint16_t addr4, - uint16_t addr5, uint16_t addr6, uint16_t addr7) -{ - addr->uint16[0] = HTONS(addr0); - addr->uint16[1] = HTONS(addr1); - addr->uint16[2] = HTONS(addr2); - addr->uint16[3] = HTONS(addr3); - addr->uint16[4] = HTONS(addr4); - addr->uint16[5] = HTONS(addr5); - addr->uint16[6] = HTONS(addr6); - addr->uint16[7] = HTONS(addr7); -} - -uint8_t ipv6_prefix_ll_match(ipv6_addr_t *addr) -{ - if (addr->uint8[0] == 0xfe && addr->uint8[1] == 0x80) { - return 1; - } - - return 0; -} - -uint8_t ipv6_prefix_mcast_match(ipv6_addr_t *addr) -{ - if (addr->uint8[0] == 0xff && addr->uint8[1] == 0x02) { - return 1; - } - - return 0; -} - -uint8_t ipv6_addr_unspec_match(ipv6_addr_t *addr) -{ - if ((addr->uint16[0] == 0) && (addr->uint16[1] == 0) && - (addr->uint16[2] == 0) && (addr->uint16[3] == 0) && - (addr->uint16[4] == 0) && (addr->uint16[5] == 0) && - (addr->uint16[6] == 0) && (addr->uint16[7] == 0)) { - return 1; - } - - return 0; -} - -uint8_t ipv6_addr_sol_node_mcast_match(ipv6_addr_t *addr) -{ - /* note: cool if-condition*/ - if ((addr->uint8[0] == 0xFF) && (addr->uint8[1] == 0x02) && - (addr->uint16[1] == 0x00) && (addr->uint16[2] == 0x00) && - (addr->uint16[3] == 0x00) && (addr->uint16[4] == 0x00) && - (addr->uint8[10] == 0x00) && (addr->uint8[11] == 0x01) && - (addr->uint8[12] == 0xFF)) { - return 1; - } - - return 0; -} - -void ipv6_set_sol_node_mcast_addr(ipv6_addr_t *addr_in, ipv6_addr_t *addr_out) -{ - /* copy only the last 24-bit of the ip-address that is beeing resolved */ - addr_out->uint16[0] = HTONS(0xff02); - addr_out->uint16[1] = 0; - addr_out->uint16[2] = 0; - addr_out->uint16[3] = 0; - addr_out->uint16[4] = 0; - addr_out->uint16[5] = HTONS(0x0001); - addr_out->uint8[12] = 0xff; - addr_out->uint8[13] = addr_in->uint8[13]; - addr_out->uint16[7] = addr_in->uint16[7]; -} - -void ipv6_print_addr(ipv6_addr_t *ipaddr) -{ - printf("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", - ((uint8_t *)ipaddr)[0], ((uint8_t *)ipaddr)[1], ((uint8_t *)ipaddr)[2], - ((uint8_t *)ipaddr)[3], ((uint8_t *)ipaddr)[4], ((uint8_t *)ipaddr)[5], - ((uint8_t *)ipaddr)[6], ((uint8_t *)ipaddr)[7], ((uint8_t *)ipaddr)[8], - ((uint8_t *)ipaddr)[9], ((uint8_t *)ipaddr)[10], ((uint8_t *)ipaddr)[11], - ((uint8_t *)ipaddr)[12], ((uint8_t *)ipaddr)[13], ((uint8_t *)ipaddr)[14], - ((uint8_t *)ipaddr)[15]); -} - -uint8_t ipv6_next_hdr_unknown(uint8_t next_hdr) -{ - return next_hdr == PROTO_NUM_ICMPV6 || - next_hdr == PROTO_NUM_NONE; -} - - -uint32_t get_remaining_time(timex_t *t) -{ - timex_t now; - vtimer_now(&now); - - return (timex_sub(*t, now).seconds); -} - -void set_remaining_time(timex_t *t, uint32_t time) -{ - timex_t tmp = {time, 0}; - - timex_t now; - vtimer_now(&now); - *t = timex_add(now, tmp); -} - -void ipv6_init_iface_as_router(void) -{ - ipv6_addr_t addr; - - ipv6_set_all_rtrs_mcast_addr(&addr); - ipv6_iface_add_addr(&addr, ADDR_STATE_PREFERRED, 0, 0, ADDR_TYPE_MULTICAST); -} - - -uint8_t ipv6_is_router(void) -{ - ipv6_addr_t addr; - - ipv6_set_all_rtrs_mcast_addr(&addr); - - if (ipv6_iface_addr_match(&addr) != NULL) { - return 1; - } - - return 0; -} - -void set_tcp_packet_handler_pid(int pid) -{ - tcp_packet_handler_pid = pid; -} - -void set_udp_packet_handler_pid(int pid) -{ - udp_packet_handler_pid = pid; -} - -void set_rpl_process_pid(int pid) -{ - rpl_process_pid = pid; -} diff --git a/sys/net/sixlowpan/sixlowip.h b/sys/net/sixlowpan/sixlowip.h deleted file mode 100644 index 88746a6cbc..0000000000 --- a/sys/net/sixlowpan/sixlowip.h +++ /dev/null @@ -1,188 +0,0 @@ -/** - * IPv6 constants, data structs, and prototypes - * - * Copyright (C) 2013 INRIA. - * - * This file subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more - * details. - * - * @ingroup sixlowpan - * @{ - * @file sixlowip.h - * @brief 6lowpan IP layer header - * @author Stephan Zeisberg - * @author Martin Lenders - * @author Eric Engel - * @author Oliver Gesch - * @} - */ - -/* 6LoWPAN IP header file */ - -#ifndef SIXLOWIP_H -#define SIXLOWIP_H - -#include -#include -#include - -/* set maximum transmission unit */ -#define MTU 256 -/* IPv6 field values */ -#define IPV6_VER 0x60 -#define PROTO_NUM_ICMPV6 58 -#define PROTO_NUM_NONE 59 -#define ND_HOPLIMIT 0xFF -#define SIXLOWPAN_IPV6_LL_ADDR_LEN 8 -/* size of global buffer */ -#define BUFFER_SIZE (LL_HDR_LEN + MTU) - -#define MULTIHOP_HOPLIMIT 64 - -#define IP_PKT_RECV_BUF_SIZE 64 -#define DEBUGLINE printf("%s:%d\n",__FILE__,__LINE__) - -/* extern variables */ -extern uint8_t ipv6_ext_hdr_len; -extern uint8_t opt_hdr_len; -extern uint16_t packet_length; -extern uint8_t packet_dispatch; -extern uint8_t iface_addr_list_count; -extern mutex_t buf_mutex; - -extern double start; - -/* base header lengths */ -#define LL_HDR_LEN 0x4 -#define ICMPV6_HDR_LEN 0x4 -#define IPV6_HDR_LEN 0x28 -#define LLHDR_IPV6HDR_LEN (LL_HDR_LEN + IPV6_HDR_LEN) -#define LLHDR_ICMPV6HDR_LEN (LL_HDR_LEN + IPV6_HDR_LEN + ICMPV6_HDR_LEN) -#define IPV6HDR_ICMPV6HDR_LEN (IPV6_HDR_LEN + ipv6_ext_hdr_len + ICMPV6_HDR_LEN) - -#define IFACE_ADDR_LIST_LEN 10 // maybe to much -/* rfc 4862 section 2. address states */ -#define ADDR_STATE_TENTATIVE 0 -#define ADDR_STATE_PREFERRED 1 -#define ADDR_STATE_DEPRECATED 2 -/* addresses with this state are always permitted */ -#define ADDR_STATE_ANY 4 -/* how the address is configured */ -#define ADDR_CONFIGURED_AUTO 1 -#define ADDR_CONFIGURED_MANUAL 2 -/* address types */ -#define ADDR_TYPE_NONE 0 -#define ADDR_TYPE_UNICAST 1 -#define ADDR_TYPE_MULTICAST 2 -#define ADDR_TYPE_ANYCAST 3 -#define ADDR_TYPE_SOL_NODE_MCAST 4 -#define ADDR_TYPE_LOOPBACK 5 -#define ADDR_TYPE_LINK_LOCAL 6 -#define ADDR_TYPE_GLOBAL 7 -/* dispatch types */ -#define DISPATCH_TYPE_IPV6 0x41 -#define DISPATCH_TYPE_LOWPAN_HC1 0x42 -/* compression types */ -#define COMPRESSION_TYPE_NONE - -/* buffer */ -extern uint8_t buffer[BUFFER_SIZE]; - - -/* ipv6 extension header length */ - -typedef union __attribute__((packed)) { - uint8_t uint8[16]; - uint16_t uint16[8]; - uint32_t uint32[4]; -} ipv6_addr_t; - -struct __attribute__((packed)) icmpv6_hdr_t { - uint8_t type; - uint8_t code; - uint16_t checksum; -}; - -typedef struct __attribute__((packed)) { - uint8_t version_trafficclass; - uint8_t trafficclass_flowlabel; - uint16_t flowlabel; - uint16_t length; - uint8_t nextheader; - uint8_t hoplimit; - ipv6_addr_t srcaddr; - ipv6_addr_t destaddr; -} ipv6_hdr_t; - -/* link layer addressing */ -typedef union __attribute__((packed)) { - uint8_t uint8[8]; - uint16_t uint16[4]; -} ieee_802154_long_t; - -typedef union __attribute__((packed)) { - uint8_t uint8[2]; - uint16_t uint16[1]; -} ieee_802154_short_t; - -typedef struct __attribute__((packed)) { - uint8_t state; - timex_t val_ltime; - timex_t pref_ltime; - uint8_t type; - ipv6_addr_t addr; -} addr_list_t; - -typedef struct __attribute__((packed)) { - ieee_802154_short_t saddr; - ieee_802154_long_t laddr; - addr_list_t addr_list[IFACE_ADDR_LIST_LEN]; - uint8_t adv_cur_hop_limit; - uint32_t adv_reachable_time; - uint32_t adv_retrans_timer; -} iface_t; - -extern iface_t iface; - -/* function prototypes */ -struct icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len); -ipv6_hdr_t *get_ipv6_buf(void); -uint8_t *get_payload_buf(uint8_t ext_len); -uint8_t *get_payload_buf_send(uint8_t ext_len); - -int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr); -void ipv6_init_iface_as_router(void); -uint8_t ipv6_is_router(void); -void ipv6_set_ll_prefix(ipv6_addr_t *ipaddr); -void ipv6_set_all_rtrs_mcast_addr(ipv6_addr_t *ipaddr); -void ipv6_set_all_nds_mcast_addr(ipv6_addr_t *ipaddr); -void ipv6_set_loaddr(ipv6_addr_t *ipaddr); -void ipv6_set_sol_node_mcast_addr(ipv6_addr_t *addr_in, ipv6_addr_t *addr_out); -void sixlowpan_bootstrapping(void); -void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len, uint8_t next_header); -void ipv6_print_addr(ipv6_addr_t *ipaddr); -void ipv6_process(void); -void ipv6_get_saddr(ipv6_addr_t *src, ipv6_addr_t *dst); -uint8_t ipv6_get_addr_match(ipv6_addr_t *src, ipv6_addr_t *dst); -uint8_t ipv6_prefix_mcast_match(ipv6_addr_t *addr); -uint8_t ipv6_prefix_ll_match(ipv6_addr_t *addr); -void ipv6_iface_add_addr(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime, - uint32_t pref_ltime, uint8_t type); -addr_list_t *ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr); -addr_list_t *ipv6_iface_addr_match(ipv6_addr_t *addr); -void ipv6_iface_print_addrs(void); -void ipv6_init_addr_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix); -void ipv6_init_address(ipv6_addr_t *addr, uint16_t addr0, uint16_t addr1, - uint16_t addr2, uint16_t addr3, uint16_t addr4, - uint16_t addr5, uint16_t addr6, uint16_t addr7); -uint32_t get_remaining_time(timex_t *t); -void set_remaining_time(timex_t *t, uint32_t time); -void ipv6_set_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix); -uint8_t ipv6_addr_unspec_match(ipv6_addr_t *addr); -uint8_t ipv6_addr_sol_node_mcast_match(ipv6_addr_t *addr); -uint8_t ipv6_next_hdr_unrec(uint8_t next_hdr); -void set_tcp_packet_handler_pid(int pid); -void set_udp_packet_handler_pid(int pid); -void set_rpl_process_pid(int pid); -#endif /* SIXLOWIP_H*/ diff --git a/sys/net/sixlowpan/sixlowmac.h b/sys/net/sixlowpan/sixlowmac.h deleted file mode 100644 index 553b1bab03..0000000000 --- a/sys/net/sixlowpan/sixlowmac.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 6LoWPAN MAC - layer 2 prototypes - * - * Copyright (C) 2013 INRIA. - * - * This file subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more - * details. - * - * @ingroup sixlowpan - * @{ - * @file sixlowmac.h - * @brief 6lowpan link layer functions - * @author Stephan Zeisberg - * @author Martin Lenders - * @author Eric Engel - * @author Oliver Gesch - * @} - */ - -#ifndef SIXLOWMAC_H -#define SIXLOWMAC_H - -#include -#include -#include "sixlowip.h" -#include "radio/radio.h" -#include - -#define RADIO_STACK_SIZE (MINIMUM_STACK_SIZE + 256) -#define RADIO_RCV_BUF_SIZE (64) -#define RADIO_SENDING_DELAY (1000) - -extern uint16_t fragmentcounter; - -uint8_t get_radio_address(void); -void set_radio_address(uint8_t addr); -void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload, - uint8_t length, uint8_t mcast); -void init_802154_long_addr(ieee_802154_long_t *laddr); -void init_802154_short_addr(ieee_802154_short_t *saddr); -void sixlowmac_init(transceiver_type_t type); -ieee_802154_long_t *mac_get_eui(ipv6_addr_t *ipaddr); - -#endif /* SIXLOWMAC_H*/ diff --git a/sys/net/sixlowpan/sixlownd.h b/sys/net/sixlowpan/sixlownd.h deleted file mode 100644 index a4fb9941b2..0000000000 --- a/sys/net/sixlowpan/sixlownd.h +++ /dev/null @@ -1,267 +0,0 @@ -/* - * 6lowpan neighbor discovery - * - * Copyright (C) 2013 INRIA. - * - * This file subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more - * details. - * - * @ingroup sixlowpan - * @{ - * @file sixlownd.h - * @brief 6lowpan neighbor discovery constants, data structs, and prototypes - * @author Stephan Zeisberg - * @author Martin Lenders - * @author Oliver Gesch - * @} - */ - -#ifndef SIXLOWND_H -#define SIXLOWND_H - -#include -#include "vtimer.h" -#include "sixlowpan.h" -#include "sixlowip.h" - -/* parameter problem [rfc4443] */ -#define PARA_PROB_LEN (8) -#define PARA_PROB_CODE_ERR (0) /* Erroneous header field encountered */ -#define PARA_PROB_NXT_HDR_UNREC (1) /* Unrecognized Next Header type encountered */ -#define PARA_PROB_IPV6_OPT_UNREC (2) /* Unrecognized IPv6 option encountered */ -/* router solicitation */ -#define RTR_SOL_LEN (4) -#define RTR_SOL_INTERVAL (4) -#define RTR_SOL_MAX (3) -/* router advertisment */ -#define RTR_ADV_M_FLAG (0) -#define RTR_ADV_O_FLAG (0) -#define RTR_ADV_MAX (3) -#define RTR_ADV_MAX_INTERVAL (600) -#define RTR_ADV_LEN (12) -/* neighbour solicitation */ -#define NBR_SOL_LEN (20) -/* neighbour advertisement */ -#define NBR_ADV_LEN (20) -#define NBR_ADV_FLAG_R (0x80) -#define NBR_ADV_FLAG_S (0x40) -#define NBR_ADV_FLAG_O (0x20) -/* stllao option rfc4861 4.6.1 */ -#define OPT_STLLAO_MIN_LEN (8) -#define OPT_STLLAO_MAX_LEN (16) -#define OPT_SLLAO_TYPE (1) -#define OPT_TLLAO_TYPE (2) -/* prefix info option rfc 4.6.2 */ -#define OPT_PI_LIST_LEN (5) //TODO: initalwert suchen -#define OPT_PI_TYPE (3) -#define OPT_PI_LEN (4) -#define OPT_PI_HDR_LEN (32) -#define OPT_PI_FLAG_A (0x40) -#define OPT_PI_FLAG_L (0x80) -#define OPT_PI_VLIFETIME_INFINITE (0xffffffff) -/* mtu option rfc4861 4.6.4 */ -#define OPT_MTU_TYPE (5) -#define OPT_MTU_LEN (1) -#define OPT_MTU_HDR_LEN (8) -/* aro - address registration option draft-ietf-6lowpan-nd-14 4.2 */ -#define OPT_ARO_TYPE (31) /* TBD1 */ -#define OPT_ARO_LEN (2) -#define OPT_ARO_HDR_LEN (16) -#define OPT_ARO_LTIME (300) /* geeigneten wert finden */ -#define OPT_ARO_STATE_SUCCESS (0) -#define OPT_ARO_STATE_DUP_ADDR (1) -#define OPT_ARO_STATE_NBR_CACHE_FULL (2) -/* 6lowpan context option */ -#define OPT_6CO_TYPE (32) -#define OPT_6CO_MIN_LEN (2) -#define OPT_6CO_MAX_LEN (3) -#define OPT_6CO_HDR_LEN (8) -#define OPT_6CO_LTIME (5) /* geeigneten Wert finden */ -#define OPT_6CO_FLAG_C (0x10) -#define OPT_6CO_FLAG_CID (0x0F) -#define OPT_6CO_FLAG_C_VALUE_SET (1) -#define OPT_6CO_FLAG_C_VALUE_UNSET (0) -/* authoritative border router option */ -#define OPT_ABRO_TYPE (33) -#define OPT_ABRO_LEN (3) -#define OPT_ABRO_HDR_LEN (24) -/* authoritive border router cache size */ -#define ABR_CACHE_SIZE (2) -/* neighbor cache size */ -#define NBR_CACHE_SIZE (8) -#define NBR_CACHE_TYPE_GC (1) -#define NBR_CACHE_TYPE_REG (2) -#define NBR_CACHE_TYPE_TEN (3) -#define NBR_CACHE_LTIME_TEN (20) -/* neighbor status values */ -#define NBR_STATUS_INCOMPLETE (0) -#define NBR_STATUS_REACHABLE (1) -#define NBR_STATUS_STALE (2) -#define NBR_STATUS_DELAY (3) -#define NBR_STATUS_PROBE (4) -/* default router list size */ -#define DEF_RTR_LST_SIZE (3) /* geeigneten wert finden */ - -extern unsigned int nd_nbr_cache_rem_pid; - -enum option_types_t { - OPT_SLLAO = 1, - OPT_TLLAO, - OPT_PI, - OPT_MTU, - OPT_ARO, - OPT_6CO, - OPT_ABRO, - OPT_DAR, - OPT_DAC, -}; - -typedef struct __attribute__((packed)) { - uint8_t type; - uint8_t length; -} opt_buf_t; - -typedef struct __attribute__((packed)) { - uint8_t type; - uint8_t length; -} opt_stllao_t; - -typedef struct __attribute__((packed)) { - uint8_t type; - uint8_t length; - uint16_t reserved; - uint32_t mtu; -} opt_mtu_t; - -typedef struct __attribute__((packed)) { - uint8_t type; - uint8_t length; - uint8_t prefix_length; - uint8_t l_a_reserved1; - uint32_t val_ltime; - uint32_t pref_ltime; - uint32_t reserved2; - ipv6_addr_t addr; -} opt_pi_t; - -typedef struct __attribute__((packed)) { - uint8_t type; - uint8_t length; - uint8_t status; - uint8_t reserved1; - uint16_t reserved2; - uint16_t reg_ltime; - ieee_802154_long_t eui64; -} opt_aro_t; - -typedef struct __attribute__((packed)) { - uint8_t type; - uint8_t length; - uint8_t c_length; - uint8_t c_flags; - uint16_t reserved; - uint16_t val_ltime; -} opt_6co_hdr_t; - -typedef struct __attribute__((packed)) { - uint8_t type; - uint8_t length; - uint16_t version; - uint32_t reserved; - ipv6_addr_t addr; -} opt_abro_t; - -typedef struct __attribute__((packed)) { - uint8_t inuse; - uint8_t adv; - ipv6_addr_t addr; - uint8_t length; - uint8_t l_a_reserved1; - uint32_t val_ltime; - uint32_t pref_ltime; - uint8_t infinite; -} plist_t; - -struct __attribute__((packed)) rtr_adv_t { - uint8_t hoplimit; - uint8_t autoconfig_flags; - uint16_t router_lifetime; - uint32_t reachable_time; - uint32_t retrans_timer; -}; - -struct __attribute__((packed)) nbr_sol_t { - uint32_t reserved; - ipv6_addr_t tgtaddr; -}; - -struct __attribute__((packed)) nbr_adv_t { - uint8_t rso; - uint8_t reserved[3]; - ipv6_addr_t tgtaddr; -}; - -struct __attribute__((packed)) para_prob_t { - uint8_t pointer; -}; - -/* authoritive border router cache - draft-draft-ietf-6lowpan-nd-17 */ -typedef struct __attribute__((packed)) abr_cache_t { - uint16_t version; - ipv6_addr_t abr_addr; - uint8_t cids[LOWPAN_CONTEXT_MAX]; -} abr_cache_t; - -/* neighbor cache - rfc4861 5.1. */ -typedef struct __attribute__((packed)) { - uint8_t type; - uint8_t state; - uint8_t isrouter; - ipv6_addr_t addr; - ieee_802154_long_t laddr; - ieee_802154_short_t saddr; - timex_t ltime; -} nbr_cache_t; - -/* default router list - rfc4861 5.1. */ -typedef struct __attribute__((packed)) { - ipv6_addr_t addr; - timex_t inval_time; -} def_rtr_lst_t; - -void init_rtr_sol(uint8_t sllao); -void recv_rtr_sol(void); -void recv_rtr_adv(void); -void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi, - uint8_t sixco, uint8_t abro); -uint8_t plist_search(ipv6_addr_t *addr); -uint8_t plist_cmp(ipv6_addr_t *addr1, ipv6_addr_t *addr2); -int8_t plist_add(ipv6_addr_t *addr, uint8_t size, uint32_t val_ltime, - uint32_t pref_ltime, uint8_t adv_opt, uint8_t l_a_reserved1); -void set_llao(opt_stllao_t *sllao, uint8_t type, uint8_t length); - -abr_cache_t *abr_get_version(uint16_t version, ipv6_addr_t *abr_addr); -abr_cache_t *abr_add_context(uint16_t version, ipv6_addr_t *abr_addr, - uint8_t cid); -void abr_remove_context(uint8_t cid); - -nbr_cache_t *nbr_cache_search(ipv6_addr_t *ipaddr); -uint8_t nbr_cache_add(ipv6_addr_t *ipaddr, ieee_802154_long_t *laddr, - uint8_t isrouter, uint8_t state, uint8_t type, - uint16_t ltime, ieee_802154_short_t *saddr); -void nbr_cache_auto_rem(void); -void nbr_cache_rem(ipv6_addr_t *addr); -uint16_t icmpv6_csum(uint8_t proto); -def_rtr_lst_t *def_rtr_lst_search(ipv6_addr_t *ipaddr); -void def_rtr_lst_add(ipv6_addr_t *ipaddr, uint32_t rtr_ltime); -void def_rtr_lst_rem(def_rtr_lst_t *entry); -void init_para_prob(ipv6_addr_t *src, ipv6_addr_t *dest, uint8_t code, - uint32_t pointer, uint8_t *packet, uint8_t packet_len); -void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ, - uint8_t slloa, uint8_t aro); -void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt, - uint8_t rso, uint8_t sllao, uint8_t aro, uint8_t aro_state); -void recv_nbr_adv(void); -void recv_nbr_sol(void); -#endif /* SIXLOWND_H*/ diff --git a/sys/net/sixlowpan/sixlowpan.h b/sys/net/sixlowpan/sixlowpan.h deleted file mode 100644 index 388dd77750..0000000000 --- a/sys/net/sixlowpan/sixlowpan.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 6lowpan constants, data structs, and prototypes - * - * Copyright (C) 2013 INRIA. - * - * This file subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more - * details. - * - * @ingroup sixlowpan - * @{ - * @file sixlowpan.h - * @brief 6lowpan header - * @author Stephan Zeisberg - * @author Martin Lenders - * @author Oliver Gesch - * @author Eric Engel - * @} - */ - -#ifndef SIXLOWPAN_H -#define SIXLOWPAN_H - -#define IP_PROCESS_STACKSIZE (3072) -#define NC_STACKSIZE (512) -#define CON_STACKSIZE (512) -#define LOWPAN_TRANSFER_BUF_STACKSIZE (512) - -/* fragment size in bytes*/ -#define FRAG_PART_ONE_HDR_LEN (4) -#define FRAG_PART_N_HDR_LEN (5) - -#define LOWPAN_IPHC_DISPATCH (0x60) -#define LOWPAN_IPHC_FL_C (0x10) -#define LOWPAN_IPHC_TC_C (0x08) -#define LOWPAN_IPHC_CID (0x80) -#define LOWPAN_IPHC_SAC (0x40) -#define LOWPAN_IPHC_SAM (0x30) -#define LOWPAN_IPHC_DAC (0x04) -#define LOWPAN_IPHC_DAM (0x03) -#define LOWPAN_IPHC_M (0x08) -#define LOWPAN_IPHC_NH (0x04) -#define LOWPAN_IPV6_DISPATCH (0x41) -#define LOWPAN_CONTEXT_MAX (16) - -#define LOWPAN_REAS_BUF_TIMEOUT (15 * 1000 * 1000) /* TODO: Set back to 3 * 1000 * (1000) */ - -/* icmp message types rfc4443 */ -#define ICMP_PARA_PROB (4) -/* icmp message types rfc4861 4.*/ -#define ICMP_RTR_ADV (134) -#define ICMP_RTR_SOL (133) -#define ICMP_NBR_ADV (136) -#define ICMP_NBR_SOL (135) -#define ICMP_REDIRECT (137) /* will be filtered out by the border router */ -#define ICMP_RPL_CONTROL (155) - -#include "transceiver.h" -#include "sixlowip.h" -#include "vtimer.h" -#include "mutex.h" - -extern mutex_t lowpan_context_mutex; -extern uint16_t local_address; - -typedef struct { - uint8_t num; - ipv6_addr_t prefix; - uint8_t length; - uint8_t comp; - uint16_t lifetime; -} lowpan_context_t; - -typedef struct lowpan_interval_list_t { - uint8_t start; - uint8_t end; - struct lowpan_interval_list_t *next; -} lowpan_interval_list_t; - -typedef struct lowpan_reas_buf_t { - /* Source Address */ - ieee_802154_long_t s_laddr; - /* Destination Address */ - ieee_802154_long_t d_laddr; - /* Identification Number */ - uint16_t ident_no; - /* Timestamp of last packet fragment */ - long timestamp; - /* Size of reassembled packet with possible IPHC header */ - uint16_t packet_size; - /* Additive size of currently already received fragments */ - uint16_t current_packet_size; - /* Pointer to allocated memory for reassembled packet + 6LoWPAN Dispatch Byte */ - uint8_t *packet; - /* Pointer to list of intervals of received packet fragments (if any) */ - lowpan_interval_list_t *interval_list_head; - /* Pointer to next reassembly buffer (if any) */ - struct lowpan_reas_buf_t *next; -} lowpan_reas_buf_t; - -extern lowpan_reas_buf_t *head; - -/** - * @brief Initializes 6lowpan - * - * @param[in] trans transceiver to use with 6lowpan - * @param[in] r_addr phy layer address - * @param[in] as_border 1 if node shoud act as border router, 0 otherwise - */ -void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border); - -/** - * @brief Initializes a 6lowpan router with address prefix - * - * @param[in] trans transceiver to use with 6lowpan - * @param[in] prefix the address prefix to advertise - * @param[in] r_addr phy layer address - */ -void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix, - uint8_t r_addr); -void lowpan_init(ieee_802154_long_t *addr, uint8_t *data); -void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr, - ieee_802154_long_t *d_laddr); -void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, uint8_t *ptr); -void lowpan_iphc_decoding(uint8_t *data, uint8_t length, - ieee_802154_long_t *s_laddr, - ieee_802154_long_t *d_laddr); -uint8_t lowpan_context_len(void); -void add_fifo_packet(lowpan_reas_buf_t *current_packet); -lowpan_context_t *lowpan_context_update( - uint8_t num, const ipv6_addr_t *prefix, - uint8_t length, uint8_t comp, - uint16_t lifetime); -lowpan_context_t *lowpan_context_get(void); -lowpan_context_t *lowpan_context_lookup(ipv6_addr_t *addr); -lowpan_context_t *lowpan_context_num_lookup(uint8_t num); -lowpan_reas_buf_t *collect_garbage_fifo(lowpan_reas_buf_t *current_buf); -lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf); -void check_timeout(void); -void lowpan_ipv6_set_dispatch(uint8_t *data); -void init_reas_bufs(lowpan_reas_buf_t *buf); -void printReasBuffers(void); -void printFIFOBuffers(void); -#endif