Let IPv6 and ICMP use new 6LoWPAN layer (+fixes)

This commit is contained in:
Martin Lenders 2014-02-13 13:57:59 +01:00
parent e2e62596be
commit 00acab920b
17 changed files with 1140 additions and 569 deletions

View File

@ -92,13 +92,13 @@ ifneq (,$(filter sixlowpan,$(USEMODULE)))
ifeq (,$(filter net_help,$(USEMODULE))) ifeq (,$(filter net_help,$(USEMODULE)))
USEMODULE += net_help USEMODULE += net_help
endif endif
ifeq (,$(filter semaphore,$(USEMODULE))) ifeq (,$(filter net_if,$(USEMODULE)))
USEMODULE += net_if
endif
ifeq (,$(filter semaphore, $(USEMODULE)))
USEMODULE += semaphore USEMODULE += semaphore
endif endif
ifeq (,$(filter transceiver,$(USEMODULE))) ifeq (,$(filter vtimer, $(USEMODULE)))
USEMODULE += transceiver
endif
ifeq (,$(filter vtimer,$(USEMODULE)))
USEMODULE += vtimer USEMODULE += vtimer
endif endif
endif endif

View File

@ -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. * @param[in] data_len Length of data payload.
*/ */
void icmpv6_send_echo_request(ipv6_addr_t *destaddr, uint16_t id, 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); 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. * @param[in] data_len Length of data payload.
*/ */
void icmpv6_send_echo_reply(ipv6_addr_t *destaddr, uint16_t id, 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. * @brief Send ICMPv6 router solicitation.

View File

@ -24,6 +24,9 @@
#include <stdint.h> #include <stdint.h>
#include "inet_ntop.h"
#include "net_help.h"
#include "net_if.h"
#include "sixlowpan/types.h" #include "sixlowpan/types.h"
/** /**
@ -32,7 +35,17 @@
#define IPV6_MTU (256) #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) #define IPV6_MAX_ADDR_STR_LEN (40)
@ -160,7 +173,11 @@ void ipv6_register_rpl_handler(int pid);
* *
* @param[in,out] ipv6_addr The address to set. * @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 * @brief Sets IPv6 address *out* according to the remaining
@ -181,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); uint16_t addr5, uint16_t addr6, uint16_t addr7);
/** /**
* @brief Sets IPv6 address *out* using the given *prefix* and this * @brief Sets IPv6 address *out* using the given *prefix* and an interface's
* nodes EUI-64 (i. e. interface must be initialized). * EUI-64.
*
* *
* @param[out] out Address to be set. * @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* * @param[in] prefix 64-bit network prefix to be used for *out*
* (only the first 64 bit of the ipv6_addr_t type * (only the first 64 bit of the ipv6_addr_t type
* are copied to *out*) * 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, ipv6_addr_t *ipv6_addr_set_by_eui64(ipv6_addr_t *out, int if_id,
const ipv6_addr_t *prefix); const ipv6_addr_t *prefix);
/** /**
* @brief Sets IPv6 address *out* with the first *bits* bit taken * @brief Sets IPv6 address *out* with the first *bits* bit taken
@ -213,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. * @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 * @brief Set *ipv6_addr* to a link-local all routers multicast
@ -226,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 * @param[out] ipv6_addr Is set to a link-local all routers multicast
* address. * 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 * @brief Set *ipv6_addr* to a link-local all nodes multicast address
@ -239,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 * @param[out] ipv6_addr Is set to a link-local all nodes multicast
* address. * 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 * @brief Set *ipv6_addr_out* to the solicited-node multicast address
@ -254,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 * @param[in] ipv6_addr_in The IPv6 address the solicited-node
* address. * address.
*/ */
void ipv6_addr_set_solicited_node_addr(ipv6_addr_t *ipv6_addr_out, static inline void ipv6_addr_set_solicited_node_addr(ipv6_addr_t *ipv6_addr_out,
const ipv6_addr_t *ipv6_addr_in); 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). * @brief Converts IPv6 address into string.
* Note that addr_str must allocate at least
* IPV6_MAX_ADDR_STR_LEN byte (40 byte).
* *
* @param[out] addr_str The IPv6 address as string. Must allocate * @param[out] addr_str The IPv6 address as string. Must allocate
* at least IPV6_MAX_ADDR_STR_LEN byte (40 * at least IPV6_MAX_ADDR_STR_LEN byte (40
* byte). * byte).
* @param[in] str_len The maximum length available to *addr_str*.
* @param[in] ipv6_addr IPv6 address to be converted. * @param[in] ipv6_addr IPv6 address to be converted.
* *
* @return Pointer to addr_str. * @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. * @brief Checks if two IPv6 addresses are equal.
@ -279,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. * @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). * @brief Checks if *ipv6_addr* is unspecified (all zero).
@ -292,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. * @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. * @brief Check if *ipv6_addr* is a link-local address.
@ -305,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. * @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. * @brief Check if *ipv6_addr* is unique local unicast address.
@ -319,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, * @return 1 if *ipv6_addr* is unique local unicast address,
* 0 otherwise. * 0 otherwise.
*/ */
int ipv6_addr_is_unique_local_unicast(const ipv6_addr_t *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 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);
/** /**
* @brief Check if *ipv6_addr* is solicited-node multicast address. * @brief Check if *ipv6_addr* is solicited-node multicast address.
@ -346,7 +440,28 @@ int ipv6_addr_is_multicast(const ipv6_addr_t *ipv6_addr);
* @return 1 if *ipv6_addr* is solicited-node multicast address, * @return 1 if *ipv6_addr* is solicited-node multicast address,
* 0 otherwise. * 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 * TODO to wrap sixlowpan initialisations
@ -354,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"> * @see <a href="http://tools.ietf.org/html/rfc4862">
* RFC 4862 * RFC 4862
* </a> * </a>
* *
* @param[in] if_id The interface's ID.
* @param[in] addr Address to be added to the interface. * @param[in] addr Address to be added to the interface.
* @param[in] type Type of this address. * @param[in] type Type of this address.
* @param[in] state Initial state of the 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 * @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, 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 * @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 * address. The use-case for this function is to find a
* suitable address for the source address field of an IPv6 * suitable address for the source address field of an IPv6
* address upon sending. *src* may be empty (all zero) if there * address upon sending. *src* may be empty (all zero) if there
@ -381,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 * @param[out] src The best source address for this node (may be
* all zero if ther is none). * 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 * @param[in] dest The destination address for a packet we search
* the source address for. * the source address for.
*/ */
void ipv6_iface_get_best_src_addr(ipv6_addr_t *src, void ipv6_net_if_get_best_src_addr(ipv6_addr_t *src, const ipv6_addr_t *dest);
const ipv6_addr_t *dest);
/**
* @brief Print all addresses attached to the interface to stdout.
*/
void ipv6_iface_print_addrs(void);
/** /**
* @brief Registers a function that decides how to route incomming * @brief Registers a function that decides how to route incomming

View File

@ -24,6 +24,7 @@
#include <stdint.h> #include <stdint.h>
#include "net_if.h"
#include "timex.h" #include "timex.h"
#include "sixlowpan/types.h" #include "sixlowpan/types.h"
@ -32,6 +33,7 @@
#define NDP_OPT_SLLAO_TYPE (1) #define NDP_OPT_SLLAO_TYPE (1)
#define NDP_OPT_TLLAO_TYPE (2) #define NDP_OPT_TLLAO_TYPE (2)
#define NDP_OPT_PI_VLIFETIME_INFINITE (0xffffffff) #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_SUCCESS (0)
#define NDP_OPT_ARO_STATE_DUP_ADDR (1) #define NDP_OPT_ARO_STATE_DUP_ADDR (1)
#define NDP_OPT_ARO_STATE_NBR_CACHE_FULL (2) #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 * @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)) { typedef struct __attribute__((packed)) ndp_prefix_info_t {
uint8_t inuse; ///< Prefix is in in use. /**
uint8_t adv; * @brief The next on the interface. Intialise with NULL
ipv6_addr_t addr; ///< The Prefix. */
uint8_t length; ///< Length of the prefix. struct ndp_prefix_info_t *addr_next;
uint8_t l_a_reserved1; ///< L and A flag of prefix information option /**
uint32_t val_ltime; ///< valid lifetime * @brief The prev address on the interface. Initialise with NULL
uint32_t pref_ltime; ///< preferred lifetime */
uint8_t infinite; ///< flag to set to infinite lifetime struct ndp_prefix_info_t *addr_prev;
} ndp_prefix_list_t; /**
* @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 * @brief Default router list to store information spread by
@ -84,7 +105,7 @@ typedef struct __attribute__((packed)) {
typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) {
ipv6_addr_t addr; ///< Address of router. ipv6_addr_t addr; ///< Address of router.
timex_t inval_time; ///< remaining time until this entry is timex_t inval_time; ///< remaining time until this entry is
///< invalid. ///< invalid.
} ndp_default_router_list_t; } ndp_default_router_list_t;
/** /**
@ -94,14 +115,16 @@ typedef struct __attribute__((packed)) {
* </a>. * </a>.
*/ */
typedef struct __attribute__((packed)) { 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_type_t type; ///< Type of neighbor cache entry.
ndp_nce_state_t state; ///< State of neighbor cache entry. ndp_nce_state_t state; ///< State of neighbor cache entry.
uint8_t isrouter; ///< Flag to signify that this neighbor uint8_t isrouter; ///< Flag to signify that this neighbor
///< is a router. ///< is a router.
ipv6_addr_t addr; ///< IPv6 address of the neighbor. ipv6_addr_t addr; ///< IPv6 address of the neighbor.
ieee_802154_long_t laddr; ///< EUI-64 of neighbor uint8_t lladdr[8]; ///< Link-layer address of the neighbor
ieee_802154_short_t saddr; ///< IEEE 802.15.4 16-bit short address uint8_t lladdr_len; ///< Length of link-layer address of the
///< of neighbor. ///< neighbor
timex_t ltime; ///< lifetime of entry. timex_t ltime; ///< lifetime of entry.
} ndp_neighbor_cache_t; } ndp_neighbor_cache_t;
@ -118,9 +141,76 @@ typedef struct __attribute__((packed)) {
} ndp_a6br_cache_t; } ndp_a6br_cache_t;
ndp_default_router_list_t *ndp_default_router_list_search(ipv6_addr_t *ipaddr); 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); ndp_neighbor_cache_t *ndp_neighbor_cache_search(ipv6_addr_t *ipaddr);
/*TODO: to implement*/ ndp_neighbor_cache_t *ndp_get_ll_address(ipv6_addr_t *ipaddr);
uint8_t ndp_prefix_list_search(ipv6_addr_t *addr); 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_most_current(void);
ndp_a6br_cache_t *ndp_a6br_cache_get_oldest(void); ndp_a6br_cache_t *ndp_a6br_cache_get_oldest(void);

