- Made a function from the ME_TO_DOUBLE() macro (in src/mantissa.h).
[olsrd.git] / src / print_packet.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas T√łnnesen(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  * $Id: print_packet.c,v 1.11 2007/08/28 20:45:17 bernd67 Exp $
40  */
41
42 #include "print_packet.h"
43 #include "mantissa.h"
44 #include "defs.h"
45 #include "olsr.h"
46 #include "lq_packet.h"
47
48 static void
49 print_messagedump(FILE *, olsr_u8_t *, olsr_16_t);
50
51 static void
52 print_midmsg(FILE *, olsr_u8_t *, olsr_16_t);
53
54 static void
55 print_hnamsg(FILE *, olsr_u8_t *, olsr_16_t);
56
57 static void
58 print_olsr_tcmsg(FILE *, olsr_u8_t *, olsr_16_t);
59
60 static void
61 print_olsr_tcmsg_lq(FILE *, olsr_u8_t *, olsr_16_t);
62
63 static void
64 print_hellomsg(FILE *, olsr_u8_t *, olsr_16_t);
65
66 static void
67 print_hellomsg_lq(FILE *, olsr_u8_t *, olsr_16_t);
68
69 /* Entire packet */
70 olsr_8_t
71 print_olsr_serialized_packet(FILE *handle, union olsr_packet *pkt, 
72                              olsr_u16_t size, union olsr_ip_addr *from_addr)
73 {
74   olsr_16_t remainsize = size - OLSR_HEADERSIZE;
75   union olsr_message *msg;
76
77   /* Print packet header (no IP4/6 difference) */
78   fprintf(handle, "  ============== OLSR PACKET ==============\n   source: %s\n   length: %d bytes\n   seqno: %d\n\n",
79           from_addr ? olsr_ip_to_string(from_addr) : "UNKNOWN",
80           ntohs(pkt->v4.olsr_packlen), ntohs(pkt->v4.olsr_seqno));
81
82   /* Check size */
83   if(size != ntohs(pkt->v4.olsr_packlen))
84     fprintf(handle, "   SIZE MISSMATCH(%d != %d)!\n", size, ntohs(pkt->v4.olsr_packlen));
85
86   msg = (union olsr_message *)pkt->v4.olsr_msg;
87
88   /* Print all messages */
89   while((remainsize > 0) && ntohs(msg->v4.olsr_msgsize))
90     {
91       print_olsr_serialized_message(handle, msg);
92       remainsize -= ntohs(msg->v4.olsr_msgsize);
93       msg = (union olsr_message *)((char *)msg + ntohs(msg->v4.olsr_msgsize));
94     }
95
96   /* Done */
97   fprintf(handle, "  =========================================\n\n");
98   return 1;
99 }
100
101 /* Single message */
102 olsr_8_t
103 print_olsr_serialized_message(FILE *handle, union olsr_message *msg)
104 {
105
106   fprintf(handle, "   ------------ OLSR MESSAGE ------------\n");
107   fprintf(handle, "    Sender main addr: %s\n", 
108           olsr_ip_to_string((union olsr_ip_addr *)&msg->v4.originator));
109   fprintf(handle, "    Type: %s, size: %d, vtime: %0.2f\n", 
110           olsr_msgtype_to_string(msg->v4.olsr_msgtype), 
111           ntohs(msg->v4.olsr_msgsize),
112           me_to_double(msg->v4.olsr_vtime));
113   fprintf(handle, "    TTL: %d, Hopcnt: %d, seqno: %d\n",
114           (olsr_cnf->ip_version == AF_INET) ? msg->v4.ttl : msg->v6.ttl,
115           (olsr_cnf->ip_version == AF_INET) ? msg->v4.hopcnt : msg->v6.hopcnt,
116           ntohs((olsr_cnf->ip_version == AF_INET) ? msg->v4.seqno : msg->v6.seqno));
117
118   switch(msg->v4.olsr_msgtype)
119     {
120       /* Print functions for individual messagetypes */
121     case(MID_MESSAGE):
122       print_midmsg(handle,
123                    (olsr_cnf->ip_version == AF_INET) ? 
124                    (olsr_u8_t *)&msg->v4.message : (olsr_u8_t *)&msg->v6.message,
125                    ntohs(msg->v4.olsr_msgsize));
126       break;
127     case(HNA_MESSAGE):
128       print_hnamsg(handle,
129                    (olsr_cnf->ip_version == AF_INET) ? 
130                    (olsr_u8_t *)&msg->v4.message : (olsr_u8_t *)&msg->v6.message,
131                    ntohs(msg->v4.olsr_msgsize));
132       break;
133     case(TC_MESSAGE):
134       print_olsr_tcmsg(handle,
135                   (olsr_cnf->ip_version == AF_INET) ? 
136                   (olsr_u8_t *)&msg->v4.message : (olsr_u8_t *)&msg->v6.message,
137                   ntohs(msg->v4.olsr_msgsize));
138       break;
139     case(LQ_TC_MESSAGE):
140       print_olsr_tcmsg_lq(handle,
141                      (olsr_cnf->ip_version == AF_INET) ? 
142                      (olsr_u8_t *)&msg->v4.message : (olsr_u8_t *)&msg->v6.message,
143                      ntohs(msg->v4.olsr_msgsize));
144       break;
145     case(HELLO_MESSAGE):
146       print_hellomsg(handle,
147                      (olsr_cnf->ip_version == AF_INET) ? 
148                      (olsr_u8_t *)&msg->v4.message : (olsr_u8_t *)&msg->v6.message,
149                      ntohs(msg->v4.olsr_msgsize));
150       break;
151     case(LQ_HELLO_MESSAGE):
152       print_hellomsg_lq(handle,
153                         (olsr_cnf->ip_version == AF_INET) ? 
154                         (olsr_u8_t *)&msg->v4.message : (olsr_u8_t *)&msg->v6.message,
155                      ntohs(msg->v4.olsr_msgsize));
156       break;
157     default:
158       print_messagedump(handle, (olsr_u8_t *)msg, ntohs(msg->v4.olsr_msgsize));
159     }
160
161   fprintf(handle, "   --------------------------------------\n\n");
162   return 1;
163 }
164
165
166 static void
167 print_messagedump(FILE *handle, olsr_u8_t *msg, olsr_16_t size)
168 {
169   int i, x = 0;
170
171   fprintf(handle, "     Data dump:\n     ");
172   for(i = 0; i < size; i++)
173     {
174       if(x == 4)
175         {
176           x = 0;
177           fprintf(handle, "\n     ");
178         }
179       x++;
180       if(olsr_cnf->ip_version == AF_INET)
181         fprintf(handle, " %-3i ", (u_char) msg[i]);
182       else
183         fprintf(handle, " %-2x ", (u_char) msg[i]);
184     }
185   fprintf(handle, "\n");
186 }
187
188
189 static void
190 print_hellomsg(FILE *handle, olsr_u8_t *data, olsr_16_t totsize)
191 {
192   union olsr_ip_addr *haddr;
193   int hellosize = totsize - ((olsr_cnf->ip_version == AF_INET) ? OLSR_MSGHDRSZ_IPV4 : OLSR_MSGHDRSZ_IPV6);
194
195   fprintf(handle, "    +Htime: %0.2f\n", me_to_double(data[2]));
196
197   fprintf(handle, "    +Willingness: %d\n", data[3]);
198
199   if(olsr_cnf->ip_version == AF_INET)
200     {
201       /* IPv4 */
202       struct hellomsg *h;
203       struct hellinfo *hinf;
204
205       h = (struct hellomsg *)data;
206
207       for (hinf = h->hell_info; 
208            (char *)hinf < ((char *)data + hellosize); 
209            hinf = (struct hellinfo *)((char *)hinf + ntohs(hinf->size)))
210         {
211
212           fprintf(handle, "    ++ Link: %s, Status: %s, Size: %d\n", 
213                   olsr_link_to_string(EXTRACT_LINK(hinf->link_code)), 
214                   olsr_status_to_string(EXTRACT_STATUS(hinf->link_code)),
215                   ntohs(hinf->size));
216
217           for (haddr = (union olsr_ip_addr  *)&hinf->neigh_addr; 
218                (char *)haddr < (char *)hinf + ntohs(hinf->size); 
219                haddr = (union olsr_ip_addr *)&haddr->v6.s6_addr[4])
220             {
221
222               fprintf(handle, "    ++ %s\n", olsr_ip_to_string(haddr));
223             }
224         }
225
226       
227     }
228   else
229     {
230       /* IPv6 */
231       struct hellomsg6 *h6;
232       struct hellinfo6 *hinf6;
233
234       h6 = (struct hellomsg6 *)data;
235
236       for (hinf6 = h6->hell_info; (char *)hinf6 < ((char *)data + (hellosize)); 
237            hinf6 = (struct hellinfo6 *)((char *)hinf6 + ntohs(hinf6->size)))
238         {
239           fprintf(handle, "    ++ Link: %s, Status: %s, Size: %d\n", 
240                   olsr_link_to_string(EXTRACT_LINK(hinf6->link_code)), 
241                   olsr_status_to_string(EXTRACT_STATUS(hinf6->link_code)),
242                   ntohs(hinf6->size));
243
244           for (haddr = (union olsr_ip_addr *)hinf6->neigh_addr; 
245                (char *)haddr < (char *)hinf6 + ntohs(hinf6->size); 
246                haddr++)
247             {
248               fprintf(handle, "    ++ %s\n", olsr_ip_to_string(haddr));
249             }
250         }
251
252     }
253
254 }
255
256 static void
257 print_hellomsg_lq(FILE *handle, olsr_u8_t *data, olsr_16_t totsize)
258 {
259   union olsr_ip_addr *haddr;
260   int hellosize = totsize - ((olsr_cnf->ip_version == AF_INET) ? OLSR_MSGHDRSZ_IPV4 : OLSR_MSGHDRSZ_IPV6);
261
262   fprintf(handle, "    +Htime: %0.2f\n", me_to_double(data[2]));
263
264   fprintf(handle, "    +Willingness: %d\n", data[3]);
265
266   if(olsr_cnf->ip_version == AF_INET)
267     {
268       /* IPv4 */
269       struct hellomsg *h;
270       struct hellinfo *hinf;
271
272       h = (struct hellomsg *)data;
273
274       for (hinf = h->hell_info; 
275            (char *)hinf < ((char *)data + hellosize); 
276            hinf = (struct hellinfo *)((char *)hinf + ntohs(hinf->size)))
277         {
278
279           fprintf(handle, "    ++ Link: %s, Status: %s, Size: %d\n", 
280                   olsr_link_to_string(EXTRACT_LINK(hinf->link_code)), 
281                   olsr_status_to_string(EXTRACT_STATUS(hinf->link_code)),
282                   ntohs(hinf->size));
283
284           for (haddr = (union olsr_ip_addr  *)&hinf->neigh_addr; 
285                (char *)haddr < (char *)hinf + ntohs(hinf->size); 
286                haddr = (union olsr_ip_addr *)&haddr->v6.s6_addr[8])
287             {
288               olsr_u8_t *quality = (olsr_u8_t *)haddr + olsr_cnf->ipsize;
289               fprintf(handle, "    ++ %s\n", olsr_ip_to_string(haddr));
290               fprintf(handle, "    ++ LQ = %d, RLQ = %d\n", quality[0], quality[1]);
291             }
292         }
293
294       
295     }
296   else
297     {
298       /* IPv6 */
299       struct hellomsg6 *h6;
300       struct hellinfo6 *hinf6;
301
302       h6 = (struct hellomsg6 *)data;
303
304       for (hinf6 = h6->hell_info; (char *)hinf6 < ((char *)data + (hellosize)); 
305            hinf6 = (struct hellinfo6 *)((char *)hinf6 + ntohs(hinf6->size)))
306         {
307           fprintf(handle, "    ++ Link: %s, Status: %s, Size: %d\n", 
308                   olsr_link_to_string(EXTRACT_LINK(hinf6->link_code)), 
309                   olsr_status_to_string(EXTRACT_STATUS(hinf6->link_code)),
310                   ntohs(hinf6->size));
311
312           for (haddr = (union olsr_ip_addr *)hinf6->neigh_addr; 
313                (char *)haddr < (char *)hinf6 + ntohs(hinf6->size) + 4; 
314                haddr++)
315             {
316               olsr_u8_t *quality = (olsr_u8_t *)haddr + olsr_cnf->ipsize;
317               fprintf(handle, "    ++ %s\n", olsr_ip_to_string(haddr));
318               fprintf(handle, "    ++ LQ = %d, RLQ = %d\n", quality[0], quality[1]);
319             }
320         }
321
322     }
323 }
324
325 static void
326 print_olsr_tcmsg_lq(FILE *handle, olsr_u8_t *data, olsr_16_t totsize)
327 {
328   int remsize = totsize - ((olsr_cnf->ip_version == AF_INET) ? OLSR_MSGHDRSZ_IPV4 : OLSR_MSGHDRSZ_IPV6);
329   
330   fprintf(handle, "    +ANSN: %d\n", htons(((struct olsr_tcmsg *)data)->ansn));
331
332   data += 4;
333   remsize -= 4;
334
335   while(remsize)
336     {
337       fprintf(handle, "    +Neighbor: %s\n", olsr_ip_to_string((union olsr_ip_addr *) data));
338       data += olsr_cnf->ipsize;
339       fprintf(handle, "    +LQ: %d, ", *data);
340       data += 1;
341       fprintf(handle, "RLQ: %d\n", *data);
342       data += 2;
343       remsize -= (olsr_cnf->ipsize + 4);
344     }
345
346 }
347
348
349 static void
350 print_olsr_tcmsg(FILE *handle, olsr_u8_t *data, olsr_16_t totsize)
351 {
352   int remsize = totsize - ((olsr_cnf->ip_version == AF_INET) ? OLSR_MSGHDRSZ_IPV4 : OLSR_MSGHDRSZ_IPV6);
353   
354   fprintf(handle, "    +ANSN: %d\n", htons(((struct olsr_tcmsg *)data)->ansn));
355
356   data += 4;
357   remsize -= 4;
358
359   while(remsize)
360     {
361       fprintf(handle, "    +Neighbor: %s\n", olsr_ip_to_string((union olsr_ip_addr *) data));
362       data += olsr_cnf->ipsize;
363
364       remsize -= olsr_cnf->ipsize;
365     }
366
367 }
368
369
370 static void
371 print_hnamsg(FILE *handle, olsr_u8_t *data, olsr_16_t totsize)
372 {
373   int remsize = totsize - ((olsr_cnf->ip_version == AF_INET) ? OLSR_MSGHDRSZ_IPV4 : OLSR_MSGHDRSZ_IPV6);
374
375   while(remsize)
376     {
377       fprintf(handle, "    +Network: %s\n", olsr_ip_to_string((union olsr_ip_addr *) data));
378       data += olsr_cnf->ipsize;
379       fprintf(handle, "    +Netmask: %s\n", olsr_ip_to_string((union olsr_ip_addr *) data));
380       data += olsr_cnf->ipsize;
381
382       remsize -= (olsr_cnf->ipsize*2);
383     }
384
385 }
386
387 static void
388 print_midmsg(FILE *handle, olsr_u8_t *data, olsr_16_t totsize)
389 {
390   int remsize = totsize - ((olsr_cnf->ip_version == AF_INET) ? OLSR_MSGHDRSZ_IPV4 : OLSR_MSGHDRSZ_IPV6);
391
392   while(remsize)
393     {
394       fprintf(handle, "    +Alias: %s\n", olsr_ip_to_string((union olsr_ip_addr *) data));
395       data += olsr_cnf->ipsize;
396       remsize -= olsr_cnf->ipsize;
397     }
398 }