mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-24 14:03:55 +01:00
added some neigbor discovery options to icmp message functions
This commit is contained in:
parent
2ddc48de4e
commit
0440c19f6b
@ -1,11 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <vtimer.h>
|
||||
#include "msg.h"
|
||||
#include "sixlowip.h"
|
||||
#include "sixlowmac.h"
|
||||
#include "sixlownd.h"
|
||||
#include "sixlowpan.h"
|
||||
#include <stdio.h>
|
||||
#include "drivers/cc110x/cc1100.h"
|
||||
#include "radio/radio.h"
|
||||
|
||||
msg msg_queue[IP_PKT_RECV_BUF_SIZE];
|
||||
struct ipv6_hdr_t* ipv6_buf;
|
||||
@ -26,15 +26,20 @@ struct icmpv6_hdr_t* get_icmpv6_buf(uint8_t ext_len){
|
||||
void bootstrapping(uint8_t *addr){
|
||||
#ifdef SIXLOWPAN_NODE
|
||||
/* create link-local address based on eui-64 */
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
//ipv6_buf = get_ipv6_buf();
|
||||
//RADIO.set_address(5);
|
||||
//create_link_local_prefix(&ipv6_buf->srcaddr);
|
||||
//init_802154_long_addr((uint8_t*)&(ipv6_buf->srcaddr.uint8[8]));
|
||||
//set_eui64(&ipv6_buf->srcaddr);
|
||||
// print6addr(&ipv6_buf->srcaddr);
|
||||
/* send router solicitation */
|
||||
init_rtr_sol();
|
||||
|
||||
init_rtr_sol(OPT_SLLAO);
|
||||
//init_rtr_adv(NULL, 0, 0, 0, 0, 0);
|
||||
|
||||
//init_rtr_adv(&ipv6_buf->srcaddr, 0, 0, OPT_PI, 0, 0);
|
||||
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
output(addr,(uint8_t*)ipv6_buf);
|
||||
//send_rtr_adv(&ipv6_buf->destaddr);
|
||||
#endif
|
||||
@ -48,10 +53,9 @@ void ip_process(void){
|
||||
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
ipv6_buf = (struct ipv6_hdr_t*) m.content.ptr;
|
||||
|
||||
|
||||
printf("INFO: packet received, source: ");
|
||||
print6addr(&ipv6_buf->srcaddr);
|
||||
|
||||
/* identifiy packet */
|
||||
nextheader = &ipv6_buf->nextheader;
|
||||
|
||||
@ -65,7 +69,26 @@ void ip_process(void){
|
||||
switch(icmp_buf->type) {
|
||||
case(ICMP_RTR_SOL):{
|
||||
printf("INFO: packet type: icmp router solicitation\n");
|
||||
recv_rtr_sol();
|
||||
/* processing router solicitation */
|
||||
recv_rtr_sol();
|
||||
/* init solicited router advertisment*/
|
||||
init_rtr_adv(&ipv6_buf->srcaddr, 0, 0, OPT_PI, 0, 0);
|
||||
/* send solicited router advertisment */
|
||||
uint8_t addr = 0;
|
||||
output(&addr,(uint8_t*)ipv6_buf);
|
||||
|
||||
break;
|
||||
}
|
||||
case(ICMP_RTR_ADV):{
|
||||
printf("INFO: packet type: icmp router advertisment\n");
|
||||
/* processing router advertisment */
|
||||
recv_rtr_adv();
|
||||
/* init neighbor solicitation */
|
||||
//init_nbr_sol();
|
||||
break;
|
||||
}
|
||||
case(ICMP_NBR_SOL):{
|
||||
printf("INFO: packet type: icmp neighbor solicitation\n");
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@ -78,10 +101,69 @@ void ip_process(void){
|
||||
}
|
||||
}
|
||||
|
||||
void iface_addr_list_add(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime,
|
||||
uint32_t pref_ltime, uint8_t type){
|
||||
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;
|
||||
iface.addr_list[iface_addr_list_count].val_ltime.absolute.seconds = val_ltime;
|
||||
timex_t vtime, ptime;
|
||||
vtime.seconds = val_ltime;
|
||||
ptime.seconds = pref_ltime;
|
||||
vtimer_set_wakeup(&(iface.addr_list[iface_addr_list_count].val_ltime),vtime,NULL);
|
||||
//iface.addr_list[iface_addr_list_count].pref_ltime.absolute.seconds = pref_ltime;
|
||||
vtimer_set_wakeup(&(iface.addr_list[iface_addr_list_count].pref_ltime), ptime, NULL);
|
||||
iface.addr_list[iface_addr_list_count].type = type;
|
||||
iface_addr_list_count++;
|
||||
}
|
||||
}
|
||||
|
||||
addr_list_t * iface_addr_list_search(ipv6_addr_t *addr){
|
||||
int i;
|
||||
for(i = 0; i < IFACE_ADDR_LIST_LEN; i++){
|
||||
if(memcmp(&(iface.addr_list[i].addr.uint8[0]),
|
||||
&(addr->uint8[0]),16) == 0){
|
||||
return &(iface.addr_list[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addr_list_t * iface_addr_list_prefix_equals(ipv6_addr_t *addr){
|
||||
int i;
|
||||
for(i = 0; i < IFACE_ADDR_LIST_LEN; i++){
|
||||
if(memcmp(&(iface.addr_list[i].addr.uint8[0]),
|
||||
&(addr->uint8[0]), 8) == 0){
|
||||
return &(iface.addr_list[i]);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void setup_addr_with_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);
|
||||
}
|
||||
|
||||
ieee_802154_long_t* get_eui(ipv6_addr_t *ipaddr){
|
||||
return ((ieee_802154_long_t *) &(ipaddr->uint8[8]));
|
||||
}
|
||||
|
||||
void create_prefix(ipv6_addr_t *inout, uint16_t prefix){
|
||||
inout->uint16[0] = prefix;
|
||||
inout->uint16[1] = 0;
|
||||
inout->uint16[2] = 0;
|
||||
inout->uint16[3] = 0;
|
||||
inout->uint16[4] = 0;
|
||||
inout->uint16[5] = 0;
|
||||
inout->uint16[6] = 0;
|
||||
inout->uint16[7] = 0;
|
||||
}
|
||||
|
||||
void create_all_routers_mcast_addr(ipv6_addr_t *ipaddr){
|
||||
ipaddr->uint16[0] = HTONS(0xff02);
|
||||
ipaddr->uint16[1] = 0;
|
||||
@ -104,10 +186,57 @@ void create_all_nodes_mcast_addr(ipv6_addr_t *ipaddr){
|
||||
ipaddr->uint16[7] = HTONS(0x0001);
|
||||
}
|
||||
|
||||
void get_src_ipaddr(ipv6_addr_t *ipaddr){
|
||||
void iface_find_src_ipaddr(ipv6_addr_t *ipaddr, uint8_t state,
|
||||
uint8_t dest_addr_type){
|
||||
int i;
|
||||
for(i=0;i<16;i++){
|
||||
ipaddr->uint8[i] = iface.ipaddr.uint8[i];
|
||||
int found = 0;
|
||||
|
||||
switch(dest_addr_type) {
|
||||
case(ADDR_TYPE_MULTICAST):{
|
||||
printf("a\n");
|
||||
for(i = 0; i < IFACE_ADDR_LIST_LEN; i++){
|
||||
if(prefix_link_local_check(&(iface.addr_list[i].addr))){
|
||||
printf("b\n");
|
||||
if(iface.addr_list[i].state == state){
|
||||
printf("c\n");
|
||||
memcpy(&(ipaddr->uint8[0]),
|
||||
&(iface.addr_list[i].addr.uint8[0]),16);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(ADDR_TYPE_LINK_LOCAL):{
|
||||
for(i = 0; i < IFACE_ADDR_LIST_LEN; i++){
|
||||
if(prefix_link_local_check(&(iface.addr_list[i].addr))){
|
||||
if(iface.addr_list[i].state == state){
|
||||
memcpy(&(ipaddr->uint8[0]),
|
||||
&(iface.addr_list[i].addr.uint8[0]),16);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(ADDR_TYPE_GLOBAL):{
|
||||
for(i = 0; i < IFACE_ADDR_LIST_LEN; i++){
|
||||
if(!(prefix_link_local_check(&(iface.addr_list[i].addr)))){
|
||||
if(iface.addr_list[i].state == state){
|
||||
memcpy(&(ipaddr->uint8[0]),
|
||||
&(iface.addr_list[i].addr.uint8[0]),16);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(found == 0){
|
||||
memset(ipaddr, 0, 16);
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,6 +247,26 @@ void create_link_local_prefix(ipv6_addr_t *ipaddr){
|
||||
ipaddr->uint16[3] = 0;
|
||||
}
|
||||
|
||||
uint8_t prefix_link_local_check(ipv6_addr_t *addr){
|
||||
if(addr->uint8[0] == 0xfe && addr->uint8[1] == 0x80){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void create_solicited_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 print6addr(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],
|
||||
@ -127,3 +276,16 @@ void print6addr(ipv6_addr_t *ipaddr){
|
||||
((uint8_t *)ipaddr)[12], ((uint8_t *)ipaddr)[13], ((uint8_t *)ipaddr)[14],
|
||||
((uint8_t *)ipaddr)[15]);
|
||||
}
|
||||
|
||||
uint32_t get_remaining_time(vtimer_t *t){
|
||||
timex_t time;
|
||||
time = vtimer_remaining(t);
|
||||
|
||||
uint32_t seconds = time.nanoseconds / 1000000;
|
||||
|
||||
return seconds;
|
||||
}
|
||||
|
||||
void set_remaining_time(vtimer_t *t, uint32_t time){
|
||||
t->absolute.nanoseconds = time * 1000000;
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#define SIXLOWIP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vtimer.h>
|
||||
|
||||
/* set maximum transmission unit */
|
||||
#define MTU 1280
|
||||
@ -18,9 +19,6 @@
|
||||
#define MSBA2_OUI 0x005BA2 // 24bit OUI
|
||||
#define R8BIT 0xA2 // random 8bit
|
||||
#define OUI 0x005BA2
|
||||
/* radio driver */
|
||||
#define RADIO_CONF radio_cc1100
|
||||
#define RADIO RADIO_CONF
|
||||
|
||||
#define MULTIHOP_HOPLIMIT 64
|
||||
|
||||
@ -30,6 +28,8 @@
|
||||
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;
|
||||
|
||||
/* base header lengths */
|
||||
#define LL_HDR_LEN 0x4
|
||||
@ -39,6 +39,30 @@ extern uint16_t packet_length;
|
||||
#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 5 // 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_LINK_LOCAL 5
|
||||
#define ADDR_TYPE_GLOBAL 6
|
||||
/* dispatch types */
|
||||
#define DISPATCH_TYPE_IPV6 0x41
|
||||
#define DISPATCH_TYPE_LOWPAN_HC1 0x42
|
||||
/* compression types */
|
||||
#define COMPRESSION_TYPE_NONE
|
||||
|
||||
/* buffer */
|
||||
uint8_t buffer[BUFFER_SIZE];
|
||||
|
||||
@ -79,10 +103,21 @@ typedef union __attribute__ ((packed)) ieee_802154_short_t {
|
||||
uint16_t uint16[1];
|
||||
} ieee_802154_short_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) addr_list_t {
|
||||
uint8_t state;
|
||||
vtimer_t val_ltime;
|
||||
vtimer_t pref_ltime;
|
||||
uint8_t type;
|
||||
ipv6_addr_t addr;
|
||||
} addr_list_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) iface_t {
|
||||
ieee_802154_short_t saddr;
|
||||
ieee_802154_long_t laddr;
|
||||
ipv6_addr_t ipaddr;
|
||||
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;
|
||||
@ -106,5 +141,14 @@ ieee_802154_long_t* get_eui(ipv6_addr_t *ipaddr);
|
||||
void bootstrapping(uint8_t *addr);
|
||||
void print6addr(ipv6_addr_t *ipaddr);
|
||||
void ip_process(void);
|
||||
|
||||
void iface_find_src_ipaddr(ipv6_addr_t *ipaddr, uint8_t state,
|
||||
uint8_t dest_addr_type);
|
||||
uint8_t prefix_link_local_check(ipv6_addr_t *addr);
|
||||
void iface_addr_list_add(ipv6_addr_t* addr, uint8_t state, uint32_t val_ltime,
|
||||
uint32_t pref_ltime, uint8_t type);
|
||||
addr_list_t * iface_addr_list_prefix_equals(ipv6_addr_t *addr);
|
||||
void setup_addr_with_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix);
|
||||
uint32_t get_remaining_time(vtimer_t *t);
|
||||
void set_remaining_time(vtimer_t *t, uint32_t time);
|
||||
void create_prefix(ipv6_addr_t *inout, uint16_t prefix);
|
||||
#endif /* SIXLOWIP_H*/
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include "msg.h"
|
||||
#include "radio/radio.h"
|
||||
#include "transceiver.h"
|
||||
#include "vtimer.h"
|
||||
#include "ieee802154_frame.h"
|
||||
|
||||
char radio_stack_buffer[RADIO_STACK_SIZE];
|
||||
@ -46,6 +47,13 @@ void set_radio_channel(uint8_t channel){
|
||||
msg_send_receive(&mesg,&mesg,transceiver_pid);
|
||||
}
|
||||
|
||||
void switch_to_rx(void){
|
||||
mesg.type = SWITCH_RX;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
tcmd.transceivers = TRANSCEIVER_CC1100;
|
||||
msg_send(&mesg, transceiver_pid, 1);
|
||||
}
|
||||
|
||||
void init_802154_short_addr(ieee_802154_short_t *saddr){
|
||||
saddr->uint8[0] = 0;
|
||||
saddr->uint8[1] = get_radio_address();
|
||||
@ -72,7 +80,7 @@ void recv_ieee802154_frame(void){
|
||||
ieee802154_frame_t frame;
|
||||
|
||||
msg_init_queue(msg_q, RADIO_RCV_BUF_SIZE);
|
||||
|
||||
|
||||
while (1) {
|
||||
msg_receive(&m);
|
||||
if (m.type == PKT_PENDING) {
|
||||
@ -80,12 +88,11 @@ void recv_ieee802154_frame(void){
|
||||
|
||||
hdrlen = read_802154_frame(p->data, &frame, p->length);
|
||||
length = p->length - hdrlen;
|
||||
|
||||
|
||||
/* deliver packet to network(6lowpan)-layer */
|
||||
input(frame.payload, length);
|
||||
|
||||
|
||||
p->processing--;
|
||||
// printf("\n");
|
||||
}
|
||||
else if (m.type == ENOBUFFER) {
|
||||
puts("Transceiver buffer full");
|
||||
@ -117,9 +124,6 @@ void set_ieee802154_frame_values(ieee802154_frame_t *frame){
|
||||
}
|
||||
|
||||
void send_ieee802154_frame(uint8_t *addr, uint8_t *payload, uint8_t length){
|
||||
|
||||
set_radio_channel(13);
|
||||
|
||||
mesg.type = SND_PKT;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
|
||||
@ -139,8 +143,6 @@ void send_ieee802154_frame(uint8_t *addr, uint8_t *payload, uint8_t length){
|
||||
frame.src_addr[0] = 0;
|
||||
frame.src_addr[1] = 5;
|
||||
|
||||
|
||||
|
||||
/* check if destination address is NULL => broadcast */
|
||||
if(addr[0] == 0 && addr[1] == 0){
|
||||
frame.dest_addr[0] = 0xff;
|
||||
@ -162,15 +164,14 @@ void send_ieee802154_frame(uint8_t *addr, uint8_t *payload, uint8_t length){
|
||||
p.dst = *addr;
|
||||
// TODO: geeignete ring-bufferung nötig
|
||||
p.data = buf;
|
||||
|
||||
//p.data = snd_buffer[i % RADIO_SND_BUF_SIZE];
|
||||
msg_send(&mesg, transceiver_pid, 1);
|
||||
//swtimer_usleep(RADIO_SENDING_DELAY);
|
||||
//switch_to_rx();
|
||||
}
|
||||
|
||||
void sixlowmac_init(transceiver_type_t type){
|
||||
int recv_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE,
|
||||
PRIORITY_MAIN-1, CREATE_STACKTEST, recv_ieee802154_frame , "radio");
|
||||
PRIORITY_MAIN-2, CREATE_STACKTEST, recv_ieee802154_frame , "radio");
|
||||
transceiver_type = type;
|
||||
transceiver_init(transceiver_type);
|
||||
transceiver_start();
|
||||
|
||||
@ -3,13 +3,48 @@
|
||||
#include "sixlowmac.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
#include <vtimer.h>
|
||||
|
||||
uint8_t rtr_sol_count = 0;
|
||||
/* extern variables */
|
||||
uint8_t opt_hdr_len = 0;
|
||||
uint8_t ipv6_ext_hdr_len = 0;
|
||||
uint16_t packet_length;
|
||||
|
||||
/* counter */
|
||||
uint8_t nbr_count = 0;
|
||||
uint8_t def_rtr_count = 0;
|
||||
uint8_t rtr_sol_count = 0;
|
||||
uint8_t prefix_count = 0;
|
||||
|
||||
/* global interface*/
|
||||
iface_t iface;
|
||||
|
||||
/* datastructures */
|
||||
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];
|
||||
|
||||
/* pointer */
|
||||
static uint8_t *llao;
|
||||
addr_list_t *addr_list_ptr;
|
||||
|
||||
static struct 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 opt_buf_t *opt_buf;
|
||||
static struct opt_stllao_t *opt_stllao_buf;
|
||||
static struct opt_mtu_t *opt_mtu_buf;
|
||||
static struct opt_pi_t *opt_pi_buf;
|
||||
static struct opt_aro_t *opt_aro_buf;
|
||||
|
||||
nbr_cache_t *nbr_entry;
|
||||
def_rtr_lst_t *def_rtr_entry;
|
||||
|
||||
/* elements */
|
||||
ipv6_addr_t tmpaddr;
|
||||
|
||||
static struct rtr_adv_t* get_rtr_adv_buf(uint8_t ext_len){
|
||||
return ((struct rtr_adv_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len]));
|
||||
}
|
||||
@ -18,6 +53,11 @@ static struct nbr_sol_t* get_nbr_sol_buf(uint8_t ext_len){
|
||||
return ((struct nbr_sol_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + ext_len]));
|
||||
}
|
||||
|
||||
static struct opt_buf_t* get_opt_buf(uint8_t ext_len, uint8_t opt_len){
|
||||
return ((struct opt_buf_t*)&(buffer[LLHDR_ICMPV6HDR_LEN +
|
||||
ext_len + opt_len]));
|
||||
}
|
||||
|
||||
static struct opt_stllao_t* get_opt_stllao_buf(uint8_t ext_len, uint8_t opt_len){
|
||||
return ((struct opt_stllao_t*)&(buffer[LLHDR_ICMPV6HDR_LEN +
|
||||
ext_len + opt_len]));
|
||||
@ -38,29 +78,11 @@ static struct opt_aro_t* get_opt_aro_buf(uint8_t ext_len, uint8_t opt_len){
|
||||
ext_len + opt_len]));
|
||||
}
|
||||
|
||||
/* data stuctures */
|
||||
// TODO: prefix list size initialwert herausfinden
|
||||
pfx_elem_t plist[OPT_PI_LIST_LEN];
|
||||
|
||||
/* pointer */
|
||||
static pfx_elem_t *pelem;
|
||||
static uint8_t *llao;
|
||||
|
||||
static struct 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 opt_stllao_t *opt_stllao_buf;
|
||||
static struct opt_mtu_t *opt_mtu_buf;
|
||||
static struct opt_pi_t *opt_pi_buf;
|
||||
static struct opt_aro_t *opt_aro_buf;
|
||||
|
||||
|
||||
/* send router solicitation message - RFC4861 section 4.1 */
|
||||
void init_rtr_sol(void){
|
||||
void init_rtr_sol(uint8_t sllao){
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
if(rtr_sol_count < RTR_SOL_MAX){
|
||||
//if(rtr_sol_count < RTR_SOL_MAX){
|
||||
packet_length = 0;
|
||||
icmp_buf->type = ICMP_RTR_SOL;
|
||||
icmp_buf->code = 0;
|
||||
@ -71,40 +93,69 @@ void init_rtr_sol(void){
|
||||
ipv6_buf->hoplimit = ND_HOPLIMIT;
|
||||
|
||||
create_all_routers_mcast_addr(&ipv6_buf->destaddr);
|
||||
get_src_ipaddr(&ipv6_buf->srcaddr);
|
||||
iface_find_src_ipaddr(&ipv6_buf->srcaddr, ADDR_STATE_PREFERRED,
|
||||
ADDR_TYPE_MULTICAST);
|
||||
|
||||
opt_hdr_len = RTR_SOL_LEN;
|
||||
ipv6_buf->length = ICMPV6_HDR_LEN + RTR_SOL_LEN + OPT_STLLAO_LEN;
|
||||
|
||||
opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len);
|
||||
set_llao((uint8_t*)opt_stllao_buf, OPT_SLLAO_TYPE, 2);
|
||||
|
||||
packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + ipv6_ext_hdr_len +
|
||||
RTR_SOL_LEN + OPT_STLLAO_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);
|
||||
packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + ipv6_ext_hdr_len +
|
||||
RTR_SOL_LEN + OPT_STLLAO_LEN;
|
||||
} else {
|
||||
packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + ipv6_ext_hdr_len +
|
||||
RTR_SOL_LEN;
|
||||
}
|
||||
icmp_buf->checksum = 0;
|
||||
|
||||
icmp_buf->checksum = ~icmpv6_csum(ICMPV6_NXT_HDR);
|
||||
rtr_sol_count++;
|
||||
// rtr_sol_count++;
|
||||
// sleep 4 sec
|
||||
//swtimer_usleep(RTR_SOL_INTERVAL * 1000000);
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
void recv_rtr_sol(void){
|
||||
opt_hdr_len = RTR_SOL_LEN;
|
||||
/* get link layer address option from buf */
|
||||
if(opt_stllao_buf->type == OPT_STLLAO_LEN){
|
||||
ipv6_buf = get_ipv6_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);
|
||||
llao = (uint8_t*)opt_stllao_buf;
|
||||
opt_hdr_len += (opt_stllao_buf->length) << 3;
|
||||
}
|
||||
|
||||
if(llao != NULL){
|
||||
// TODO: Neighbor lookup
|
||||
nbr_entry = nbr_cache_search(&ipv6_buf->srcaddr);
|
||||
if(nbr_entry != NULL){
|
||||
/* found neighbor in cache, update values and check long addr */
|
||||
if(memcmp(&llao[2],&nbr_entry->laddr,8) == 0){
|
||||
nbr_entry->isrouter = 0;
|
||||
} else {
|
||||
/* new long addr found, update */
|
||||
memcpy(&nbr_entry->laddr,&llao[2],8);
|
||||
nbr_entry->state = NBR_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);
|
||||
}
|
||||
}
|
||||
|
||||
//send_rtr_adv();
|
||||
/* init solicited router advertisment*/
|
||||
// init_rtr_adv(&ipv6_buf->srcaddr, 0, 0, 0, 0, 0);
|
||||
/* send solicited router advertisment */
|
||||
// uint8_t addr = 0;
|
||||
// output(&addr,(uint8_t*)ipv6_buf);
|
||||
}
|
||||
|
||||
void init_rtr_adv(ipv6_addr_t *addr){
|
||||
void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi,
|
||||
uint8_t sixco, uint8_t abro){
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
|
||||
@ -113,8 +164,13 @@ void init_rtr_adv(ipv6_addr_t *addr){
|
||||
ipv6_buf->flowlabel = 0;
|
||||
ipv6_buf->nextheader = ICMPV6_NXT_HDR;
|
||||
ipv6_buf->hoplimit = ND_HOPLIMIT;
|
||||
/* not solicited */
|
||||
create_all_nodes_mcast_addr(&ipv6_buf->destaddr);
|
||||
|
||||
if(addr == NULL){
|
||||
/* not solicited */
|
||||
create_all_nodes_mcast_addr(&ipv6_buf->destaddr);
|
||||
} else {
|
||||
memcpy(&ipv6_buf->destaddr, addr, 16);
|
||||
}
|
||||
|
||||
icmp_buf->type = ICMP_RTR_ADV;
|
||||
icmp_buf->code = 0;
|
||||
@ -125,45 +181,50 @@ void init_rtr_adv(ipv6_addr_t *addr){
|
||||
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->router_lifetime = RTR_ADV_MAX_INTERVAL * RTR_ADV_MAX;
|
||||
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;
|
||||
|
||||
/* set link layer address option */
|
||||
opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len);
|
||||
set_llao((uint8_t *)opt_stllao_buf,OPT_STLLAO_LEN, 2);
|
||||
opt_hdr_len += OPT_STLLAO_LEN;
|
||||
packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + RTR_ADV_LEN;
|
||||
|
||||
/* set MTU options */
|
||||
opt_mtu_buf = get_opt_mtu_buf(ipv6_ext_hdr_len, opt_hdr_len);
|
||||
opt_mtu_buf->type = OPT_MTU_TYPE;
|
||||
opt_mtu_buf->length = OPT_MTU_LEN;
|
||||
opt_mtu_buf->reserved = 0;
|
||||
/* 1500 octets mtu */
|
||||
opt_mtu_buf->mtu = HTONL(1500);
|
||||
opt_hdr_len += OPT_MTU_HDR_LEN;
|
||||
|
||||
/* set packet length */
|
||||
packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN +
|
||||
RTR_ADV_LEN + OPT_STLLAO_LEN + OPT_MTU_HDR_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_STLLAO_LEN, 2);
|
||||
opt_hdr_len += OPT_STLLAO_LEN;
|
||||
packet_length += OPT_STLLAO_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->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;
|
||||
packet_length += OPT_MTU_HDR_LEN;
|
||||
}
|
||||
/* set payload length field */
|
||||
|
||||
/* set prefix option */
|
||||
opt_pi_buf = get_opt_pi_buf(ipv6_ext_hdr_len, opt_hdr_len);
|
||||
for(int i=0;i<OPT_PI_LIST_LEN; i++){
|
||||
if(plist[i].inuse && plist[i].adv){
|
||||
opt_pi_buf->addr = plist[i].addr;
|
||||
if(pi == OPT_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);
|
||||
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;
|
||||
opt_pi_buf->prefix_length = plist[i].length;
|
||||
opt_pi_buf->l_a_reserved1 = plist[i].l_a_reserved1;
|
||||
opt_pi_buf->val_ltime = HTONL(pelem->val_ltime);
|
||||
opt_pi_buf->pref_ltime = HTONL(pelem->val_ltime);
|
||||
opt_pi_buf->val_ltime = HTONL(plist[i].val_ltime);
|
||||
opt_pi_buf->pref_ltime = HTONL(plist[i].val_ltime);
|
||||
opt_pi_buf->reserved2 = 0;
|
||||
packet_length += OPT_PI_HDR_LEN;
|
||||
opt_hdr_len += OPT_PI_HDR_LEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ipv6_buf->length = packet_length - IPV6_HDR_LEN;
|
||||
@ -174,8 +235,110 @@ void init_rtr_adv(ipv6_addr_t *addr){
|
||||
//printf("%x\n",icmp_buf->checksum);
|
||||
}
|
||||
|
||||
void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ){
|
||||
ipv6_ext_hdr_len = 0;
|
||||
void recv_rtr_adv(void){
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
opt_hdr_len = RTR_ADV_LEN;
|
||||
rtr_adv_buf = get_rtr_adv_buf(ipv6_ext_hdr_len);
|
||||
|
||||
/* update interface reachable time and retrans timer */
|
||||
if(rtr_adv_buf->reachable_time != 0){
|
||||
iface.adv_reachable_time = HTONL(rtr_adv_buf->reachable_time);
|
||||
}
|
||||
|
||||
if(rtr_adv_buf->retrans_timer != 0){
|
||||
iface.adv_retrans_timer = HTONL(rtr_adv_buf->retrans_timer);
|
||||
}
|
||||
|
||||
def_rtr_entry = def_rtr_lst_search(&ipv6_buf->srcaddr);
|
||||
|
||||
if(rtr_adv_buf->router_lifetime != 0){
|
||||
if(def_rtr_entry != NULL){
|
||||
def_rtr_entry->inval_timer.absolute.seconds =
|
||||
HTONL(rtr_adv_buf->router_lifetime);
|
||||
vtimer_set(&(def_rtr_entry->inval_timer));
|
||||
} else {
|
||||
def_rtr_lst_add(&(ipv6_buf->srcaddr), HTONL(rtr_adv_buf->router_lifetime));
|
||||
}
|
||||
} else {
|
||||
/* remove router from default router list */
|
||||
if(def_rtr_entry != NULL){
|
||||
def_rtr_lst_rem(def_rtr_entry);
|
||||
}
|
||||
}
|
||||
|
||||
/* read options */
|
||||
while(packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len){
|
||||
opt_buf = get_opt_buf(ipv6_ext_hdr_len, opt_hdr_len);
|
||||
timex_t tmp;
|
||||
|
||||
switch(opt_buf->type){
|
||||
case(OPT_SLLAO_TYPE):{
|
||||
break;
|
||||
}
|
||||
case(OPT_MTU_TYPE):{
|
||||
break;
|
||||
}
|
||||
/* rfc 4862 section 5.5.3 */
|
||||
case(OPT_PI_TYPE):{
|
||||
opt_pi_buf = get_opt_pi_buf(ipv6_ext_hdr_len, opt_hdr_len);
|
||||
/* crazy condition, read 5.5.3a-b-c for further information */
|
||||
if((!(opt_pi_buf->l_a_reserved1 & OPT_PI_FLAG_A)) ||
|
||||
(prefix_link_local_check(&opt_pi_buf->addr)) ||
|
||||
(opt_pi_buf->pref_ltime > opt_pi_buf->val_ltime)){
|
||||
break;
|
||||
} else{
|
||||
addr_list_ptr = iface_addr_list_prefix_equals(&opt_pi_buf->addr);
|
||||
if(addr_list_ptr == NULL){
|
||||
/* 5.5.3d */
|
||||
if(opt_pi_buf->val_ltime != 0){
|
||||
setup_addr_with_prefix(&tmpaddr, &opt_pi_buf->addr);
|
||||
/* add into address list */
|
||||
iface_addr_list_add(&tmpaddr,ADDR_STATE_TENTATIVE,
|
||||
opt_pi_buf->val_ltime,
|
||||
opt_pi_buf->pref_ltime,
|
||||
ADDR_CONFIGURED_AUTO);
|
||||
}
|
||||
} else {
|
||||
/* 5.5.3e */
|
||||
set_remaining_time(&(addr_list_ptr->pref_ltime), opt_pi_buf->pref_ltime);
|
||||
//addr_list_ptr->pref_ltime.absolute.seconds = opt_pi_buf->pref_ltime;
|
||||
//vtimer_set(&addr_list_ptr->pref_ltime);
|
||||
|
||||
/* 7200 = 2hours in seconds */
|
||||
if(HTONL(opt_pi_buf->val_ltime) > 7200 ||
|
||||
HTONL(opt_pi_buf->val_ltime) >
|
||||
//addr_list_ptr->val_ltime.absolute.seconds){
|
||||
get_remaining_time(&(addr_list_ptr->val_ltime))){
|
||||
set_remaining_time(&(addr_list_ptr->val_ltime),HTONL(opt_pi_buf->val_ltime));
|
||||
addr_list_ptr->val_ltime.absolute.seconds = HTONL(opt_pi_buf->val_ltime);
|
||||
vtimer_set(&addr_list_ptr->val_ltime);
|
||||
} else {
|
||||
/* reset valid lifetime to 2 hours */
|
||||
//set_remaining_time(addr_list_ptr->val_ltime, 7200);
|
||||
//addr_list_ptr->val_ltime.absolute.seconds = 7200;
|
||||
tmp.seconds = 7200;
|
||||
vtimer_set_wakeup(&(addr_list_ptr->val_ltime), tmp, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(OPT_6CO_TYPE):{
|
||||
break;
|
||||
}
|
||||
case(OPT_ABRO_TYPE):{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* multiplied with 8 because options length is in units of 8 bytes */
|
||||
opt_hdr_len += (opt_buf->length * 8);
|
||||
}
|
||||
}
|
||||
|
||||
void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ,
|
||||
uint8_t sllao, uint8_t aro){
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
ipv6_buf->version_trafficclass = IPV6_VER;
|
||||
ipv6_buf->trafficclass_flowlabel = 0;
|
||||
@ -184,88 +347,60 @@ void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ){
|
||||
ipv6_buf->hoplimit = ND_HOPLIMIT;
|
||||
|
||||
if(src == NULL){
|
||||
// TODO: src auswaehlen
|
||||
|
||||
} else{
|
||||
ipv6_buf->srcaddr = *src;
|
||||
memcpy(&(ipv6_buf->srcaddr), src, 16);
|
||||
}
|
||||
if(dest == NULL){
|
||||
// TODO: solicited knoten erstellen
|
||||
create_solicited_node_mcast_addr(targ, &(ipv6_buf->destaddr));
|
||||
} else{
|
||||
ipv6_buf->destaddr = *dest;
|
||||
memcpy(&(ipv6_buf->destaddr.uint8[0]), &(dest->uint8[0]), 16);
|
||||
}
|
||||
|
||||
|
||||
ipv6_ext_hdr_len = 0;
|
||||
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
icmp_buf->type = ICMP_NBR_SOL;
|
||||
icmp_buf->code = 0;
|
||||
|
||||
nbr_sol_buf = get_nbr_sol_buf(ipv6_ext_hdr_len);
|
||||
nbr_sol_buf->reserved = 0;
|
||||
nbr_sol_buf->tgtaddr = *targ;
|
||||
nbr_sol_buf->reserved = 0;
|
||||
memcpy(&(nbr_sol_buf->tgtaddr), targ, 16);
|
||||
opt_hdr_len = NBR_SOL_LEN;
|
||||
|
||||
/* set sllao option */
|
||||
opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len);
|
||||
set_llao((uint8_t*)opt_stllao_buf, OPT_SLLAO_TYPE, 1);
|
||||
opt_hdr_len += OPT_STLLAO_LEN;
|
||||
packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + NBR_SOL_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_LEN;
|
||||
|
||||
packet_length += OPT_STLLAO_LEN;
|
||||
}
|
||||
|
||||
/* set aro option */
|
||||
opt_aro_buf = get_opt_aro_buf(ipv6_ext_hdr_len, 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;
|
||||
opt_aro_buf->eui64 = *get_eui(src);
|
||||
opt_hdr_len += OPT_ARO_HDR_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->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), get_eui(src),8);
|
||||
opt_hdr_len += OPT_ARO_HDR_LEN;
|
||||
|
||||
packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + NBR_SOL_LEN +
|
||||
OPT_STLLAO_LEN + OPT_ARO_HDR_LEN;
|
||||
packet_length += OPT_ARO_HDR_LEN;
|
||||
}
|
||||
|
||||
ipv6_buf->length = packet_length - IPV6_HDR_LEN;
|
||||
}
|
||||
|
||||
void pfx_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){
|
||||
if(pfx_chk_list(addr,size) == 1){
|
||||
pelem->inuse = 1;
|
||||
pelem->length = size;
|
||||
pelem->adv = adv_opt;
|
||||
pelem->l_a_reserved1 = l_a_reserved1;
|
||||
pelem->val_ltime = val_ltime;
|
||||
pelem->pref_ltime = pref_ltime;
|
||||
pelem->addr = *addr;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t pfx_chk_list(ipv6_addr_t *addr, uint8_t size){
|
||||
pelem = NULL;
|
||||
for(int i=0 ; i < size ; i++){
|
||||
if(plist[i].inuse){
|
||||
if(pfx_cmp(&plist[i].addr, addr)){
|
||||
*pelem = plist[i];
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
*pelem = plist[i];
|
||||
}
|
||||
}
|
||||
if(pelem){
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
uint8_t pfx_cmp(ipv6_addr_t *addr1, ipv6_addr_t *addr2){
|
||||
if(memcmp(addr1, addr2, 8) == 0){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* link-layer address option - RFC4861 section 4.6.1/ RFC4944 8. */
|
||||
void set_llao(uint8_t *llao, uint8_t type, uint8_t length){
|
||||
llao[0] = type;
|
||||
llao[1] = length;
|
||||
void set_llao(opt_stllao_t *sllao, uint8_t type, uint8_t length){
|
||||
sllao->type = type;
|
||||
sllao->length = length;
|
||||
|
||||
uint8_t *llao = (uint8_t*)sllao;
|
||||
// get link layer address
|
||||
switch(length) {
|
||||
case(1):{
|
||||
@ -276,21 +411,17 @@ void set_llao(uint8_t *llao, uint8_t type, uint8_t length){
|
||||
case(2):{
|
||||
memcpy(&llao[2], &(iface.laddr), 8);
|
||||
memset(&llao[10], 0, 6);
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
printf("ERROR: llao not set\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
//ieee_802154_long_t *mac = get_eui(&ipv6_buf->srcaddr);
|
||||
//get_ieee_802154_long_t_from_ipaddr(&ipv6_buf->srcaddr,&mac);
|
||||
|
||||
//memcpy(&llao[2], mac, SIXLOWPAN_IPV6_LL_ADDR_LEN);
|
||||
// padding (all zeros) - 48bit
|
||||
//memset(&llao[2 + SIXLOWPAN_IPV6_LL_ADDR_LEN], 0,
|
||||
// OPT_STLLAO_LEN - SIXLOWPAN_IPV6_LL_ADDR_LEN - 2);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// checksum calculation
|
||||
|
||||
uint16_t csum(uint16_t sum, uint8_t *buf, uint16_t len){
|
||||
int count;
|
||||
@ -322,16 +453,111 @@ uint16_t csum(uint16_t sum, uint8_t *buf, uint16_t len){
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
uint16_t icmpv6_csum(uint8_t proto){
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
uint16_t sum;
|
||||
uint16_t len = ipv6_buf->length;
|
||||
sum = len + proto;
|
||||
|
||||
sum = csum(sum, (uint8_t *)&ipv6_buf->srcaddr, 2 * sizeof(ipv6_addr_t));
|
||||
sum = csum(sum,(uint8_t*)get_icmpv6_buf(0),len);
|
||||
|
||||
return (sum == 0) ? 0xffff : HTONS(sum);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// neighbor cache functions
|
||||
|
||||
nbr_cache_t * nbr_cache_search(ipv6_addr_t *ipaddr){
|
||||
int i;
|
||||
for(i = 0; i < NBR_CACHE_SIZE; i++){
|
||||
if(memcmp(&(nbr_cache[i].addr.uint8[0]), &(ipaddr->uint8[0]), 16) == 0){
|
||||
return &nbr_cache[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nbr_cache_add(ipv6_addr_t *ipaddr, ieee_802154_long_t *laddr,
|
||||
uint8_t isrouter, uint8_t state){
|
||||
if(nbr_count == NBR_CACHE_SIZE){
|
||||
printf("ERROR: neighbor cache full\n");
|
||||
} else {
|
||||
memcpy(&(nbr_cache[nbr_count].addr), ipaddr, 16);
|
||||
memcpy(&(nbr_cache[nbr_count].laddr), laddr, 8);
|
||||
nbr_cache[nbr_count].isrouter = isrouter;
|
||||
nbr_cache[nbr_count].state = state;
|
||||
|
||||
nbr_count++;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// default router list functions
|
||||
|
||||
def_rtr_lst_t * def_rtr_lst_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){
|
||||
return &def_rtr_lst[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void def_rtr_lst_add(ipv6_addr_t *ipaddr, uint32_t rtr_ltime){
|
||||
if(def_rtr_count == DEF_RTR_LST_SIZE){
|
||||
DEBUG("ERROR: default router list full\n");
|
||||
} else {
|
||||
memcpy(&(def_rtr_lst[def_rtr_count].addr), ipaddr, 16);
|
||||
def_rtr_lst[def_rtr_count].inval_timer.absolute.seconds = rtr_ltime;
|
||||
vtimer_set(&(def_rtr_lst[def_rtr_count].inval_timer));
|
||||
|
||||
def_rtr_count++;
|
||||
}
|
||||
}
|
||||
|
||||
void def_rtr_lst_rem(def_rtr_lst_t *entry){
|
||||
int i;
|
||||
for(i = 0; i < DEF_RTR_LST_SIZE; i++){
|
||||
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));
|
||||
def_rtr_count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// prefix list functions
|
||||
|
||||
void 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){
|
||||
if(prefix_count == OPT_PI_LIST_LEN){
|
||||
printf("ERROR: prefix list full\n");
|
||||
} else {
|
||||
plist[prefix_count].inuse = 1;
|
||||
plist[prefix_count].length = size;
|
||||
plist[prefix_count].adv = adv_opt;
|
||||
plist[prefix_count].l_a_reserved1 = l_a_reserved1;
|
||||
plist[prefix_count].val_ltime = val_ltime;
|
||||
plist[prefix_count].pref_ltime = pref_ltime;
|
||||
memcpy(&(plist[prefix_count].addr.uint8[0]), &(addr->uint8[0]), 16);
|
||||
|
||||
prefix_count++;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t plist_search(ipv6_addr_t *addr){
|
||||
int i;
|
||||
for(i = 0; i < OPT_PI_LIST_LEN; i++){
|
||||
if(memcmp(&(plist[i].addr.uint8[0]), &addr->uint8[0], 16) == 0){
|
||||
return &plist[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include <stdint.h>
|
||||
#include "vtimer.h"
|
||||
|
||||
/* router solicitation */
|
||||
#define RTR_SOL_LEN 4
|
||||
@ -28,6 +29,9 @@
|
||||
#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
|
||||
@ -37,10 +41,41 @@
|
||||
#define OPT_ARO_LEN 2
|
||||
#define OPT_ARO_HDR_LEN 16
|
||||
#define OPT_ARO_LTIME 300 // geeigneten wert finden
|
||||
/* 6lowpan context option */
|
||||
#define OPT_6CO_TYPE 32
|
||||
/* authoritative border router option */
|
||||
#define OPT_ABRO_TYPE 33
|
||||
/* neighbor cache size */
|
||||
#define NBR_CACHE_SIZE 8
|
||||
/* 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
|
||||
|
||||
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)) opt_buf_t {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
} opt_buf_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) opt_stllao_t {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
} opt_stllao_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) opt_mtu_t {
|
||||
@ -71,7 +106,7 @@ typedef struct __attribute__ ((packed)) opt_aro_t {
|
||||
ieee_802154_long_t eui64;
|
||||
} opt_aro_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) pfx_elem_t {
|
||||
typedef struct __attribute__ ((packed)) plist_t {
|
||||
uint8_t inuse;
|
||||
uint8_t adv;
|
||||
ipv6_addr_t addr;
|
||||
@ -79,7 +114,8 @@ typedef struct __attribute__ ((packed)) pfx_elem_t {
|
||||
uint8_t l_a_reserved1;
|
||||
uint32_t val_ltime;
|
||||
uint32_t pref_ltime;
|
||||
} pfx_elem_t;
|
||||
uint8_t infinite;
|
||||
} plist_t;
|
||||
|
||||
struct __attribute__ ((packed)) rtr_adv_t {
|
||||
uint8_t hoplimit;
|
||||
@ -95,14 +131,38 @@ struct __attribute__ ((packed)) nbr_sol_t {
|
||||
};
|
||||
|
||||
|
||||
void init_rtr_sol(void);
|
||||
void recv_rtr_sol(void);
|
||||
void init_rtr_adv(ipv6_addr_t *addr);
|
||||
uint8_t pfx_chk_list(ipv6_addr_t *addr, uint8_t size);
|
||||
uint8_t pfx_cmp(ipv6_addr_t *addr1, ipv6_addr_t *addr2);
|
||||
void pfx_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(uint8_t *llao, uint8_t type, uint8_t length);
|
||||
/* neighbor cache - rfc4861 5.1. */
|
||||
typedef struct __attribute__ ((packed)) nbr_cache_t {
|
||||
uint8_t state;
|
||||
uint8_t isrouter;
|
||||
ipv6_addr_t addr;
|
||||
ieee_802154_long_t laddr;
|
||||
} nbr_cache_t;
|
||||
|
||||
/* default router list - rfc4861 5.1. */
|
||||
typedef struct __attribute__ ((packed)) def_rtr_lst_t {
|
||||
ipv6_addr_t addr;
|
||||
vtimer_t inval_timer;
|
||||
} def_rtr_lst_t;
|
||||
|
||||
void init_rtr_sol(uint8_t sllao);
|
||||
void recv_rtr_sol(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);
|
||||
void 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);
|
||||
nbr_cache_t * nbr_cache_search(ipv6_addr_t *ipaddr);
|
||||
void nbr_cache_add(ipv6_addr_t *ipaddr, ieee_802154_long_t *laddr,
|
||||
uint8_t isrouter, uint8_t state);
|
||||
uint16_t icmpv6_csum(uint8_t proto);
|
||||
uint16_t csum(uint16_t sum, uint8_t *buf, uint16_t len);
|
||||
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_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ,
|
||||
uint8_t slloa, uint8_t aro);
|
||||
void 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);
|
||||
|
||||
@ -1,14 +1,19 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <vtimer.h>
|
||||
#include "thread.h"
|
||||
#include "msg.h"
|
||||
#include "sixlowmac.h"
|
||||
#include "sixlowpan.h"
|
||||
#include "sixlowip.h"
|
||||
#include "sixlownd.h"
|
||||
#include "transceiver.h"
|
||||
#include "ieee802154_frame.h"
|
||||
|
||||
uint8_t iface_addr_list_count = 0;
|
||||
uint16_t packet_length;
|
||||
uint8_t packet_dispatch;
|
||||
uint16_t tag;
|
||||
uint8_t packet_size = 0;
|
||||
uint8_t header_size = 0;
|
||||
@ -17,36 +22,54 @@ uint8_t max_frag_initial = 0;
|
||||
uint8_t position;
|
||||
uint8_t max_frag;
|
||||
|
||||
struct ipv6_hdr_t *ipv6_buf;
|
||||
|
||||
uint8_t frag_size;
|
||||
uint8_t *reas_buf;
|
||||
uint8_t byte_offset;
|
||||
uint8_t first_frag = 0;
|
||||
|
||||
static struct ipv6_hdr_t *ipv6_buf;
|
||||
unsigned int ip_process_pid;
|
||||
|
||||
iface_t iface;
|
||||
ipv6_addr_t loaddr;
|
||||
|
||||
char ip_process_buf[IP_PROCESS_STACKSIZE];
|
||||
|
||||
/* deliver packet to mac*/
|
||||
void output(uint8_t *addr, uint8_t *data){
|
||||
/* TODO: compression and set global dispatch byte */
|
||||
packet_dispatch = 0x41;
|
||||
|
||||
/* check/set dispatch byte */
|
||||
switch(packet_dispatch){
|
||||
case(DISPATCH_TYPE_IPV6):{
|
||||
memmove(data + 1, data, packet_length);
|
||||
data[0] = packet_dispatch;
|
||||
packet_length++;
|
||||
break;
|
||||
}
|
||||
case(DISPATCH_TYPE_LOWPAN_HC1):{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf("ERROR: wrong dispatch byte\n");
|
||||
}
|
||||
|
||||
packet_size = (uint8_t)packet_length;
|
||||
/* check if packet needs to be fragmented */
|
||||
if(packet_size + header_size > PAYLOAD_SIZE - IEEE_802154_MAX_HDR_LEN){
|
||||
printf("INFO: packet is to large, fragmentation started. size:"
|
||||
" %hu byte\n", packet_length);
|
||||
|
||||
uint8_t *ptr = data;
|
||||
uint8_t fragbuf[packet_size + header_size];
|
||||
uint8_t remaining;
|
||||
uint8_t i = 2;
|
||||
/* first fragment */
|
||||
|
||||
max_frame = PAYLOAD_SIZE - IEEE_802154_MAX_HDR_LEN;
|
||||
max_frag_initial = ((max_frame - 4 - header_size) / 8) * 8;
|
||||
|
||||
memcpy(fragbuf + 4, ptr, max_frag_initial);
|
||||
memcpy(fragbuf + 4, data, max_frag_initial);
|
||||
|
||||
fragbuf[0] = (((0xc0 << 8) | packet_length) >> 8) & 0xff;
|
||||
fragbuf[1] = ((0xc0 << 8) | packet_length) & 0xff;
|
||||
@ -59,11 +82,11 @@ void output(uint8_t *addr, uint8_t *data){
|
||||
position = max_frag_initial;
|
||||
max_frag = ((max_frame - 5) / 8) * 8;
|
||||
|
||||
ptr += position;
|
||||
data += position;
|
||||
|
||||
while(packet_size - position > max_frame - 5){
|
||||
memset(&fragbuf,0,packet_size + header_size);
|
||||
memcpy(fragbuf + 5, ptr, max_frag);
|
||||
memcpy(fragbuf + 5, data, max_frag);
|
||||
|
||||
fragbuf[0] = (((0xe0 << 8) | packet_length) >> 8) & 0xff;
|
||||
fragbuf[1] = ((0xe0 << 8) | packet_length) & 0xff;
|
||||
@ -73,14 +96,16 @@ void output(uint8_t *addr, uint8_t *data){
|
||||
|
||||
send_ieee802154_frame(addr,(uint8_t*)&fragbuf, max_frag + 5);
|
||||
printf(" frag %d size: %d byte\n",i , max_frag);
|
||||
ptr += position;
|
||||
data += max_frag;
|
||||
position += max_frag;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
remaining = packet_size - position;
|
||||
|
||||
memset(&fragbuf,0,packet_size + header_size);
|
||||
memcpy(fragbuf + 5, ptr, remaining);
|
||||
memcpy(fragbuf + 5, data, remaining);
|
||||
|
||||
fragbuf[0] = (((0xe0 << 8) | packet_length) >> 8) & 0xff;
|
||||
fragbuf[1] = ((0xe0 << 8) | packet_length) & 0xff;
|
||||
@ -150,13 +175,26 @@ void input(uint8_t *data, uint8_t length){
|
||||
frag_size = length - hdr_length;
|
||||
byte_offset = datagram_offset * 8;
|
||||
if((frag_size % 8) != 0){
|
||||
printf("ERROR: received invalid fragment\n");
|
||||
return;
|
||||
if((byte_offset + frag_size) != datagram_size){
|
||||
printf("ERROR: received invalid fragment\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
memcpy(reas_buf + byte_offset, data + hdr_length, byte_offset);
|
||||
if((byte_offset + frag_size) == datagram_size){
|
||||
m.content.ptr = (char*)reas_buf;
|
||||
msg_send(&m,ip_process_pid, 1);
|
||||
//m.content.ptr = (char*)reas_buf;
|
||||
switch(reas_buf[0]) {
|
||||
case(DISPATCH_TYPE_IPV6):{
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
memcpy(ipv6_buf, reas_buf + 1, datagram_size - 1);
|
||||
m.content.ptr = (char*) ipv6_buf;
|
||||
packet_length = datagram_size - 1;
|
||||
msg_send(&m,ip_process_pid, 1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf("ERROR: packet with unknown dispatch received\n");
|
||||
}
|
||||
free(reas_buf);
|
||||
}
|
||||
break;
|
||||
@ -171,16 +209,25 @@ void input(uint8_t *data, uint8_t length){
|
||||
|
||||
void sixlowpan_init(transceiver_type_t trans){
|
||||
/* init mac-layer and radio transceiver */
|
||||
vtimer_init();
|
||||
sixlowmac_init(trans);
|
||||
/* init interface addresses */
|
||||
memset(&iface,0,sizeof(iface_t));
|
||||
init_802154_short_addr(&(iface.saddr));
|
||||
init_802154_long_addr(&(iface.laddr));
|
||||
create_link_local_prefix(&(iface.ipaddr));
|
||||
memcpy(&(iface.ipaddr.uint8[8]), &iface.laddr, 8);
|
||||
//create_link_local_prefix(&(iface.ipaddr));
|
||||
//memcpy(&(iface.ipaddr.uint8[8]), &iface.laddr, 8);
|
||||
create_link_local_prefix(&loaddr);
|
||||
ipv6_addr_t prefix;
|
||||
create_prefix(&prefix, HTONS(0xabcd));
|
||||
plist_add(&prefix, 64, OPT_PI_VLIFETIME_INFINITE,0,1,0);
|
||||
|
||||
memcpy(&(loaddr.uint8[8]), &(iface.laddr.uint8[0]), 8);
|
||||
iface_addr_list_add(&loaddr, ADDR_STATE_PREFERRED, 0, 0,
|
||||
ADDR_CONFIGURED_AUTO);
|
||||
|
||||
ip_process_pid = thread_create(ip_process_buf, IP_PROCESS_STACKSIZE,
|
||||
PRIORITY_MAIN-1, CREATE_STACKTEST,
|
||||
ip_process, "ip_process");
|
||||
// send_ieee802154_frame();
|
||||
//send_ieee802154_frame();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user