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 static void icmp_input(
void);
109 static void icmp_output(
void);
110 static void mcast_fwd(
void *p);
114 struct multicast_on_behalf{
116 uip_ipaddr_t mcast_ip;
117 uint8_t mcast_payload[
UIP_BUFSIZE - UIP_IPUDPH_LEN];
119 #define UIP_ICMP_MOB 18 123 static struct multicast_on_behalf *locmobptr;
128 UIP_ICMP6_HANDLER_CODE_ANY, icmp_input);
133 uint16_t payload_len=0;
136 struct multicast_on_behalf *mob;
137 mob = (
struct multicast_on_behalf *)UIP_ICMP_PAYLOAD;
138 memcpy(&mob->mcast_payload, &
uip_buf[UIP_IPUDPH_LEN], uip_slen);
149 payload_len = UIP_ICMP_MOB + uip_slen;
155 VERBOSE_PRINTF(
"ESMRF: ICMPv6 Out - Hdr @ %p, payload @ %p to: ",
UIP_ICMP_BUF, mob);
159 uipbuf_set_len_field(
UIP_IP_BUF, UIP_ICMPH_LEN + payload_len);
167 uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + payload_len;
169 VERBOSE_PRINTF(
"ESMRF: ICMPv6 Out - %u bytes, uip_len %u bytes, uip_ext_len %u bytes\n",
173 ESMRF_STATS_ADD(icmp_out);
180 #if UIP_CONF_IPV6_CHECKS 182 PRINTF(
"ESMRF: ICMPv6 In, bad ICMP code\n");
183 ESMRF_STATS_ADD(icmp_bad);
187 PRINTF(
"ESMRF: ICMPv6 In, bad TTL\n");
188 ESMRF_STATS_ADD(icmp_bad);
195 PRINTF(
"ESMRF: ICMPv6 In from ");
201 VERBOSE_PRINTF(
"ESMRF: ICMPv6 In, parse from %p to %p\n",
203 (uint8_t *)UIP_ICMP_PAYLOAD +
uip_len -
204 uip_l3_icmp_hdr_len);
207 locmobptr = (
struct multicast_on_behalf *) UIP_ICMP_PAYLOAD;
208 loclen =
uip_len - (uip_l3_icmp_hdr_len + UIP_ICMP_MOB);
215 c->
rport = locmobptr->mcast_port;
218 memcpy(&
uip_buf[UIP_IPUDPH_LEN], locmobptr->mcast_payload,
230 UIP_UDP_BUF->udpchksum = 0;
234 memcpy(
uip_buf, &mcast_buf, mcast_len);
238 UIP_UDP_BUF->udpchksum = 0;
242 PRINTF(
"ESMRF: Forward this packet\n");
252 memcpy(
uip_buf, &mcast_buf, mcast_len);
263 uip_ipaddr_t *parent_ipaddr;
264 const uip_lladdr_t *parent_lladdr;
276 PRINTF(
"ESMRF: No DODAG\n");
277 UIP_MCAST6_STATS_ADD(mcast_dropped);
278 return UIP_MCAST6_DROP;
282 parent_ipaddr = rpl_parent_get_ipaddr(d->preferred_parent);
285 if(parent_lladdr == NULL) {
286 PRINTF(
"ESMRF: No Parent found\n");
287 UIP_MCAST6_STATS_ADD(mcast_dropped);
288 return UIP_MCAST6_DROP;
295 if(memcmp(parent_lladdr, packetbuf_addr(PACKETBUF_ADDR_SENDER),
297 PRINTF(
"ESMRF: Routable in but ESMRF ignored it\n");
298 UIP_MCAST6_STATS_ADD(mcast_dropped);
299 return UIP_MCAST6_DROP;
303 UIP_MCAST6_STATS_ADD(mcast_dropped);
304 PRINTF(
"ESMRF: TTL too low\n");
305 return UIP_MCAST6_DROP;
308 UIP_MCAST6_STATS_ADD(mcast_in_all);
309 UIP_MCAST6_STATS_ADD(mcast_in_unique);
315 UIP_MCAST6_STATS_ADD(mcast_fwd);
322 fwd_delay = ESMRF_FWD_DELAY();
325 #if ESMRF_MIN_FWD_DELAY 326 if(fwd_delay < ESMRF_MIN_FWD_DELAY) {
327 fwd_delay = ESMRF_MIN_FWD_DELAY;
338 fwd_spread = ESMRF_INTERVAL_COUNT;
339 if(fwd_spread > ESMRF_MAX_SPREAD) {
340 fwd_spread = ESMRF_MAX_SPREAD;
343 fwd_delay = fwd_delay * (1 + ((
random_rand() >> 11) % fwd_spread));
348 ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL);
350 PRINTF(
"ESMRF: %u bytes: fwd in %u [%u]\n",
351 uip_len, fwd_delay, fwd_spread);
353 PRINTF(
"ESMRF: Group unknown, dropping\n");
357 if(!uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr)) {
358 PRINTF(
"ESMRF: Not a group member. No further processing\n");
359 return UIP_MCAST6_DROP;
361 PRINTF(
"ESMRF: Ours. Deliver to upper layers\n");
362 UIP_MCAST6_STATS_ADD(mcast_in_ours);
363 return UIP_MCAST6_ACCEPT;
371 UIP_MCAST6_STATS_INIT(&stats);
385 PRINTF(
"ESMRF: There is no DODAG\n");
388 if(dag_t->rank == 256){
389 PRINTF(
"ESMRF: I am the Root, thus send the multicast packet normally. \n");
393 PRINTF(
"ESMRF: I am not the Root\n");
394 PRINTF(
"Send multicast-on-befalf message (ICMPv6) instead to ");
395 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.
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.