mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #644 from authmillenon/decouple_network_stack
Decouple network stack from transceiver
This commit is contained in:
commit
79a16df7b8
16
Makefile.dep
16
Makefile.dep
@ -79,6 +79,12 @@ ifneq (,$(filter destiny,$(USEMODULE)))
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter sixlowborder,$(USEMODULE)))
|
||||
ifeq (,$(filter sixlowpan,$(USEMODULE)))
|
||||
USEMODULE += sixlowpan
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter sixlowpan,$(USEMODULE)))
|
||||
ifeq (,$(filter ieee802154,$(USEMODULE)))
|
||||
USEMODULE += ieee802154
|
||||
@ -86,13 +92,13 @@ ifneq (,$(filter sixlowpan,$(USEMODULE)))
|
||||
ifeq (,$(filter net_help,$(USEMODULE)))
|
||||
USEMODULE += net_help
|
||||
endif
|
||||
ifeq (,$(filter semaphore,$(USEMODULE)))
|
||||
ifeq (,$(filter net_if,$(USEMODULE)))
|
||||
USEMODULE += net_if
|
||||
endif
|
||||
ifeq (,$(filter semaphore, $(USEMODULE)))
|
||||
USEMODULE += semaphore
|
||||
endif
|
||||
ifeq (,$(filter transceiver,$(USEMODULE)))
|
||||
USEMODULE += transceiver
|
||||
endif
|
||||
ifeq (,$(filter vtimer,$(USEMODULE)))
|
||||
ifeq (,$(filter vtimer, $(USEMODULE)))
|
||||
USEMODULE += vtimer
|
||||
endif
|
||||
endif
|
||||
|
@ -39,15 +39,6 @@ extern uint8_t ipv6_ext_hdr_len;
|
||||
|
||||
msg_t msg_q[RCV_BUFFER_SIZE];
|
||||
|
||||
/* prints current IPv6 adresses */
|
||||
void rpl_udp_ip(int argc, char **argv)
|
||||
{
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
ipv6_iface_print_addrs();
|
||||
}
|
||||
|
||||
void rpl_udp_set_id(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
@ -95,7 +86,8 @@ void rpl_udp_monitor(void)
|
||||
else if (m.type == IPV6_PACKET_RECEIVED) {
|
||||
ipv6_buf = (ipv6_hdr_t *) m.content.ptr;
|
||||
printf("IPv6 datagram received (next header: %02X)", ipv6_buf->nextheader);
|
||||
printf(" from %s ", ipv6_addr_to_str(addr_str, &ipv6_buf->srcaddr));
|
||||
printf(" from %s ", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
&ipv6_buf->srcaddr));
|
||||
|
||||
if (ipv6_buf->nextheader == IPV6_PROTO_NUM_ICMPV6) {
|
||||
icmpv6_buf = (icmpv6_hdr_t *) &ipv6_buf[(LL_HDR_LEN + IPV6_HDR_LEN) + ipv6_ext_hdr_len];
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "net_if.h"
|
||||
#include "posix_io.h"
|
||||
#include "shell.h"
|
||||
#include "shell_commands.h"
|
||||
@ -37,7 +38,6 @@ const shell_command_t shell_commands[] = {
|
||||
{"loop", "", rpl_udp_loop},
|
||||
{"server", "Starts a UDP server", udp_server},
|
||||
{"send", "Send a UDP datagram", udp_send},
|
||||
{"ip", "Print all assigned IP addresses", rpl_udp_ip},
|
||||
{"ign", "ignore node", rpl_udp_ignore},
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
@ -48,6 +48,7 @@ int main(void)
|
||||
|
||||
/* start shell */
|
||||
posix_open(uart0_handler_pid, 0);
|
||||
net_if_set_src_address_mode(0, NET_IF_TRANS_ADDR_M_SHORT);
|
||||
|
||||
shell_t shell;
|
||||
shell_init(&shell, shell_commands, UART0_BUFSIZE, uart0_readc, uart0_putc);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <string.h>
|
||||
#include "vtimer.h"
|
||||
#include "thread.h"
|
||||
#include "net_if.h"
|
||||
#include "sixlowpan.h"
|
||||
#include "destiny.h"
|
||||
#include "rpl.h"
|
||||
@ -64,7 +65,9 @@ void rpl_udp_init(int argc, char **argv)
|
||||
return;
|
||||
}
|
||||
|
||||
state = rpl_init(TRANSCEIVER, id);
|
||||
net_if_set_hardware_address(0, id);
|
||||
|
||||
state = rpl_init(0);
|
||||
|
||||
if (state != SIXLOWERROR_SUCCESS) {
|
||||
printf("Error initializing RPL\n");
|
||||
@ -95,11 +98,13 @@ void rpl_udp_init(int argc, char **argv)
|
||||
ipv6_addr_t prefix, tmp;
|
||||
ipv6_addr_init(&std_addr, 0xABCD, 0xEF12, 0, 0, 0x1034, 0x00FF, 0xFE00, id);
|
||||
ipv6_addr_init_prefix(&prefix, &std_addr, 64);
|
||||
plist_add(&prefix, 64, NDP_OPT_PI_VLIFETIME_INFINITE, 0, 1, ICMPV6_NDP_OPT_PI_FLAG_AUTONOM);
|
||||
ipv6_init_iface_as_router();
|
||||
ndp_add_prefix_info(0, &prefix, 64, NDP_OPT_PI_VLIFETIME_INFINITE,
|
||||
NDP_OPT_PI_PLIFETIME_INFINITE, 1,
|
||||
ICMPV6_NDP_OPT_PI_FLAG_AUTONOM);
|
||||
ipv6_init_as_router();
|
||||
/* add global address */
|
||||
ipv6_addr_set_by_eui64(&tmp, &std_addr);
|
||||
ipv6_iface_add_addr(&tmp, IPV6_ADDR_TYPE_GLOBAL, NDP_ADDR_STATE_PREFERRED, 0, 0);
|
||||
ipv6_addr_set_by_eui64(&tmp, 0, &std_addr);
|
||||
ipv6_net_if_add_addr(0, &tmp, NDP_ADDR_STATE_PREFERRED, 0, 0, 0);
|
||||
|
||||
/* set channel to 10 */
|
||||
tcmd.transceivers = TRANSCEIVER;
|
||||
@ -134,7 +139,8 @@ void rpl_udp_loop(int argc, char **argv)
|
||||
|
||||
if (!is_root) {
|
||||
printf("my preferred parent:\n");
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str, (&mydodag->my_preferred_parent->addr)));
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
(&mydodag->my_preferred_parent->addr)));
|
||||
printf("parent lifetime: %d\n", mydodag->my_preferred_parent->lifetime);
|
||||
}
|
||||
|
||||
@ -142,9 +148,11 @@ void rpl_udp_loop(int argc, char **argv)
|
||||
|
||||
for (int i = 0; i < RPL_MAX_ROUTING_ENTRIES; i++) {
|
||||
if (rtable[i].used) {
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str, (&rtable[i].address)));
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
(&rtable[i].address)));
|
||||
puts("next hop");
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str, (&rtable[i].next_hop)));
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
(&rtable[i].next_hop)));
|
||||
printf("entry %d lifetime %d\n", i, rtable[i].lifetime);
|
||||
|
||||
if (!rpl_equal_id(&rtable[i].address, &rtable[i].next_hop)) {
|
||||
@ -171,7 +179,8 @@ void rpl_udp_table(int argc, char **argv)
|
||||
|
||||
for (int i = 0; i < RPL_MAX_ROUTING_ENTRIES; i++) {
|
||||
if (rtable[i].used) {
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str, (&rtable[i].address)));
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
(&rtable[i].address)));
|
||||
printf("entry %d lifetime %d\n", i, rtable[i].lifetime);
|
||||
|
||||
if (!rpl_equal_id(&rtable[i].address, &rtable[i].next_hop)) {
|
||||
@ -200,12 +209,14 @@ void rpl_udp_dodag(int argc, char **argv)
|
||||
}
|
||||
|
||||
printf("Part of Dodag:\n");
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str, (&mydodag->dodag_id)));
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
(&mydodag->dodag_id)));
|
||||
printf("my rank: %d\n", mydodag->my_rank);
|
||||
|
||||
if (!is_root) {
|
||||
printf("my preferred parent:\n");
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str, (&mydodag->my_preferred_parent->addr)));
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
(&mydodag->my_preferred_parent->addr)));
|
||||
}
|
||||
|
||||
printf("---------------------------\n");
|
||||
|
@ -128,7 +128,9 @@ void udp_send(int argc, char **argv)
|
||||
printf("Error sending packet!\n");
|
||||
}
|
||||
else {
|
||||
printf("Successful deliverd %i bytes over UDP to %s to 6LoWPAN\n", bytes_sent, ipv6_addr_to_str(addr_str, &ipaddr));
|
||||
printf("Successful deliverd %i bytes over UDP to %s to 6LoWPAN\n",
|
||||
bytes_sent, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
&ipaddr));
|
||||
}
|
||||
|
||||
destiny_socket_close(sock);
|
||||
|
@ -57,6 +57,9 @@ endif
|
||||
ifneq (,$(filter sixlowpan,$(USEMODULE)))
|
||||
DIRS += net/network_layer/sixlowpan
|
||||
endif
|
||||
ifneq (,$(filter sixlowborder,$(USEMODULE)))
|
||||
DIRS += net/network_layer/sixlowpan/border
|
||||
endif
|
||||
ifneq (,$(filter rpl,$(USEMODULE)))
|
||||
DIRS += net/routing/rpl
|
||||
endif
|
||||
|
@ -51,6 +51,10 @@
|
||||
#include "rtc.h"
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_SIXLOWPAN
|
||||
#include "sixlowpan.h"
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_DESTINY
|
||||
#include "destiny.h"
|
||||
#endif
|
||||
@ -63,6 +67,14 @@
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#ifndef CONF_RADIO_ADDR
|
||||
#define CONF_RADIO_ADDR (1)
|
||||
#endif
|
||||
|
||||
#ifndef CONF_PAN_ID
|
||||
#define CONF_PAN_ID (0xabcd)
|
||||
#endif
|
||||
|
||||
extern int main(void);
|
||||
|
||||
void auto_init(void)
|
||||
@ -103,6 +115,7 @@ void auto_init(void)
|
||||
MCI_initialize();
|
||||
#endif
|
||||
#ifdef MODULE_NET_IF
|
||||
int iface;
|
||||
DEBUG("Auto init net_if module.\n");
|
||||
transceiver_type_t transceivers = 0;
|
||||
#ifdef MODULE_AT86RF231
|
||||
@ -128,13 +141,32 @@ void auto_init(void)
|
||||
if (transceivers != 0) {
|
||||
transceiver_init(transceivers);
|
||||
transceiver_start();
|
||||
int iface = net_if_init_interface(0, transceivers);
|
||||
iface = net_if_init_interface(0, transceivers);
|
||||
|
||||
if (!net_if_get_hardware_address(iface)) {
|
||||
DEBUG("Auto init radio address on interface %d to 0x%04x\n", iface, CONF_RADIO_ADDR);
|
||||
DEBUG("Change this value at compile time with macro CONF_RADIO_ADDR\n");
|
||||
net_if_set_hardware_address(iface, CONF_RADIO_ADDR);
|
||||
}
|
||||
|
||||
if (net_if_get_pan_id(iface) <= 0) {
|
||||
DEBUG("Auto init PAN ID on interface %d to 0x%04x\n", iface, CONF_PAN_ID);
|
||||
DEBUG("Change this value at compile time with macro CONF_PAN_ID\n");
|
||||
net_if_set_pan_id(iface, CONF_PAN_ID);
|
||||
}
|
||||
|
||||
if (iface >= 0) {
|
||||
DEBUG("Interface %d initialized\n", iface);
|
||||
DEBUG("Auto init interface %d\n", iface);
|
||||
}
|
||||
}
|
||||
else {
|
||||
iface = -1;
|
||||
}
|
||||
|
||||
#ifdef MODULE_SIXLOWPAN
|
||||
DEBUG("Auto init 6LoWPAN module.\n");
|
||||
sixlowpan_lowpan_init();
|
||||
#endif
|
||||
#endif
|
||||
#ifdef MODULE_PROFILING
|
||||
extern void profiling_init(void);
|
||||
|
@ -26,23 +26,44 @@
|
||||
#include <stdint.h>
|
||||
|
||||
/* maximum 802.15.4 header length */
|
||||
#define IEEE_802154_MAX_HDR_LEN 23
|
||||
#define IEEE_802154_MAX_HDR_LEN (23)
|
||||
/* ...and FCS*/
|
||||
#define IEEE_802154_FCS_LEN 2
|
||||
#define IEEE_802154_FCS_LEN (2)
|
||||
|
||||
#define IEEE_802154_BEACON_FRAME 0
|
||||
#define IEEE_802154_DATA_FRAME 1
|
||||
#define IEEE_802154_ACK_FRAME 2
|
||||
#define IEEE_802154_MAC_CMD_FRAME 3
|
||||
#define IEEE_802154_BEACON_FRAME (0)
|
||||
#define IEEE_802154_DATA_FRAME (1)
|
||||
#define IEEE_802154_ACK_FRAME (2)
|
||||
#define IEEE_802154_MAC_CMD_FRAME (3)
|
||||
|
||||
#define IEEE_802154_SHORT_ADDR_M 2
|
||||
#define IEEE_802154_LONG_ADDR_M 3
|
||||
#define IEEE_802154_SHORT_ADDR_M (2)
|
||||
#define IEEE_802154_LONG_ADDR_M (3)
|
||||
|
||||
#define IEEE_802154_SHORT_MCAST_ADDR (0xffff)
|
||||
#define IEEE_802154_LONG_MCAST_ADDR {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff}}
|
||||
/**
|
||||
* @brief Transform 16-bit number from network order (big-endian) to
|
||||
* little-endian byte order (as used by IEEE 802.15.4).
|
||||
*/
|
||||
#define NTOLES(a) (((a) >> 8) | (((a) & 0x00ff) << 8))
|
||||
|
||||
#define IEEE_802154_PAN_ID 0x1234
|
||||
/**
|
||||
* @brief Transform 16-bit number from little-endian byte order to network
|
||||
* order (big-endian).
|
||||
*/
|
||||
#define LETONS(a) NTOLES(a)
|
||||
|
||||
/**
|
||||
* @brief Transform 16-bit number from host byte order to little-endian byte
|
||||
* order (as used by IEEE 802.15.4).
|
||||
*/
|
||||
#define HTOLES(a) a
|
||||
|
||||
/**
|
||||
* @brief Transform 16-bit number from little-endian byte order to host byte
|
||||
* order.
|
||||
*/
|
||||
#define LETOHS(a) HTOLES(a)
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t frame_type;
|
||||
@ -84,6 +105,7 @@ uint8_t ieee802154_frame_init(ieee802154_frame_t *frame, uint8_t *buf);
|
||||
uint8_t ieee802154_frame_get_hdr_len(ieee802154_frame_t *frame);
|
||||
uint8_t ieee802154_frame_read(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len);
|
||||
void ieee802154_frame_print_fcf_frame(ieee802154_frame_t *frame);
|
||||
uint16_t ieee802154_frame_get_fcs(const uint8_t *frame, uint8_t frame_len);
|
||||
|
||||
/** @} */
|
||||
#endif /* IEEE802154_IEEE802154_FRAME */
|
||||
|
@ -150,7 +150,7 @@ void icmpv6_send_parameter_prob(ipv6_addr_t *src, ipv6_addr_t *dest,
|
||||
* @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,
|
||||
uint16_t seq, uint8_t *data,
|
||||
size_t data_len);
|
||||
|
||||
/**
|
||||
@ -163,7 +163,7 @@ void icmpv6_send_echo_request(ipv6_addr_t *destaddr, uint16_t id,
|
||||
* @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);
|
||||
uint16_t seq, uint8_t *data, size_t data_len);
|
||||
|
||||
/**
|
||||
* @brief Send ICMPv6 router solicitation.
|
||||
@ -232,5 +232,16 @@ 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);
|
||||
|
||||
/**
|
||||
* @brief Calculates the checksum for ICMPv6 packets.
|
||||
*
|
||||
* @param[in] ipv6_buf The initialized IPv6 header of the packet.
|
||||
* @param[in] icmpv6_buf The initialized ICMPv6_header of the packet
|
||||
* (except checksum, payload is expected directly
|
||||
* after the packet header in memory).
|
||||
*
|
||||
* @return The internet checksum of the given ICMPv6 packet.
|
||||
*/
|
||||
uint16_t icmpv6_csum(ipv6_hdr_t *ipv6_buf, icmpv6_hdr_t *icmpv6_buf);
|
||||
/** @} */
|
||||
#endif /* SIXLOWPAN_ICMP_H */
|
||||
|
@ -24,6 +24,9 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "inet_ntop.h"
|
||||
#include "net_help.h"
|
||||
#include "net_if.h"
|
||||
#include "sixlowpan/types.h"
|
||||
|
||||
/**
|
||||
@ -32,7 +35,17 @@
|
||||
#define IPV6_MTU (256)
|
||||
|
||||
/**
|
||||
* @brief Maximum length of a IPv6 address represented as string.
|
||||
* @brief Length of an IPv6 address in byte.
|
||||
*/
|
||||
#define IPV6_ADDR_LEN (16)
|
||||
|
||||
/**
|
||||
* @brief Length of an IPv6 address in bit.
|
||||
*/
|
||||
#define IPV6_ADDR_BIT_LEN (128)
|
||||
|
||||
/**
|
||||
* @brief Maximum length of an IPv6 address represented as string.
|
||||
*/
|
||||
#define IPV6_MAX_ADDR_STR_LEN (40)
|
||||
|
||||
@ -92,7 +105,22 @@ ipv6_hdr_t *ipv6_get_buf(void);
|
||||
* is going to try to find a route
|
||||
*/
|
||||
int ipv6_sendto(const ipv6_addr_t *dest, uint8_t next_header,
|
||||
const uint8_t *payload, uint16_t payload_length);
|
||||
const uint8_t *payload, uint16_t payload_length);
|
||||
|
||||
/**
|
||||
* @brief Send an IPv6 packet defined by its header.
|
||||
*
|
||||
* @param[in] packet Pointer to an prepared IPv6 packet header.
|
||||
* The payload is expected directly after the
|
||||
* packet.
|
||||
*
|
||||
* @return length of payload : on success
|
||||
* -1 : if no route to the given dest could be obtained
|
||||
* Packet is dropped
|
||||
* In case of reactive routing: routing is going
|
||||
* to try to find a route
|
||||
*/
|
||||
int ipv6_send_packet(ipv6_hdr_t *packet);
|
||||
|
||||
/**
|
||||
* @brief Determines if node is a router.
|
||||
@ -101,6 +129,20 @@ int ipv6_sendto(const ipv6_addr_t *dest, uint8_t next_header,
|
||||
*/
|
||||
uint8_t ipv6_is_router(void);
|
||||
|
||||
/**
|
||||
* @brief Sets the default hop limit to use with IPv6 packets.
|
||||
*
|
||||
* @param[in] hop_limit The hop limit to set the default hop limit to.
|
||||
*/
|
||||
void ipv6_set_default_hop_limit(uint8_t hop_limit);
|
||||
|
||||
/**
|
||||
* @brief Gets the default hop limit that is used for IPv6 packets.
|
||||
*
|
||||
* @return The current default hop limit for IPv6 packets.
|
||||
*/
|
||||
uint8_t ipv6_get_default_hop_limit(void);
|
||||
|
||||
/**
|
||||
* @brief Registers a handler thread for incoming IP packets.
|
||||
*
|
||||
@ -131,7 +173,11 @@ void ipv6_register_rpl_handler(int pid);
|
||||
*
|
||||
* @param[in,out] ipv6_addr The address to set.
|
||||
*/
|
||||
void ipv6_addr_set_link_local_prefix(ipv6_addr_t *ipv6_addr);
|
||||
static inline void ipv6_addr_set_link_local_prefix(ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
ipv6_addr->uint32[0] = HTONL(0xfe800000);
|
||||
ipv6_addr->uint32[1] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets IPv6 address *out* according to the remaining
|
||||
@ -152,16 +198,20 @@ void ipv6_addr_init(ipv6_addr_t *out, uint16_t addr0, uint16_t addr1,
|
||||
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).
|
||||
* @brief Sets IPv6 address *out* using the given *prefix* and an interface's
|
||||
* EUI-64.
|
||||
*
|
||||
*
|
||||
* @param[out] out Address to be set.
|
||||
* @param[in] if_id The interface to take the EUI-64 from.
|
||||
* @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*)
|
||||
*
|
||||
* @return The Address to be set on success, NULL on error.
|
||||
*/
|
||||
void ipv6_addr_set_by_eui64(ipv6_addr_t *out,
|
||||
const ipv6_addr_t *prefix);
|
||||
ipv6_addr_t *ipv6_addr_set_by_eui64(ipv6_addr_t *out, int if_id,
|
||||
const ipv6_addr_t *prefix);
|
||||
|
||||
/**
|
||||
* @brief Sets IPv6 address *out* with the first *bits* bit taken
|
||||
@ -184,7 +234,13 @@ void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix,
|
||||
*
|
||||
* @param[out] ipv6_addr Is set to the loopback address.
|
||||
*/
|
||||
void ipv6_addr_set_loopback_addr(ipv6_addr_t *ipv6_addr);
|
||||
static inline void ipv6_addr_set_loopback_addr(ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
ipv6_addr->uint32[0] = 0;
|
||||
ipv6_addr->uint32[1] = 0;
|
||||
ipv6_addr->uint32[2] = 0;
|
||||
ipv6_addr->uint32[3] = HTONL(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set *ipv6_addr* to a link-local all routers multicast
|
||||
@ -197,7 +253,13 @@ void ipv6_addr_set_loopback_addr(ipv6_addr_t *ipv6_addr);
|
||||
* @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);
|
||||
static inline void ipv6_addr_set_all_routers_addr(ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
ipv6_addr->uint32[0] = HTONL(0xff020000);
|
||||
ipv6_addr->uint32[1] = 0;
|
||||
ipv6_addr->uint32[2] = 0;
|
||||
ipv6_addr->uint32[3] = HTONL(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set *ipv6_addr* to a link-local all nodes multicast address
|
||||
@ -210,7 +272,13 @@ void ipv6_addr_set_all_routers_addr(ipv6_addr_t *ipv6_addr);
|
||||
* @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);
|
||||
static inline void ipv6_addr_set_all_nodes_addr(ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
ipv6_addr->uint32[0] = HTONL(0xff020000);
|
||||
ipv6_addr->uint32[1] = 0;
|
||||
ipv6_addr->uint32[2] = 0;
|
||||
ipv6_addr->uint32[3] = HTONL(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set *ipv6_addr_out* to the solicited-node multicast address
|
||||
@ -225,22 +293,34 @@ void ipv6_addr_set_all_nodes_addr(ipv6_addr_t *ipv6_addr);
|
||||
* @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);
|
||||
static inline 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->uint32[0] = HTONL(0xff020000);
|
||||
ipv6_addr_out->uint32[1] = 0;
|
||||
ipv6_addr_out->uint32[2] = HTONS(1);
|
||||
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];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts IPv6 address into string (unabbrivated notation).
|
||||
* Note that addr_str must allocate at least
|
||||
* IPV6_MAX_ADDR_STR_LEN byte (40 byte).
|
||||
* @brief Converts IPv6 address into string.
|
||||
*
|
||||
* @param[out] addr_str The IPv6 address as string. Must allocate
|
||||
* at least IPV6_MAX_ADDR_STR_LEN byte (40
|
||||
* byte).
|
||||
* @param[in] str_len The maximum length available to *addr_str*.
|
||||
* @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);
|
||||
static inline const char *ipv6_addr_to_str(char *addr_str, uint8_t str_len,
|
||||
const ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
return inet_ntop(AF_INET6, ipv6_addr, addr_str, (size_t)str_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if two IPv6 addresses are equal.
|
||||
@ -250,7 +330,13 @@ char *ipv6_addr_to_str(char *addr_str, const ipv6_addr_t *ipv6_addr);
|
||||
*
|
||||
* @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);
|
||||
static inline int ipv6_addr_is_equal(const ipv6_addr_t *a, const ipv6_addr_t *b)
|
||||
{
|
||||
return (a->uint32[0] == b->uint32[0]) &&
|
||||
(a->uint32[1] == b->uint32[1]) &&
|
||||
(a->uint32[2] == b->uint32[2]) &&
|
||||
(a->uint32[3] == b->uint32[3]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if *ipv6_addr* is unspecified (all zero).
|
||||
@ -263,7 +349,48 @@ int ipv6_addr_is_equal(const ipv6_addr_t *a, const ipv6_addr_t *b);
|
||||
*
|
||||
* @return 1 if *ipv6_addr* is unspecified address, 0 otherwise.
|
||||
*/
|
||||
int ipv6_addr_is_unspecified(const ipv6_addr_t *ipv6_addr);
|
||||
static inline 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if *ipv6_addr* is a multicast address.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4291">
|
||||
* RFC 4291
|
||||
* </a>
|
||||
*
|
||||
* @param[in] ipv6_addr An IPv6 address.
|
||||
*
|
||||
* @return 1 if *ipv6_addr* is multicast address, 0 otherwise.
|
||||
*/
|
||||
static inline int ipv6_addr_is_multicast(const ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
return (ipv6_addr->uint8[0] == 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if *ipv6_addr* is a loopback address.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4291">
|
||||
* RFC 4291
|
||||
* </a>
|
||||
*
|
||||
* @param[in] ipv6_addr An IPv6 address.
|
||||
*
|
||||
* @return 1 if *ipv6_addr* is loopback address, 0 otherwise.
|
||||
*/
|
||||
static inline int ipv6_addr_is_loopback(const ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
return ipv6_addr->uint32[0] == 0 &&
|
||||
ipv6_addr->uint32[1] == 0 &&
|
||||
ipv6_addr->uint32[2] == 0 &&
|
||||
NTOHL(ipv6_addr->uint32[3]) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if *ipv6_addr* is a link-local address.
|
||||
@ -276,7 +403,13 @@ int ipv6_addr_is_unspecified(const ipv6_addr_t *ipv6_addr);
|
||||
*
|
||||
* @return 1 if *ipv6_addr* is link-local address, 0 otherwise.
|
||||
*/
|
||||
int ipv6_addr_is_link_local(const ipv6_addr_t *ipv6_addr);
|
||||
static inline int ipv6_addr_is_link_local(const ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
return ((ipv6_addr->uint32[0] == HTONL(0xfe800000)) &&
|
||||
(ipv6_addr->uint32[1] == 0)) ||
|
||||
(ipv6_addr_is_multicast(ipv6_addr) &&
|
||||
(ipv6_addr->uint8[1] & 0x0f) == 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if *ipv6_addr* is unique local unicast address.
|
||||
@ -290,20 +423,10 @@ int ipv6_addr_is_link_local(const ipv6_addr_t *ipv6_addr);
|
||||
* @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 <a href="http://tools.ietf.org/html/rfc4291">
|
||||
* RFC 4291
|
||||
* </a>
|
||||
*
|
||||
* @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);
|
||||
static inline int ipv6_addr_is_unique_local_unicast(const ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
return ((ipv6_addr->uint8[0] == 0xfc) || (ipv6_addr->uint8[0] == 0xfd));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if *ipv6_addr* is solicited-node multicast address.
|
||||
@ -317,7 +440,28 @@ int ipv6_addr_is_multicast(const ipv6_addr_t *ipv6_addr);
|
||||
* @return 1 if *ipv6_addr* is solicited-node multicast address,
|
||||
* 0 otherwise.
|
||||
*/
|
||||
int ipv6_addr_is_solicited_node(const ipv6_addr_t *ipv6_addr);
|
||||
static inline int ipv6_addr_is_solicited_node(const ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
return (ipv6_addr->uint32[0] == HTONL(0xff020000)) &&
|
||||
(ipv6_addr->uint32[1] == 0) &&
|
||||
(ipv6_addr->uint32[2] == HTONL(1)) &&
|
||||
(ipv6_addr->uint8[12] == 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get pointer to potential EUI-64 bit of the IPv6 address.
|
||||
*
|
||||
* @param[in] ipv6_addr An IPv6 address of this node.
|
||||
* @param[in] prefix_len Length of the prefix. Only multiples of 8 are
|
||||
* possible.
|
||||
*
|
||||
* @return The IID (as EUI-64) of this node.
|
||||
*/
|
||||
static inline net_if_eui64_t *ipv6_addr_get_iid(const ipv6_addr_t *ipv6_addr,
|
||||
uint8_t prefix_len)
|
||||
{
|
||||
return ((net_if_eui64_t *) &ipv6_addr->uint8[prefix_len / 8]);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO to wrap sixlowpan initialisations
|
||||
@ -325,26 +469,35 @@ int ipv6_addr_is_solicited_node(const ipv6_addr_t *ipv6_addr);
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Add an IPv6 address to this nodes interface.
|
||||
* @brief Add an IPv6 address to one of this nodes interfaces.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4862">
|
||||
* RFC 4862
|
||||
* </a>
|
||||
*
|
||||
* @param[in] if_id The interface's ID.
|
||||
* @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] val_ltime Valid lifetime of this address in seconds. Set 0
|
||||
* for unspecified.
|
||||
* @param[in] pref_ltime Preferred lifetime of this address in
|
||||
* seconds.
|
||||
* seconds. Set 0 for unspecified.
|
||||
* @param[in] is_anycast Determines if an address is anycast. Anycast
|
||||
* addresses are syntactically undistinguishable
|
||||
* from unicast addresses and can only be identified
|
||||
* with this flag. If *addr* is no unicast address
|
||||
* and *is_anycast* is set, this function will fail.
|
||||
*
|
||||
* @return 1 on success, 0 on failure.
|
||||
*/
|
||||
void ipv6_iface_add_addr(const ipv6_addr_t *addr, ipv6_addr_type_t type,
|
||||
int ipv6_net_if_add_addr(int if_id, const ipv6_addr_t *addr,
|
||||
ndp_addr_state_t state, uint32_t val_ltime,
|
||||
uint32_t pref_ltime);
|
||||
uint32_t pref_ltime, uint8_t is_anycast);
|
||||
|
||||
/**
|
||||
* @brief Tries to determine best suitable source address attached to
|
||||
* the interface of this node based on the given destination
|
||||
* an 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
|
||||
@ -352,16 +505,11 @@ void ipv6_iface_add_addr(const ipv6_addr_t *addr, ipv6_addr_type_t type,
|
||||
*
|
||||
* @param[out] src The best source address for this node (may be
|
||||
* all zero if ther is none).
|
||||
* @param[in] if_id The interface's ID.
|
||||
* @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);
|
||||
void ipv6_net_if_get_best_src_addr(ipv6_addr_t *src, const ipv6_addr_t *dest);
|
||||
|
||||
/**
|
||||
* @brief Registers a function that decides how to route incomming
|
||||
@ -375,7 +523,7 @@ void ipv6_iface_print_addrs(void);
|
||||
*
|
||||
* @param next_hop function that returns the next hop to reach dest
|
||||
*/
|
||||
void ipv6_iface_set_routing_provider(ipv6_addr_t *(*next_hop)(ipv6_addr_t* dest));
|
||||
void ipv6_iface_set_routing_provider(ipv6_addr_t *(*next_hop)(ipv6_addr_t *dest));
|
||||
|
||||
/**
|
||||
* @brief Calculates the IPv6 upper-layer checksum.
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "transceiver.h"
|
||||
#include "net_help.h"
|
||||
#include "net_if.h"
|
||||
#include "sixlowpan/types.h"
|
||||
|
||||
/**
|
||||
@ -178,26 +180,44 @@ typedef struct __attribute__((packed)) {
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initializes 6LoWPAN.
|
||||
* @brief Initializes all addresses on an interface needed for 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.
|
||||
* @param[in] if_id The interface to use with 6LoWPAN.
|
||||
*
|
||||
* @return 1 on success, 0 on failure.
|
||||
*/
|
||||
void sixlowpan_lowpan_init(transceiver_type_t trans, uint8_t r_addr,
|
||||
int as_border);
|
||||
int sixlowpan_lowpan_init_interface(int if_id);
|
||||
|
||||
/**
|
||||
* @brief Initializes a 6LoWPAN router with address prefix
|
||||
* @brief Checks if an EUI-64 was set from a short address. If so
|
||||
* it returns this address, else 0
|
||||
*
|
||||
* @param[in] trans transceiver to use with 6LoWPAN.
|
||||
* @param[in] prefix the address prefix to advertise.
|
||||
* @param[in] r_addr PHY layer address.
|
||||
* @param[in] iid An EUI-64.
|
||||
*
|
||||
* @return The short address on success, 0 on failure.
|
||||
*/
|
||||
void sixlowpan_lowpan_adhoc_init(transceiver_type_t trans,
|
||||
const ipv6_addr_t *prefix,
|
||||
uint8_t r_addr);
|
||||
static inline uint16_t sixlowpan_lowpan_eui64_to_short_addr(const net_if_eui64_t *iid)
|
||||
{
|
||||
if (iid->uint32[0] == HTONL(0x000000ff) &&
|
||||
iid->uint16[2] == HTONS(0xfe00)) {
|
||||
return NTOHS(iid->uint16[3]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes all addresses and prefixes on an interface needed
|
||||
* for 6LoWPAN. Calling this function together with
|
||||
* sixlowpan_lowpan_init_interface() is not necessary.
|
||||
*
|
||||
* @param[in] if_id The interface to use with 6LoWPAN.
|
||||
* @param[in] prefix the address prefix to advertise.
|
||||
*
|
||||
* @return 1 on success, 0 on failure.
|
||||
*/
|
||||
int sixlowpan_lowpan_init_adhoc_interface(int if_id,
|
||||
const ipv6_addr_t *prefix);
|
||||
|
||||
/**
|
||||
* @brief Initializes a 6LoWPAN border router with an address
|
||||
@ -205,26 +225,26 @@ void sixlowpan_lowpan_adhoc_init(transceiver_type_t trans,
|
||||
* @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.
|
||||
* @param[in] if_id The interface to use with 6LoWPAN.
|
||||
*
|
||||
* @return SIXLOWERROR_SUCCESS on success, otherwise SIXLOWERROR_ADDRESS if
|
||||
* address was not generated from IEEE 802.15.4 16-bit short
|
||||
* address.
|
||||
* @return 1 on success, 0 on failure.
|
||||
*/
|
||||
uint8_t sixlowpan_lowpan_border_init(transceiver_type_t trans,
|
||||
const ipv6_addr_t *border_router_addr);
|
||||
int sixlowpan_lowpan_border_init(int if_id);
|
||||
|
||||
/**
|
||||
* @brief Send data via 6LoWPAN to destination node dest.
|
||||
* @brief Send data via 6LoWPAN to destination node or next hop dest.
|
||||
*
|
||||
* @param[in] dest EUI-64 of destination node.
|
||||
* @param[in] if_id The interface to send the data over.
|
||||
* @param[in] dest Hardware address of the next hop or destination node.
|
||||
* @param[in] dest_len Length of the destination address in byte.
|
||||
* @param[in] data Data to send to destination node (may be
|
||||
* manipulated).
|
||||
* @param[in] data_len Length of data.
|
||||
*
|
||||
* @return length of transmitted data on success, -1 on failure.
|
||||
*/
|
||||
void sixlowpan_lowpan_sendto(const ieee_802154_long_t *dest,
|
||||
uint8_t *data, uint16_t data_len);
|
||||
int sixlowpan_lowpan_sendto(int if_id, const void *dest, int dest_len,
|
||||
uint8_t *data, uint16_t data_len);
|
||||
|
||||
/**
|
||||
* @brief Set header compression status for 6LoWPAN.
|
||||
@ -272,5 +292,12 @@ void sixlowpan_lowpan_print_fifo_buffers(void);
|
||||
void sixlowpan_lowpan_print_reassembly_buffers(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initializes 6LoWPAN module.
|
||||
*
|
||||
* @return 1 on success, 0 on failure.
|
||||
*/
|
||||
int sixlowpan_lowpan_init(void);
|
||||
|
||||
/** @} */
|
||||
#endif /* SIXLOWPAN_LOWPAN_H */
|
||||
|
@ -34,78 +34,29 @@
|
||||
#define IEEE_802154_MAX_ADDR_STR_LEN (12)
|
||||
|
||||
/**
|
||||
* @brief Gets current radio transmitter address.
|
||||
* @brief Send an IEEE 802.15.4 frame to a long address.
|
||||
*
|
||||
* @return Current radio address as 8-bit value.
|
||||
* @param[in] if_id The interface to send over (will be ignored if
|
||||
* *mcast* is 1).
|
||||
* @param[in] dest The destination address of the frame (will be
|
||||
* ignored if *mcast* is 1).
|
||||
* @param[in] dest_len The lengts of the destination address in byte.
|
||||
* @param[in] payload The payload of the frame.
|
||||
* @param[in] length The length of the payload.
|
||||
* @param[in] mcast send frame as multicast frame (*addr* and *if_id*
|
||||
* will be ignored).
|
||||
*
|
||||
* @return Length of transmitted data in byte
|
||||
*/
|
||||
uint8_t sixlowpan_mac_get_radio_address(void);
|
||||
int sixlowpan_mac_send_ieee802154_frame(int if_id, const void *dest,
|
||||
uint8_t dest_len, const void *payload, uint8_t length, uint8_t mcast);
|
||||
|
||||
/**
|
||||
* @brief Sets radio transmitter address.
|
||||
* @brief Initialise 6LoWPAN MAC layer and register it to interface layer
|
||||
*
|
||||
* @param[in] addr 8-bit radio address.
|
||||
* @return PID of the MAC receiver thread.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief Converts IEEE 802.15.4 long address into string.
|
||||
* Note that addr_str must allocate at least
|
||||
* IEEE_802154_MAX_ADDR_STR_LEN byte (12 byte).
|
||||
*
|
||||
* @param[out] addr_str The IEEE 802.15.4 long address as string. Must
|
||||
* allocate at least IEEE_802154_ADDR_STR_LEN byte (12
|
||||
* byte).
|
||||
* @param[in] laddr IEEE 802.15.4 address to be converted.
|
||||
*
|
||||
* @return Pointer to addr_str.
|
||||
*/
|
||||
char *sixlowpan_mac_802154_long_addr_to_str(char *addr_str, const ieee_802154_long_t *laddr);
|
||||
int sixlowpan_mac_init(void);
|
||||
|
||||
/** @} */
|
||||
#endif /* SIXLOWPAN_MAC_H */
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "net_if.h"
|
||||
#include "timex.h"
|
||||
#include "sixlowpan/types.h"
|
||||
|
||||
@ -32,6 +33,7 @@
|
||||
#define NDP_OPT_SLLAO_TYPE (1)
|
||||
#define NDP_OPT_TLLAO_TYPE (2)
|
||||
#define NDP_OPT_PI_VLIFETIME_INFINITE (0xffffffff)
|
||||
#define NDP_OPT_PI_PLIFETIME_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)
|
||||
@ -64,18 +66,37 @@ typedef enum __attribute__((packed)) {
|
||||
|
||||
/**
|
||||
* @brief Prefix list type to store information spread by prefix
|
||||
* information option.
|
||||
* information option on the interface.
|
||||
*
|
||||
* @see net_if_addr_t
|
||||
*/
|
||||
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;
|
||||
typedef struct __attribute__((packed)) ndp_prefix_info_t {
|
||||
/**
|
||||
* @brief The next on the interface. Intialise with NULL
|
||||
*/
|
||||
struct ndp_prefix_info_t *addr_next;
|
||||
/**
|
||||
* @brief The prev address on the interface. Initialise with NULL
|
||||
*/
|
||||
struct ndp_prefix_info_t *addr_prev;
|
||||
/**
|
||||
* @brief Flags to define upper layer protocols this address applies to.
|
||||
* For this layer NET_IF_L3P_IPV6_PREFIX must be set.
|
||||
*/
|
||||
net_if_l3p_t prefix_protocol;
|
||||
ipv6_addr_t *prefix_data; ///< The Prefix.
|
||||
uint8_t prefix_len; ///< Length of the prefix.
|
||||
uint8_t inuse; ///< Prefix is in in use.
|
||||
/**
|
||||
* Use this information in Prefix Information Options of Router
|
||||
* Advertisements.
|
||||
*/
|
||||
uint8_t advertisable;
|
||||
uint8_t flags; ///< flags of the prefix information option
|
||||
uint32_t valid_lifetime; ///< valid lifetime
|
||||
uint32_t preferred_lifetime; ///< preferred lifetime
|
||||
uint8_t infinite; ///< flag to set to infinite lifetime
|
||||
} ndp_prefix_info_t;
|
||||
|
||||
/**
|
||||
* @brief Default router list to store information spread by
|
||||
@ -84,7 +105,7 @@ typedef struct __attribute__((packed)) {
|
||||
typedef struct __attribute__((packed)) {
|
||||
ipv6_addr_t addr; ///< Address of router.
|
||||
timex_t inval_time; ///< remaining time until this entry is
|
||||
///< invalid.
|
||||
///< invalid.
|
||||
} ndp_default_router_list_t;
|
||||
|
||||
/**
|
||||
@ -94,14 +115,16 @@ typedef struct __attribute__((packed)) {
|
||||
* </a>.
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
int if_id; ///< Interface the IPv6 address is reachable
|
||||
///< over
|
||||
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.
|
||||
///< 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.
|
||||
uint8_t lladdr[8]; ///< Link-layer address of the neighbor
|
||||
uint8_t lladdr_len; ///< Length of link-layer address of the
|
||||
///< neighbor
|
||||
timex_t ltime; ///< lifetime of entry.
|
||||
} ndp_neighbor_cache_t;
|
||||
|
||||
@ -118,9 +141,76 @@ typedef struct __attribute__((packed)) {
|
||||
} ndp_a6br_cache_t;
|
||||
|
||||
ndp_default_router_list_t *ndp_default_router_list_search(ipv6_addr_t *ipaddr);
|
||||
uint8_t ndp_neighbor_cache_add(int if_id, const ipv6_addr_t *ipaddr,
|
||||
const void *lladdr, uint8_t lladdr_len,
|
||||
uint8_t isrouter, ndp_nce_state_t state,
|
||||
ndp_nce_type_t type, uint16_t ltime);
|
||||
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_neighbor_cache_t *ndp_get_ll_address(ipv6_addr_t *ipaddr);
|
||||
int ndp_addr_is_on_link(ipv6_addr_t *dest_addr);
|
||||
|
||||
/**
|
||||
* @brief Adds a prefix information to an interface. If it already exists,
|
||||
* the values *valid_lifetime*, *preferred_lifetime*, *advertisable*,
|
||||
* and flags will be updated accordingly and the prefix will be marked
|
||||
* as *in_use*.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.6.2">
|
||||
* RFC 4861, section 4.6.2
|
||||
* </a>.
|
||||
*
|
||||
* @param[in] if_id The interface's ID.
|
||||
* @param[in] prefix The prefix.
|
||||
* @param[in] prefix_len The length of the prefix in bit.
|
||||
* @param[in] valid_lifetime The time in seconds this prefix is valid
|
||||
* for on-link determination.
|
||||
* NDP_OPT_PI_VLIFETIME_INFINITE for infinite
|
||||
* lifetime.
|
||||
* @param[in] preferred_lifetime The time in seconds addresses generated with
|
||||
* this prefix remain preferred.
|
||||
* NDP_OPT_PI_PLIFETIME_INFINITE for infinite
|
||||
* lifetime.
|
||||
* @param[in] advertisable Set this to a value != 0 to advertise this
|
||||
* prefix information with the Prefix
|
||||
* Information Option, set it to 0 if not.
|
||||
* @param[in] flags Flags for the Prefix Information Option.
|
||||
* Valid values are
|
||||
* ICMPV6_NDP_OPT_PI_FLAG_ON_LINK and
|
||||
* ICMPV6_NDP_OPT_PI_FLAG_AUTONOM
|
||||
*/
|
||||
int ndp_add_prefix_info(int if_id, const ipv6_addr_t *prefix,
|
||||
uint8_t prefix_len, uint32_t valid_lifetime,
|
||||
uint32_t preferred_lifetime, uint8_t advertisable,
|
||||
uint8_t flags);
|
||||
|
||||
/**
|
||||
* @brief Searches the information for the longest prefix up to *up_to* bits
|
||||
* on an interface fitting to an address *addr*.
|
||||
*
|
||||
* @param[in] if_id The interface's ID.
|
||||
* @param[in] addr The address to search the prefix for.
|
||||
* @param[in] up_to The number of bits up to which point the search should
|
||||
* go. Set to IPV6_ADDR_BIT_LEN for the whole address.
|
||||
* Values greater then IPV6_ADDR_BIT_LEN are set to
|
||||
* IPV6_ADDR_BIT_LEN.
|
||||
*
|
||||
* @return The found prefix information, NULL when none is found.
|
||||
*/
|
||||
ndp_prefix_info_t *ndp_prefix_info_search(int if_id, const ipv6_addr_t *addr,
|
||||
uint8_t up_to);
|
||||
|
||||
/**
|
||||
* @brief Searches the information for the prefix that matches *prefix* with
|
||||
* length *prefix_len*.
|
||||
*
|
||||
* @param[in] if_id The interface's ID.
|
||||
* @param[in] prefix The prefix to search for.
|
||||
* @param[in] prefix_len The length of the prefix in bit.
|
||||
*
|
||||
* @return The found prefix information, NULL when none is found.
|
||||
*/
|
||||
ndp_prefix_info_t *ndp_prefix_info_match(int if_id, const ipv6_addr_t *prefix,
|
||||
uint8_t prefix_len);
|
||||
ndp_a6br_cache_t *ndp_a6br_cache_get_most_current(void);
|
||||
ndp_a6br_cache_t *ndp_a6br_cache_get_oldest(void);
|
||||
|
||||
|
@ -49,25 +49,6 @@ typedef union __attribute__((packed)) {
|
||||
uint32_t uint32[4]; ///< devided by 4 32-bit words.
|
||||
} ipv6_addr_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent IPv6 address types.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4291">
|
||||
* RFC 4291
|
||||
* </a>
|
||||
*/
|
||||
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
|
||||
*
|
||||
@ -78,7 +59,7 @@ typedef enum __attribute__((packed)) {
|
||||
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.
|
||||
///< 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.
|
||||
|
@ -18,6 +18,13 @@
|
||||
|
||||
#include "ieee802154_frame.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#if ENABLE_DEBUG
|
||||
#define DEBUG_ENABLED
|
||||
#endif
|
||||
#include "debug.h"
|
||||
|
||||
#define IEEE_802154_FCS_POLY (0x8408) /* x^16 + x^12 + x^5 + 1 for LSB first */
|
||||
|
||||
uint8_t ieee802154_hdr_ptr;
|
||||
uint8_t ieee802154_payload_ptr;
|
||||
@ -28,16 +35,16 @@ uint8_t ieee802154_frame_init(ieee802154_frame_t *frame, uint8_t *buf)
|
||||
/* Frame Control Field - 802.15.4 - 2006 - 7.2.1.1 */
|
||||
uint8_t index = 0;
|
||||
|
||||
buf[index] = ((frame->fcf.frame_type) |
|
||||
(frame->fcf.sec_enb << 3) |
|
||||
(frame->fcf.frame_pend << 4) |
|
||||
(frame->fcf.ack_req << 5) |
|
||||
(frame->fcf.panid_comp << 6));
|
||||
buf[index] = (((frame->fcf.frame_type) & 0x07) |
|
||||
((frame->fcf.sec_enb << 3) & 0x08) |
|
||||
((frame->fcf.frame_pend << 4) & 0x10) |
|
||||
((frame->fcf.ack_req << 5) & 0x20) |
|
||||
((frame->fcf.panid_comp << 6) & 0x40));
|
||||
index++;
|
||||
|
||||
buf[index] = ((frame->fcf.dest_addr_m << 2) |
|
||||
(frame->fcf.frame_ver << 4) |
|
||||
(frame->fcf.src_addr_m << 6));
|
||||
buf[index] = (((frame->fcf.dest_addr_m << 2) & 0x0c) |
|
||||
((frame->fcf.frame_ver << 4) & 0x30) |
|
||||
((frame->fcf.src_addr_m << 6) & 0xc0));
|
||||
|
||||
index++;
|
||||
|
||||
@ -55,49 +62,62 @@ uint8_t ieee802154_frame_init(ieee802154_frame_t *frame, uint8_t *buf)
|
||||
|
||||
/* Destination Address - 802.15.4 - 2006 - 7.2.1.4 */
|
||||
if (frame->fcf.dest_addr_m == 0x02) {
|
||||
buf[index] = frame->dest_addr[0];
|
||||
buf[index + 1] = frame->dest_addr[1];
|
||||
buf[index] = frame->dest_addr[1];
|
||||
buf[index + 1] = frame->dest_addr[0];
|
||||
index += 2;
|
||||
}
|
||||
else if (frame->fcf.dest_addr_m == 0x03) {
|
||||
buf[index] = frame->dest_addr[0];
|
||||
buf[index + 1] = frame->dest_addr[1];
|
||||
buf[index + 2] = frame->dest_addr[2];
|
||||
buf[index + 3] = frame->dest_addr[3];
|
||||
buf[index + 4] = frame->dest_addr[4];
|
||||
buf[index + 5] = frame->dest_addr[5];
|
||||
buf[index + 6] = frame->dest_addr[6];
|
||||
buf[index + 7] = frame->dest_addr[7];
|
||||
buf[index] = frame->dest_addr[7];
|
||||
buf[index + 1] = frame->dest_addr[6];
|
||||
buf[index + 2] = frame->dest_addr[5];
|
||||
buf[index + 3] = frame->dest_addr[4];
|
||||
buf[index + 4] = frame->dest_addr[3];
|
||||
buf[index + 5] = frame->dest_addr[2];
|
||||
buf[index + 6] = frame->dest_addr[1];
|
||||
buf[index + 7] = frame->dest_addr[0];
|
||||
index += 8;
|
||||
}
|
||||
|
||||
/* Source PAN Identifier - 802.15.4 - 2006 - 7.2.1.5 */
|
||||
if (!(frame->fcf.panid_comp & 0x01)) {
|
||||
if (frame->fcf.src_addr_m == 0x02 || frame->fcf.src_addr_m == 0x03) {
|
||||
buf[index] = ((frame->src_pan_id >> 8) & 0xff);
|
||||
buf[index + 1] = (frame->src_pan_id & 0xff);
|
||||
buf[index + 1] = ((frame->src_pan_id >> 8) & 0xff);
|
||||
buf[index] = (frame->src_pan_id & 0xff);
|
||||
index += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Source Address field - 802.15.4 - 2006 - 7.2.1.6 */
|
||||
if (frame->fcf.src_addr_m == 0x02) {
|
||||
buf[index] = frame->src_addr[0];
|
||||
buf[index + 1] = frame->src_addr[1];
|
||||
buf[index] = frame->src_addr[1];
|
||||
buf[index + 1] = frame->src_addr[0];
|
||||
index += 2;
|
||||
}
|
||||
else if (frame->fcf.src_addr_m == 0x03) {
|
||||
buf[index] = frame->src_addr[0];
|
||||
buf[index + 1] = frame->src_addr[1];
|
||||
buf[index + 2] = frame->src_addr[2];
|
||||
buf[index + 3] = frame->src_addr[3];
|
||||
buf[index + 4] = frame->src_addr[4];
|
||||
buf[index + 5] = frame->src_addr[5];
|
||||
buf[index + 6] = frame->src_addr[6];
|
||||
buf[index + 7] = frame->src_addr[7];
|
||||
buf[index] = frame->src_addr[7];
|
||||
buf[index + 1] = frame->src_addr[6];
|
||||
buf[index + 2] = frame->src_addr[5];
|
||||
buf[index + 3] = frame->src_addr[4];
|
||||
buf[index + 4] = frame->src_addr[3];
|
||||
buf[index + 5] = frame->src_addr[2];
|
||||
buf[index + 6] = frame->src_addr[1];
|
||||
buf[index + 7] = frame->src_addr[0];
|
||||
index += 8;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
DEBUG("INFO: IEEE 802.15.4 header initialized:\n");
|
||||
|
||||
for (size_t i = 0; i < index; i++) {
|
||||
printf("%02x ", buf[i]);
|
||||
|
||||
if (!((i + 1) % 16) || i == index - 1) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
@ -170,13 +190,14 @@ uint8_t ieee802154_frame_read(uint8_t *buf, ieee802154_frame_t *frame,
|
||||
|
||||
index += 2;
|
||||
|
||||
switch(frame->fcf.dest_addr_m) {
|
||||
switch (frame->fcf.dest_addr_m) {
|
||||
case (0): {
|
||||
printf("fcf.dest_addr_m: pan identifier/address fields empty\n");
|
||||
DEBUG("fcf.dest_addr_m: pan identifier/address fields empty\n");
|
||||
break;
|
||||
}
|
||||
|
||||
case (2): {
|
||||
/* read address in little-endian order */
|
||||
frame->dest_addr[0] = buf[index];
|
||||
frame->dest_addr[1] = buf[index + 1];
|
||||
index += 2;
|
||||
@ -184,14 +205,15 @@ uint8_t ieee802154_frame_read(uint8_t *buf, ieee802154_frame_t *frame,
|
||||
}
|
||||
|
||||
case (3): {
|
||||
frame->dest_addr[0] = buf[index];
|
||||
frame->dest_addr[1] = buf[index + 1];
|
||||
frame->dest_addr[2] = buf[index + 2];
|
||||
frame->dest_addr[3] = buf[index + 3];
|
||||
frame->dest_addr[4] = buf[index + 4];
|
||||
frame->dest_addr[5] = buf[index + 5];
|
||||
frame->dest_addr[6] = buf[index + 6];
|
||||
frame->dest_addr[7] = buf[index + 7];
|
||||
/* read address in network order */
|
||||
frame->dest_addr[7] = buf[index];
|
||||
frame->dest_addr[6] = buf[index + 1];
|
||||
frame->dest_addr[5] = buf[index + 2];
|
||||
frame->dest_addr[4] = buf[index + 3];
|
||||
frame->dest_addr[3] = buf[index + 4];
|
||||
frame->dest_addr[2] = buf[index + 5];
|
||||
frame->dest_addr[1] = buf[index + 6];
|
||||
frame->dest_addr[0] = buf[index + 7];
|
||||
index += 8;
|
||||
break;
|
||||
}
|
||||
@ -202,13 +224,14 @@ uint8_t ieee802154_frame_read(uint8_t *buf, ieee802154_frame_t *frame,
|
||||
index += 2;
|
||||
}
|
||||
|
||||
switch(frame->fcf.src_addr_m) {
|
||||
switch (frame->fcf.src_addr_m) {
|
||||
case (0): {
|
||||
printf("fcf.src_addr_m: pan identifier/address fields empty\n");
|
||||
DEBUG("fcf.src_addr_m: pan identifier/address fields empty\n");
|
||||
break;
|
||||
}
|
||||
|
||||
case (2): {
|
||||
/* read address in little-endian order */
|
||||
frame->src_addr[0] = buf[index];
|
||||
frame->src_addr[1] = buf[index + 1];
|
||||
index += 2;
|
||||
@ -216,14 +239,15 @@ uint8_t ieee802154_frame_read(uint8_t *buf, ieee802154_frame_t *frame,
|
||||
}
|
||||
|
||||
case (3): {
|
||||
frame->src_addr[0] = buf[index];
|
||||
frame->src_addr[1] = buf[index + 1];
|
||||
frame->src_addr[2] = buf[index + 2];
|
||||
frame->src_addr[3] = buf[index + 3];
|
||||
frame->src_addr[4] = buf[index + 4];
|
||||
frame->src_addr[5] = buf[index + 5];
|
||||
frame->src_addr[6] = buf[index + 6];
|
||||
frame->src_addr[7] = buf[index + 7];
|
||||
/* read address in network order */
|
||||
frame->src_addr[7] = buf[index];
|
||||
frame->src_addr[6] = buf[index + 1];
|
||||
frame->src_addr[5] = buf[index + 2];
|
||||
frame->src_addr[4] = buf[index + 3];
|
||||
frame->src_addr[3] = buf[index + 4];
|
||||
frame->src_addr[2] = buf[index + 5];
|
||||
frame->src_addr[1] = buf[index + 6];
|
||||
frame->src_addr[0] = buf[index + 7];
|
||||
index += 8;
|
||||
break;
|
||||
}
|
||||
@ -236,6 +260,27 @@ uint8_t ieee802154_frame_read(uint8_t *buf, ieee802154_frame_t *frame,
|
||||
return hdrlen;
|
||||
}
|
||||
|
||||
/* crc with lsb first */
|
||||
uint16_t ieee802154_frame_get_fcs(const uint8_t *frame, uint8_t frame_len)
|
||||
{
|
||||
uint16_t r = 0;
|
||||
|
||||
for (uint8_t byte = 0; byte < frame_len; ++byte) {
|
||||
r ^= frame[byte];
|
||||
|
||||
for (uint8_t bit = 8; bit > 0; --bit) {
|
||||
if (r & 0x0001) {
|
||||
r = (r >> 1) ^ IEEE_802154_FCS_POLY;
|
||||
}
|
||||
else {
|
||||
r = (r >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void ieee802154_frame_print_fcf_frame(ieee802154_frame_t *frame)
|
||||
{
|
||||
printf("frame type: %02x\n"
|
||||
|
@ -16,6 +16,7 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* TODO: Put this in its own module */
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -37,9 +38,10 @@
|
||||
|
||||
#include "net_help.h"
|
||||
|
||||
#define READER_STACK_SIZE (KERNEL_CONF_STACKSIZE_DEFAULT)
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
ipv6_addr_t abr_addr;
|
||||
#define READER_STACK_SIZE (KERNEL_CONF_STACKSIZE_DEFAULT)
|
||||
|
||||
char serial_reader_stack[READER_STACK_SIZE];
|
||||
uint16_t serial_reader_pid;
|
||||
@ -47,6 +49,8 @@ uint16_t serial_reader_pid;
|
||||
uint8_t serial_out_buf[BORDER_BUFFER_SIZE];
|
||||
uint8_t serial_in_buf[BORDER_BUFFER_SIZE];
|
||||
|
||||
ipv6_addr_t *abr_addr;
|
||||
|
||||
uint8_t *get_serial_out_buffer(int offset)
|
||||
{
|
||||
if (offset > BUFFER_SIZE) {
|
||||
@ -120,45 +124,48 @@ void serial_reader_f(void)
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t sixlowpan_lowpan_border_init(transceiver_type_t trans,
|
||||
const ipv6_addr_t *border_router_addr)
|
||||
int sixlowpan_lowpan_border_init(int if_id)
|
||||
{
|
||||
ipv6_addr_t addr;
|
||||
ipv6_net_if_addr_t *addr = NULL;
|
||||
uint8_t abr_addr_initialized = 0;
|
||||
|
||||
serial_reader_pid = thread_create(
|
||||
serial_reader_stack, READER_STACK_SIZE,
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
serial_reader_f, "serial_reader");
|
||||
ip_process_pid = thread_create(ip_process_buf, IP_PROCESS_STACKSIZE,
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
border_process_lowpan,
|
||||
"border_process_lowpan");
|
||||
|
||||
if (border_router_addr == NULL) {
|
||||
border_router_addr = &addr;
|
||||
|
||||
addr = flowcontrol_init();
|
||||
if (ip_process_pid < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* only allow addresses generated accoding to
|
||||
* RFC 4944 (Section 6) & RFC 2464 (Section 4) from short address
|
||||
* -- 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)
|
||||
) {
|
||||
return SIXLOWERROR_ADDRESS;
|
||||
if (!sixlowpan_lowpan_init_interface(if_id)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* radio-address is 8-bit so this must be tested extra */
|
||||
if (border_router_addr->uint8[14] != 0) {
|
||||
return SIXLOWERROR_ADDRESS;
|
||||
while (net_if_iter_addresses(if_id, (net_if_addr_t **) &addr)) {
|
||||
if (!ipv6_addr_is_multicast(addr->addr_data) &&
|
||||
!ipv6_addr_is_link_local(addr->addr_data) &&
|
||||
!ipv6_addr_is_loopback(addr->addr_data) &&
|
||||
!ipv6_addr_is_unique_local_unicast(addr->addr_data)) {
|
||||
abr_addr_initialized = 1;
|
||||
abr_addr = addr->addr_data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&(abr_addr.uint8[0]), &(border_router_addr->uint8[0]), 16);
|
||||
if (!abr_addr_initialized) {
|
||||
DEBUG("sixlowpan_lowpan_border_init(): A prefix must be initialized to"
|
||||
"interface %d first", if_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sixlowpan_lowpan_init(trans, border_router_addr->uint8[15], 1);
|
||||
ipv6_init_as_router();
|
||||
|
||||
ipv6_init_iface_as_router();
|
||||
|
||||
return SIXLOWERROR_SUCCESS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void border_process_lowpan(void)
|
@ -29,7 +29,7 @@
|
||||
#include "ip.h"
|
||||
#include "semaphore.h"
|
||||
|
||||
extern ipv6_addr_t abr_addr;
|
||||
extern ipv6_addr_t *abr_addr;
|
||||
|
||||
uint16_t border_get_serial_reader(void);
|
||||
|
@ -48,7 +48,7 @@ void demultiplex(border_packet_t *packet)
|
||||
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));
|
||||
ipv6_send_bytes(ipv6_buf);
|
||||
ipv6_send_packet(ipv6_buf);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ void demultiplex(border_packet_t *packet)
|
||||
context->context.lifetime
|
||||
);
|
||||
mutex_unlock(&lowpan_context_mutex);
|
||||
abr_add_context(context->context.version, &abr_addr, context->context.cid);
|
||||
abr_add_context(context->context.version, abr_addr, context->context.cid);
|
||||
/* Send router advertisement */
|
||||
break;
|
||||
}
|
||||
@ -141,7 +141,7 @@ int readpacket(uint8_t *packet_buf, size_t size)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((size_t) (line_buf_ptr - packet_buf) >= size - 1) {
|
||||
if ((size_t)(line_buf_ptr - packet_buf) >= size - 1) {
|
||||
return -SIXLOWERROR_ARRAYFULL;
|
||||
}
|
||||
|
||||
@ -179,8 +179,8 @@ int writepacket(uint8_t *packet_buf, size_t size)
|
||||
{
|
||||
uint8_t *byte_ptr = packet_buf;
|
||||
|
||||
while ((size_t) (byte_ptr - packet_buf) < size) {
|
||||
if ((size_t) (byte_ptr - packet_buf) > BORDER_BUFFER_SIZE) {
|
||||
while ((size_t)(byte_ptr - packet_buf) < size) {
|
||||
if ((size_t)(byte_ptr - packet_buf) > BORDER_BUFFER_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -42,7 +42,7 @@ enum option_types_t {
|
||||
OPT_DAC,
|
||||
};
|
||||
|
||||
extern unsigned int nd_nbr_cache_rem_pid;
|
||||
extern int nd_nbr_cache_rem_pid;
|
||||
|
||||
|
||||
void recv_echo_req(void);
|
||||
@ -53,12 +53,7 @@ void recv_nbr_adv(void);
|
||||
void recv_nbr_sol(void);
|
||||
|
||||
void nbr_cache_auto_rem(void);
|
||||
int 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*/
|
||||
|
@ -25,23 +25,26 @@
|
||||
#include "vtimer.h"
|
||||
#include "mutex.h"
|
||||
#include "msg.h"
|
||||
#include "net_help.h"
|
||||
#include "net_if.h"
|
||||
#include "sixlowpan/mac.h"
|
||||
|
||||
#include "ip.h"
|
||||
#include "icmp.h"
|
||||
#include "lowpan.h"
|
||||
|
||||
#include "destiny/socket.h"
|
||||
#include "net_help.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#if ENABLE_DEBUG
|
||||
#define DEBUG_ENABLED
|
||||
char addr_str[IPV6_MAX_ADDR_STR_LEN];
|
||||
#endif
|
||||
#include "debug.h"
|
||||
|
||||
#define IP_PKT_RECV_BUF_SIZE (64)
|
||||
#define LLHDR_IPV6HDR_LEN (LL_HDR_LEN + IPV6_HDR_LEN)
|
||||
#define IPV6_NET_IF_ADDR_BUFFER_LEN (NET_IF_MAX * IPV6_NET_IF_ADDR_LIST_LEN)
|
||||
|
||||
uint8_t ip_send_buffer[BUFFER_SIZE];
|
||||
uint8_t buffer[BUFFER_SIZE];
|
||||
@ -50,28 +53,79 @@ 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;
|
||||
ipv6_addr_t *(*ip_get_next_hop)(ipv6_addr_t*) = 0;
|
||||
ipv6_addr_t *(*ip_get_next_hop)(ipv6_addr_t *) = 0;
|
||||
|
||||
static ipv6_net_if_ext_t ipv6_net_if_ext[NET_IF_MAX];
|
||||
static ipv6_net_if_addr_t ipv6_net_if_addr_buffer[IPV6_NET_IF_ADDR_BUFFER_LEN];
|
||||
static ipv6_addr_t ipv6_addr_buffer[IPV6_NET_IF_ADDR_BUFFER_LEN];
|
||||
static uint8_t ipv6_net_if_addr_buffer_count = 0;
|
||||
|
||||
static uint8_t default_hop_limit = MULTIHOP_HOPLIMIT;
|
||||
|
||||
/* registered upper layer threads */
|
||||
int sixlowip_reg[SIXLOWIP_MAX_REGISTERED];
|
||||
|
||||
void ipv6_send_bytes(ipv6_hdr_t *bytes)
|
||||
int ipv6_send_packet(ipv6_hdr_t *packet)
|
||||
{
|
||||
uint16_t offset = IPV6_HDR_LEN + HTONS(bytes->length);
|
||||
uint16_t length = IPV6_HDR_LEN + NTOHS(packet->length);
|
||||
ndp_neighbor_cache_t *nce;
|
||||
|
||||
bytes->flowlabel = HTONS(bytes->flowlabel);
|
||||
bytes->length = HTONS(bytes->length);
|
||||
ipv6_net_if_get_best_src_addr(&packet->srcaddr, &packet->destaddr);
|
||||
|
||||
memset(bytes, 0, BUFFER_SIZE);
|
||||
memcpy(bytes + LL_HDR_LEN, bytes, offset);
|
||||
if (!ipv6_addr_is_multicast(&packet->destaddr) &&
|
||||
ndp_addr_is_on_link(&packet->destaddr)) {
|
||||
nce = ndp_get_ll_address(&packet->destaddr);
|
||||
|
||||
sixlowpan_lowpan_sendto((ieee_802154_long_t *) &bytes->destaddr.uint16[4],
|
||||
(uint8_t *)bytes,
|
||||
offset);
|
||||
|
||||
if (nce == NULL || sixlowpan_lowpan_sendto(nce->if_id, &nce->lladdr,
|
||||
nce->lladdr_len,
|
||||
(uint8_t *)packet,
|
||||
length) < 0) {
|
||||
/* XXX: this is wrong, but until ND does not work correctly,
|
||||
* this is the only way (aka the old way)*/
|
||||
uint16_t raddr = NTOHS(packet->destaddr.uint16[7]);
|
||||
sixlowpan_lowpan_sendto(0, &raddr, 2, (uint8_t *)packet, length);
|
||||
/* return -1; */
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
else {
|
||||
/* see if dest should be routed to a different next hop */
|
||||
if (ipv6_addr_is_multicast(&packet->destaddr)) {
|
||||
/* if_id will be ignored */
|
||||
uint16_t addr = 0xffff;
|
||||
return sixlowpan_lowpan_sendto(0, &addr, 2, (uint8_t *)packet,
|
||||
length);
|
||||
}
|
||||
|
||||
if (ip_get_next_hop == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ipv6_addr_t *dest = ip_get_next_hop(&packet->destaddr);
|
||||
|
||||
if (dest == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
nce = ndp_get_ll_address(&packet->destaddr);
|
||||
|
||||
if (nce == NULL || sixlowpan_lowpan_sendto(nce->if_id, &nce->lladdr,
|
||||
nce->lladdr_len,
|
||||
(uint8_t *)packet, length) < 0) {
|
||||
/* XXX: this is wrong, but until ND does not work correctly,
|
||||
* this is the only way (aka the old way)*/
|
||||
uint16_t raddr = NTOHS(packet->destaddr.uint16[7]);
|
||||
sixlowpan_lowpan_sendto(0, &raddr, 2, (uint8_t *)packet, length);
|
||||
/* return -1; */
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
ipv6_hdr_t *ipv6_get_buf_send(void)
|
||||
@ -100,10 +154,9 @@ uint8_t *get_payload_buf(uint8_t ext_len)
|
||||
}
|
||||
|
||||
int ipv6_sendto(const ipv6_addr_t *dest, uint8_t next_header,
|
||||
const uint8_t *payload, uint16_t payload_length)
|
||||
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);
|
||||
@ -119,31 +172,23 @@ int ipv6_sendto(const ipv6_addr_t *dest, uint8_t next_header,
|
||||
ipv6_buf->flowlabel = 0;
|
||||
ipv6_buf->nextheader = next_header;
|
||||
ipv6_buf->hoplimit = MULTIHOP_HOPLIMIT;
|
||||
ipv6_buf->length = payload_length;
|
||||
ipv6_buf->length = HTONS(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;
|
||||
return ipv6_send_packet(ipv6_buf);
|
||||
}
|
||||
|
||||
/* see if dest should be routed to a different next hop */
|
||||
if (ip_get_next_hop == NULL || ipv6_addr_is_multicast(&ipv6_buf->destaddr)) {
|
||||
dest = &ipv6_buf->destaddr;
|
||||
}
|
||||
else {
|
||||
dest = ip_get_next_hop(&ipv6_buf->destaddr);
|
||||
}
|
||||
void ipv6_set_default_hop_limit(uint8_t hop_limit)
|
||||
{
|
||||
default_hop_limit = hop_limit;
|
||||
}
|
||||
|
||||
if (dest == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
sixlowpan_lowpan_sendto((ieee_802154_long_t *) &dest->uint16[4],
|
||||
(uint8_t *)ipv6_buf, packet_length);
|
||||
|
||||
return payload_length;
|
||||
uint8_t ipv6_get_default_hop_limit(void)
|
||||
{
|
||||
return default_hop_limit;
|
||||
}
|
||||
|
||||
/* Register an upper layer thread */
|
||||
@ -261,19 +306,40 @@ uint8_t ipv6_get_addr_match(const ipv6_addr_t *src,
|
||||
return val;
|
||||
}
|
||||
|
||||
int is_our_address(ipv6_addr_t *addr)
|
||||
{
|
||||
ipv6_net_if_ext_t *net_if_ext;
|
||||
ipv6_net_if_addr_t *myaddr;
|
||||
uint8_t prefix, suffix;
|
||||
int if_id = -1;
|
||||
|
||||
while ((if_id = net_if_iter_interfaces(if_id)) >= 0) {
|
||||
net_if_ext = ipv6_net_if_get_ext(if_id);
|
||||
myaddr = NULL;
|
||||
prefix = net_if_ext->prefix / 8;
|
||||
suffix = IPV6_ADDR_LEN - prefix;
|
||||
|
||||
while ((myaddr = (ipv6_net_if_addr_t *)net_if_iter_addresses(if_id,
|
||||
(net_if_addr_t **) &myaddr)) != NULL) {
|
||||
if ((ipv6_get_addr_match(myaddr->addr_data, addr) >= net_if_ext->prefix) &&
|
||||
(memcmp(&addr->uint8[prefix], &myaddr->addr_data->uint8[prefix], suffix) == 0)) {
|
||||
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;
|
||||
uint8_t i;
|
||||
uint16_t packet_length;
|
||||
|
||||
msg_init_queue(ip_msg_queue, IP_PKT_RECV_BUF_SIZE);
|
||||
|
||||
ipv6_addr_init(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00,
|
||||
sixlowpan_mac_get_radio_address());
|
||||
|
||||
while (1) {
|
||||
msg_receive(&m_recv_lowpan);
|
||||
|
||||
@ -291,39 +357,18 @@ void ipv6_process(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* destination is foreign address */
|
||||
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;
|
||||
|
||||
ipv6_addr_t* dest;
|
||||
if (ip_get_next_hop == NULL) {
|
||||
dest = &ipv6_buf->destaddr;
|
||||
}
|
||||
else {
|
||||
dest = ip_get_next_hop(&ipv6_buf->destaddr);
|
||||
}
|
||||
|
||||
if (dest == NULL || --ipv6_buf->hoplimit == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* copy received packet to send buffer */
|
||||
memcpy(ipv6_get_buf_send(), ipv6_get_buf(), packet_length);
|
||||
/* send packet to node ID derived from dest IP */
|
||||
sixlowpan_lowpan_sendto((ieee_802154_long_t *) &dest->uint16[4],
|
||||
(uint8_t *)ipv6_get_buf_send(),
|
||||
packet_length);
|
||||
}
|
||||
/* destination is our address */
|
||||
else {
|
||||
if (is_our_address(&ipv6_buf->destaddr)) {
|
||||
switch (*nextheader) {
|
||||
case (IPV6_PROTO_NUM_ICMPV6): {
|
||||
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
|
||||
/* checksum test*/
|
||||
if (ipv6_csum(ipv6_buf, (uint8_t*) icmp_buf, ipv6_buf->length, IPV6_PROTO_NUM_ICMPV6) != 0xffff) {
|
||||
printf("ERROR: wrong checksum\n");
|
||||
if (ipv6_csum(ipv6_buf, (uint8_t *) icmp_buf, NTOHS(ipv6_buf->length),
|
||||
IPV6_PROTO_NUM_ICMPV6) != 0xffff) {
|
||||
DEBUG("ERROR: wrong checksum\n");
|
||||
}
|
||||
|
||||
icmpv6_demultiplex(icmp_buf);
|
||||
break;
|
||||
}
|
||||
@ -334,7 +379,7 @@ void ipv6_process(void)
|
||||
msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid);
|
||||
}
|
||||
else {
|
||||
printf("INFO: No TCP handler registered.\n");
|
||||
DEBUG("INFO: No TCP handler registered.\n");
|
||||
}
|
||||
|
||||
break;
|
||||
@ -346,14 +391,14 @@ void ipv6_process(void)
|
||||
msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid);
|
||||
}
|
||||
else {
|
||||
printf("INFO: No UDP handler registered.\n");
|
||||
DEBUG("INFO: No UDP handler registered.\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case (IPV6_PROTO_NUM_NONE): {
|
||||
printf("INFO: Packet with no Header following the IPv6 Header received.\n");
|
||||
DEBUG("INFO: Packet with no Header following the IPv6 Header received.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -361,97 +406,205 @@ void ipv6_process(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* destination is foreign address */
|
||||
else {
|
||||
packet_length = IPV6_HDR_LEN + NTOHS(ipv6_buf->length);
|
||||
ndp_neighbor_cache_t *nce;
|
||||
|
||||
ipv6_addr_t *dest;
|
||||
|
||||
if (ip_get_next_hop == NULL) {
|
||||
dest = &ipv6_buf->destaddr;
|
||||
}
|
||||
else {
|
||||
dest = ip_get_next_hop(&ipv6_buf->destaddr);
|
||||
}
|
||||
|
||||
if ((dest == NULL) || ((--ipv6_buf->hoplimit) == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nce = ndp_get_ll_address(dest);
|
||||
|
||||
/* copy received packet to send buffer */
|
||||
memcpy(ipv6_get_buf_send(), ipv6_get_buf(), packet_length);
|
||||
|
||||
/* send packet to node ID derived from dest IP */
|
||||
if (nce != NULL) {
|
||||
sixlowpan_lowpan_sendto(nce->if_id, &nce->lladdr,
|
||||
nce->lladdr_len,
|
||||
(uint8_t *)ipv6_get_buf_send(),
|
||||
packet_length);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
ipv6_net_if_ext_t *ipv6_net_if_get_ext(int if_id)
|
||||
{
|
||||
if (net_if_get_interface(if_id)) {
|
||||
return &ipv6_net_if_ext[if_id];
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int ipv6_net_if_add_addr(int if_id, const ipv6_addr_t *addr,
|
||||
ndp_addr_state_t state, uint32_t val_ltime,
|
||||
uint32_t pref_ltime, uint8_t is_anycast)
|
||||
{
|
||||
ipv6_net_if_addr_t *addr_entry;
|
||||
ipv6_net_if_hit_t hit;
|
||||
|
||||
if (ipv6_addr_is_unspecified(addr) == 128) {
|
||||
printf("ERROR: unspecified address (::) can't be assigned to interface.\n");
|
||||
return;
|
||||
DEBUG("ERROR: unspecified address (::) can't be assigned to interface.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ipv6_iface_addr_match(addr) != 0) {
|
||||
return;
|
||||
if (ipv6_addr_is_multicast(addr) && is_anycast) {
|
||||
DEBUG("ERROR: anycast addresses must not be multicast addresses "
|
||||
"(i.e. start with ff::/2)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
if (ipv6_net_if_addr_match(&hit, addr)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ipv6_net_if_addr_buffer_count < IPV6_NET_IF_ADDR_BUFFER_LEN) {
|
||||
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++;
|
||||
|
||||
ipv6_addr_t *addr_data = &ipv6_addr_buffer[ipv6_net_if_addr_buffer_count];
|
||||
memcpy(addr_data, addr, sizeof(ipv6_addr_t));
|
||||
|
||||
addr_entry = &ipv6_net_if_addr_buffer[ipv6_net_if_addr_buffer_count];
|
||||
addr_entry->addr_data = addr_data;
|
||||
addr_entry->addr_len = 128;
|
||||
|
||||
if (is_anycast) {
|
||||
addr_entry->addr_protocol = NET_IF_L3P_IPV6_ANYCAST;
|
||||
}
|
||||
else if (ipv6_addr_is_multicast(addr_data)) {
|
||||
addr_entry->addr_protocol = NET_IF_L3P_IPV6_MULTICAST;
|
||||
}
|
||||
else {
|
||||
addr_entry->addr_protocol = NET_IF_L3P_IPV6_UNICAST;
|
||||
}
|
||||
|
||||
addr_entry->ndp_state = state;
|
||||
addr_entry->valid_lifetime = timex_add(now, valtime);
|
||||
addr_entry->preferred_lifetime = timex_add(now, preftime);
|
||||
addr_entry->is_anycast = is_anycast;
|
||||
|
||||
ipv6_net_if_addr_buffer_count++;
|
||||
|
||||
net_if_add_address(if_id, (net_if_addr_t *)addr_entry);
|
||||
|
||||
/* 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) {
|
||||
if (is_anycast || !ipv6_addr_is_multicast(addr)) {
|
||||
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);
|
||||
if (ipv6_net_if_addr_match(&hit, &sol_node_mcast_addr) == NULL) {
|
||||
ipv6_net_if_add_addr(if_id, &sol_node_mcast_addr, state,
|
||||
val_ltime, pref_ltime, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ipv6_net_if_hit_t *ipv6_net_if_addr_match(ipv6_net_if_hit_t *hit,
|
||||
const ipv6_addr_t *addr)
|
||||
{
|
||||
int if_id = -1;
|
||||
ipv6_net_if_addr_t *addr_entry = NULL;
|
||||
|
||||
while ((if_id = net_if_iter_interfaces(if_id)) >= 0) {
|
||||
while (net_if_iter_addresses(if_id, (net_if_addr_t **) &addr_entry) != NULL) {
|
||||
if (addr_entry->addr_protocol & NET_IF_L3P_IPV6) {
|
||||
uint8_t byte_al = addr_entry->addr_len / 8;
|
||||
uint8_t mask[] = {0x00, 0x80, 0xc0, 0xe0,
|
||||
0xf0, 0xf8, 0xfc, 0xfe
|
||||
};
|
||||
|
||||
if (memcmp(addr_entry->addr_data, addr, byte_al) == 0 &&
|
||||
(addr_entry->addr_len % 8 == 0 ||
|
||||
((addr_entry->addr_data->uint8[byte_al] - addr->uint8[byte_al]) & mask[addr_entry->addr_len - (byte_al * 8)]))) {
|
||||
hit->if_id = if_id;
|
||||
hit->addr = addr_entry;
|
||||
return hit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
addr_list_t *ipv6_iface_addr_match(const ipv6_addr_t *addr)
|
||||
ipv6_net_if_hit_t *ipv6_net_if_addr_prefix_eq(ipv6_net_if_hit_t *hit,
|
||||
ipv6_addr_t *addr)
|
||||
{
|
||||
int i;
|
||||
int if_id = -1;
|
||||
ipv6_net_if_addr_t *addr_entry = NULL;
|
||||
|
||||
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]);
|
||||
while ((if_id = net_if_iter_interfaces(if_id)) >= 0) {
|
||||
while (net_if_iter_addresses(if_id, (net_if_addr_t **) &addr_entry) != NULL) {
|
||||
if (addr_entry->addr_protocol & NET_IF_L3P_IPV6) {
|
||||
if (memcmp(addr_entry->addr_data, &addr, 8) == 0) {
|
||||
hit->if_id = if_id;
|
||||
hit->addr = addr_entry;
|
||||
return hit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
/* TODO ipv6_net_if_hit_t returning function similar wrapping
|
||||
* ipv6_net_if_get_best_src_addr() to search on all interfaces */
|
||||
|
||||
ipv6_addr_t *ipv6_addr_set_by_eui64(ipv6_addr_t *out, int if_id,
|
||||
const ipv6_addr_t *prefix)
|
||||
{
|
||||
uint8_t force_generation = 0;
|
||||
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);
|
||||
if (net_if_get_src_address_mode(if_id) == NET_IF_TRANS_ADDR_M_SHORT) {
|
||||
force_generation = 1;
|
||||
}
|
||||
|
||||
if (net_if_get_eui64((net_if_eui64_t *) &out->uint8[8], if_id,
|
||||
force_generation)) {
|
||||
#ifdef MODULE_SIXLOWPAN
|
||||
|
||||
if (!sixlowpan_lowpan_eui64_to_short_addr((net_if_eui64_t *)&out->uint8[8])) {
|
||||
out->uint8[8] ^= 0x02;
|
||||
}
|
||||
|
||||
#else
|
||||
out->uint8[8] ^= 0x02;
|
||||
#endif
|
||||
return out;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix,
|
||||
@ -476,96 +629,51 @@ void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix,
|
||||
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)
|
||||
void ipv6_net_if_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;
|
||||
int if_id = 0; // TODO: get this somehow
|
||||
uint8_t tmp = 0;
|
||||
uint8_t bmatch = 0;
|
||||
ipv6_net_if_addr_t *addr = NULL;
|
||||
ipv6_net_if_addr_t *tmp_addr = NULL;
|
||||
|
||||
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));
|
||||
while ((addr = (ipv6_net_if_addr_t *)net_if_iter_addresses(if_id,
|
||||
(net_if_addr_t **)&addr))) {
|
||||
if (addr->ndp_state == NDP_ADDR_STATE_PREFERRED) {
|
||||
if (!ipv6_addr_is_link_local(addr->addr_data) &&
|
||||
!ipv6_addr_is_multicast(addr->addr_data) &&
|
||||
!ipv6_addr_is_unique_local_unicast(addr->addr_data)) {
|
||||
tmp = ipv6_get_addr_match(dest, addr->addr_data);
|
||||
|
||||
if (tmp >= bmatch) {
|
||||
bmatch = tmp;
|
||||
itmp = i;
|
||||
tmp_addr = addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
while ((addr = (ipv6_net_if_addr_t *)net_if_iter_addresses(if_id,
|
||||
(net_if_addr_t **)&addr))) {
|
||||
if (addr->ndp_state == NDP_ADDR_STATE_PREFERRED &&
|
||||
ipv6_addr_is_link_local(addr->addr_data) &&
|
||||
!ipv6_addr_is_multicast(addr->addr_data)) {
|
||||
tmp_addr = addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itmp == -1) {
|
||||
if (tmp_addr == NULL) {
|
||||
memset(src, 0, 16);
|
||||
}
|
||||
else {
|
||||
memcpy(src, &(iface.addr_list[itmp].addr), 16);
|
||||
memcpy(src, tmp_addr->addr_data, 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)
|
||||
@ -580,66 +688,6 @@ void ipv6_addr_init(ipv6_addr_t *out, uint16_t addr0, uint16_t addr1,
|
||||
out->uint16[7] = HTONS(addr7);
|
||||
}
|
||||
|
||||
int ipv6_addr_is_link_local(const ipv6_addr_t *addr)
|
||||
{
|
||||
return (addr->uint16[0] == HTONS(0xfe80));
|
||||
}
|
||||
|
||||
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",
|
||||
NTOHS(ipv6_addr->uint16[0]), NTOHS(ipv6_addr->uint16[1]),
|
||||
NTOHS(ipv6_addr->uint16[2]), NTOHS(ipv6_addr->uint16[3]),
|
||||
NTOHS(ipv6_addr->uint16[4]), NTOHS(ipv6_addr->uint16[5]),
|
||||
NTOHS(ipv6_addr->uint16[6]), NTOHS(ipv6_addr->uint16[7]));
|
||||
return addr_str;
|
||||
}
|
||||
|
||||
uint32_t get_remaining_time(timex_t *t)
|
||||
{
|
||||
timex_t now;
|
||||
@ -657,22 +705,32 @@ void set_remaining_time(timex_t *t, uint32_t time)
|
||||
*t = timex_add(now, tmp);
|
||||
}
|
||||
|
||||
void ipv6_init_iface_as_router(void)
|
||||
int ipv6_init_as_router(void)
|
||||
{
|
||||
ipv6_addr_t addr;
|
||||
int if_id = -1;
|
||||
|
||||
ipv6_addr_set_all_routers_addr(&addr);
|
||||
ipv6_iface_add_addr(&addr, NDP_ADDR_STATE_PREFERRED, 0, 0, IPV6_ADDR_TYPE_MULTICAST);
|
||||
|
||||
while ((if_id = net_if_iter_interfaces(if_id)) >= 0) {
|
||||
if (!ipv6_net_if_add_addr(if_id, &addr, NDP_ADDR_STATE_PREFERRED, 0, 0,
|
||||
0)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint8_t ipv6_is_router(void)
|
||||
{
|
||||
ipv6_addr_t addr;
|
||||
ipv6_net_if_hit_t hit;
|
||||
|
||||
ipv6_addr_set_all_routers_addr(&addr);
|
||||
|
||||
if (ipv6_iface_addr_match(&addr) != NULL) {
|
||||
if (ipv6_net_if_addr_match(&hit, &addr) != NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -695,9 +753,11 @@ void ipv6_register_next_header_handler(uint8_t next_header, int pid)
|
||||
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;
|
||||
@ -705,7 +765,8 @@ void ipv6_register_next_header_handler(uint8_t next_header, int pid)
|
||||
}
|
||||
|
||||
/* register routing function */
|
||||
void ipv6_iface_set_routing_provider(ipv6_addr_t *(*next_hop)(ipv6_addr_t* dest)) {
|
||||
void ipv6_iface_set_routing_provider(ipv6_addr_t *(*next_hop)(ipv6_addr_t *dest))
|
||||
{
|
||||
ip_get_next_hop = next_hop;
|
||||
}
|
||||
|
||||
@ -718,9 +779,11 @@ uint16_t ipv6_csum(ipv6_hdr_t *ipv6_header, uint8_t *buf, uint16_t len, uint8_t
|
||||
{
|
||||
uint16_t sum = 0;
|
||||
DEBUG("Calculate checksum over src: %s, dst: %s, len: %04X, buf: %p, proto: %u\n",
|
||||
ipv6_addr_to_str(addr_str, &ipv6_header->srcaddr),
|
||||
ipv6_addr_to_str(addr_str, &ipv6_header->destaddr),
|
||||
len, buf, proto);
|
||||
ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
&ipv6_header->srcaddr),
|
||||
ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
&ipv6_header->destaddr),
|
||||
len, buf, proto);
|
||||
sum = len + proto;
|
||||
sum = csum(sum, (uint8_t *)&ipv6_header->srcaddr, 2 * sizeof(ipv6_addr_t));
|
||||
sum = csum(sum, buf, len);
|
||||
|
@ -25,8 +25,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "kernel.h"
|
||||
#include "timex.h"
|
||||
#include "mutex.h"
|
||||
#include "net_if.h"
|
||||
|
||||
#include "sixlowpan/ip.h"
|
||||
#include "sixlowpan/types.h"
|
||||
@ -39,52 +41,61 @@
|
||||
#define MULTIHOP_HOPLIMIT (64)
|
||||
|
||||
#define SIXLOWIP_MAX_REGISTERED (4)
|
||||
#define IP_PROCESS_STACKSIZE (KERNEL_CONF_STACKSIZE_MAIN)
|
||||
|
||||
/* extern variables */
|
||||
extern uint8_t ipv6_ext_hdr_len;
|
||||
extern int ip_process_pid;
|
||||
|
||||
/* 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
|
||||
#define IPV6_NET_IF_ADDR_LIST_LEN (10) // maybe to much
|
||||
|
||||
/* buffer */
|
||||
extern uint8_t buffer[BUFFER_SIZE];
|
||||
extern char ip_process_buf[IP_PROCESS_STACKSIZE];
|
||||
|
||||
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;
|
||||
struct net_if_addr_t *addr_next;
|
||||
struct net_if_addr_t *addr_prev;
|
||||
net_if_l3p_t addr_protocol;
|
||||
ipv6_addr_t *addr_data;
|
||||
uint8_t addr_len;
|
||||
ndp_addr_state_t ndp_state;
|
||||
timex_t valid_lifetime;
|
||||
timex_t preferred_lifetime;
|
||||
uint8_t is_anycast;
|
||||
} ipv6_net_if_addr_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
ieee_802154_short_t saddr;
|
||||
ieee_802154_long_t laddr;
|
||||
addr_list_t addr_list[IFACE_ADDR_LIST_LEN];
|
||||
ipv6_net_if_addr_t *addr;
|
||||
int if_id;
|
||||
} ipv6_net_if_hit_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t prefix; ///< prefix length of the sub-net
|
||||
uint8_t adv_cur_hop_limit;
|
||||
uint32_t adv_reachable_time;
|
||||
uint32_t adv_retrans_timer;
|
||||
} iface_t;
|
||||
|
||||
extern iface_t iface;
|
||||
} ipv6_net_if_ext_t;
|
||||
|
||||
/* function prototypes */
|
||||
void ipv6_send_bytes(ipv6_hdr_t *bytes);
|
||||
ipv6_net_if_ext_t *ipv6_net_if_get_ext(int if_id);
|
||||
|
||||
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);
|
||||
int ipv6_init_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);
|
||||
ipv6_net_if_hit_t *ipv6_net_if_addr_prefix_eq(ipv6_net_if_hit_t *hit, ipv6_addr_t *addr);
|
||||
ipv6_net_if_hit_t *ipv6_net_if_addr_match(ipv6_net_if_hit_t *hit, const ipv6_addr_t *addr);
|
||||
uint32_t get_remaining_time(timex_t *t);
|
||||
void set_remaining_time(timex_t *t, uint32_t time);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,10 +25,13 @@
|
||||
#define _SIXLOWPAN_LOWPAN_H
|
||||
|
||||
#include "mutex.h"
|
||||
#include "net_if.h"
|
||||
#include "vtimer.h"
|
||||
|
||||
#include "sixlowpan/lowpan.h"
|
||||
|
||||
#define IEEE802154_TRANSCEIVER (TRANSCEIVER_AT86RF231 | TRANSCEIVER_CC2420 | TRANSCEIVER_MC1322X)
|
||||
|
||||
typedef struct {
|
||||
uint8_t num;
|
||||
ipv6_addr_t prefix;
|
||||
@ -40,9 +43,8 @@ typedef struct {
|
||||
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);
|
||||
void lowpan_read(uint8_t *data, uint8_t length, net_if_eui64_t *s_addr,
|
||||
net_if_eui64_t *d_addr);
|
||||
uint8_t lowpan_context_len(void);
|
||||
lowpan_context_t *lowpan_context_update(uint8_t num,
|
||||
const ipv6_addr_t *prefix,
|
||||
|
@ -24,13 +24,10 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ltc4150.h"
|
||||
#include "hwtimer.h"
|
||||
#include "thread.h"
|
||||
#include "msg.h"
|
||||
#include "radio/radio.h"
|
||||
#include "transceiver.h"
|
||||
#include "vtimer.h"
|
||||
#include "net_if.h"
|
||||
#include "sixlowpan/mac.h"
|
||||
|
||||
#include "ip.h"
|
||||
@ -49,109 +46,36 @@
|
||||
#define RADIO_RCV_BUF_SIZE (64)
|
||||
#define RADIO_SENDING_DELAY (1000)
|
||||
|
||||
#define DEFAULT_IEEE_802154_PAN_ID (0x1234)
|
||||
|
||||
char radio_stack_buffer[RADIO_STACK_SIZE];
|
||||
msg_t msg_q[RADIO_RCV_BUF_SIZE];
|
||||
|
||||
static uint8_t r_src_addr;
|
||||
uint8_t buf[PAYLOAD_SIZE];
|
||||
uint8_t lowpan_mac_buf[PAYLOAD_SIZE];
|
||||
static uint8_t macdsn;
|
||||
|
||||
static radio_packet_t p;
|
||||
static msg_t mesg;
|
||||
int transceiver_type;
|
||||
static transceiver_command_t tcmd;
|
||||
|
||||
uint8_t sixlowpan_mac_get_radio_address(void)
|
||||
static inline void mac_short_to_eui64(net_if_eui64_t *eui64,
|
||||
uint16_t short_addr)
|
||||
{
|
||||
int16_t address;
|
||||
DEBUG("sixlowpan_mac_get_radio_address()\n");
|
||||
|
||||
tcmd.transceivers = transceiver_type;
|
||||
tcmd.data = &address;
|
||||
mesg.content.ptr = (char *)&tcmd;
|
||||
mesg.type = GET_ADDRESS;
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
|
||||
return (uint8_t)address;
|
||||
}
|
||||
|
||||
void sixlowpan_mac_set_radio_address(uint8_t addr)
|
||||
{
|
||||
int16_t address = (int16_t)addr;
|
||||
|
||||
tcmd.transceivers = transceiver_type;
|
||||
tcmd.data = &address;
|
||||
mesg.content.ptr = (char *)&tcmd;
|
||||
mesg.type = SET_ADDRESS;
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
}
|
||||
|
||||
void set_radio_channel(uint8_t channel)
|
||||
{
|
||||
int16_t chan = (int16_t)channel;
|
||||
|
||||
tcmd.transceivers = transceiver_type;
|
||||
tcmd.data = &chan;
|
||||
mesg.content.ptr = (char *)&tcmd;
|
||||
mesg.type = SET_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 sixlowpan_mac_init_802154_short_addr(ieee_802154_short_t *saddr)
|
||||
{
|
||||
DEBUG("sixlowpan_mac_init_802154_short_addr(saddr=%02X)\n", *saddr);
|
||||
saddr->uint8[0] = 0;
|
||||
saddr->uint8[1] = sixlowpan_mac_get_radio_address();
|
||||
}
|
||||
|
||||
ieee_802154_long_t *sixlowpan_mac_get_eui64(const ipv6_addr_t *ipaddr)
|
||||
{
|
||||
return ((ieee_802154_long_t *) &ipaddr->uint8[8]);
|
||||
}
|
||||
|
||||
void sixlowpan_mac_init_802154_long_addr(ieee_802154_long_t *laddr)
|
||||
{
|
||||
#ifdef DEBUG_ENABLED
|
||||
char addr_str[IEEE_802154_MAX_ADDR_STR_LEN];
|
||||
sixlowpan_mac_802154_long_addr_to_str(addr_str, laddr);
|
||||
DEBUG("sixlowpan_mac_init_802154_long_addr(laddr=%s)\n", addr_str);
|
||||
#endif
|
||||
|
||||
// 16bit Pan-ID:16-zero-bits:16-bit-short-addr = 48bit
|
||||
laddr->uint16[0] = IEEE_802154_PAN_ID;
|
||||
|
||||
/* RFC 4944 Section 6 / RFC 2464 Section 4 */
|
||||
laddr->uint8[0] ^= 0x02;
|
||||
laddr->uint8[2] = 0;
|
||||
laddr->uint8[3] = 0xFF;
|
||||
laddr->uint8[4] = 0xFE;
|
||||
laddr->uint8[5] = 0;
|
||||
laddr->uint8[6] = 0;
|
||||
laddr->uint8[7] = sixlowpan_mac_get_radio_address();
|
||||
}
|
||||
|
||||
char *sixlowpan_mac_802154_long_addr_to_str(char *addr_str, const ieee_802154_long_t *laddr) {
|
||||
sprintf(addr_str,
|
||||
"%02x:%02x:%02x:%02x",
|
||||
laddr->uint16[0], laddr->uint16[1],
|
||||
laddr->uint16[2], laddr->uint16[3]);
|
||||
return addr_str;
|
||||
eui64->uint32[0] = HTONL(0x000000ff);
|
||||
eui64->uint16[2] = HTONS(0xfe00);
|
||||
eui64->uint16[3] = LETONS(short_addr);
|
||||
}
|
||||
|
||||
void recv_ieee802154_frame(void)
|
||||
{
|
||||
msg_t m;
|
||||
#if (defined(MODULE_AT86RF231) | \
|
||||
defined(MODULE_CC2420) | \
|
||||
defined(MODULE_MC1322X))
|
||||
ieee802154_packet_t *p;
|
||||
#else
|
||||
radio_packet_t *p;
|
||||
uint8_t hdrlen, length;
|
||||
uint8_t hdrlen;
|
||||
#endif
|
||||
uint8_t length;
|
||||
ieee802154_frame_t frame;
|
||||
net_if_eui64_t src, dst;
|
||||
|
||||
msg_init_queue(msg_q, RADIO_RCV_BUF_SIZE);
|
||||
|
||||
@ -159,22 +83,84 @@ void recv_ieee802154_frame(void)
|
||||
msg_receive(&m);
|
||||
|
||||
if (m.type == PKT_PENDING) {
|
||||
|
||||
#if (defined(MODULE_AT86RF231) | \
|
||||
defined(MODULE_CC2420) | \
|
||||
defined(MODULE_MC1322X))
|
||||
p = (ieee802154_packet_t *) m.content.ptr;
|
||||
memcpy(&frame, &p->frame, sizeof(ieee802154_frame_t));
|
||||
length = p->frame.payload_len;
|
||||
#else
|
||||
p = (radio_packet_t *) m.content.ptr;
|
||||
hdrlen = ieee802154_frame_read(p->data, &frame, p->length);
|
||||
length = p->length - hdrlen - IEEE_802154_FCS_LEN;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
DEBUG("INFO: Received IEEE 802.15.4. packet (length = %d):\n", length);
|
||||
DEBUG("INFO: FCF:\n");
|
||||
ieee802154_frame_print_fcf_frame(&frame);
|
||||
|
||||
DEBUG("Sender:");
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
printf("%02x ", frame.src_addr[i]);
|
||||
}
|
||||
|
||||
DEBUG("\n");
|
||||
|
||||
DEBUG("Receiver:");
|
||||
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
printf("%02x ", frame.dest_addr[i]);
|
||||
}
|
||||
|
||||
DEBUG("\n");
|
||||
|
||||
DEBUG("Payload:\n");
|
||||
|
||||
for (uint8_t i = 0; i < frame.payload_len; i++) {
|
||||
printf("%02x ", frame.payload[i]);
|
||||
|
||||
if (!((i + 1) % 16) || i == frame.payload_len - 1) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (frame.fcf.src_addr_m == IEEE_802154_SHORT_ADDR_M) {
|
||||
mac_short_to_eui64(&src, *((uint16_t *)frame.src_addr));
|
||||
}
|
||||
else if (frame.fcf.src_addr_m == IEEE_802154_LONG_ADDR_M) {
|
||||
memcpy(&src, frame.src_addr, 8);
|
||||
}
|
||||
else {
|
||||
DEBUG("Unknown IEEE 802.15.4 source address mode.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (frame.fcf.dest_addr_m == IEEE_802154_SHORT_ADDR_M) {
|
||||
mac_short_to_eui64(&dst, *((uint16_t *)frame.dest_addr));
|
||||
}
|
||||
else if (frame.fcf.dest_addr_m == IEEE_802154_LONG_ADDR_M) {
|
||||
memcpy(&dst, frame.dest_addr, 8);
|
||||
}
|
||||
else {
|
||||
DEBUG("Unknown IEEE 802.15.4 destination address mode.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* deliver packet to network(6lowpan)-layer */
|
||||
lowpan_read(frame.payload, length, (ieee_802154_long_t *)&frame.src_addr,
|
||||
(ieee_802154_long_t *)&frame.dest_addr);
|
||||
lowpan_read(frame.payload, length, &src, &dst);
|
||||
/* TODO: get interface ID somehow */
|
||||
|
||||
p->processing--;
|
||||
}
|
||||
else if (m.type == ENOBUFFER) {
|
||||
puts("Transceiver buffer full");
|
||||
DEBUG("Transceiver buffer full");
|
||||
}
|
||||
else {
|
||||
puts("Unknown packet received");
|
||||
DEBUG("Unknown packet received");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -186,86 +172,158 @@ void set_ieee802154_fcf_values(ieee802154_frame_t *frame, uint8_t dest_mode,
|
||||
frame->fcf.sec_enb = 0;
|
||||
frame->fcf.frame_pend = 0;
|
||||
frame->fcf.ack_req = 0;
|
||||
frame->fcf.panid_comp = 0;
|
||||
frame->fcf.panid_comp = (frame->dest_pan_id == frame->src_pan_id);
|
||||
frame->fcf.frame_ver = 0;
|
||||
frame->fcf.src_addr_m = src_mode;
|
||||
frame->fcf.dest_addr_m = dest_mode;
|
||||
#if ENABLE_DEBUG
|
||||
#ifdef DEBUG_ENABLED
|
||||
ieee802154_frame_print_fcf_frame(frame);
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_ieee802154_frame_values(ieee802154_frame_t *frame)
|
||||
void set_ieee802154_frame_values(int if_id, uint16_t dest_pan,
|
||||
ieee802154_frame_t *frame)
|
||||
{
|
||||
int32_t pan_id = net_if_get_pan_id(if_id);
|
||||
// TODO: addresse aus ip paket auslesen und in frame einfuegen
|
||||
frame->dest_pan_id = IEEE_802154_PAN_ID;
|
||||
frame->src_pan_id = IEEE_802154_PAN_ID;
|
||||
|
||||
if (pan_id < 0) {
|
||||
frame->dest_pan_id = NTOLES(dest_pan);
|
||||
frame->src_pan_id = HTOLES(DEFAULT_IEEE_802154_PAN_ID);
|
||||
}
|
||||
else {
|
||||
frame->dest_pan_id = NTOLES(dest_pan);
|
||||
frame->src_pan_id = HTOLES((uint16_t)pan_id);
|
||||
}
|
||||
|
||||
frame->seq_nr = macdsn;
|
||||
macdsn++;
|
||||
}
|
||||
|
||||
void sixlowpan_mac_send_ieee802154_frame(const ieee_802154_long_t *addr,
|
||||
const uint8_t *payload,
|
||||
uint8_t length, uint8_t mcast)
|
||||
int sixlowpan_mac_prepare_ieee802144_frame(
|
||||
ieee802154_frame_t *frame, int if_id, uint16_t dest_pan, const void *dest,
|
||||
uint8_t dest_len, const void *payload, uint8_t length, uint8_t mcast)
|
||||
{
|
||||
uint16_t daddr;
|
||||
/* TODO: check if dedicated response struct is necessary */
|
||||
msg_t transceiver_rsp;
|
||||
r_src_addr = local_address;
|
||||
mesg.type = SND_PKT;
|
||||
mesg.content.ptr = (char *) &tcmd;
|
||||
uint8_t src_mode = net_if_get_src_address_mode(if_id);
|
||||
uint8_t dest_mode;
|
||||
uint16_t *fcs;
|
||||
set_ieee802154_frame_values(if_id, dest_pan, frame);
|
||||
|
||||
tcmd.transceivers = transceiver_type;
|
||||
tcmd.data = &p;
|
||||
|
||||
ieee802154_frame_t frame;
|
||||
|
||||
memset(&frame, 0, sizeof(frame));
|
||||
set_ieee802154_fcf_values(&frame, IEEE_802154_LONG_ADDR_M,
|
||||
IEEE_802154_LONG_ADDR_M);
|
||||
set_ieee802154_frame_values(&frame);
|
||||
|
||||
memcpy(&(frame.dest_addr[0]), &(addr->uint8[0]), 8);
|
||||
memcpy(&(frame.src_addr[0]), &(iface.laddr.uint8[0]), 8);
|
||||
|
||||
daddr = HTONS(addr->uint16[3]);
|
||||
frame.payload = (uint8_t *)payload; // payload won't be changed so cast is legal.
|
||||
frame.payload_len = length;
|
||||
uint8_t hdrlen = ieee802154_frame_get_hdr_len(&frame);
|
||||
|
||||
memset(&buf, 0, PAYLOAD_SIZE);
|
||||
ieee802154_frame_init(&frame, (uint8_t *)&buf);
|
||||
memcpy(&buf[hdrlen], frame.payload, frame.payload_len);
|
||||
/* set FCS */
|
||||
/* RSSI = 0 */
|
||||
buf[frame.payload_len+hdrlen] = 0;
|
||||
/* FCS Valid = 1 / LQI Correlation Value = 0 */
|
||||
buf[frame.payload_len+hdrlen+1] = 0x80;
|
||||
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);
|
||||
|
||||
p.length = hdrlen + frame.payload_len + IEEE_802154_FCS_LEN;
|
||||
|
||||
if (mcast == 0) {
|
||||
p.dst = daddr;
|
||||
if (dest_len == 8) {
|
||||
dest_mode = IEEE_802154_LONG_ADDR_M;
|
||||
}
|
||||
else if (dest_len == 2) {
|
||||
dest_mode = IEEE_802154_SHORT_ADDR_M;
|
||||
}
|
||||
else {
|
||||
p.dst = 0;
|
||||
DEBUG("Illegal IEEE 802.15.4 address for address length %d\n", dest_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p.data = buf;
|
||||
msg_send_receive(&mesg, &transceiver_rsp, transceiver_pid);
|
||||
set_ieee802154_fcf_values(frame, dest_mode, src_mode);
|
||||
|
||||
hwtimer_wait(5000);
|
||||
|
||||
if (src_mode == IEEE_802154_LONG_ADDR_M) {
|
||||
net_if_get_eui64((net_if_eui64_t *)&frame->src_addr[0], if_id, 0);
|
||||
}
|
||||
else if (src_mode == IEEE_802154_SHORT_ADDR_M) {
|
||||
uint16_t src = HTONS(net_if_get_hardware_address(if_id));
|
||||
memcpy(&frame->src_addr[0], &src, 2);
|
||||
}
|
||||
else {
|
||||
DEBUG("Illegal IEEE 802.15.4 address mode: %d\n", src_mode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mcast) {
|
||||
memset(&frame->dest_addr[0], 0xff, dest_len);
|
||||
}
|
||||
else {
|
||||
memcpy(&frame->dest_addr[0], dest, dest_len);
|
||||
}
|
||||
|
||||
frame->payload = (uint8_t *)payload; // payload won't be changed so cast is legal.
|
||||
frame->payload_len = length;
|
||||
uint8_t hdrlen = ieee802154_frame_get_hdr_len(frame);
|
||||
|
||||
memset(&lowpan_mac_buf, 0, PAYLOAD_SIZE);
|
||||
ieee802154_frame_init(frame, (uint8_t *)&lowpan_mac_buf);
|
||||
memcpy(&lowpan_mac_buf[hdrlen], frame->payload, frame->payload_len);
|
||||
/* set FCS */
|
||||
fcs = (uint16_t *)&lowpan_mac_buf[frame->payload_len + hdrlen];
|
||||
*fcs = ieee802154_frame_get_fcs(lowpan_mac_buf, frame->payload_len + hdrlen);
|
||||
DEBUG("IEEE802.15.4 frame - FCF: %02X %02X DPID: %02X SPID: %02X DSN: %02X\n",
|
||||
lowpan_mac_buf[0], lowpan_mac_buf[1], frame->dest_pan_id,
|
||||
frame->src_pan_id, frame->seq_nr);
|
||||
|
||||
return hdrlen;
|
||||
}
|
||||
|
||||
void sixlowpan_mac_init(transceiver_type_t type)
|
||||
int sixlowpan_mac_send_data(int if_id,
|
||||
const void *dest, uint8_t dest_len,
|
||||
const void *payload,
|
||||
uint8_t payload_len, uint8_t mcast)
|
||||
{
|
||||
if (mcast) {
|
||||
return net_if_send_packet_broadcast(IEEE_802154_SHORT_ADDR_M,
|
||||
payload,
|
||||
payload_len);
|
||||
}
|
||||
else {
|
||||
if (dest_len == 8) {
|
||||
return net_if_send_packet_long(if_id, (net_if_eui64_t *) dest,
|
||||
payload, (size_t)payload_len);
|
||||
}
|
||||
else if (dest_len == 2) {
|
||||
return net_if_send_packet(if_id, NTOHS(*((uint16_t *)dest)),
|
||||
payload, (size_t)payload_len);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sixlowpan_mac_send_ieee802154_frame(int if_id,
|
||||
const void *dest, uint8_t dest_len,
|
||||
const void *payload,
|
||||
uint8_t payload_len, uint8_t mcast)
|
||||
{
|
||||
if (net_if_get_interface(if_id) &&
|
||||
net_if_get_interface(if_id)->transceivers & IEEE802154_TRANSCEIVER) {
|
||||
return sixlowpan_mac_send_data(if_id, dest, dest_len, payload,
|
||||
payload_len, mcast);
|
||||
}
|
||||
else {
|
||||
ieee802154_frame_t frame;
|
||||
uint16_t dest_pan = HTONS(0xabcd);
|
||||
uint8_t length;
|
||||
int hdrlen = sixlowpan_mac_prepare_ieee802144_frame(&frame, if_id,
|
||||
dest_pan, dest,
|
||||
dest_len, payload,
|
||||
payload_len, mcast);
|
||||
|
||||
if (hdrlen < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
length = hdrlen + frame.payload_len + IEEE_802154_FCS_LEN;
|
||||
|
||||
return sixlowpan_mac_send_data(if_id, dest, dest_len, lowpan_mac_buf,
|
||||
length, mcast);
|
||||
}
|
||||
}
|
||||
|
||||
int sixlowpan_mac_init(void)
|
||||
{
|
||||
int recv_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE,
|
||||
PRIORITY_MAIN - 2, CREATE_STACKTEST, recv_ieee802154_frame , "radio");
|
||||
transceiver_type = type;
|
||||
transceiver_init(transceiver_type);
|
||||
transceiver_start();
|
||||
transceiver_register(type, recv_pid);
|
||||
int if_id = -1;
|
||||
|
||||
while ((if_id = net_if_iter_interfaces(if_id)) >= 0) {
|
||||
net_if_register(if_id, recv_pid);
|
||||
}
|
||||
|
||||
macdsn = rand() % 256;
|
||||
|
||||
return recv_pid;
|
||||
}
|
||||
|
@ -169,14 +169,6 @@ void etx_beacon(void)
|
||||
etx_probe_t *packet = etx_get_send_buf();
|
||||
uint8_t p_length = 0;
|
||||
|
||||
/*
|
||||
* xxx If you get a -Wmissing-braces warning here:
|
||||
* A -Wmissing-braces warning at this point is a gcc-bug!
|
||||
* Please delete this information once it's fixed
|
||||
* See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
|
||||
*/
|
||||
ieee_802154_long_t empty_addr = { {0} };
|
||||
|
||||
while (true) {
|
||||
thread_sleep();
|
||||
mutex_lock(&etx_mutex);
|
||||
@ -194,8 +186,11 @@ void etx_beacon(void)
|
||||
}
|
||||
|
||||
packet->length = p_length;
|
||||
sixlowpan_mac_send_ieee802154_frame(&empty_addr, &etx_send_buf[0],
|
||||
ETX_DATA_MAXLEN + ETX_PKT_HDR_LEN, 1);
|
||||
/* will be send broadcast, so if_id and destination address will be
|
||||
* ignored (see documentation)
|
||||
*/
|
||||
sixlowpan_mac_send_ieee802154_frame(0, NULL, 8, &etx_send_buf[0],
|
||||
ETX_DATA_MAXLEN + ETX_PKT_HDR_LEN, 1);
|
||||
DEBUG("sent beacon!\n");
|
||||
etx_set_packets_received();
|
||||
cur_round++;
|
||||
@ -394,7 +389,7 @@ void etx_radio(void)
|
||||
ipv6_addr_t candidate_addr;
|
||||
|
||||
ipv6_addr_set_link_local_prefix(&ll_address);
|
||||
ipv6_iface_get_best_src_addr(&candidate_addr, &ll_address);
|
||||
ipv6_net_if_get_best_src_addr(&candidate_addr, &ll_address);
|
||||
|
||||
while (1) {
|
||||
msg_receive(&m);
|
||||
@ -457,7 +452,7 @@ 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 {
|
||||
|
@ -88,23 +88,28 @@ static uint8_t *get_rpl_send_payload_buf(uint8_t ext_len)
|
||||
return &(rpl_send_buffer[IPV6_HDR_LEN + ext_len]);
|
||||
}
|
||||
|
||||
static icmpv6_hdr_t *get_rpl_send_icmpv6_buf(uint8_t ext_len) {
|
||||
static icmpv6_hdr_t *get_rpl_send_icmpv6_buf(uint8_t ext_len)
|
||||
{
|
||||
return ((icmpv6_hdr_t *) &(rpl_send_buffer[IPV6_HDR_LEN + ext_len]));
|
||||
}
|
||||
|
||||
static struct rpl_dio_t *get_rpl_send_dio_buf(void) {
|
||||
static struct rpl_dio_t *get_rpl_send_dio_buf(void)
|
||||
{
|
||||
return ((struct rpl_dio_t *) &(rpl_send_buffer[IPV6_HDR_LEN + ICMPV6_HDR_LEN]));
|
||||
}
|
||||
|
||||
static struct rpl_dao_t *get_rpl_send_dao_buf(void) {
|
||||
static struct rpl_dao_t *get_rpl_send_dao_buf(void)
|
||||
{
|
||||
return ((struct rpl_dao_t *) &(rpl_send_buffer[IPV6_HDR_LEN + ICMPV6_HDR_LEN]));
|
||||
}
|
||||
|
||||
static struct rpl_dao_ack_t *get_rpl_send_dao_ack_buf(void) {
|
||||
static struct rpl_dao_ack_t *get_rpl_send_dao_ack_buf(void)
|
||||
{
|
||||
return ((struct rpl_dao_ack_t *) &(rpl_send_buffer[IPV6_HDR_LEN + ICMPV6_HDR_LEN]));
|
||||
}
|
||||
|
||||
static struct rpl_dis_t *get_rpl_send_dis_buf(void) {
|
||||
static struct rpl_dis_t *get_rpl_send_dis_buf(void)
|
||||
{
|
||||
return ((struct rpl_dis_t *) &(rpl_send_buffer[IPV6_HDR_LEN + ICMPV6_HDR_LEN]));
|
||||
}
|
||||
|
||||
@ -129,20 +134,24 @@ static ipv6_hdr_t *get_rpl_ipv6_buf(void)
|
||||
return ((ipv6_hdr_t *) &(rpl_buffer[0]));
|
||||
}
|
||||
|
||||
static struct rpl_dio_t *get_rpl_dio_buf(void) {
|
||||
static struct rpl_dio_t *get_rpl_dio_buf(void)
|
||||
{
|
||||
return ((struct rpl_dio_t *) &(rpl_buffer[IPV6_HDR_LEN + ICMPV6_HDR_LEN]));
|
||||
}
|
||||
|
||||
static struct rpl_dao_t *get_rpl_dao_buf(void) {
|
||||
static struct rpl_dao_t *get_rpl_dao_buf(void)
|
||||
{
|
||||
return ((struct rpl_dao_t *) &(rpl_buffer[IPV6_HDR_LEN + ICMPV6_HDR_LEN]));
|
||||
}
|
||||
|
||||
static struct rpl_dao_ack_t *get_rpl_dao_ack_buf(void) {
|
||||
static struct rpl_dao_ack_t *get_rpl_dao_ack_buf(void)
|
||||
{
|
||||
return ((struct rpl_dao_ack_t *) &(buffer[(LL_HDR_LEN + IPV6_HDR_LEN + ICMPV6_HDR_LEN)]));
|
||||
}
|
||||
|
||||
static struct rpl_dis_t *get_rpl_dis_buf(void) {
|
||||
return ((struct rpl_dis_t *) & (rpl_buffer[IPV6_HDR_LEN + ICMPV6_HDR_LEN]));
|
||||
static struct rpl_dis_t *get_rpl_dis_buf(void)
|
||||
{
|
||||
return ((struct rpl_dis_t *) &(rpl_buffer[IPV6_HDR_LEN + ICMPV6_HDR_LEN]));
|
||||
}
|
||||
|
||||
static rpl_opt_t *get_rpl_opt_buf(uint8_t rpl_msg_len)
|
||||
@ -182,15 +191,11 @@ rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t rpl_init(transceiver_type_t trans, uint16_t rpl_address)
|
||||
uint8_t rpl_init(int if_id)
|
||||
{
|
||||
mutex_init(&rpl_send_mutex);
|
||||
mutex_init(&rpl_recv_mutex);
|
||||
|
||||
if (rpl_address == 0) {
|
||||
return SIXLOWERROR_ADDRESS;
|
||||
}
|
||||
|
||||
rpl_instances_init();
|
||||
|
||||
/* initialize routing table */
|
||||
@ -204,11 +209,11 @@ 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_lowpan_init(trans, rpl_address, 0);
|
||||
sixlowpan_lowpan_init_interface(if_id);
|
||||
/* need link local prefix to query _our_ corresponding address */
|
||||
ipv6_addr_t ll_address;
|
||||
ipv6_addr_set_link_local_prefix(&ll_address);
|
||||
ipv6_iface_get_best_src_addr(&my_address, &ll_address);
|
||||
ipv6_net_if_get_best_src_addr(&my_address, &ll_address);
|
||||
ipv6_register_rpl_handler(rpl_process_pid);
|
||||
|
||||
/* initialize ETX-calculation if needed */
|
||||
@ -345,6 +350,7 @@ void send_DIS(ipv6_addr_t *destination)
|
||||
void send_DAO(ipv6_addr_t *destination, uint8_t lifetime, bool default_lifetime, uint8_t start_index)
|
||||
{
|
||||
DEBUG("Send DAO\n");
|
||||
|
||||
if (i_am_root) {
|
||||
return;
|
||||
}
|
||||
@ -364,6 +370,7 @@ void send_DAO(ipv6_addr_t *destination, uint8_t lifetime, bool default_lifetime,
|
||||
mutex_unlock(&rpl_send_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
destination = &my_dodag->my_preferred_parent->addr;
|
||||
}
|
||||
|
||||
@ -479,7 +486,7 @@ void rpl_process(void)
|
||||
code = ((uint8_t *)m_recv.content.ptr);
|
||||
/* differentiate packet types */
|
||||
ipv6_buf = ipv6_get_buf();
|
||||
memcpy(&rpl_buffer, ipv6_buf, ipv6_buf->length + IPV6_HDR_LEN);
|
||||
memcpy(&rpl_buffer, ipv6_buf, NTOHS(ipv6_buf->length) + IPV6_HDR_LEN);
|
||||
|
||||
switch (*code) {
|
||||
case (ICMP_CODE_DIS): {
|
||||
@ -572,7 +579,7 @@ void recv_rpl_dio(void)
|
||||
* 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)) {
|
||||
while (len < (NTOHS(ipv6_buf->length) - ICMPV6_HDR_LEN)) {
|
||||
DEBUG("parsing DIO options\n");
|
||||
rpl_opt_buf = get_rpl_opt_buf(len);
|
||||
|
||||
@ -664,6 +671,7 @@ void recv_rpl_dio(void)
|
||||
else {
|
||||
DEBUG("Cannot access DODAG because of DIO with infinite rank\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -694,7 +702,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();
|
||||
@ -917,14 +925,13 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
|
||||
ipv6_send_buf->flowlabel = 0;
|
||||
ipv6_send_buf->nextheader = next_header;
|
||||
ipv6_send_buf->hoplimit = MULTIHOP_HOPLIMIT;
|
||||
ipv6_send_buf->length = p_len;
|
||||
ipv6_send_buf->length = HTONS(p_len);
|
||||
|
||||
memcpy(&(ipv6_send_buf->destaddr), destination, 16);
|
||||
ipv6_iface_get_best_src_addr(&(ipv6_send_buf->srcaddr), &(ipv6_send_buf->destaddr));
|
||||
ipv6_net_if_get_best_src_addr(&(ipv6_send_buf->srcaddr), &(ipv6_send_buf->destaddr));
|
||||
|
||||
icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
icmp_send_buf->checksum = 0;
|
||||
icmp_send_buf->checksum = ~ipv6_csum(ipv6_send_buf, (uint8_t*) icmp_send_buf, ipv6_send_buf->length, IPV6_PROTO_NUM_ICMPV6);
|
||||
icmp_send_buf->checksum = icmpv6_csum(ipv6_send_buf, icmp_send_buf);
|
||||
|
||||
/* The packet was "assembled" in rpl.c. Therefore rpl_send_buf was used.
|
||||
* Therefore memcpy is not needed because the payload is at the
|
||||
@ -937,9 +944,7 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
|
||||
packet_length = IPV6_HDR_LEN + p_len;
|
||||
|
||||
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);
|
||||
ipv6_send_packet(ipv6_send_buf);
|
||||
}
|
||||
else {
|
||||
/* find appropriate next hop before sending */
|
||||
@ -960,9 +965,7 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
|
||||
}
|
||||
}
|
||||
|
||||
sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(next_hop->uint16[4]),
|
||||
(uint8_t *)ipv6_send_buf,
|
||||
packet_length);
|
||||
ipv6_send_packet(ipv6_send_buf);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,7 +35,7 @@
|
||||
#define RPL_PKT_RECV_BUF_SIZE 16
|
||||
#define RPL_PROCESS_STACKSIZE KERNEL_CONF_STACKSIZE_DEFAULT
|
||||
|
||||
uint8_t rpl_init(transceiver_type_t trans, uint16_t rpl_address);
|
||||
uint8_t rpl_init(int if_id);
|
||||
void rpl_init_root(void);
|
||||
rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp);
|
||||
|
||||
|
@ -222,6 +222,7 @@ void rpl_delete_worst_parent(void)
|
||||
void rpl_delete_all_parents(void)
|
||||
{
|
||||
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
|
||||
|
||||
if (my_dodag != NULL) {
|
||||
my_dodag->my_preferred_parent = NULL;
|
||||
}
|
||||
@ -356,7 +357,9 @@ void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_ran
|
||||
DEBUG("\tminhoprankincrease :\t%04X\n", my_dodag->minhoprankincrease);
|
||||
DEBUG("\tdefault_lifetime:\t%02X\n", my_dodag->default_lifetime);
|
||||
DEBUG("\tgrounded:\t%02X\n", my_dodag->grounded);
|
||||
DEBUG("\tmy_preferred_parent:\t%s\n", ipv6_addr_to_str(addr_str, &my_dodag->my_preferred_parent->addr));
|
||||
DEBUG("\tmy_preferred_parent:\t%s\n",
|
||||
ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
&my_dodag->my_preferred_parent->addr));
|
||||
DEBUG("\tmy_preferred_parent rank\t%02X\n", my_dodag->my_preferred_parent->rank);
|
||||
DEBUG("\tmy_preferred_parent lifetime\t%04X\n", my_dodag->my_preferred_parent->lifetime);
|
||||
|
||||
|
@ -166,11 +166,13 @@ void trickle_interval_over(void)
|
||||
timex_normalize(&I_time);
|
||||
|
||||
vtimer_remove(&trickle_t_timer);
|
||||
|
||||
if (vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid) != 0) {
|
||||
puts("[ERROR] setting Wakeup");
|
||||
}
|
||||
|
||||
vtimer_remove(&trickle_I_timer);
|
||||
|
||||
if (vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid) != 0) {
|
||||
puts("[ERROR] setting Wakeup");
|
||||
}
|
||||
|
@ -121,9 +121,11 @@ void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header,
|
||||
printf("--- %s TCP packet: ---\n",
|
||||
(in_or_out == INC_PACKET ? "Incoming" : "Outgoing"));
|
||||
printf("IPv6 Source: %s\n",
|
||||
ipv6_addr_to_str(addr_str, &ipv6_header->srcaddr));
|
||||
ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
&ipv6_header->srcaddr));
|
||||
printf("IPv6 Dest: %s\n",
|
||||
ipv6_addr_to_str(addr_str, &ipv6_header->destaddr));
|
||||
ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
&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));
|
||||
@ -148,10 +150,10 @@ void print_socket(socket_t *current_socket)
|
||||
current_socket->type,
|
||||
current_socket->protocol);
|
||||
printf("Local address: %s\n",
|
||||
ipv6_addr_to_str(addr_str,
|
||||
ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
¤t_socket->local_address.sin6_addr));
|
||||
printf("Foreign address: %s\n",
|
||||
ipv6_addr_to_str(addr_str,
|
||||
ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
|
||||
¤t_socket->foreign_address.sin6_addr));
|
||||
printf("Local Port: %u, Foreign Port: %u\n",
|
||||
NTOHS(current_socket->local_address.sin6_port),
|
||||
@ -494,13 +496,13 @@ int send_tcp(socket_internal_t *current_socket, tcp_hdr_t *current_tcp_packet,
|
||||
}
|
||||
|
||||
return ipv6_sendto(¤t_tcp_socket->foreign_address.sin6_addr,
|
||||
IPPROTO_TCP, (uint8_t *)(current_tcp_packet),
|
||||
compressed_size);
|
||||
IPPROTO_TCP, (uint8_t *)(current_tcp_packet),
|
||||
compressed_size);
|
||||
#else
|
||||
switch_tcp_packet_byte_order(current_tcp_packet);
|
||||
return ipv6_sendto(¤t_tcp_socket->foreign_address.sin6_addr,
|
||||
IPPROTO_TCP, (uint8_t *)(current_tcp_packet),
|
||||
header_length * 4 + payload_length);
|
||||
IPPROTO_TCP, (uint8_t *)(current_tcp_packet),
|
||||
header_length * 4 + payload_length);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -539,7 +541,7 @@ int destiny_socket_connect(int socket, sockaddr6_t *addr, uint32_t addrlen)
|
||||
current_int_tcp_socket->recv_pid = thread_getpid();
|
||||
|
||||
/* Local address information */
|
||||
ipv6_iface_get_best_src_addr(&src_addr, &addr->sin6_addr);
|
||||
ipv6_net_if_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);
|
||||
|
||||
@ -1011,7 +1013,7 @@ int32_t destiny_socket_sendto(int s, const void *buf, 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_iface_get_best_src_addr(&(temp_ipv6_header->srcaddr), &(temp_ipv6_header->destaddr));
|
||||
ipv6_net_if_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;
|
||||
@ -1022,13 +1024,13 @@ int32_t destiny_socket_sendto(int s, const void *buf, uint32_t len, int flags,
|
||||
temp_ipv6_header->length = UDP_HDR_LEN + len;
|
||||
|
||||
current_udp_packet->checksum = ~ipv6_csum(temp_ipv6_header,
|
||||
(uint8_t*) current_udp_packet,
|
||||
UDP_HDR_LEN + len,
|
||||
IPPROTO_UDP);
|
||||
(uint8_t *) current_udp_packet,
|
||||
UDP_HDR_LEN + len,
|
||||
IPPROTO_UDP);
|
||||
|
||||
return ipv6_sendto(&to->sin6_addr, IPPROTO_UDP,
|
||||
(uint8_t *)(current_udp_packet),
|
||||
NTOHS(current_udp_packet->length));
|
||||
(uint8_t *)(current_udp_packet),
|
||||
NTOHS(current_udp_packet->length));
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
|
@ -23,18 +23,21 @@
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "destiny/socket.h" /* for AF_INET6 */
|
||||
#include "inet_pton.h"
|
||||
#include "inet_ntop.h"
|
||||
#include "net_help.h"
|
||||
#include "net_if.h"
|
||||
#include "transceiver.h"
|
||||
|
||||
#ifndef MODULE_SIXLOWPAN
|
||||
#define ADDR_REGISTERED_MAX (6)
|
||||
#define ADDRS_LEN_MAX (16)
|
||||
|
||||
static uint8_t addr_registered = 0;
|
||||
static uint8_t addrs[ADDR_REGISTERED_MAX][ADDRS_LEN_MAX];
|
||||
#else
|
||||
#include "ipv6.h"
|
||||
#endif
|
||||
|
||||
void _net_if_ifconfig_add(int if_id, int argc, char **argv);
|
||||
void _net_if_ifconfig_add_ipv6(int if_id, int argc, char **argv);
|
||||
@ -45,8 +48,9 @@ void _net_if_ifconfig_set_hwaddr(int if_id, char *addr);
|
||||
void _net_if_ifconfig_set_pan_id(int if_id, char *pan_id);
|
||||
void _net_if_ifconfig_set_channel(int if_id, char *channel);
|
||||
void _net_if_ifconfig_create(char *transceivers_str);
|
||||
int _net_if_ifconfig_ipv6_addr_convert(net_if_addr_t *addr, char *type,
|
||||
char *addr_data_str, char *addr_data_len);
|
||||
int _net_if_ifconfig_ipv6_addr_convert(net_if_addr_t *addr, void *addr_data,
|
||||
char *type, char *addr_data_str,
|
||||
char *addr_data_len);
|
||||
void _net_if_ifconfig_list(int if_id);
|
||||
|
||||
int isnumber(char *str)
|
||||
@ -335,20 +339,60 @@ void _net_if_ifconfig_add_ipv6(int if_id, int argc, char **argv)
|
||||
type = NULL;
|
||||
}
|
||||
|
||||
#ifdef MODULE_SIXLOWPAN
|
||||
ipv6_addr_t ipv6_addr;
|
||||
void *addr_data = &ipv6_addr;
|
||||
#else
|
||||
void *addr_data = (void *)&addrs[addr_registered][0];
|
||||
#endif
|
||||
|
||||
addr_data_str = strtok(addr_str, "/");
|
||||
addr_data_len = strtok(NULL, "/");
|
||||
|
||||
if (!_net_if_ifconfig_ipv6_addr_convert(&addr, type, addr_data_str, addr_data_len)) {
|
||||
if (!_net_if_ifconfig_ipv6_addr_convert(&addr, addr_data, type,
|
||||
addr_data_str, addr_data_len)) {
|
||||
add_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MODULE_SIXLOWPAN
|
||||
|
||||
if (addr.addr_protocol & NET_IF_L3P_IPV6_PREFIX) {
|
||||
if (ndp_add_prefix_info(if_id, &ipv6_addr, addr.addr_len,
|
||||
NDP_OPT_PI_VLIFETIME_INFINITE,
|
||||
NDP_OPT_PI_PLIFETIME_INFINITE, 1,
|
||||
ICMPV6_NDP_OPT_PI_FLAG_AUTONOM) != SIXLOWERROR_SUCCESS) {
|
||||
add_usage();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (addr.addr_protocol & NET_IF_L3P_IPV6_ADDR) {
|
||||
uint8_t is_anycast = 0;
|
||||
|
||||
if (addr.addr_protocol & NET_IF_L3P_IPV6_ANYCAST) {
|
||||
is_anycast = 1;
|
||||
}
|
||||
|
||||
if (!ipv6_net_if_add_addr(if_id, &ipv6_addr, NDP_ADDR_STATE_PREFERRED,
|
||||
0, 0, is_anycast)) {
|
||||
add_usage();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
add_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (net_if_add_address(if_id, &addr) < 0) {
|
||||
add_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
addr_registered++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void _net_if_ifconfig_add(int if_id, int argc, char **argv)
|
||||
@ -413,13 +457,21 @@ void _net_if_ifconfig_create(char *transceivers_str)
|
||||
|
||||
static inline int _is_multicast(uint8_t *addr)
|
||||
{
|
||||
#ifdef MODULE_SIXLOWPAN
|
||||
return ipv6_addr_is_multicast((ipv6_addr_t *) addr);
|
||||
#else
|
||||
return *addr == 0xff;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int _is_link_local(uint8_t *addr)
|
||||
{
|
||||
#ifdef MODULE_SIXLOWPAN
|
||||
return ipv6_addr_is_link_local((ipv6_addr_t *) addr);
|
||||
#else
|
||||
return (addr[0] == 0xfe && addr[1] == 0x80) ||
|
||||
(_is_multicast(addr) && (addr[1] & 0x0f) == 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
int _set_protocol_from_type(char *type, net_if_addr_t *addr)
|
||||
@ -448,14 +500,15 @@ int _set_protocol_from_type(char *type, net_if_addr_t *addr)
|
||||
}
|
||||
}
|
||||
|
||||
int _net_if_ifconfig_ipv6_addr_convert(net_if_addr_t *addr, char *type,
|
||||
char *addr_data_str, char *addr_data_len)
|
||||
int _net_if_ifconfig_ipv6_addr_convert(net_if_addr_t *addr, void *addr_data,
|
||||
char *type, char *addr_data_str,
|
||||
char *addr_data_len)
|
||||
{
|
||||
if (addr_data_len && !isnumber(addr_data_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr->addr_data = (void *)&addrs[addr_registered][0];
|
||||
addr->addr_data = addr_data;
|
||||
|
||||
if (!inet_pton(AF_INET6, addr_data_str, addr->addr_data)) {
|
||||
return 0;
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "transceiver.h"
|
||||
#include "net_if.h"
|
||||
#include "ipv6.h"
|
||||
|
||||
#ifdef MODULE_NATIVENET
|
||||
@ -42,12 +42,13 @@
|
||||
|
||||
#define PORT (1234)
|
||||
|
||||
void init_local_address(uint16_t r_addr)
|
||||
int init_local_address(uint16_t r_addr)
|
||||
{
|
||||
ipv6_addr_t std_addr;
|
||||
ipv6_addr_init(&std_addr, 0xabcd, 0xef12, 0, 0, 0x1034, 0x00ff, 0xfe00,
|
||||
r_addr);
|
||||
sixlowpan_lowpan_adhoc_init(TRANSCEIVER, &std_addr, r_addr);
|
||||
0);
|
||||
return net_if_set_hardware_address(r_addr) &&
|
||||
sixlowpan_lowpan_adhoc_init(0, &std_addr);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
@ -80,7 +81,10 @@ int main(void)
|
||||
};
|
||||
char buffer[14];
|
||||
|
||||
init_local_address(R_ADDR);
|
||||
if (!init_local_address(R_ADDR)) {
|
||||
fprintf(stderr, "Can not initialize IP for hardware address %d.", R_ADDR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(buffer, "Hello, World!", 14);
|
||||
memcpy(&my_addr, &in6addr_any, sizeof(my_addr));
|
||||
|
Loading…
Reference in New Issue
Block a user