44 #include "contiki-net.h" 53 #if ROUTING_CONF_RPL_LITE 54 #include "net/routing/rpl-lite/rpl.h" 57 #if ROUTING_CONF_RPL_CLASSIC 58 #include "net/routing/rpl-classic/rpl.h" 59 #include "net/routing/rpl-classic/rpl-private.h" 63 extern uint16_t uip_slen;
68 #define ESMRF_VERBOSE NONE 70 #if DEBUG && ESMRF_VERBOSE 71 #define VERBOSE_PRINTF(...) PRINTF(__VA_ARGS__) 72 #define VERBOSE_PRINT_SEED(s) PRINT_SEED(s) 74 #define VERBOSE_PRINTF(...) 75 #define VERBOSE_PRINT_SEED(...) 81 static struct esmrf_stats stats;
83 #define ESMRF_STATS_ADD(x) stats.x++ 84 #define ESMRF_STATS_INIT() do { memset(&stats, 0, sizeof(stats)); } while(0) 86 #define ESMRF_STATS_ADD(x) 87 #define ESMRF_STATS_INIT() 93 #define ESMRF_FWD_DELAY() (CLOCK_SECOND / 8) 95 #define ESMRF_INTERVAL_COUNT ((CLOCK_SECOND >> 2) / fwd_delay) 99 static struct ctimer mcast_periodic;
100 static uint8_t mcast_len;
102 static uint8_t fwd_delay;
103 static uint8_t fwd_spread;
105 static uip_ipaddr_t src_ip;
106 static uip_ipaddr_t des_ip;
110 static void icmp_input(
void);
111 static void icmp_output(
void);
112 static void mcast_fwd(
void *p);
116 struct multicast_on_behalf{
118 uip_ipaddr_t mcast_ip;
119 uint8_t mcast_payload[
UIP_BUFSIZE - UIP_IPUDPH_LEN];
121 #define UIP_ICMP_MOB 18 125 static struct multicast_on_behalf *locmobptr;
130 UIP_ICMP6_HANDLER_CODE_ANY, icmp_input);
135 uint16_t payload_len=0;
138 struct multicast_on_behalf *mob;
139 mob = (
struct multicast_on_behalf *)UIP_ICMP_PAYLOAD;
140 memcpy(&mob->mcast_payload, &
uip_buf[UIP_IPUDPH_LEN], uip_slen);
151 payload_len = UIP_ICMP_MOB + uip_slen;
157 VERBOSE_PRINTF(
"ESMRF: ICMPv6 Out - Hdr @ %p, payload @ %p to: ",
UIP_ICMP_BUF, mob);
161 uipbuf_set_len_field(
UIP_IP_BUF, UIP_ICMPH_LEN + payload_len);
169 uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + payload_len;
171 VERBOSE_PRINTF(
"ESMRF: ICMPv6 Out - %u bytes, uip_len %u bytes, uip_ext_len %u bytes\n",
175 ESMRF_STATS_ADD(icmp_out);
182 #if UIP_CONF_IPV6_CHECKS 184 PRINTF(
"ESMRF: ICMPv6 In, bad ICMP code\n");
185 ESMRF_STATS_ADD(icmp_bad);
189 PRINTF(
"ESMRF: ICMPv6 In, bad TTL\n");
190 ESMRF_STATS_ADD(icmp_bad);
197 PRINTF(
"ESMRF: ICMPv6 In from ");
203 VERBOSE_PRINTF(
"ESMRF: ICMPv6 In, parse from %p to %p\n",
205 (uint8_t *)UIP_ICMP_PAYLOAD +
uip_len -
206 uip_l3_icmp_hdr_len);
209 locmobptr = (
struct multicast_on_behalf *) UIP_ICMP_PAYLOAD;
210 loclen =
uip_len - (uip_l3_icmp_hdr_len + UIP_ICMP_MOB);
217 c->
rport = locmobptr->mcast_port;
220 memcpy(&
uip_buf[UIP_IPUDPH_LEN], locmobptr->mcast_payload,
232 UIP_UDP_BUF->udpchksum = 0;
236 memcpy(
uip_buf, &mcast_buf, mcast_len);
240 UIP_UDP_BUF->udpchksum = 0;
244 PRINTF(
"ESMRF: Forward this packet\n");
254 memcpy(
uip_buf, &mcast_buf, mcast_len);
265 uip_ipaddr_t *parent_ipaddr;
266 const uip_lladdr_t *parent_lladdr;
278 PRINTF(
"ESMRF: No DODAG\n");
279 UIP_MCAST6_STATS_ADD(mcast_dropped);
280 return UIP_MCAST6_DROP;
284 parent_ipaddr = rpl_parent_get_ipaddr(d->preferred_parent);
287 if(parent_lladdr == NULL) {
288 PRINTF(
"ESMRF: No Parent found\n");
289 UIP_MCAST6_STATS_ADD(mcast_dropped);
290 return UIP_MCAST6_DROP;
297 if(memcmp(parent_lladdr, packetbuf_addr(PACKETBUF_ADDR_SENDER),
299 PRINTF(
"ESMRF: Routable in but ESMRF ignored it\n");
300 UIP_MCAST6_STATS_ADD(mcast_dropped);
301 return UIP_MCAST6_DROP;
305 UIP_MCAST6_STATS_ADD(mcast_dropped);
306 PRINTF(
"ESMRF: TTL too low\n");
307 return UIP_MCAST6_DROP;
310 UIP_MCAST6_STATS_ADD(mcast_in_all);
311 UIP_MCAST6_STATS_ADD(mcast_in_unique);
317 UIP_MCAST6_STATS_ADD(mcast_fwd);
324 fwd_delay = ESMRF_FWD_DELAY();
327 #if ESMRF_MIN_FWD_DELAY 328 if(fwd_delay < ESMRF_MIN_FWD_DELAY) {
329 fwd_delay = ESMRF_MIN_FWD_DELAY;
340 fwd_spread = ESMRF_INTERVAL_COUNT;
341 if(fwd_spread > ESMRF_MAX_SPREAD) {
342 fwd_spread = ESMRF_MAX_SPREAD;
345 fwd_delay = fwd_delay * (1 + ((
random_rand() >> 11) % fwd_spread));
350 ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL);
352 PRINTF(
"ESMRF: %u bytes: fwd in %u [%u]\n",
353 uip_len, fwd_delay, fwd_spread);
355 PRINTF(
"ESMRF: Group unknown, dropping\n");
359 if(!uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr)) {
360 PRINTF(
"ESMRF: Not a group member. No further processing\n");
361 return UIP_MCAST6_DROP;
363 PRINTF(
"ESMRF: Ours. Deliver to upper layers\n");
364 UIP_MCAST6_STATS_ADD(mcast_in_ours);
365 return UIP_MCAST6_ACCEPT;
373 UIP_MCAST6_STATS_INIT(&stats);
387 PRINTF(
"ESMRF: There is no DODAG\n");
390 if(dag_t->rank == RPL_MIN_HOPRANKINC){
391 PRINTF(
"ESMRF: I am the Root, thus send the multicast packet normally. \n");
395 PRINTF(
"ESMRF: I am not the Root\n");
396 PRINTF(
"Send multicast-on-befalf message (ICMPv6) instead to ");
397 PRINT6ADDR(&dag_t->dag_id);
void uip_mcast6_route_init()
Multicast routing table init routine.
#define UIP_IP_BUF
Direct access to IPv6 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.
Public configuration and API declarations for ContikiRPL.
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
Direct access to ICMP, UDP, and TCP headers and payload, with implicit ext header offset (global uip_...
#define UIP_BUFSIZE
The size of the uIP packet buffer.
static void icmp_in(void)
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.
uint16_t uip_ext_len
The length of the extension headers.
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.
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.
const uip_lladdr_t * uip_ds6_nbr_lladdr_from_ipaddr(const uip_ipaddr_t *ipaddr)
Get the link-layer address associated with a specified IPv6 address.
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.
bool uip_remove_ext_hdr(void)
Removes all IPv6 extension headers from uip_buf, updates length fields (uip_len and uip_ext_len) ...
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.