View File

@ -49,25 +49,6 @@ typedef union __attribute__((packed)) {
uint32_t uint32[4]; ///< devided by 4 32-bit words. uint32_t uint32[4]; ///< devided by 4 32-bit words.
} ipv6_addr_t; } 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 * @brief Data type to represent an IPv6 packet header
* *
@ -78,7 +59,7 @@ typedef enum __attribute__((packed)) {
typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) {
uint8_t version_trafficclass; ///< Version field + first 4 bit of Traffic Class. uint8_t version_trafficclass; ///< Version field + first 4 bit of Traffic Class.
uint8_t trafficclass_flowlabel; ///< last 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 flowlabel; ///< last 16 bit of Flow Label.
uint16_t length; ///< payload length of this packet. uint16_t length; ///< payload length of this packet.
uint8_t nextheader; ///< type of next header in this packet. uint8_t nextheader; ///< type of next header in this packet.

View File

@ -29,7 +29,7 @@
#include "ip.h" #include "ip.h"
#include "semaphore.h" #include "semaphore.h"
extern ipv6_addr_t abr_addr; extern ipv6_addr_t *abr_addr;
uint16_t border_get_serial_reader(void); uint16_t border_get_serial_reader(void);

View File

@ -77,7 +77,7 @@ void demultiplex(border_packet_t *packet)
context->context.lifetime context->context.lifetime
); );
mutex_unlock(&lowpan_context_mutex); 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 */ /* Send router advertisement */
break; break;
} }
@ -141,7 +141,7 @@ int readpacket(uint8_t *packet_buf, size_t size)
break; break;
} }
if ((size_t) (line_buf_ptr - packet_buf) >= size - 1) { if ((size_t)(line_buf_ptr - packet_buf) >= size - 1) {
return -SIXLOWERROR_ARRAYFULL; return -SIXLOWERROR_ARRAYFULL;
} }
@ -179,8 +179,8 @@ int writepacket(uint8_t *packet_buf, size_t size)
{ {
uint8_t *byte_ptr = packet_buf; uint8_t *byte_ptr = packet_buf;
while ((size_t) (byte_ptr - packet_buf) < size) { while ((size_t)(byte_ptr - packet_buf) < size) {
if ((size_t) (byte_ptr - packet_buf) > BORDER_BUFFER_SIZE) { if ((size_t)(byte_ptr - packet_buf) > BORDER_BUFFER_SIZE) {
return -1; return -1;
} }

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,7 @@ enum option_types_t {
OPT_DAC, OPT_DAC,
}; };
extern unsigned int nd_nbr_cache_rem_pid; extern int nd_nbr_cache_rem_pid;
void recv_echo_req(void); void recv_echo_req(void);
@ -53,9 +53,6 @@ void recv_nbr_adv(void);
void recv_nbr_sol(void); void recv_nbr_sol(void);
void nbr_cache_auto_rem(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, ndp_a6br_cache_t *abr_add_context(uint16_t version, ipv6_addr_t *abr_addr,
uint8_t cid); uint8_t cid);
void abr_remove_context(uint8_t cid); void abr_remove_context(uint8_t cid);

View File

@ -25,6 +25,7 @@
#include "vtimer.h" #include "vtimer.h"
#include "mutex.h" #include "mutex.h"
#include "msg.h" #include "msg.h"
#include "net_help.h"
#include "net_if.h" #include "net_if.h"
#include "sixlowpan/mac.h" #include "sixlowpan/mac.h"
@ -32,17 +33,18 @@
#include "icmp.h" #include "icmp.h"
#include "lowpan.h" #include "lowpan.h"
#include "destiny/socket.h"
#include "net_help.h" #include "net_help.h"
#define ENABLE_DEBUG (0) #define ENABLE_DEBUG (0)
#if ENABLE_DEBUG #if ENABLE_DEBUG
#define DEBUG_ENABLED
char addr_str[IPV6_MAX_ADDR_STR_LEN]; char addr_str[IPV6_MAX_ADDR_STR_LEN];
#endif #endif
#include "debug.h" #include "debug.h"
#define IP_PKT_RECV_BUF_SIZE (64) #define IP_PKT_RECV_BUF_SIZE (64)
#define LLHDR_IPV6HDR_LEN (LL_HDR_LEN + IPV6_HDR_LEN) #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 ip_send_buffer[BUFFER_SIZE];
uint8_t buffer[BUFFER_SIZE]; uint8_t buffer[BUFFER_SIZE];
@ -51,34 +53,79 @@ ipv6_hdr_t *ipv6_buf;
icmpv6_hdr_t *icmp_buf; icmpv6_hdr_t *icmp_buf;
uint8_t *nextheader; uint8_t *nextheader;
uint8_t iface_addr_list_count = 0;
int udp_packet_handler_pid = 0; int udp_packet_handler_pid = 0;
int tcp_packet_handler_pid = 0; int tcp_packet_handler_pid = 0;
int rpl_process_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; static uint8_t default_hop_limit = MULTIHOP_HOPLIMIT;
/* registered upper layer threads */ /* registered upper layer threads */
int sixlowip_reg[SIXLOWIP_MAX_REGISTERED]; int sixlowip_reg[SIXLOWIP_MAX_REGISTERED];
int ipv6_send_packet(ipv6_hdr_t *bytes) int ipv6_send_packet(ipv6_hdr_t *packet)
{ {
int if_id = 0; uint16_t length = IPV6_HDR_LEN + NTOHS(packet->length);
uint16_t offset = IPV6_HDR_LEN + HTONS(bytes->length); ndp_neighbor_cache_t *nce;
bytes->flowlabel = HTONS(bytes->flowlabel); ipv6_net_if_get_best_src_addr(&packet->srcaddr, &packet->destaddr);
bytes->length = HTONS(bytes->length);
memset(bytes, 0, BUFFER_SIZE); if (!ipv6_addr_is_multicast(&packet->destaddr) &&
memcpy(bytes + LL_HDR_LEN, bytes, offset); ndp_addr_is_on_link(&packet->destaddr)) {
nce = ndp_get_ll_address(&packet->destaddr);
if (sixlowpan_lowpan_sendto(nce->if_id, &nce->lladdr, nce->lladdr_len,
(uint8_t *)packet, length) < 0) { if (nce == NULL || sixlowpan_lowpan_sendto(nce->if_id, &nce->lladdr,
return -1; 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);
}
return 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) ipv6_hdr_t *ipv6_get_buf_send(void)
@ -110,7 +157,6 @@ 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; uint8_t *p_ptr;
uint16_t packet_length;
if (next_header == IPV6_PROTO_NUM_TCP) { if (next_header == IPV6_PROTO_NUM_TCP) {
p_ptr = get_payload_buf_send(ipv6_ext_hdr_len); p_ptr = get_payload_buf_send(ipv6_ext_hdr_len);
@ -125,32 +171,14 @@ int ipv6_sendto(const ipv6_addr_t *dest, uint8_t next_header,
ipv6_buf->trafficclass_flowlabel = 0; ipv6_buf->trafficclass_flowlabel = 0;
ipv6_buf->flowlabel = 0; ipv6_buf->flowlabel = 0;
ipv6_buf->nextheader = next_header; ipv6_buf->nextheader = next_header;
ipv6_buf->hoplimit = default_hop_limit; ipv6_buf->hoplimit = MULTIHOP_HOPLIMIT;
ipv6_buf->length = payload_length; ipv6_buf->length = HTONS(payload_length);
memcpy(&(ipv6_buf->destaddr), dest, 16); memcpy(&(ipv6_buf->destaddr), dest, 16);
ipv6_iface_get_best_src_addr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr));
memcpy(p_ptr, payload, payload_length); 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);
}
if (dest == NULL) {
return -1;
}
sixlowpan_lowpan_sendto(0, &dest->uint16[4], 8,
(uint8_t *)ipv6_buf, packet_length);
return payload_length;
} }
void ipv6_set_default_hop_limit(uint8_t hop_limit) void ipv6_set_default_hop_limit(uint8_t hop_limit)
@ -278,19 +306,40 @@ uint8_t ipv6_get_addr_match(const ipv6_addr_t *src,
return val; 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) void ipv6_process(void)
{ {
msg_t m_recv_lowpan, m_send_lowpan; msg_t m_recv_lowpan, m_send_lowpan;
msg_t m_recv, m_send; msg_t m_recv, m_send;
ipv6_addr_t myaddr;
uint8_t i; uint8_t i;
uint16_t packet_length; uint16_t packet_length;
msg_init_queue(ip_msg_queue, IP_PKT_RECV_BUF_SIZE); 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) { while (1) {
msg_receive(&m_recv_lowpan); msg_receive(&m_recv_lowpan);
@ -308,40 +357,16 @@ 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 */ /* destination is our address */
else { if (is_our_address(&ipv6_buf->destaddr)) {
switch (*nextheader) { switch (*nextheader) {
case (IPV6_PROTO_NUM_ICMPV6): { case (IPV6_PROTO_NUM_ICMPV6): {
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
/* checksum test*/ /* checksum test*/
if (ipv6_csum(ipv6_buf, (uint8_t *) icmp_buf, ipv6_buf->length, IPV6_PROTO_NUM_ICMPV6) != 0xffff) { if (ipv6_csum(ipv6_buf, (uint8_t *) icmp_buf, NTOHS(ipv6_buf->length),
printf("ERROR: wrong checksum\n"); IPV6_PROTO_NUM_ICMPV6) != 0xffff) {
DEBUG("ERROR: wrong checksum\n");
} }
icmpv6_demultiplex(icmp_buf); icmpv6_demultiplex(icmp_buf);
@ -354,7 +379,7 @@ void ipv6_process(void)
msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid); msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid);
} }
else { else {
printf("INFO: No TCP handler registered.\n"); DEBUG("INFO: No TCP handler registered.\n");
} }
break; break;
@ -366,14 +391,14 @@ void ipv6_process(void)
msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid); msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid);
} }
else { else {
printf("INFO: No UDP handler registered.\n"); DEBUG("INFO: No UDP handler registered.\n");
} }
break; break;
} }
case (IPV6_PROTO_NUM_NONE): { 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; break;
} }
@ -381,97 +406,205 @@ void ipv6_process(void)
break; 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); msg_reply(&m_recv_lowpan, &m_send_lowpan);
} }
} }
void ipv6_iface_add_addr(const ipv6_addr_t *addr, ipv6_addr_type_t type, ipv6_net_if_ext_t *ipv6_net_if_get_ext(int if_id)
ndp_addr_state_t state, uint32_t val_ltime,
uint32_t pref_ltime)
{ {
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) { if (ipv6_addr_is_unspecified(addr) == 128) {
printf("ERROR: unspecified address (::) can't be assigned to interface.\n"); DEBUG("ERROR: unspecified address (::) can't be assigned to interface.\n");
return; return 0;
} }
if (ipv6_iface_addr_match(addr) != 0) { if (ipv6_addr_is_multicast(addr) && is_anycast) {
return; 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) { if (ipv6_net_if_addr_match(&hit, addr)) {
memcpy(&(iface.addr_list[iface_addr_list_count].addr.uint8[0]), return 1;
&(addr->uint8[0]), 16); }
iface.addr_list[iface_addr_list_count].state = state;
if (ipv6_net_if_addr_buffer_count < IPV6_NET_IF_ADDR_BUFFER_LEN) {
timex_t valtime = {val_ltime, 0}; timex_t valtime = {val_ltime, 0};
timex_t preftime = {pref_ltime, 0}; timex_t preftime = {pref_ltime, 0};
timex_t now; timex_t now;
vtimer_now(&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); ipv6_addr_t *addr_data = &ipv6_addr_buffer[ipv6_net_if_addr_buffer_count];
iface.addr_list[iface_addr_list_count].type = type; memcpy(addr_data, addr, sizeof(ipv6_addr_t));
iface_addr_list_count++;
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 */ /* Register to Solicited-Node multicast address according to RFC 4291 */
if (type == IPV6_ADDR_TYPE_ANYCAST || type == IPV6_ADDR_TYPE_LINK_LOCAL || if (is_anycast || !ipv6_addr_is_multicast(addr)) {
type == IPV6_ADDR_TYPE_GLOBAL || type == IPV6_ADDR_TYPE_UNICAST) {
ipv6_addr_t sol_node_mcast_addr; ipv6_addr_t sol_node_mcast_addr;
ipv6_addr_set_solicited_node_addr(&sol_node_mcast_addr, addr); ipv6_addr_set_solicited_node_addr(&sol_node_mcast_addr, addr);
if (ipv6_iface_addr_match(&sol_node_mcast_addr) == NULL) { if (ipv6_net_if_addr_match(&hit, &sol_node_mcast_addr) == NULL) {
ipv6_iface_add_addr(&sol_node_mcast_addr, ipv6_net_if_add_addr(if_id, &sol_node_mcast_addr, state,
IPV6_ADDR_TYPE_SOLICITED_NODE, val_ltime, pref_ltime, 0);
state, val_ltime, pref_ltime); }
}
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++) { while ((if_id = net_if_iter_interfaces(if_id)) >= 0) {
if (memcmp(&(iface.addr_list[i].addr.uint8[0]), while (net_if_iter_addresses(if_id, (net_if_addr_t **) &addr_entry) != NULL) {
&(addr->uint8[0]), 16) == 0) { if (addr_entry->addr_protocol & NET_IF_L3P_IPV6) {
return &(iface.addr_list[i]); if (memcmp(addr_entry->addr_data, &addr, 8) == 0) {
hit->if_id = if_id;
hit->addr = addr_entry;
return hit;
}
}
} }
} }
return NULL; return NULL;
} }
addr_list_t *ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr) /* TODO ipv6_net_if_hit_t returning function similar wrapping
{ * ipv6_net_if_get_best_src_addr() to search on all interfaces */
int i;
ipv6_addr_t *ipv6_addr_set_by_eui64(ipv6_addr_t *out, int if_id,
for (i = 0; i < iface_addr_list_count; i++) { const ipv6_addr_t *prefix)
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)
{ {
uint8_t force_generation = 0;
out->uint16[0] = prefix->uint16[0]; out->uint16[0] = prefix->uint16[0];
out->uint16[1] = prefix->uint16[1]; out->uint16[1] = prefix->uint16[1];
out->uint16[2] = prefix->uint16[2]; out->uint16[2] = prefix->uint16[2];
out->uint16[3] = prefix->uint16[3]; 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, void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix,
@ -496,96 +629,51 @@ void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix,
out->uint8[bytes] = prefix->uint8[bytes] & mask; out->uint8[bytes] = prefix->uint8[bytes] & mask;
} }
void ipv6_addr_set_all_routers_addr(ipv6_addr_t *ipv6_addr) void ipv6_net_if_get_best_src_addr(ipv6_addr_t *src, const ipv6_addr_t *dest)
{
ipv6_addr->uint16[0] = HTONS(0xff02);
ipv6_addr->uint16[1] = 0;
ipv6_addr->uint16[2] = 0;
ipv6_addr->uint16[3] = 0;
ipv6_addr->uint16[4] = 0;
ipv6_addr->uint16[5] = 0;
ipv6_addr->uint16[6] = 0;
ipv6_addr->uint16[7] = HTONS(0x0002);
}
void ipv6_addr_set_all_nodes_addr(ipv6_addr_t *ipv6_addr)
{
ipv6_addr->uint16[0] = HTONS(0xff02);
ipv6_addr->uint16[1] = 0;
ipv6_addr->uint16[2] = 0;
ipv6_addr->uint16[3] = 0;
ipv6_addr->uint16[4] = 0;
ipv6_addr->uint16[5] = 0;
ipv6_addr->uint16[6] = 0;
ipv6_addr->uint16[7] = HTONS(0x0001);
}
void ipv6_addr_set_loopback_addr(ipv6_addr_t *ipv6_addr)
{
ipv6_addr->uint16[0] = 0;
ipv6_addr->uint16[1] = 0;
ipv6_addr->uint16[2] = 0;
ipv6_addr->uint16[3] = 0;
ipv6_addr->uint16[4] = 0;
ipv6_addr->uint16[5] = 0;
ipv6_addr->uint16[6] = 0;
ipv6_addr->uint16[7] = HTONS(0x0001);
}
void ipv6_iface_get_best_src_addr(ipv6_addr_t *src, const ipv6_addr_t *dest)
{ {
/* try to find best match if dest is not mcast or link local */ /* 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 tmp = 0;
uint8_t bmatch = 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))) { if (!(ipv6_addr_is_link_local(dest)) && !(ipv6_addr_is_multicast(dest))) {
for (int i = 0; i < IFACE_ADDR_LIST_LEN; i++) { while ((addr = (ipv6_net_if_addr_t *)net_if_iter_addresses(if_id,
if (iface.addr_list[i].state == NDP_ADDR_STATE_PREFERRED) { (net_if_addr_t **)&addr))) {
if (!ipv6_addr_is_link_local(&(iface.addr_list[i].addr)) && if (addr->ndp_state == NDP_ADDR_STATE_PREFERRED) {
!ipv6_addr_is_multicast(&(iface.addr_list[i].addr)) && if (!ipv6_addr_is_link_local(addr->addr_data) &&
!ipv6_addr_is_unique_local_unicast(&(iface.addr_list[i].addr))) { !ipv6_addr_is_multicast(addr->addr_data) &&
tmp = ipv6_get_addr_match(dest, &(iface.addr_list[i].addr)); !ipv6_addr_is_unique_local_unicast(addr->addr_data)) {
tmp = ipv6_get_addr_match(dest, addr->addr_data);
if (tmp >= bmatch) { if (tmp >= bmatch) {
bmatch = tmp; bmatch = tmp;
itmp = i; tmp_addr = addr;
} }
} }
} }
} }
} }
else { else {
for (int j = 0; j < IFACE_ADDR_LIST_LEN; j++) { while ((addr = (ipv6_net_if_addr_t *)net_if_iter_addresses(if_id,
if ((iface.addr_list[j].state == NDP_ADDR_STATE_PREFERRED) && (net_if_addr_t **)&addr))) {
ipv6_addr_is_link_local(&(iface.addr_list[j].addr)) && if (addr->ndp_state == NDP_ADDR_STATE_PREFERRED &&
!ipv6_addr_is_multicast(&(iface.addr_list[j].addr))) { ipv6_addr_is_link_local(addr->addr_data) &&
itmp = j; !ipv6_addr_is_multicast(addr->addr_data)) {
tmp_addr = addr;
} }
} }
} }
if (itmp == -1) { if (tmp_addr == NULL) {
memset(src, 0, 16); memset(src, 0, 16);
} }
else { 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, 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 addr2, uint16_t addr3, uint16_t addr4,
uint16_t addr5, uint16_t addr6, uint16_t addr7) uint16_t addr5, uint16_t addr6, uint16_t addr7)
@ -600,66 +688,6 @@ void ipv6_addr_init(ipv6_addr_t *out, uint16_t addr0, uint16_t addr1,
out->uint16[7] = HTONS(addr7); 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) uint32_t get_remaining_time(timex_t *t)
{ {
timex_t now; timex_t now;
@ -677,22 +705,32 @@ void set_remaining_time(timex_t *t, uint32_t time)
*t = timex_add(now, tmp); *t = timex_add(now, tmp);
} }
void ipv6_init_iface_as_router(void) int ipv6_init_as_router(void)
{ {
ipv6_addr_t addr; ipv6_addr_t addr;
int if_id = -1;
ipv6_addr_set_all_routers_addr(&addr); 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) uint8_t ipv6_is_router(void)
{ {
ipv6_addr_t addr; ipv6_addr_t addr;
ipv6_net_if_hit_t hit;
ipv6_addr_set_all_routers_addr(&addr); 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; return 1;
} }
@ -741,8 +779,10 @@ uint16_t ipv6_csum(ipv6_hdr_t *ipv6_header, uint8_t *buf, uint16_t len, uint8_t
{ {
uint16_t sum = 0; uint16_t sum = 0;
DEBUG("Calculate checksum over src: %s, dst: %s, len: %04X, buf: %p, proto: %u\n", 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_MAX_ADDR_STR_LEN,
ipv6_addr_to_str(addr_str, &ipv6_header->destaddr), &ipv6_header->srcaddr),
ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
&ipv6_header->destaddr),
len, buf, proto); len, buf, proto);
sum = len + proto; sum = len + proto;
sum = csum(sum, (uint8_t *)&ipv6_header->srcaddr, 2 * sizeof(ipv6_addr_t)); sum = csum(sum, (uint8_t *)&ipv6_header->srcaddr, 2 * sizeof(ipv6_addr_t));

View File

@ -25,8 +25,10 @@
#include <stdint.h> #include <stdint.h>
#include "kernel.h"
#include "timex.h" #include "timex.h"
#include "mutex.h" #include "mutex.h"
#include "net_if.h"
#include "sixlowpan/ip.h" #include "sixlowpan/ip.h"
#include "sixlowpan/types.h" #include "sixlowpan/types.h"
@ -39,52 +41,61 @@
#define MULTIHOP_HOPLIMIT (64) #define MULTIHOP_HOPLIMIT (64)
#define SIXLOWIP_MAX_REGISTERED (4) #define SIXLOWIP_MAX_REGISTERED (4)
#define IP_PROCESS_STACKSIZE (KERNEL_CONF_STACKSIZE_MAIN)
/* extern variables */ /* extern variables */
extern uint8_t ipv6_ext_hdr_len; extern uint8_t ipv6_ext_hdr_len;
extern int ip_process_pid;
/* base header lengths */ /* base header lengths */
#define LL_HDR_LEN (0x4) #define LL_HDR_LEN (0x4)
#define ICMPV6_HDR_LEN (0x4) #define ICMPV6_HDR_LEN (0x4)
#define IPV6_HDR_LEN (0x28) #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 */ /* buffer */
extern uint8_t buffer[BUFFER_SIZE]; extern uint8_t buffer[BUFFER_SIZE];
extern char ip_process_buf[IP_PROCESS_STACKSIZE];
extern int sixlowip_reg[SIXLOWIP_MAX_REGISTERED]; extern int sixlowip_reg[SIXLOWIP_MAX_REGISTERED];
typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) {
ipv6_addr_t addr; struct net_if_addr_t *addr_next;
ipv6_addr_type_t type; struct net_if_addr_t *addr_prev;
ndp_addr_state_t state; net_if_l3p_t addr_protocol;
timex_t val_ltime; ipv6_addr_t *addr_data;
timex_t pref_ltime; uint8_t addr_len;
} addr_list_t; 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)) { typedef struct __attribute__((packed)) {
ieee_802154_short_t saddr; ipv6_net_if_addr_t *addr;
ieee_802154_long_t laddr; int if_id;
addr_list_t addr_list[IFACE_ADDR_LIST_LEN]; } ipv6_net_if_hit_t;
typedef struct __attribute__((packed)) {
uint8_t prefix; ///< prefix length of the sub-net
uint8_t adv_cur_hop_limit; uint8_t adv_cur_hop_limit;
uint32_t adv_reachable_time; uint32_t adv_reachable_time;
uint32_t adv_retrans_timer; uint32_t adv_retrans_timer;
} iface_t; } ipv6_net_if_ext_t;
extern iface_t iface;
/* function prototypes */ /* 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); icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len);
uint8_t *get_payload_buf(uint8_t ext_len); uint8_t *get_payload_buf(uint8_t ext_len);
uint8_t *get_payload_buf_send(uint8_t ext_len); uint8_t *get_payload_buf_send(uint8_t ext_len);
int icmpv6_demultiplex(const icmpv6_hdr_t *hdr); 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); void ipv6_process(void);
addr_list_t *ipv6_iface_addr_prefix_eq(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);
addr_list_t *ipv6_iface_addr_match(const 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); uint32_t get_remaining_time(timex_t *t);
void set_remaining_time(timex_t *t, uint32_t time); void set_remaining_time(timex_t *t, uint32_t time);

View File

@ -25,6 +25,7 @@
#define _SIXLOWPAN_LOWPAN_H #define _SIXLOWPAN_LOWPAN_H
#include "mutex.h" #include "mutex.h"
#include "net_if.h"
#include "vtimer.h" #include "vtimer.h"
#include "sixlowpan/lowpan.h" #include "sixlowpan/lowpan.h"
@ -42,9 +43,8 @@ typedef struct {
extern uint16_t local_address; extern uint16_t local_address;
extern mutex_t lowpan_context_mutex; extern mutex_t lowpan_context_mutex;
void lowpan_read(uint8_t *data, uint8_t length, void lowpan_read(uint8_t *data, uint8_t length, net_if_eui64_t *s_addr,
ieee_802154_long_t *s_laddr, net_if_eui64_t *d_addr);
ieee_802154_long_t *d_laddr);
uint8_t lowpan_context_len(void); uint8_t lowpan_context_len(void);
lowpan_context_t *lowpan_context_update(uint8_t num, lowpan_context_t *lowpan_context_update(uint8_t num,
const ipv6_addr_t *prefix, const ipv6_addr_t *prefix,

View File

@ -191,15 +191,11 @@ rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp)
return NULL; 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_send_mutex);
mutex_init(&rpl_recv_mutex); mutex_init(&rpl_recv_mutex);
if (rpl_address == 0) {
return SIXLOWERROR_ADDRESS;
}
rpl_instances_init(); rpl_instances_init();
/* initialize routing table */ /* initialize routing table */
@ -213,11 +209,15 @@ uint8_t rpl_init(transceiver_type_t trans, uint16_t rpl_address)
objective_functions[0] = rpl_get_of0(); objective_functions[0] = rpl_get_of0();
/* objective_functions[1] = rpl_get_of_ETX() */ /* objective_functions[1] = rpl_get_of_ETX() */
sixlowpan_lowpan_init(trans, rpl_address, 0); if (!sixlowpan_lowpan_init()) {
return 0;
}
sixlowpan_lowpan_init_interface(if_id);
/* need link local prefix to query _our_ corresponding address */ /* need link local prefix to query _our_ corresponding address */
ipv6_addr_t ll_address; ipv6_addr_t ll_address;
ipv6_addr_set_link_local_prefix(&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); ipv6_register_rpl_handler(rpl_process_pid);
/* initialize ETX-calculation if needed */ /* initialize ETX-calculation if needed */
@ -932,7 +932,7 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
ipv6_send_buf->length = HTONS(p_len); ipv6_send_buf->length = HTONS(p_len);
memcpy(&(ipv6_send_buf->destaddr), destination, 16); 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 = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len);
icmp_send_buf->checksum = 0; icmp_send_buf->checksum = 0;

