Contiki 2.6
|
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 /*---------------------------------------------------------------------------*/