From Harald Welte:
[obnox/wireshark/wip.git] / epan / address_to_str.c
1 /* address_to_str.c
2  * Routines for utilities to convert addresses to strings.
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <stdlib.h>
30 #include <string.h>
31
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>         /* needed for <netinet/in.h> */
34 #endif
35
36 #ifdef HAVE_NETINET_IN_H
37 # include <netinet/in.h>        /* needed for <arpa/inet.h> on some platforms */
38 #endif
39
40 #ifdef HAVE_ARPA_INET_H
41 #include <arpa/inet.h>
42 #endif
43
44 #ifdef HAVE_SYS_SOCKET_H
45 #include <sys/socket.h>         /* needed to define AF_ values on UNIX */
46 #endif
47
48 #ifdef HAVE_WINSOCK2_H
49 #include <winsock2.h>           /* needed to define AF_ values on Windows */
50 #endif
51
52 #ifdef NEED_INET_V6DEFS_H
53 # include "wsutil/inet_v6defs.h"
54 #endif
55
56 #include "to_str.h"
57 #include "value_string.h"
58 #include "addr_resolv.h"
59 #include "pint.h"
60 #include "atalk-utils.h"
61 #include "sna-utils.h"
62 #include "osi-utils.h"
63 #include <epan/dissectors/packet-mtp3.h>
64 #include <stdio.h>
65 #include "emem.h"
66
67 /* private to_str.c API, don't export to .h! */
68 char *word_to_hex(char *out, guint16 word);
69 char *word_to_hex_npad(char *out, guint16 word);
70 char *dword_to_hex_punct(char *out, guint32 dword, char punct);
71 char *dword_to_hex(char *out, guint32 dword);
72 char *bytes_to_hexstr(char *out, const guint8 *ad, guint32 len);
73 char *bytes_to_hexstr_punct(char *out, const guint8 *ad, guint32 len, char punct);
74
75 /*
76  * If a user _does_ pass in a too-small buffer, this is probably
77  * going to be too long to fit.  However, even a partial string
78  * starting with "[Buf" should provide enough of a clue to be
79  * useful.
80  */
81 #define BUF_TOO_SMALL_ERR "[Buffer too small]"
82
83 /* Wrapper for the most common case of asking
84  * for a string using a colon as the hex-digit separator.
85  */
86 /* XXX FIXME
87 remove this one later when every call has been converted to ep_address_to_str()
88 */
89 gchar *
90 ether_to_str(const guint8 *ad)
91 {
92         return bytestring_to_str(ad, 6, ':');
93 }
94
95 gchar *
96 tvb_ether_to_str(tvbuff_t *tvb, const gint offset)
97 {
98         return bytestring_to_str(tvb_get_ptr(tvb, offset, 6), 6, ':');
99 }
100
101 /*
102  This function is very fast and this function is called a lot.
103  XXX update the ep_address_to_str stuff to use this function.
104 */
105 const gchar *
106 ip_to_str(const guint8 *ad) {
107   gchar *buf;
108
109   buf=ep_alloc(MAX_IP_STR_LEN);
110   ip_to_str_buf(ad, buf, MAX_IP_STR_LEN);
111   return buf;
112 }
113
114 #define IPV4_LENGTH 4
115 const gchar *
116 tvb_ip_to_str(tvbuff_t *tvb, const gint offset)
117 {
118   gchar *buf;
119
120   buf=ep_alloc(MAX_IP_STR_LEN);
121   ip_to_str_buf(tvb_get_ptr(tvb, offset, IPV4_LENGTH), buf, MAX_IP_STR_LEN);
122   return buf;
123 }
124
125 /* XXX FIXME
126 remove this one later when every call has been converted to ep_address_to_str()
127 */
128 gchar *
129 ip6_to_str(const struct e_in6_addr *ad) {
130   gchar *str;
131
132   str=ep_alloc(MAX_IP6_STR_LEN);
133   ip6_to_str_buf(ad, str);
134   return str;
135 }
136
137 #define IPV6_LENGTH 16
138 gchar *
139 tvb_ip6_to_str(tvbuff_t *tvb, const gint offset)
140 {
141   gchar *buf;
142
143   buf=ep_alloc(MAX_IP6_STR_LEN);
144   ip6_to_str_buf((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, IPV6_LENGTH), buf);
145   return buf;
146 }
147
148 /* const char *
149  * inet_ntop6(src, dst, size)
150  *      convert IPv6 binary address into presentation (printable) format
151  * author:
152  *      Paul Vixie, 1996.
153  */
154 static void
155 ip6_to_str_buf_len(const guchar* src, char *buf, size_t buf_len)
156 {
157         struct { int base, len; } best, cur;
158         guint words[8];
159         int i;
160
161         if (buf_len < MAX_IP6_STR_LEN) {        /* buf_len < 40 */
162                 g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len);     /* Let the unexpected value alert user */
163                 return;
164         }
165
166         /*
167          * Preprocess:
168          *      Copy the input (bytewise) array into a wordwise array.
169          *      Find the longest run of 0x00's in src[] for :: shorthanding.
170          */
171         for (i = 0; i < 16; i += 2) {
172                 words[i / 2] = (src[i+1] << 0);
173                 words[i / 2] |= (src[i] << 8);
174         }
175         best.base = -1; best.len = 0;
176         cur.base = -1;  cur.len = 0;
177         for (i = 0; i < 8; i++) {
178                 if (words[i] == 0) {
179                         if (cur.base == -1) {
180                                 cur.base = i;
181                                 cur.len = 1;
182                         } else
183                                 cur.len++;
184                 } else {
185                         if (cur.base != -1) {
186                                 if (best.base == -1 || cur.len > best.len)
187                                         best = cur;
188                                 cur.base = -1;
189                         }
190                 }
191         }
192         if (cur.base != -1) {
193                 if (best.base == -1 || cur.len > best.len)
194                         best = cur;
195         }
196         if (best.base != -1 && best.len < 2)
197                 best.base = -1;
198
199         /* Is this address an encapsulated IPv4? */
200         /* XXX, 
201          * Orginal code dated 1996 uses ::/96 as a valid IPv4-compatible addresses
202          * but since Feb 2006 ::/96 is deprecated one.
203          * Quoting wikipedia [0]:
204          * > The 96-bit zero-value prefix ::/96, originally known as IPv4-compatible 
205          * > addresses, was mentioned in 1995[35] but first described in 1998.[41] 
206          * > This class of addresses was used to represent IPv4 addresses within 
207          * > an IPv6 transition technology. Such an IPv6 address has its first 
208          * > (most significant) 96 bits set to zero, while its last 32 bits are the 
209          * > IPv4 address that is represented. 
210          * > In February 2006 the Internet Engineering Task Force (IETF) has deprecated 
211          * > the use of IPv4-compatible addresses.[1] The only remaining use of this address 
212          * > format is to represent an IPv4 address in a table or database with fixed size 
213          * > members that must also be able to store an IPv6 address.
214          *
215          * If needed it can be fixed by changing next line:
216          *   if (best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
217          * to:
218          *   if (best.base == 0 && best.len == 5 && words[5] == 0xffff)
219          *
220          * [0] http://en.wikipedia.org/wiki/IPv6_address#Historical_notes
221          */
222
223         if (best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
224         {
225                 /* best.len == 6 -> ::IPv4; 5 -> ::ffff:IPv4 */
226                 buf = g_stpcpy(buf, "::");
227                 if (best.len == 5)
228                 buf = g_stpcpy(buf, "ffff:");
229                 ip_to_str_buf(src + 12, buf, MAX_IP_STR_LEN);
230                 /* max: 2 + 5 + 16 == 23 bytes */
231                 return;
232         }
233
234         /*
235          * Format the result.
236          */
237         for (i = 0; i < 8; i++) {
238                 /* Are we inside the best run of 0x00's? */
239                 if (i == best.base) {
240                         *buf++ = ':';
241                         i += best.len;
242
243                         /* Was it a trailing run of 0x00's? */
244                         if (i == 8) {
245                                 *buf++ = ':';
246                                 break;
247                         }
248                 }
249                 /* Are we following an initial run of 0x00s or any real hex? */
250                 if (i != 0)
251                         *buf++ = ':';
252
253                 buf = word_to_hex_npad(buf, words[i]); /* max: 4B */
254                 /* max: 8 * 4 + 7 == 39 bytes */
255         }
256         *buf = '\0';    /* 40 byte */
257 }
258
259 void
260 ip6_to_str_buf(const struct e_in6_addr *ad, gchar *buf)
261 {
262   ip6_to_str_buf_len((const guchar*)ad, buf, MAX_IP6_STR_LEN);
263 }
264
265 gchar*
266 ipx_addr_to_str(const guint32 net, const guint8 *ad)
267 {
268         gchar   *buf;
269         char    *name;
270
271         name = get_ether_name_if_known(ad);
272
273         if (name) {
274                 buf = ep_strdup_printf("%s.%s", get_ipxnet_name(net), name);
275         }
276         else {
277                 buf = ep_strdup_printf("%s.%s", get_ipxnet_name(net),
278                     bytestring_to_str(ad, 6, '\0'));
279         }
280         return buf;
281 }
282
283 gchar*
284 ipxnet_to_string(const guint8 *ad)
285 {
286         guint32 addr = pntohl(ad);
287         return ipxnet_to_str_punct(addr, ' ');
288 }
289
290 gchar *
291 ipxnet_to_str_punct(const guint32 ad, const char punct)
292 {
293   gchar *buf = ep_alloc(12);
294
295   *dword_to_hex_punct(buf, ad, punct) = '\0';
296   return buf;
297 }
298
299 static void
300 vines_addr_to_str_buf(const guint8 *addrp, gchar *buf, int buf_len)
301 {
302   if (buf_len < 14) {
303      g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len);        /* Let the unexpected value alert user */
304      return;
305   }
306
307   buf    = dword_to_hex(buf, pntohl(&addrp[0]));        /* 8 bytes */
308   *buf++ = '.';                                         /* 1 byte */
309   buf    = word_to_hex(buf, pntohs(&addrp[4]));         /* 4 bytes */
310   *buf   = '\0';                                        /* 1 byte */
311 }
312
313 gchar *
314 tvb_vines_addr_to_str(tvbuff_t *tvb, const gint offset)
315 {
316   gchar *buf;
317
318   buf=ep_alloc(214); /* XXX, 14 here? */
319
320   vines_addr_to_str_buf(tvb_get_ptr(tvb, offset, VINES_ADDR_LEN), buf, 214);
321   return buf;
322 }
323
324 /*
325  This function is very fast and this function is called a lot.
326  XXX update the ep_address_to_str stuff to use this function.
327 */
328 gchar *
329 eui64_to_str(const guint64 ad) {
330   gchar *buf;
331   guint8 *p_eui64;
332
333   p_eui64 = ep_alloc(8);
334   buf=ep_alloc(EUI64_STR_LEN);
335
336   /* Copy and convert the address to network byte order. */
337   *(guint64 *)(void *)(p_eui64) = pntoh64(&(ad));
338
339   g_snprintf(buf, EUI64_STR_LEN, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", 
340   p_eui64[0], p_eui64[1], p_eui64[2], p_eui64[3],
341   p_eui64[4], p_eui64[5], p_eui64[6], p_eui64[7] );
342   return buf;
343 }
344 gchar *
345 tvb_eui64_to_str(tvbuff_t *tvb, const gint offset, const guint encoding)
346 {
347   if(encoding)
348   {
349     return eui64_to_str(tvb_get_letoh64(tvb, offset));
350   }else {
351     return eui64_to_str(tvb_get_ntoh64(tvb, offset));
352   }
353 }
354
355 static void
356 usb_addr_to_str_buf(const guint8 *addrp, gchar *buf, int buf_len)
357 {
358   if(pletohl(&addrp[0])==0xffffffff){
359     g_snprintf(buf, buf_len, "host");
360   } else {
361     g_snprintf(buf, buf_len, "%d.%d", pletohl(&addrp[0]), pletohl(&addrp[4]));
362   }
363 }
364
365 static void
366 tipc_addr_to_str_buf( const guint8 *data, gchar *buf, int buf_len){
367         guint8 zone;
368         guint16 subnetwork;
369         guint16 processor;
370         guint32 tipc_address;
371
372         tipc_address = data[0];
373         tipc_address = (tipc_address << 8) ^ data[1];
374         tipc_address = (tipc_address << 8) ^ data[2];
375         tipc_address = (tipc_address << 8) ^ data[3];
376
377         processor = tipc_address & 0x0fff;
378
379         tipc_address = tipc_address >> 12;
380         subnetwork = tipc_address & 0x0fff;
381
382         tipc_address = tipc_address >> 12;
383         zone = tipc_address & 0xff;
384
385         g_snprintf(buf,buf_len,"%u.%u.%u",zone,subnetwork,processor);
386 }
387
388 static void
389 ib_addr_to_str_buf( const address *addr, gchar *buf, int buf_len){
390         if (addr->len >= 16) {  /* GID is 128bits */
391                 #define PREAMBLE_STR_LEN                (sizeof("GID: ") - 1)
392                 g_snprintf(buf,buf_len,"GID: ");
393                 if (buf_len < (int)PREAMBLE_STR_LEN ||
394                                 inet_ntop(AF_INET6, addr->data, buf + PREAMBLE_STR_LEN, 
395                                                   buf_len - PREAMBLE_STR_LEN) == NULL ) /* Returns NULL if no space and does not touch buf */
396                         g_snprintf ( buf, buf_len, BUF_TOO_SMALL_ERR ); /* Let the unexpected value alert user */
397         } else {        /* this is a LID (16 bits) */
398                 guint16 lid_number;
399                 
400                 memcpy((void *)&lid_number, addr->data, sizeof lid_number);
401                 g_snprintf(buf,buf_len,"LID: %u",lid_number);
402         }
403 }
404
405 /* XXX FIXME
406 remove this one later when every call has been converted to ep_address_to_str()
407 */
408 gchar *
409 fc_to_str(const guint8 *ad)
410 {
411     return bytestring_to_str (ad, 3, '.');
412 }
413
414 gchar *
415 tvb_fc_to_str(tvbuff_t *tvb, const gint offset)
416 {
417     return bytestring_to_str (tvb_get_ptr(tvb, offset, 3), 3, '.');
418 }
419
420 /* FC Network Header Network Address Authority Identifiers */
421
422 #define FC_NH_NAA_IEEE          1       /* IEEE 802.1a */
423 #define FC_NH_NAA_IEEE_E        2       /* IEEE Exteneded */
424 #define FC_NH_NAA_LOCAL         3
425 #define FC_NH_NAA_IP            4       /* 32-bit IP address */
426 #define FC_NH_NAA_IEEE_R        5       /* IEEE Registered */
427 #define FC_NH_NAA_IEEE_R_E      6       /* IEEE Registered Exteneded */
428 /* according to FC-PH 3 draft these are now reclaimed and reserved */
429 #define FC_NH_NAA_CCITT_INDV    12      /* CCITT 60 bit individual address */
430 #define FC_NH_NAA_CCITT_GRP     14      /* CCITT 60 bit group address */
431
432 gchar *
433 fcwwn_to_str (const guint8 *ad)
434 {
435     int fmt;
436     guint8 oui[6];
437     gchar *ethstr;
438     gchar *ethptr;
439
440     if (ad == NULL) return NULL;
441
442     ethstr=ep_alloc(512);
443     ethptr = bytes_to_hexstr_punct(ethstr, ad, 8, ':'); /* 23 bytes */
444
445     fmt = (ad[0] & 0xF0) >> 4;
446
447     switch (fmt) {
448
449     case FC_NH_NAA_IEEE:
450     case FC_NH_NAA_IEEE_E:
451         memcpy (oui, &ad[2], 6);
452
453         g_snprintf (ethptr, 512-23, " (%s)", get_manuf_name (oui));
454         break;
455
456     case FC_NH_NAA_IEEE_R:
457         oui[0] = ((ad[0] & 0x0F) << 4) | ((ad[1] & 0xF0) >> 4);
458         oui[1] = ((ad[1] & 0x0F) << 4) | ((ad[2] & 0xF0) >> 4);
459         oui[2] = ((ad[2] & 0x0F) << 4) | ((ad[3] & 0xF0) >> 4);
460         oui[3] = ((ad[3] & 0x0F) << 4) | ((ad[4] & 0xF0) >> 4);
461         oui[4] = ((ad[4] & 0x0F) << 4) | ((ad[5] & 0xF0) >> 4);
462         oui[5] = ((ad[5] & 0x0F) << 4) | ((ad[6] & 0xF0) >> 4);
463
464         g_snprintf (ethptr, 512-23, " (%s)", get_manuf_name (oui));
465         break;
466
467     default:
468         *ethptr = '\0';
469         break;
470     }
471     return (ethstr);
472 }
473
474 gchar *
475 tvb_fcwwn_to_str(tvbuff_t *tvb, const gint offset)
476 {
477         return fcwwn_to_str (tvb_get_ptr(tvb, offset, 8));
478 }
479
480 /*XXX FIXME the code below may be called very very frequently in the future.
481   optimize it for speed and get rid of the slow sprintfs */
482 /* XXX - perhaps we should have individual address types register
483    a table of routines to do operations such as address-to-name translation,
484    address-to-string translation, and the like, and have this call them,
485    and also have an address-to-string-with-a-name routine */
486 /* XXX - use this, and that future address-to-string-with-a-name routine,
487    in "col_set_addr()"; it might also be useful to have address types
488    export the names of the source and destination address fields, so
489    that "col_set_addr()" need know nothing whatsoever about particular
490    address types */
491 /* convert an address struct into a printable string */
492
493 gchar*
494 ep_address_to_str(const address *addr)
495 {
496   gchar *str;
497
498   str=ep_alloc(MAX_ADDR_STR_LEN);
499   address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
500   return str;
501 }
502
503 /* The called routines use se_alloc'ed memory */
504 gchar*
505 se_address_to_str(const address *addr)
506 {
507   gchar *str;
508
509   str=se_alloc(MAX_ADDR_STR_LEN);
510   address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
511   return str;
512 }
513
514 void
515 address_to_str_buf(const address *addr, gchar *buf, int buf_len)
516 {
517   const guint8 *addrdata;
518   struct atalk_ddp_addr ddp_addr;
519
520   char temp[32];
521   char *tempptr = temp;
522
523   if (!buf || !buf_len)
524     return;
525
526   switch(addr->type){
527   case AT_NONE:
528     buf[0] = '\0';
529     break;
530   case AT_ETHER:                                        /* 18 bytes */
531     tempptr = bytes_to_hexstr_punct(tempptr, addr->data, 6, ':');       /* 17 bytes */
532     break;
533   case AT_IPv4:
534     ip_to_str_buf(addr->data, buf, buf_len);
535     break;
536   case AT_IPv6:
537     ip6_to_str_buf_len(addr->data, buf, buf_len);
538     break;
539   case AT_IPX:                                          /* 22 bytes */
540     addrdata = addr->data;
541     tempptr = bytes_to_hexstr(tempptr, &addrdata[0], 4);                /*  8 bytes */
542     *tempptr++ = '.';                                                   /*  1 byte  */
543     tempptr = bytes_to_hexstr(tempptr, &addrdata[4], 6);                /* 12 bytes */
544     break;
545   case AT_SNA:
546     sna_fid_to_str_buf(addr, buf, buf_len);
547     break;
548   case AT_ATALK:
549     memcpy(&ddp_addr, addr->data, sizeof ddp_addr);
550     atalk_addr_to_str_buf(&ddp_addr, buf, buf_len);
551     break;
552   case AT_VINES:
553     vines_addr_to_str_buf(addr->data, buf, buf_len);
554     break;
555   case AT_USB:
556     usb_addr_to_str_buf(addr->data, buf, buf_len);
557     break;
558   case AT_OSI:
559     print_nsap_net_buf(addr->data, addr->len, buf, buf_len);
560     break;
561   case AT_ARCNET:                                       /* 5 bytes */
562     tempptr = g_stpcpy(tempptr, "0x");                                  /* 2 bytes */
563     tempptr = bytes_to_hexstr(tempptr, addr->data, 1);                  /* 2 bytes */
564     break;
565   case AT_FC:                                           /* 9 bytes */
566     tempptr = bytes_to_hexstr_punct(tempptr, addr->data, 3, '.');       /* 8 bytes */
567     break;
568   case AT_SS7PC:
569     mtp3_addr_to_str_buf((const mtp3_addr_pc_t *)addr->data, buf, buf_len);
570     break;
571   case AT_STRINGZ:
572     g_strlcpy(buf, addr->data, buf_len);
573     break;
574   case AT_EUI64:                                        /* 24 bytes */
575     tempptr = bytes_to_hexstr_punct(tempptr, addr->data, 8, ':');       /* 23 bytes */
576     break;
577   case AT_URI: {
578     int copy_len = addr->len < (buf_len - 1) ? addr->len : (buf_len - 1);
579     memcpy(buf, addr->data, copy_len );
580     buf[copy_len] = '\0';
581     }
582     break;
583   case AT_TIPC:
584     tipc_addr_to_str_buf(addr->data, buf, buf_len);
585     break;
586   case AT_IB:
587     ib_addr_to_str_buf(addr, buf, buf_len);
588     break;
589   default:
590     g_assert_not_reached();
591   }
592
593   /* copy to output buffer */
594   if (tempptr != temp) {
595     size_t temp_len = (size_t) (tempptr - temp);
596
597     if (temp_len < (size_t) buf_len) {
598       memcpy(buf, temp, temp_len);
599       buf[temp_len] = '\0';
600     } else
601      g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len);/* Let the unexpected value alert user */
602   }
603 }
604