View File

@ -35,7 +35,7 @@
#define RPL_PKT_RECV_BUF_SIZE 16 #define RPL_PKT_RECV_BUF_SIZE 16
#define RPL_PROCESS_STACKSIZE KERNEL_CONF_STACKSIZE_DEFAULT #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); void rpl_init_root(void);
rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp); rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp);

View File

@ -357,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("\tminhoprankincrease :\t%04X\n", my_dodag->minhoprankincrease);
DEBUG("\tdefault_lifetime:\t%02X\n", my_dodag->default_lifetime); DEBUG("\tdefault_lifetime:\t%02X\n", my_dodag->default_lifetime);
DEBUG("\tgrounded:\t%02X\n", my_dodag->grounded); 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 rank\t%02X\n", my_dodag->my_preferred_parent->rank);
DEBUG("\tmy_preferred_parent lifetime\t%04X\n", my_dodag->my_preferred_parent->lifetime); DEBUG("\tmy_preferred_parent lifetime\t%04X\n", my_dodag->my_preferred_parent->lifetime);

View File

@ -121,9 +121,11 @@ void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header,
printf("--- %s TCP packet: ---\n", printf("--- %s TCP packet: ---\n",
(in_or_out == INC_PACKET ? "Incoming" : "Outgoing")); (in_or_out == INC_PACKET ? "Incoming" : "Outgoing"));
printf("IPv6 Source: %s\n", 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", 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("TCP Length: %x\n", ipv6_header->length - TCP_HDR_LEN);
printf("Source Port: %x, Dest. Port: %x\n", printf("Source Port: %x, Dest. Port: %x\n",
NTOHS(tcp_header->src_port), NTOHS(tcp_header->dst_port)); 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->type,
current_socket->protocol); current_socket->protocol);
printf("Local address: %s\n", printf("Local address: %s\n",
ipv6_addr_to_str(addr_str, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
&current_socket->local_address.sin6_addr)); &current_socket->local_address.sin6_addr));
printf("Foreign address: %s\n", printf("Foreign address: %s\n",
ipv6_addr_to_str(addr_str, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
&current_socket->foreign_address.sin6_addr)); &current_socket->foreign_address.sin6_addr));
printf("Local Port: %u, Foreign Port: %u\n", printf("Local Port: %u, Foreign Port: %u\n",
NTOHS(current_socket->local_address.sin6_port), 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(&current_tcp_socket->foreign_address.sin6_addr, return ipv6_sendto(&current_tcp_socket->foreign_address.sin6_addr,
IPPROTO_TCP, (uint8_t *)(current_tcp_packet), IPPROTO_TCP, (uint8_t *)(current_tcp_packet),
compressed_size); compressed_size);
#else #else
switch_tcp_packet_byte_order(current_tcp_packet); switch_tcp_packet_byte_order(current_tcp_packet);
return ipv6_sendto(&current_tcp_socket->foreign_address.sin6_addr, return ipv6_sendto(&current_tcp_socket->foreign_address.sin6_addr,
IPPROTO_TCP, (uint8_t *)(current_tcp_packet), IPPROTO_TCP, (uint8_t *)(current_tcp_packet),
header_length * 4 + payload_length); header_length * 4 + payload_length);
#endif #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(); current_int_tcp_socket->recv_pid = thread_getpid();
/* Local address information */ /* 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(&current_tcp_socket->local_address, PF_INET6, set_socket_address(&current_tcp_socket->local_address, PF_INET6,
HTONS(get_free_source_port(IPPROTO_TCP)), 0, &src_addr); 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]; uint8_t *payload = &send_buffer[IPV6_HDR_LEN + UDP_HDR_LEN];
memcpy(&(temp_ipv6_header->destaddr), &to->sin6_addr, 16); 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->src_port = get_free_source_port(IPPROTO_UDP);
current_udp_packet->dst_port = to->sin6_port; 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; temp_ipv6_header->length = UDP_HDR_LEN + len;
current_udp_packet->checksum = ~ipv6_csum(temp_ipv6_header, current_udp_packet->checksum = ~ipv6_csum(temp_ipv6_header,
(uint8_t*) current_udp_packet, (uint8_t *) current_udp_packet,
UDP_HDR_LEN + len, UDP_HDR_LEN + len,
IPPROTO_UDP); IPPROTO_UDP);
return ipv6_sendto(&to->sin6_addr, IPPROTO_UDP, return ipv6_sendto(&to->sin6_addr, IPPROTO_UDP,
(uint8_t *)(current_udp_packet), (uint8_t *)(current_udp_packet),
NTOHS(current_udp_packet->length)); NTOHS(current_udp_packet->length));
} }
else { else {
return -1; return -1;

View File

@ -23,18 +23,21 @@
#include <string.h> #include <string.h>
#include <inttypes.h> #include <inttypes.h>
#include "destiny/socket.h" /* for AF_INET6 */
#include "inet_pton.h" #include "inet_pton.h"
#include "inet_ntop.h" #include "inet_ntop.h"
#include "net_help.h" #include "net_help.h"
#include "net_if.h" #include "net_if.h"
#include "transceiver.h" #include "transceiver.h"
#ifndef MODULE_SIXLOWPAN
#define ADDR_REGISTERED_MAX (6) #define ADDR_REGISTERED_MAX (6)
#define ADDRS_LEN_MAX (16) #define ADDRS_LEN_MAX (16)
static uint8_t addr_registered = 0; static uint8_t addr_registered = 0;
static uint8_t addrs[ADDR_REGISTERED_MAX][ADDRS_LEN_MAX]; 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(int if_id, int argc, char **argv);
void _net_if_ifconfig_add_ipv6(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_pan_id(int if_id, char *pan_id);
void _net_if_ifconfig_set_channel(int if_id, char *channel); void _net_if_ifconfig_set_channel(int if_id, char *channel);
void _net_if_ifconfig_create(char *transceivers_str); void _net_if_ifconfig_create(char *transceivers_str);
int _net_if_ifconfig_ipv6_addr_convert(net_if_addr_t *addr, char *type, int _net_if_ifconfig_ipv6_addr_convert(net_if_addr_t *addr, void *addr_data,
char *addr_data_str, char *addr_data_len); char *type, char *addr_data_str,
char *addr_data_len);
void _net_if_ifconfig_list(int if_id); void _net_if_ifconfig_list(int if_id);
int isnumber(char *str) int isnumber(char *str)
@ -335,20 +339,60 @@ void _net_if_ifconfig_add_ipv6(int if_id, int argc, char **argv)
type = NULL; 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_str = strtok(addr_str, "/");
addr_data_len = strtok(NULL, "/"); 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(); add_usage();
return; 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) { if (net_if_add_address(if_id, &addr) < 0) {
add_usage(); add_usage();
return; return;
} }
addr_registered++; addr_registered++;
#endif
} }
void _net_if_ifconfig_add(int if_id, int argc, char **argv) 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) static inline int _is_multicast(uint8_t *addr)
{ {
#ifdef MODULE_SIXLOWPAN
return ipv6_addr_is_multicast((ipv6_addr_t *) addr);
#else
return *addr == 0xff; return *addr == 0xff;
#endif
} }
static inline int _is_link_local(uint8_t *addr) 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) || return (addr[0] == 0xfe && addr[1] == 0x80) ||
(_is_multicast(addr) && (addr[1] & 0x0f) == 2); (_is_multicast(addr) && (addr[1] & 0x0f) == 2);
#endif
} }
int _set_protocol_from_type(char *type, net_if_addr_t *addr) 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, int _net_if_ifconfig_ipv6_addr_convert(net_if_addr_t *addr, void *addr_data,
char *addr_data_str, char *addr_data_len) char *type, char *addr_data_str,
char *addr_data_len)
{ {
if (addr_data_len && !isnumber(addr_data_len)) { if (addr_data_len && !isnumber(addr_data_len)) {
return 0; 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)) { if (!inet_pton(AF_INET6, addr_data_str, addr->addr_data)) {
return 0; return 0;