8a2e21e4987e85d5f678a725c248da02c87a257e
[olsrd.git] / src / print_packet.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright 
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright 
13  *   notice, this list of conditions and the following disclaimer in 
14  *   the documentation and/or other materials provided with the 
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its 
17  *   contributors may be used to endorse or promote products derived 
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  */
40
41 #include "print_packet.h"
42 #include "ipcalc.h"
43 #include "mantissa.h"
44 #include "defs.h"
45 #include "olsr.h"
46 #include "lq_packet.h"
47 #include "net_olsr.h"
48
49
50 static void
51 print_messagedump(FILE *, olsr_u8_t *, olsr_16_t);
52
53 static void
54 print_midmsg(FILE *, olsr_u8_t *, olsr_16_t);
55
56 static void
57 print_hnamsg(FILE *, olsr_u8_t *, olsr_16_t);
58
59 static void
60 print_olsr_tcmsg(FILE *, olsr_u8_t *, olsr_16_t);
61
62 static void
63 print_olsr_tcmsg_lq(FILE *, olsr_u8_t *, olsr_16_t);
64
65 static void
66 print_hellomsg(FILE *, olsr_u8_t *, olsr_16_t);
67
68 static void
69 print_hellomsg_lq(FILE *, olsr_u8_t *, olsr_16_t);
70
71 /* Entire packet */
72 olsr_8_t
73 print_olsr_serialized_packet(FILE *handle, union olsr_packet *pkt, 
74                              olsr_u16_t size, union olsr_ip_addr *from_addr)
75 {
76   olsr_16_t remainsize = size - OLSR_HEADERSIZE;
77   union olsr_message *msg;
78   struct ipaddr_str buf;
79
80   /* Print packet header (no IP4/6 difference) */
81   fprintf(handle, "  ============== OLSR PACKET ==============\n   source: %s\n   length: %d bytes\n   seqno: %d\n\n",
82           from_addr ? olsr_ip_to_string(&buf, from_addr) : "UNKNOWN",
83           ntohs(pkt->v4.olsr_packlen), ntohs(pkt->v4.olsr_seqno));
84
85   /* Check size */
86   if(size != ntohs(pkt->v4.olsr_packlen))
87     fprintf(handle, "   SIZE MISSMATCH(%d != %d)!\n", size, ntohs(pkt->v4.olsr_packlen));
88
89   msg = (union olsr_message *)pkt->v4.olsr_msg;
90
91   /* Print all messages */
92   while((remainsize > 0) && ntohs(msg->v4.olsr_msgsize))
93     {
94       print_olsr_serialized_message(handle, msg);
95       remainsize -= ntohs(msg->v4.olsr_msgsize);
96       msg = (union olsr_message *)((char *)msg + ntohs(msg->v4.olsr_msgsize));
97     }
98
99   /* Done */
100   fprintf(handle, "  =========================================\n\n");
101   return 1;
102 }
103
104 /* Single message */
105 olsr_8_t
106 print_olsr_serialized_message(FILE *handle, union olsr_message *msg)
107 {
108   struct ipaddr_str buf;
109
110   fprintf(handle, "   ------------ OLSR MESSAGE ------------\n");
111   fprintf(handle, "    Sender main addr: %s\n", 
112           olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->v4.originator));
113   fprintf(handle, "    Type: %s, size: %d, vtime: %u ms\n", 
114           olsr_msgtype_to_string(msg->v4.olsr_msgtype), 
115           ntohs(msg->v4.olsr_msgsize),
116           me_to_reltime(msg->v4.olsr_vtime));
117   fprintf(handle, "    TTL: %d, Hopcnt: %d, seqno: %d\n",
118           (olsr_cnf->ip_version == AF_INET) ? msg->v4.ttl : msg->v6.ttl,
119           (olsr_cnf->ip_version == AF_INET) ? msg->v4.hopcnt : msg->v6.hopcnt,
120           ntohs((olsr_cnf->ip_version == AF_INET) ? msg->v4.seqno : msg->v6.seqno));
121
122   switch(msg->v4.olsr_msgtype)
123     {
124       /* Print functions for individual messagetypes */
125     case(MID_MESSAGE):
126       print_midmsg(handle,
127                    (olsr_cnf->ip_version == AF_INET) ? 
128                    (olsr_u8_t *)&msg->v4.message : (olsr_u8_t *)&msg->v6.message,
129                    ntohs(msg->v4.olsr_msgsize));
130       break;
131     case(HNA_MESSAGE):
132       print_hnamsg(handle,
133                    (olsr_cnf->ip_version == AF_INET) ? 
134                    (olsr_u8_t *)&msg->v4.message : (olsr_u8_t *)&msg->v6.message,
135                    ntohs(msg->v4.olsr_msgsize));
136       break;
137     case(TC_MESSAGE):
138       print_olsr_tcmsg(handle,
139                   (olsr_cnf->ip_version == AF_INET) ? 
140                   (olsr_u8_t *)&msg->v4.message : (olsr_u8_t *)&msg->v6.message,
141                   ntohs(msg->v4.olsr_msgsize));
142       break;
143     case(LQ_TC_MESSAGE):
144       print_olsr_tcmsg_lq(handle,
145                      (olsr_cnf->ip_version == AF_INET) ? 
146                      (olsr_u8_t *)&msg->v4.message : (olsr_u8_t *)&msg->v6.message,
147                      ntohs(msg->v4.olsr_msgsize));
148       break;
149     case(HELLO_MESSAGE):
150       print_hellomsg(handle,
151                      (olsr_cnf->ip_version == AF_INET) ? 
152                      (olsr_u8_t *)&msg->v4.message : (olsr_u8_t *)&msg->v6.message,
153                      ntohs(msg->v4.olsr_msgsize));
154       break;
155     case(LQ_HELLO_MESSAGE):
156       print_hellomsg_lq(handle,
157                         (olsr_cnf->ip_version == AF_INET) ? 
158                         (olsr_u8_t *)&msg->v4.message : (olsr_u8_t *)&msg->v6.message,
159                      ntohs(msg->v4.olsr_msgsize));
160       break;
161     default:
162       print_messagedump(handle, (olsr_u8_t *)msg, ntohs(msg->v4.olsr_msgsize));
163     }
164
165   fprintf(handle, "   --------------------------------------\n\n");
166   return 1;
167 }
168
169
170 static void
171 print_messagedump(FILE *handle, olsr_u8_t *msg, olsr_16_t size)
172 {
173   int i, x = 0;
174
175   fprintf(handle, "     Data dump:\n     ");
176   for(i = 0; i < size; i++)
177     {
178       if(x == 4)
179         {
180           x = 0;
181           fprintf(handle, "\n     ");
182         }
183       x++;
184       if(olsr_cnf->ip_version == AF_INET)
185         fprintf(handle, " %-3i ", (u_char) msg[i]);
186       else
187         fprintf(handle, " %-2x ", (u_char) msg[i]);
188     }
189   fprintf(handle, "\n");
190 }
191
192
193 static void
194 print_hellomsg(FILE *handle, olsr_u8_t *data, olsr_16_t totsize)
195 {
196   union olsr_ip_addr *haddr;
197   int hellosize = totsize - ((olsr_cnf->ip_version == AF_INET) ? OLSR_MSGHDRSZ_IPV4 : OLSR_MSGHDRSZ_IPV6);
198
199   fprintf(handle, "    +Htime: %u ms\n", me_to_reltime(data[2]));
200
201   fprintf(handle, "    +Willingness: %d\n", data[3]);
202
203   if(olsr_cnf->ip_version == AF_INET)
204     {
205       /* IPv4 */
206       struct hellomsg *h;
207       struct hellinfo *hinf;
208
209       h = (struct hellomsg *)data;
210
211       for (hinf = h->hell_info; 
212            (char *)hinf < ((char *)data + hellosize); 
213            hinf = (struct hellinfo *)((char *)hinf + ntohs(hinf->size)))
214         {
215
216           fprintf(handle, "    ++ Link: %s, Status: %s, Size: %d\n", 
217                   olsr_link_to_string(EXTRACT_LINK(hinf->link_code)), 
218                   olsr_status_to_string(EXTRACT_STATUS(hinf->link_code)),
219                   ntohs(hinf->size));
220
221           for (haddr = (union olsr_ip_addr  *)&hinf->neigh_addr; 
222                (char *)haddr < (char *)hinf + ntohs(hinf->size); 
223                haddr = (union olsr_ip_addr *)&haddr->v6.s6_addr[4])
224             {
225               struct ipaddr_str buf;
226               fprintf(handle, "    ++ %s\n", olsr_ip_to_string(&buf, haddr));
227             }
228         }
229
230       
231     }
232   else
233     {
234       /* IPv6 */
235       struct hellomsg6 *h6;
236       struct hellinfo6 *hinf6;
237
238       h6 = (struct hellomsg6 *)data;
239
240       for (hinf6 = h6->hell_info; (char *)hinf6 < ((char *)data + (hellosize)); 
241            hinf6 = (struct hellinfo6 *)((char *)hinf6 + ntohs(hinf6->size)))
242         {
243           fprintf(handle, "    ++ Link: %s, Status: %s, Size: %d\n", 
244                   olsr_link_to_string(EXTRACT_LINK(hinf6->link_code)), 
245                   olsr_status_to_string(EXTRACT_STATUS(hinf6->link_code)),
246                   ntohs(hinf6->size));
247
248           for (haddr = (union olsr_ip_addr *)hinf6->neigh_addr; 
249                (char *)haddr < (char *)hinf6 + ntohs(hinf6->size); 
250                haddr++)
251             {
252               struct ipaddr_str buf;
253               fprintf(handle, "    ++ %s\n", olsr_ip_to_string(&buf, haddr));
254             }
255         }
256
257     }
258
259 }
260
261 static void
262 print_hellomsg_lq(FILE *handle, olsr_u8_t *data, olsr_16_t totsize)
263 {
264   union olsr_ip_addr *haddr;
265   int hellosize = totsize - ((olsr_cnf->ip_version == AF_INET) ? OLSR_MSGHDRSZ_IPV4 : OLSR_MSGHDRSZ_IPV6);
266
267   fprintf(handle, "    +Htime: %u ms\n", me_to_reltime(data[2]));
268
269   fprintf(handle, "    +Willingness: %d\n", data[3]);
270
271   if(olsr_cnf->ip_version == AF_INET)
272     {
273       /* IPv4 */
274       struct hellomsg *h;
275       struct hellinfo *hinf;
276
277       h = (struct hellomsg *)data;
278
279       for (hinf = h->hell_info; 
280            (char *)hinf < ((char *)data + hellosize); 
281            hinf = (struct hellinfo *)((char *)hinf + ntohs(hinf->size)))
282         {
283
284           fprintf(handle, "    ++ Link: %s, Status: %s, Size: %d\n", 
285                   olsr_link_to_string(EXTRACT_LINK(hinf->link_code)), 
286                   olsr_status_to_string(EXTRACT_STATUS(hinf->link_code)),
287                   ntohs(hinf->size));
288
289           for (haddr = (union olsr_ip_addr  *)&hinf->neigh_addr; 
290                (char *)haddr < (char *)hinf + ntohs(hinf->size); 
291                haddr = (union olsr_ip_addr *)&haddr->v6.s6_addr[8])
292             {
293               struct ipaddr_str buf;
294               olsr_u8_t *quality = (olsr_u8_t *)haddr + olsr_cnf->ipsize;
295               fprintf(handle, "    ++ %s\n", olsr_ip_to_string(&buf, haddr));
296               fprintf(handle, "    ++ LQ = %d, RLQ = %d\n", quality[0], quality[1]);
297             }
298         }
299
300       
301     }
302   else
303     {
304       /* IPv6 */
305       struct hellomsg6 *h6;
306       struct hellinfo6 *hinf6;
307
308       h6 = (struct hellomsg6 *)data;
309
310       for (hinf6 = h6->hell_info; (char *)hinf6 < ((char *)data + (hellosize)); 
311            hinf6 = (struct hellinfo6 *)((char *)hinf6 + ntohs(hinf6->size)))
312         {
313           fprintf(handle, "    ++ Link: %s, Status: %s, Size: %d\n", 
314                   olsr_link_to_string(EXTRACT_LINK(hinf6->link_code)), 
315                   olsr_status_to_string(EXTRACT_STATUS(hinf6->link_code)),
316                   ntohs(hinf6->size));
317
318           for (haddr = (union olsr_ip_addr *)hinf6->neigh_addr; 
319                (char *)haddr < (char *)hinf6 + ntohs(hinf6->size) + 4; 
320                haddr++)
321             {
322               struct ipaddr_str buf;
323               olsr_u8_t *quality = (olsr_u8_t *)haddr + olsr_cnf->ipsize;
324               fprintf(handle, "    ++ %s\n", olsr_ip_to_string(&buf, haddr));
325               fprintf(handle, "    ++ LQ = %d, RLQ = %d\n", quality[0], quality[1]);
326             }
327         }
328
329     }
330 }
331
332 static void
333 print_olsr_tcmsg_lq(FILE *handle, olsr_u8_t *data, olsr_16_t totsize)
334 {
335   int remsize = totsize - ((olsr_cnf->ip_version == AF_INET) ? OLSR_MSGHDRSZ_IPV4 : OLSR_MSGHDRSZ_IPV6);
336   
337   fprintf(handle, "    +ANSN: %d\n", htons(((struct olsr_tcmsg *)data)->ansn));
338
339   data += 4;
340   remsize -= 4;
341
342   while(remsize)
343     {
344       struct ipaddr_str buf;
345       fprintf(handle, "    +Neighbor: %s\n", olsr_ip_to_string(&buf, (union olsr_ip_addr *) data));
346       data += olsr_cnf->ipsize;
347       fprintf(handle, "    +LQ: %d, ", *data);
348       data += 1;
349       fprintf(handle, "RLQ: %d\n", *data);
350       data += 3;
351       remsize -= (olsr_cnf->ipsize + 4);
352     }
353
354 }
355
356
357 static void
358 print_olsr_tcmsg(FILE *handle, olsr_u8_t *data, olsr_16_t totsize)
359 {
360   int remsize = totsize - ((olsr_cnf->ip_version == AF_INET) ? OLSR_MSGHDRSZ_IPV4 : OLSR_MSGHDRSZ_IPV6);
361   
362   fprintf(handle, "    +ANSN: %d\n", htons(((struct olsr_tcmsg *)data)->ansn));
363
364   data += 4;
365   remsize -= 4;
366
367   while(remsize)
368     {
369       struct ipaddr_str buf;
370       fprintf(handle, "    +Neighbor: %s\n", olsr_ip_to_string(&buf, (union olsr_ip_addr *) data));
371       data += olsr_cnf->ipsize;
372
373       remsize -= olsr_cnf->ipsize;
374     }
375
376 }
377
378
379 static void
380 print_hnamsg(FILE *handle, olsr_u8_t *data, olsr_16_t totsize)
381 {
382   int remsize = totsize - ((olsr_cnf->ip_version == AF_INET) ? OLSR_MSGHDRSZ_IPV4 : OLSR_MSGHDRSZ_IPV6);
383
384   while(remsize)
385     {
386       struct ipaddr_str buf;
387       fprintf(handle, "    +Network: %s\n", olsr_ip_to_string(&buf, (union olsr_ip_addr *) data));
388       data += olsr_cnf->ipsize;
389       fprintf(handle, "    +Netmask: %s\n", olsr_ip_to_string(&buf, (union olsr_ip_addr *) data));
390       data += olsr_cnf->ipsize;
391
392       remsize -= (olsr_cnf->ipsize*2);
393     }
394
395 }
396
397 static void
398 print_midmsg(FILE *handle, olsr_u8_t *data, olsr_16_t totsize)
399 {
400   int remsize = totsize - ((olsr_cnf->ip_version == AF_INET) ? OLSR_MSGHDRSZ_IPV4 : OLSR_MSGHDRSZ_IPV6);
401
402   while(remsize)
403     {
404       struct ipaddr_str buf;
405       fprintf(handle, "    +Alias: %s\n", olsr_ip_to_string(&buf, (union olsr_ip_addr *) data));
406       data += olsr_cnf->ipsize;
407       remsize -= olsr_cnf->ipsize;
408     }
409 }
410
411 /*
412  * Local Variables:
413  * c-basic-offset: 2
414  * indent-tabs-mode: nil
415  * End:
416  */