Contiki 2.6

netflood.c

Go to the documentation of this file.
00001 /**
00002  * \addtogroup rimenetflood
00003  * @{
00004  */
00005 
00006 /*
00007  * Copyright (c) 2006, Swedish Institute of Computer Science.
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. Neither the name of the Institute nor the names of its contributors
00019  *    may be used to endorse or promote products derived from this software
00020  *    without specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * This file is part of the Contiki operating system.
00035  *
00036  * $Id: netflood.c,v 1.6 2010/01/25 13:54:06 adamdunkels Exp $
00037  */
00038 
00039 /**
00040  * \file
00041  *         Best-effort network flooding (netflood)
00042  * \author
00043  *         Adam Dunkels <adam@sics.se>
00044  */
00045 
00046 #include "net/rime/netflood.h"
00047 
00048 #include <string.h>
00049 
00050 #define HOPS_MAX 16
00051 
00052 struct netflood_hdr {
00053   uint16_t originator_seqno;
00054   rimeaddr_t originator;
00055   uint16_t hops;
00056 };
00057 
00058 #define DEBUG 0
00059 #if DEBUG
00060 #include <stdio.h>
00061 #define PRINTF(...) printf(__VA_ARGS__)
00062 #else
00063 #define PRINTF(...)
00064 #endif
00065 
00066 /*---------------------------------------------------------------------------*/
00067 static int
00068 send(struct netflood_conn *c)
00069 {
00070   PRINTF("%d.%d: netflood send to ipolite\n",
00071          rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
00072   return ipolite_send(&c->c, c->queue_time, 4);
00073 }
00074 /*---------------------------------------------------------------------------*/
00075 static void
00076 recv_from_ipolite(struct ipolite_conn *ipolite, const rimeaddr_t *from)
00077 {
00078   struct netflood_conn *c = (struct netflood_conn *)ipolite;
00079   struct netflood_hdr hdr;
00080   uint8_t hops;
00081   struct queuebuf *queuebuf;
00082 
00083   memcpy(&hdr, packetbuf_dataptr(), sizeof(struct netflood_hdr));
00084   hops = hdr.hops;
00085 
00086   /* Remember packet if we need to forward it. */
00087   queuebuf = queuebuf_new_from_packetbuf();
00088 
00089   packetbuf_hdrreduce(sizeof(struct netflood_hdr));
00090   if(c->u->recv != NULL) {
00091     if(!(rimeaddr_cmp(&hdr.originator, &c->last_originator) &&
00092          hdr.originator_seqno <= c->last_originator_seqno)) {
00093 
00094       if(c->u->recv(c, from, &hdr.originator, hdr.originator_seqno,
00095                     hops)) {
00096         
00097         if(queuebuf != NULL) {
00098           queuebuf_to_packetbuf(queuebuf);
00099           queuebuf_free(queuebuf);
00100           queuebuf = NULL;
00101           memcpy(&hdr, packetbuf_dataptr(), sizeof(struct netflood_hdr));
00102           
00103           /* Rebroadcast received packet. */
00104           if(hops < HOPS_MAX) {
00105             PRINTF("%d.%d: netflood rebroadcasting %d.%d/%d (%d.%d/%d) hops %d\n",
00106                    rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00107                    hdr.originator.u8[0], hdr.originator.u8[1],
00108                    hdr.originator_seqno,
00109                    c->last_originator.u8[0], c->last_originator.u8[1],
00110                    c->last_originator_seqno,
00111                   hops);
00112             hdr.hops++;
00113             memcpy(packetbuf_dataptr(), &hdr, sizeof(struct netflood_hdr));
00114             send(c);
00115             rimeaddr_copy(&c->last_originator, &hdr.originator);
00116             c->last_originator_seqno = hdr.originator_seqno;
00117           }
00118         }
00119       }
00120     }
00121   }
00122   if(queuebuf != NULL) {
00123     queuebuf_free(queuebuf);
00124   }
00125 }
00126 /*---------------------------------------------------------------------------*/
00127 static void
00128 sent(struct ipolite_conn *ipolite)
00129 {
00130   struct netflood_conn *c = (struct netflood_conn *)ipolite;
00131   if(c->u->sent != NULL) {
00132     c->u->sent(c);
00133   }
00134 }
00135 /*---------------------------------------------------------------------------*/
00136 static void
00137 dropped(struct ipolite_conn *ipolite)
00138 {
00139   struct netflood_conn *c = (struct netflood_conn *)ipolite;
00140   if(c->u->dropped != NULL) {
00141     c->u->dropped(c);
00142   }
00143 }
00144 /*---------------------------------------------------------------------------*/
00145 static const struct ipolite_callbacks netflood = {recv_from_ipolite, sent, dropped};
00146 /*---------------------------------------------------------------------------*/
00147 void
00148 netflood_open(struct netflood_conn *c, clock_time_t queue_time,
00149         uint16_t channel, const struct netflood_callbacks *u)
00150 {
00151   ipolite_open(&c->c, channel, 1, &netflood);
00152   c->u = u;
00153   c->queue_time = queue_time;
00154 }
00155 /*---------------------------------------------------------------------------*/
00156 void
00157 netflood_close(struct netflood_conn *c)
00158 {
00159   ipolite_close(&c->c);
00160 }
00161 /*---------------------------------------------------------------------------*/
00162 int
00163 netflood_send(struct netflood_conn *c, uint8_t seqno)
00164 {
00165   if(packetbuf_hdralloc(sizeof(struct netflood_hdr))) {
00166     struct netflood_hdr *hdr = packetbuf_hdrptr();
00167     rimeaddr_copy(&hdr->originator, &rimeaddr_node_addr);
00168     rimeaddr_copy(&c->last_originator, &hdr->originator);
00169     c->last_originator_seqno = hdr->originator_seqno = seqno;
00170     hdr->hops = 0;
00171     PRINTF("%d.%d: netflood sending '%s'\n",
00172            rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00173            (char *)packetbuf_dataptr());
00174     return ipolite_send(&c->c, 0, 4);
00175   }
00176   return 0;
00177 }
00178 /*---------------------------------------------------------------------------*/
00179 void
00180 netflood_cancel(struct netflood_conn *c)
00181 {
00182   ipolite_cancel(&c->c);
00183 }
00184 /*---------------------------------------------------------------------------*/
00185 /** @} */