44 #include "contiki-net.h" 53 #if ROUTING_CONF_RPL_LITE 54 #include "net/routing/rpl-lite/rpl.h" 56 #if ROUTING_CONF_RPL_CLASSIC 57 #include "net/routing/rpl-classic/rpl.h" 61 extern uint16_t uip_slen;
66 #define ESMRF_VERBOSE NONE 68 #if DEBUG && ESMRF_VERBOSE 69 #define VERBOSE_PRINTF(...) PRINTF(__VA_ARGS__) 70 #define VERBOSE_PRINT_SEED(s) PRINT_SEED(s) 72 #define VERBOSE_PRINTF(...) 73 #define VERBOSE_PRINT_SEED(...) 79 static struct esmrf_stats stats;
81 #define ESMRF_STATS_ADD(x) stats.x++ 82 #define ESMRF_STATS_INIT() do { memset(&stats, 0, sizeof(stats)); } while(0) 84 #define ESMRF_STATS_ADD(x) 85 #define ESMRF_STATS_INIT() 91 #define ESMRF_FWD_DELAY() (CLOCK_SECOND / 8) 93 #define ESMRF_INTERVAL_COUNT ((CLOCK_SECOND >> 2) / fwd_delay) 97 static struct ctimer mcast_periodic;
98 static uint8_t mcast_len;
100 static uint8_t fwd_delay;
101 static uint8_t fwd_spread;
103 static uip_ipaddr_t src_ip;
104 static uip_ipaddr_t des_ip;
108 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) 109 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 110 #define UIP_ICMP_PAYLOAD ((unsigned char *)&uip_buf[uip_l2_l3_icmp_hdr_len]) 111 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) 115 static void icmp_input(
void);
116 static void icmp_output(
void);
117 static void mcast_fwd(
void *p);
118 int remove_ext_hdr(
void);
122 struct multicast_on_behalf{
124 uip_ipaddr_t mcast_ip;
127 #define UIP_ICMP_MOB 18 131 static struct multicast_on_behalf *locmobptr;
136 UIP_ICMP6_HANDLER_CODE_ANY, icmp_input);
141 uint16_t payload_len=0;
144 struct multicast_on_behalf *mob;
145 mob = (
struct multicast_on_behalf *)UIP_ICMP_PAYLOAD;
157 payload_len = UIP_ICMP_MOB + uip_slen;
163 VERBOSE_PRINTF(
"ESMRF: ICMPv6 Out - Hdr @ %p, payload @ %p to: ",
UIP_ICMP_BUF, mob);
167 UIP_IP_BUF->len[0] = (UIP_ICMPH_LEN + payload_len) >> 8;
168 UIP_IP_BUF->len[1] = (UIP_ICMPH_LEN + payload_len) & 0xff;
176 uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + payload_len;
178 VERBOSE_PRINTF(
"ESMRF: ICMPv6 Out - %u bytes, uip_len %u bytes, uip_ext_len %u bytes\n",
182 ESMRF_STATS_ADD(icmp_out);
189 #if UIP_CONF_IPV6_CHECKS 191 PRINTF(
"ESMRF: ICMPv6 In, bad ICMP code\n");
192 ESMRF_STATS_ADD(icmp_bad);
196 PRINTF(
"ESMRF: ICMPv6 In, bad TTL\n");
197 ESMRF_STATS_ADD(icmp_bad);
204 PRINTF(
"ESMRF: ICMPv6 In from ");
208 ESMRF_STATS_ADD(icmp_in);
210 VERBOSE_PRINTF(
"ESMRF: ICMPv6 In, parse from %p to %p\n",
212 (uint8_t *)UIP_ICMP_PAYLOAD +
uip_len -
213 uip_l2_l3_icmp_hdr_len);
216 locmobptr = (
struct multicast_on_behalf *) UIP_ICMP_PAYLOAD;
217 loclen =
uip_len - (uip_l2_l3_icmp_hdr_len + UIP_ICMP_MOB);
224 c->
rport = locmobptr->mcast_port;
239 UIP_UDP_BUF->udpchksum = 0;
247 UIP_UDP_BUF->udpchksum = 0;
251 PRINTF(
"ESMRF: Forward this packet\n");
272 uip_ipaddr_t *parent_ipaddr;
273 const uip_lladdr_t *parent_lladdr;
285 PRINTF(
"ESMRF: No DODAG\n");
286 UIP_MCAST6_STATS_ADD(mcast_dropped);
287 return UIP_MCAST6_DROP;
291 parent_ipaddr = rpl_parent_get_ipaddr(d->preferred_parent);
292 parent_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(parent_ipaddr);
294 if(parent_lladdr == NULL) {
295 PRINTF(
"ESMRF: No Parent found\n");
296 UIP_MCAST6_STATS_ADD(mcast_dropped);
297 return UIP_MCAST6_DROP;
304 if(memcmp(parent_lladdr, packetbuf_addr(PACKETBUF_ADDR_SENDER),
306 PRINTF(
"ESMRF: Routable in but ESMRF ignored it\n");
307 UIP_MCAST6_STATS_ADD(mcast_dropped);
308 return UIP_MCAST6_DROP;
312 UIP_MCAST6_STATS_ADD(mcast_dropped);
313 PRINTF(
"ESMRF: TTL too low\n");
314 return UIP_MCAST6_DROP;
317 UIP_MCAST6_STATS_ADD(mcast_in_all);
318 UIP_MCAST6_STATS_ADD(mcast_in_unique);
324 UIP_MCAST6_STATS_ADD(mcast_fwd);
331 fwd_delay = ESMRF_FWD_DELAY();
334 #if ESMRF_MIN_FWD_DELAY 335 if(fwd_delay < ESMRF_MIN_FWD_DELAY) {
336 fwd_delay = ESMRF_MIN_FWD_DELAY;
347 fwd_spread = ESMRF_INTERVAL_COUNT;
348 if(fwd_spread > ESMRF_MAX_SPREAD) {
349 fwd_spread = ESMRF_MAX_SPREAD;
352 fwd_delay = fwd_delay * (1 + ((
random_rand() >> 11) % fwd_spread));
357 ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL);
359 PRINTF(
"ESMRF: %u bytes: fwd in %u [%u]\n",
360 uip_len, fwd_delay, fwd_spread);
362 PRINTF(
"ESMRF: Group unknown, dropping\n");
366 if(!uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr)) {
367 PRINTF(
"ESMRF: Not a group member. No further processing\n");
368 return UIP_MCAST6_DROP;
370 PRINTF(
"ESMRF: Ours. Deliver to upper layers\n");
371 UIP_MCAST6_STATS_ADD(mcast_in_ours);
372 return UIP_MCAST6_ACCEPT;
380 UIP_MCAST6_STATS_INIT(&stats);
394 PRINTF(
"ESMRF: There is no DODAG\n");
397 if(dag_t->rank == 256){
398 PRINTF(
"ESMRF: I am the Root, thus send the multicast packet normally. \n");
402 PRINTF(
"ESMRF: I am not the Root\n");
403 PRINTF(
"Send multicast-on-befalf message (ICMPv6) instead to ");
404 PRINT6ADDR(&dag_t->dag_id);
void uip_mcast6_route_init()
Multicast routing table init routine.
#define UIP_IP_BUF
Pointer to IP header.
uint8_t tcpip_output(const uip_lladdr_t *a)
Output packet to layer 2 The eventual parameter is the MAC address of the destination.
uint16_t uip_len
The length of the packet in the uip_buf buffer.
The data structure used to represent a multicast engine.
void tcpip_ipv6_output(void)
This function does address resolution and then calls tcpip_output.
void uip_process(uint8_t flag)
process the options within a hop by hop or destination option header
#define UIP_ICMP_BUF
Pointer to ICMP header.
#define UIP_BUFSIZE
The size of the uIP packet buffer.
A set of debugging macros for the IP stack
#define UIP_LLADDR_LEN
802.15.4 address
This header file contains configuration directives for uIPv6 multicast support.
uint8_t(* in)(void)
Process an incoming multicast datagram and determine whether it should be delivered up the stack or n...
#define ICMP6_ESMRF
ESMRF Multicast.
#define UIP_LLH_LEN
The link level header length.
struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Create a new UDP connection.
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
Routing driver header file
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
rpl_dag_t * rpl_get_any_dag(void)
Returns pointer to any DAG (for compatibility with legagy RPL code)
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
Header file for multicast routing table manipulation.
void(* out)(void)
Process an outgoing datagram with a multicast IPv6 destination address.
Header file for the uIP TCP/IP stack.
void(* init)(void)
Initialize the multicast engine.
uint8_t uip_ext_len
The length of the extension headers.
uint16_t uip_icmp6chksum(void)
Calculate the ICMP checksum of the packet in uip_buf.
uip_ipaddr_t ripaddr
The IP address of the remote peer.
Header file for IPv6 multicast forwarding stats maintenance
void uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler)
Register a handler which can handle a specific ICMPv6 message type.
Header file for the Packet buffer (packetbuf) management
Include file for the Contiki low-layer network stack (NETSTACK)
unsigned short random_rand(void)
Generates a new random number using the cc2538 RNG.
uip_mcast6_route_t * uip_mcast6_route_lookup(uip_ipaddr_t *group)
Lookup a multicast route.
void uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
Source address selection, see RFC 3484.
uint16_t rport
The remote port number in network byte order.
Header file for the Enhanced Stateless Multicast RPL Forwarding (ESMRF)
Representation of a uIP UDP connection.