Contiki 2.6

viztool.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010, Loughborough University - Computer Science
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the Institute nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  *
00029  * This file is part of the Contiki operating system.
00030  */
00031 
00032 /**
00033  * \file
00034  *         Small UDP app used to retrieve neighbor cache and routing table
00035  *         entries and send them to an external endpoint
00036  *
00037  * \author
00038  *         George Oikonomou - <oikonomou@users.sourceforge.net>
00039  */
00040 
00041 #include "contiki.h"
00042 #include "contiki-lib.h"
00043 #include "contiki-net.h"
00044 
00045 #include <string.h>
00046 
00047 #define DEBUG DEBUG_NONE
00048 #include "net/uip-debug.h"
00049 
00050 #define UIP_IP_BUF   ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
00051 #define UIP_UDP_BUF  ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00052 
00053 #ifndef VIZTOOL_MAX_PAYLOAD_LEN
00054 #define VIZTOOL_MAX_PAYLOAD_LEN 60
00055 #endif
00056 
00057 static struct uip_udp_conn *server_conn;
00058 static unsigned char buf[VIZTOOL_MAX_PAYLOAD_LEN];
00059 static int8_t len;
00060 
00061 #define VIZTOOL_UDP_PORT   60001
00062 
00063 /* Request Bits */
00064 #define REQUEST_TYPE_ND         1
00065 #define REQUEST_TYPE_RT         2
00066 #define REQUEST_TYPE_DRT        3
00067 #define REQUEST_TYPE_ADDR       4
00068 #define REQUEST_TYPE_TOTALS  0xFF
00069 
00070 extern uip_ds6_netif_t uip_ds6_if;
00071 extern uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB];
00072 extern uip_ds6_nbr_t uip_ds6_nbr_cache[UIP_DS6_NBR_NB];
00073 extern uip_ds6_defrt_t uip_ds6_defrt_list[UIP_DS6_DEFRT_NB];
00074 /*---------------------------------------------------------------------------*/
00075 static uint8_t
00076 process_request() CC_NON_BANKED
00077 {
00078   uint8_t len;
00079   uint8_t count; /* How many did we pack? */
00080   uint8_t i;
00081   uint8_t left;
00082   uint8_t entry_size;
00083 
00084   left = VIZTOOL_MAX_PAYLOAD_LEN - 1;
00085   len = 2; /* start filling the buffer from position [2] */
00086   count = 0;
00087   if(buf[0] == REQUEST_TYPE_ND) {
00088     /* Neighbors */
00089     PRINTF("Neighbors\n");
00090     for(i = buf[1]; i < UIP_DS6_NBR_NB; i++) {
00091       if(uip_ds6_nbr_cache[i].isused) {
00092         entry_size = sizeof(i) + sizeof(uip_ipaddr_t) + sizeof(uip_lladdr_t)
00093             + sizeof(uip_ds6_nbr_cache[i].state);
00094         PRINTF("%02u: ", i);
00095         PRINT6ADDR(&uip_ds6_nbr_cache[i].ipaddr);
00096         PRINTF(" - ");
00097         PRINTLLADDR(&uip_ds6_nbr_cache[i].lladdr);
00098         PRINTF(" - %u\n", uip_ds6_nbr_cache[i].state);
00099 
00100         memcpy(buf + len, &i, sizeof(i));
00101         len += sizeof(i);
00102         memcpy(buf + len, &uip_ds6_nbr_cache[i].ipaddr, sizeof(uip_ipaddr_t));
00103         len += sizeof(uip_ipaddr_t);
00104         memcpy(buf + len, &uip_ds6_nbr_cache[i].lladdr, sizeof(uip_lladdr_t));
00105         len += sizeof(uip_lladdr_t);
00106         memcpy(buf + len, &uip_ds6_nbr_cache[i].state,
00107             sizeof(uip_ds6_nbr_cache[i].state));
00108         len += sizeof(uip_ds6_nbr_cache[i].state);
00109 
00110         count++;
00111         left -= entry_size;
00112 
00113         if(left < entry_size) {
00114           break;
00115         }
00116       }
00117     }
00118   } else if(buf[0] == REQUEST_TYPE_RT) {
00119     uint32_t flip = 0;
00120     PRINTF("Routing table\n");
00121     for(i = buf[1]; i < UIP_DS6_ROUTE_NB; i++) {
00122       if(uip_ds6_routing_table[i].isused) {
00123         entry_size = sizeof(i) + sizeof(uip_ds6_routing_table[i].ipaddr)
00124             + sizeof(uip_ds6_routing_table[i].length)
00125             + sizeof(uip_ds6_routing_table[i].metric)
00126             + sizeof(uip_ds6_routing_table[i].nexthop)
00127             + sizeof(uip_ds6_routing_table[i].state.lifetime)
00128             + sizeof(uip_ds6_routing_table[i].state.learned_from);
00129 
00130         memcpy(buf + len, &i, sizeof(i));
00131         len += sizeof(i);
00132         memcpy(buf + len, &uip_ds6_routing_table[i].ipaddr,
00133             sizeof(uip_ds6_routing_table[i].ipaddr));
00134         len += sizeof(uip_ds6_routing_table[i].ipaddr);
00135         memcpy(buf + len, &uip_ds6_routing_table[i].length,
00136             sizeof(uip_ds6_routing_table[i].length));
00137         len += sizeof(uip_ds6_routing_table[i].length);
00138         memcpy(buf + len, &uip_ds6_routing_table[i].metric,
00139             sizeof(uip_ds6_routing_table[i].metric));
00140         len += sizeof(uip_ds6_routing_table[i].metric);
00141         memcpy(buf + len, &uip_ds6_routing_table[i].nexthop,
00142             sizeof(uip_ds6_routing_table[i].nexthop));
00143         len += sizeof(uip_ds6_routing_table[i].nexthop);
00144 
00145         PRINT6ADDR(&uip_ds6_routing_table[i].ipaddr);
00146         PRINTF(" - %02x", uip_ds6_routing_table[i].length);
00147         PRINTF(" - %02x", uip_ds6_routing_table[i].metric);
00148         PRINTF(" - ");
00149         PRINT6ADDR(&uip_ds6_routing_table[i].nexthop);
00150 
00151         flip = uip_htonl(uip_ds6_routing_table[i].state.lifetime);
00152         memcpy(buf + len, &flip, sizeof(flip));
00153         len += sizeof(flip);
00154         PRINTF(" - %08lx", uip_ds6_routing_table[i].state.lifetime);
00155 
00156         memcpy(buf + len, &uip_ds6_routing_table[i].state.learned_from,
00157             sizeof(uip_ds6_routing_table[i].state.learned_from));
00158         len += sizeof(uip_ds6_routing_table[i].state.learned_from);
00159 
00160         PRINTF(" - %02x [%u]\n", uip_ds6_routing_table[i].state.learned_from,
00161              entry_size);
00162 
00163         count++;
00164         left -= entry_size;
00165 
00166         if(left < entry_size) {
00167           break;
00168         }
00169       }
00170     }
00171   } else if (buf[0] == REQUEST_TYPE_DRT) {
00172     uint32_t flip = 0;
00173     PRINTF("Default Routes\n");
00174     for(i = buf[1]; i < UIP_DS6_DEFRT_NB; i++) {
00175       if(uip_ds6_defrt_list[i].isused) {
00176         entry_size = sizeof(i) + sizeof(uip_ds6_defrt_list[i].ipaddr)
00177             + sizeof(uip_ds6_defrt_list[i].isinfinite);
00178 
00179         memcpy(buf + len, &i, sizeof(i));
00180         len += sizeof(i);
00181         memcpy(buf + len, &uip_ds6_defrt_list[i].ipaddr,
00182             sizeof(uip_ds6_defrt_list[i].ipaddr));
00183         len += sizeof(uip_ds6_defrt_list[i].ipaddr);
00184         memcpy(buf + len, &uip_ds6_defrt_list[i].isinfinite,
00185             sizeof(uip_ds6_defrt_list[i].isinfinite));
00186         len += sizeof(uip_ds6_defrt_list[i].isinfinite);
00187 
00188         PRINT6ADDR(&uip_ds6_defrt_list[i].ipaddr);
00189         PRINTF(" - %u\n", uip_ds6_defrt_list[i].isinfinite);
00190         count++;
00191         left -= entry_size;
00192 
00193         if(left < entry_size) {
00194           break;
00195         }
00196       }
00197     }
00198   } else if (buf[0] == REQUEST_TYPE_ADDR) {
00199     PRINTF("Unicast Addresses\n");
00200     for(i = buf[1]; i < UIP_DS6_ADDR_NB; i++) {
00201       if(uip_ds6_if.addr_list[i].isused) {
00202         entry_size = sizeof(i) + sizeof(uip_ds6_if.addr_list[i].ipaddr);
00203 
00204         memcpy(buf + len, &i, sizeof(i));
00205         len += sizeof(i);
00206         memcpy(buf + len, &uip_ds6_if.addr_list[i].ipaddr,
00207             sizeof(uip_ds6_if.addr_list[i].ipaddr));
00208         len += sizeof(uip_ds6_if.addr_list[i].ipaddr);
00209 
00210         PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
00211         PRINTF("\n");
00212         count++;
00213         left -= entry_size;
00214 
00215         if(left < entry_size) {
00216           break;
00217         }
00218       }
00219     }
00220   } else if (buf[0] == REQUEST_TYPE_TOTALS) {
00221     memset(&buf[2], 0, 4);
00222     for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
00223       if(uip_ds6_if.addr_list[i].isused) {
00224         buf[2]++;
00225       }
00226     }
00227     for(i = 0; i < UIP_DS6_NBR_NB; i++) {
00228       if(uip_ds6_nbr_cache[i].isused) {
00229         buf[3]++;
00230       }
00231     }
00232     for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
00233       if(uip_ds6_routing_table[i].isused) {
00234         buf[4]++;
00235       }
00236     }
00237     for(i = 0; i < UIP_DS6_DEFRT_NB; i++) {
00238       if(uip_ds6_defrt_list[i].isused) {
00239         buf[5]++;
00240       }
00241     }
00242     len += 4;
00243     count = 4;
00244   } else {
00245     return 0;
00246   }
00247   buf[1] = count;
00248   return len;
00249 }
00250 /*---------------------------------------------------------------------------*/
00251 PROCESS(viztool_process, "Network Visualization Tool Process");
00252 /*---------------------------------------------------------------------------*/
00253 static void
00254 tcpip_handler(void) CC_NON_BANKED
00255 {
00256   if(uip_newdata()) {
00257     memset(buf, 0, VIZTOOL_MAX_PAYLOAD_LEN);
00258 
00259     PRINTF("%u bytes from [", uip_datalen());
00260     PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
00261     PRINTF("]:%u\n", UIP_HTONS(UIP_UDP_BUF->srcport));
00262 
00263     memcpy(buf, uip_appdata, uip_datalen());
00264 
00265     len = process_request();
00266     if(len) {
00267       server_conn->rport = UIP_UDP_BUF->srcport;
00268       uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr);
00269       uip_udp_packet_send(server_conn, buf, len);
00270       PRINTF("Sent %u bytes\n", len);
00271     }
00272 
00273     /* Restore server connection to allow data from any node */
00274     uip_create_unspecified(&server_conn->ripaddr);
00275     server_conn->rport = 0;
00276   }
00277   return;
00278 }
00279 /*---------------------------------------------------------------------------*/
00280 PROCESS_THREAD(viztool_process, ev, data)
00281 {
00282 
00283   PROCESS_BEGIN();
00284 
00285   server_conn = udp_new(NULL, UIP_HTONS(0), NULL);
00286   udp_bind(server_conn, UIP_HTONS(VIZTOOL_UDP_PORT));
00287 
00288   while(1) {
00289     PROCESS_YIELD();
00290     if(ev == tcpip_event) {
00291       tcpip_handler();
00292     }
00293   }
00294 
00295   PROCESS_END();
00296 }
00297 /*---------------------------------------------------------------------------*/