2 * Routines for utilities to convert addresses to strings.
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h> /* needed for <netinet/in.h> */
34 #ifdef HAVE_NETINET_IN_H
35 # include <netinet/in.h> /* needed for <arpa/inet.h> on some platforms */
38 #ifdef HAVE_ARPA_INET_H
39 #include <arpa/inet.h>
42 #ifdef HAVE_SYS_SOCKET_H
43 #include <sys/socket.h> /* needed to define AF_ values on UNIX */
46 #ifdef HAVE_WINSOCK2_H
47 #include <winsock2.h> /* needed to define AF_ values on Windows */
50 #ifdef NEED_INET_V6DEFS_H
51 # include "wsutil/inet_v6defs.h"
54 #include "to_str-int.h"
56 #include "value_string.h"
57 #include "addr_resolv.h"
58 #include "wsutil/pint.h"
59 #include "atalk-utils.h"
60 #include "sna-utils.h"
61 #include "osi-utils.h"
62 #include <epan/dissectors/packet-mtp3.h>
65 #include "wmem/wmem.h"
68 * If a user _does_ pass in a too-small buffer, this is probably
69 * going to be too long to fit. However, even a partial string
70 * starting with "[Buf" should provide enough of a clue to be
73 #define BUF_TOO_SMALL_ERR "[Buffer too small]"
75 /* Wrapper for the most common case of asking
76 * for a string using a colon as the hex-digit separator.
79 remove this one later when every call has been converted to ep_address_to_str()
82 ether_to_str(const guint8 *ad)
84 return bytestring_to_ep_str(ad, 6, ':');
88 tvb_ether_to_str(tvbuff_t *tvb, const gint offset)
90 return bytestring_to_ep_str(tvb_get_ptr(tvb, offset, 6), 6, ':');
94 This function is very fast and this function is called a lot.
95 XXX update the ep_address_to_str stuff to use this function.
98 ip_to_str(const guint8 *ad) {
101 buf=(gchar *)ep_alloc(MAX_IP_STR_LEN);
102 ip_to_str_buf(ad, buf, MAX_IP_STR_LEN);
106 #define IPV4_LENGTH 4
108 tvb_ip_to_str(tvbuff_t *tvb, const gint offset)
112 buf=(gchar *)ep_alloc(MAX_IP_STR_LEN);
113 ip_to_str_buf(tvb_get_ptr(tvb, offset, IPV4_LENGTH), buf, MAX_IP_STR_LEN);
118 remove this one later when every call has been converted to ep_address_to_str()
121 ip6_to_str(const struct e_in6_addr *ad) {
124 str=(gchar *)ep_alloc(MAX_IP6_STR_LEN);
125 ip6_to_str_buf(ad, str);
129 #define IPV6_LENGTH 16
131 tvb_ip6_to_str(tvbuff_t *tvb, const gint offset)
135 buf=(gchar *)ep_alloc(MAX_IP6_STR_LEN);
136 ip6_to_str_buf((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, IPV6_LENGTH), buf);
141 * inet_ntop6(src, dst, size)
142 * convert IPv6 binary address into presentation (printable) format
147 ip6_to_str_buf_len(const guchar* src, char *buf, size_t buf_len)
149 struct { int base, len; } best, cur;
153 if (buf_len < MAX_IP6_STR_LEN) { /* buf_len < 40 */
154 g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
160 * Copy the input (bytewise) array into a wordwise array.
161 * Find the longest run of 0x00's in src[] for :: shorthanding.
163 for (i = 0; i < 16; i += 2) {
164 words[i / 2] = (src[i+1] << 0);
165 words[i / 2] |= (src[i] << 8);
167 best.base = -1; best.len = 0;
168 cur.base = -1; cur.len = 0;
169 for (i = 0; i < 8; i++) {
171 if (cur.base == -1) {
177 if (cur.base != -1) {
178 if (best.base == -1 || cur.len > best.len)
184 if (cur.base != -1) {
185 if (best.base == -1 || cur.len > best.len)
188 if (best.base != -1 && best.len < 2)
191 /* Is this address an encapsulated IPv4? */
193 * Orginal code dated 1996 uses ::/96 as a valid IPv4-compatible addresses
194 * but since Feb 2006 ::/96 is deprecated one.
195 * Quoting wikipedia [0]:
196 * > The 96-bit zero-value prefix ::/96, originally known as IPv4-compatible
197 * > addresses, was mentioned in 1995[35] but first described in 1998.[41]
198 * > This class of addresses was used to represent IPv4 addresses within
199 * > an IPv6 transition technology. Such an IPv6 address has its first
200 * > (most significant) 96 bits set to zero, while its last 32 bits are the
201 * > IPv4 address that is represented.
202 * > In February 2006 the Internet Engineering Task Force (IETF) has deprecated
203 * > the use of IPv4-compatible addresses.[1] The only remaining use of this address
204 * > format is to represent an IPv4 address in a table or database with fixed size
205 * > members that must also be able to store an IPv6 address.
207 * If needed it can be fixed by changing next line:
208 * if (best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
210 * if (best.base == 0 && best.len == 5 && words[5] == 0xffff)
212 * [0] http://en.wikipedia.org/wiki/IPv6_address#Historical_notes
215 if (best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
217 /* best.len == 6 -> ::IPv4; 5 -> ::ffff:IPv4 */
218 buf = g_stpcpy(buf, "::");
220 buf = g_stpcpy(buf, "ffff:");
221 ip_to_str_buf(src + 12, buf, MAX_IP_STR_LEN);
222 /* max: 2 + 5 + 16 == 23 bytes */
229 for (i = 0; i < 8; i++) {
230 /* Are we inside the best run of 0x00's? */
231 if (i == best.base) {
235 /* Was it a trailing run of 0x00's? */
241 /* Are we following an initial run of 0x00s or any real hex? */
245 buf = word_to_hex_npad(buf, words[i]); /* max: 4B */
246 /* max: 8 * 4 + 7 == 39 bytes */
248 *buf = '\0'; /* 40 byte */
252 ip6_to_str_buf(const struct e_in6_addr *ad, gchar *buf)
254 ip6_to_str_buf_len((const guchar*)ad, buf, MAX_IP6_STR_LEN);
258 ipx_addr_to_str(const guint32 net, const guint8 *ad)
263 name = get_ether_name_if_known(ad);
266 buf = ep_strdup_printf("%s.%s", get_ipxnet_name(net), name);
269 buf = ep_strdup_printf("%s.%s", get_ipxnet_name(net),
270 bytestring_to_ep_str(ad, 6, '\0'));
276 ipxnet_to_string(const guint8 *ad)
278 guint32 addr = pntoh32(ad);
279 return ipxnet_to_str_punct(addr, ' ');
283 ipxnet_to_str_punct(const guint32 ad, const char punct)
285 gchar *buf = (gchar *)ep_alloc(12);
287 *dword_to_hex_punct(buf, ad, punct) = '\0';
292 vines_addr_to_str_buf(const guint8 *addrp, gchar *buf, int buf_len)
295 g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
299 buf = dword_to_hex(buf, pntoh32(&addrp[0])); /* 8 bytes */
300 *buf++ = '.'; /* 1 byte */
301 buf = word_to_hex(buf, pntoh16(&addrp[4])); /* 4 bytes */
302 *buf = '\0'; /* 1 byte */
306 tvb_vines_addr_to_str(tvbuff_t *tvb, const gint offset)
310 buf=(gchar *)ep_alloc(214); /* XXX, 14 here? */
312 vines_addr_to_str_buf(tvb_get_ptr(tvb, offset, VINES_ADDR_LEN), buf, 214);
317 This function is very fast and this function is called a lot.
318 XXX update the ep_address_to_str stuff to use this function.
321 eui64_to_str(const guint64 ad) {
325 p_eui64 = (guint8 *)ep_alloc(8);
326 buf=(gchar *)ep_alloc(EUI64_STR_LEN);
328 /* Copy and convert the address to network byte order. */
329 *(guint64 *)(void *)(p_eui64) = pntoh64(&(ad));
331 g_snprintf(buf, EUI64_STR_LEN, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
332 p_eui64[0], p_eui64[1], p_eui64[2], p_eui64[3],
333 p_eui64[4], p_eui64[5], p_eui64[6], p_eui64[7] );
337 tvb_eui64_to_str(tvbuff_t *tvb, const gint offset, const guint encoding)
341 return eui64_to_str(tvb_get_letoh64(tvb, offset));
343 return eui64_to_str(tvb_get_ntoh64(tvb, offset));
348 usb_addr_to_str_buf(const guint8 *addrp, gchar *buf, int buf_len)
350 if(pletoh32(&addrp[0])==0xffffffff){
351 g_snprintf(buf, buf_len, "host");
353 g_snprintf(buf, buf_len, "%d.%d", pletoh32(&addrp[0]), pletoh32(&addrp[4]));
358 tipc_addr_to_str_buf( const guint8 *data, gchar *buf, int buf_len){
362 guint32 tipc_address;
364 tipc_address = data[0];
365 tipc_address = (tipc_address << 8) ^ data[1];
366 tipc_address = (tipc_address << 8) ^ data[2];
367 tipc_address = (tipc_address << 8) ^ data[3];
369 processor = tipc_address & 0x0fff;
371 tipc_address = tipc_address >> 12;
372 subnetwork = tipc_address & 0x0fff;
374 tipc_address = tipc_address >> 12;
375 zone = tipc_address & 0xff;
377 g_snprintf(buf,buf_len,"%u.%u.%u",zone,subnetwork,processor);
381 ib_addr_to_str_buf( const address *addr, gchar *buf, int buf_len){
382 if (addr->len >= 16) { /* GID is 128bits */
383 #define PREAMBLE_STR_LEN ((int)(sizeof("GID: ") - 1))
384 g_snprintf(buf,buf_len,"GID: ");
385 if (buf_len < PREAMBLE_STR_LEN ||
386 inet_ntop(AF_INET6, addr->data, buf + PREAMBLE_STR_LEN,
387 buf_len - PREAMBLE_STR_LEN) == NULL ) /* Returns NULL if no space and does not touch buf */
388 g_snprintf ( buf, buf_len, BUF_TOO_SMALL_ERR ); /* Let the unexpected value alert user */
389 } else { /* this is a LID (16 bits) */
392 memcpy((void *)&lid_number, addr->data, sizeof lid_number);
393 g_snprintf(buf,buf_len,"LID: %u",lid_number);
398 remove this one later when every call has been converted to ep_address_to_str()
401 fc_to_str(const guint8 *ad)
403 return bytestring_to_ep_str (ad, 3, '.');
407 tvb_fc_to_str(tvbuff_t *tvb, const gint offset)
409 return bytestring_to_ep_str (tvb_get_ptr(tvb, offset, 3), 3, '.');
412 /* FC Network Header Network Address Authority Identifiers */
414 #define FC_NH_NAA_IEEE 1 /* IEEE 802.1a */
415 #define FC_NH_NAA_IEEE_E 2 /* IEEE Exteneded */
416 #define FC_NH_NAA_LOCAL 3
417 #define FC_NH_NAA_IP 4 /* 32-bit IP address */
418 #define FC_NH_NAA_IEEE_R 5 /* IEEE Registered */
419 #define FC_NH_NAA_IEEE_R_E 6 /* IEEE Registered Exteneded */
420 /* according to FC-PH 3 draft these are now reclaimed and reserved */
421 #define FC_NH_NAA_CCITT_INDV 12 /* CCITT 60 bit individual address */
422 #define FC_NH_NAA_CCITT_GRP 14 /* CCITT 60 bit group address */
425 fcwwn_to_str (const guint8 *ad)
432 if (ad == NULL) return NULL;
434 ethstr=(gchar *)ep_alloc(512);
435 ethptr = bytes_to_hexstr_punct(ethstr, ad, 8, ':'); /* 23 bytes */
437 fmt = (ad[0] & 0xF0) >> 4;
442 case FC_NH_NAA_IEEE_E:
443 memcpy (oui, &ad[2], 6);
445 g_snprintf (ethptr, 512-23, " (%s)", get_manuf_name (oui));
448 case FC_NH_NAA_IEEE_R:
449 oui[0] = ((ad[0] & 0x0F) << 4) | ((ad[1] & 0xF0) >> 4);
450 oui[1] = ((ad[1] & 0x0F) << 4) | ((ad[2] & 0xF0) >> 4);
451 oui[2] = ((ad[2] & 0x0F) << 4) | ((ad[3] & 0xF0) >> 4);
452 oui[3] = ((ad[3] & 0x0F) << 4) | ((ad[4] & 0xF0) >> 4);
453 oui[4] = ((ad[4] & 0x0F) << 4) | ((ad[5] & 0xF0) >> 4);
454 oui[5] = ((ad[5] & 0x0F) << 4) | ((ad[6] & 0xF0) >> 4);
456 g_snprintf (ethptr, 512-23, " (%s)", get_manuf_name (oui));
467 tvb_fcwwn_to_str(tvbuff_t *tvb, const gint offset)
469 return fcwwn_to_str (tvb_get_ptr(tvb, offset, 8));
473 remove this one later when every call has been converted to address_to_str()
476 ax25_to_str(const guint8 *ad)
478 return bytestring_to_ep_str(ad, 7, ':');
482 remove this one later when every call has been converted to address_to_str()
485 get_ax25_name(const guint8 *ad)
493 return ep_address_to_str( &addr );
496 /*XXX FIXME the code below may be called very very frequently in the future.
497 optimize it for speed and get rid of the slow sprintfs */
498 /* XXX - perhaps we should have individual address types register
499 a table of routines to do operations such as address-to-name translation,
500 address-to-string translation, and the like, and have this call them,
501 and also have an address-to-string-with-a-name routine */
502 /* XXX - use this, and that future address-to-string-with-a-name routine,
503 in "col_set_addr()"; it might also be useful to have address types
504 export the names of the source and destination address fields, so
505 that "col_set_addr()" need know nothing whatsoever about particular
507 /* convert an address struct into a printable string */
510 address_to_str(wmem_allocator_t *scope, const address *addr)
514 str=(gchar *)wmem_alloc(scope, MAX_ADDR_STR_LEN);
515 address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
520 ep_address_to_str(const address *addr)
524 str=(gchar *)ep_alloc(MAX_ADDR_STR_LEN);
525 address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
529 /* The called routines use se_alloc'ed memory */
531 se_address_to_str(const address *addr)
535 str=(gchar *)se_alloc(MAX_ADDR_STR_LEN);
536 address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
541 address_to_str_buf(const address *addr, gchar *buf, int buf_len)
543 const guint8 *addrdata;
544 struct atalk_ddp_addr ddp_addr;
545 guint16 ieee_802_15_4_short_addr;
548 char *tempptr = temp;
550 if (!buf || !buf_len)
557 case AT_ETHER: /* 18 bytes */
558 tempptr = bytes_to_hexstr_punct(tempptr, (const guint8 *)addr->data, 6, ':'); /* 17 bytes */
561 ip_to_str_buf((const guint8 *)addr->data, buf, buf_len);
564 ip6_to_str_buf_len((const guchar *)addr->data, buf, buf_len);
566 case AT_IPX: /* 22 bytes */
567 addrdata = (const guint8 *)addr->data;
568 tempptr = bytes_to_hexstr(tempptr, &addrdata[0], 4); /* 8 bytes */
569 *tempptr++ = '.'; /*1 byte */
570 tempptr = bytes_to_hexstr(tempptr, &addrdata[4], 6); /* 12 bytes */
573 sna_fid_to_str_buf(addr, buf, buf_len);
576 memcpy(&ddp_addr, addr->data, sizeof ddp_addr);
577 atalk_addr_to_str_buf(&ddp_addr, buf, buf_len);
580 vines_addr_to_str_buf((const guint8 *)addr->data, buf, buf_len);
583 usb_addr_to_str_buf((const guint8 *)addr->data, buf, buf_len);
586 print_nsap_net_buf((const guint8 *)addr->data, addr->len, buf, buf_len);
588 case AT_ARCNET: /* 5 bytes */
589 tempptr = g_stpcpy(tempptr, "0x"); /* 2 bytes */
590 tempptr = bytes_to_hexstr(tempptr, (const guint8 *)addr->data, 1); /* 2 bytes */
592 case AT_FC: /* 9 bytes */
593 tempptr = bytes_to_hexstr_punct(tempptr, (const guint8 *)addr->data, 3, '.'); /* 8 bytes */
596 mtp3_addr_to_str_buf((const mtp3_addr_pc_t *)addr->data, buf, buf_len);
599 g_strlcpy(buf, (const gchar *)addr->data, buf_len);
601 case AT_EUI64: /* 24 bytes */
602 tempptr = bytes_to_hexstr_punct(tempptr, (const guint8 *)addr->data, 8, ':'); /* 23 bytes */
605 int copy_len = addr->len < (buf_len - 1) ? addr->len : (buf_len - 1);
606 memcpy(buf, addr->data, copy_len );
607 buf[copy_len] = '\0';
611 tipc_addr_to_str_buf((const guint8 *)addr->data, buf, buf_len);
614 ib_addr_to_str_buf(addr, buf, buf_len);
617 addrdata = (const guint8 *)addr->data;
618 g_snprintf(buf, buf_len, "%c%c%c%c%c%c-%02d",
619 (addrdata[0] >> 1) & 0x7f, (addrdata[1] >> 1) & 0x7f, (addrdata[2] >> 1) & 0x7f,
620 (addrdata[3] >> 1) & 0x7f, (addrdata[4] >> 1) & 0x7f, (addrdata[5] >> 1) & 0x7f,
621 (addrdata[6] >> 1) & 0x0f );
623 case AT_IEEE_802_15_4_SHORT:
624 ieee_802_15_4_short_addr = pletoh16(addr->data);
625 if (ieee_802_15_4_short_addr == 0xffff)
626 g_snprintf(buf, buf_len, "Broadcast");
628 g_snprintf(buf, buf_len, "0x%04x", ieee_802_15_4_short_addr);
631 addrdata = (const guint8 *)addr->data;
632 g_snprintf(buf, buf_len, "%d", addrdata[0]);
635 addrdata = (const guint8 *)addr->data;
636 g_snprintf(buf, buf_len, "%d", addrdata[0] & 0x3f);
639 g_assert_not_reached();
642 /* copy to output buffer */
643 if (tempptr != temp) {
644 size_t temp_len = (size_t) (tempptr - temp);
646 if (temp_len < (size_t) buf_len) {
647 memcpy(buf, temp, temp_len);
648 buf[temp_len] = '\0';
650 g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len);/* Let the unexpected value alert user */
655 * Editor modelines - http://www.wireshark.org/tools/modelines.html
660 * indent-tabs-mode: nil
663 * vi: set shiftwidth=4 tabstop=8 expandtab:
664 * :indentSize=4:tabSize=8:noTabs=true: