2 * Routines for utilities to convert various other types 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h> /* needed for <netinet/in.h> */
36 #ifdef HAVE_NETINET_IN_H
37 # include <netinet/in.h> /* needed for <arpa/inet.h> on some platforms */
40 #ifdef HAVE_ARPA_INET_H
41 #include <arpa/inet.h>
44 #ifdef HAVE_SYS_SOCKET_H
45 #include <sys/socket.h> /* needed to define AF_ values on UNIX */
48 #ifdef HAVE_WINSOCK2_H
49 #include <winsock2.h> /* needed to define AF_ values on Windows */
52 #ifdef NEED_INET_V6DEFS_H
53 # include "inet_v6defs.h"
57 #include "value_string.h"
58 #include "addr_resolv.h"
60 #include "atalk-utils.h"
61 #include "sna-utils.h"
62 #include "osi-utils.h"
63 #include <epan/dissectors/packet-mtp3.h>
69 * If a user _does_ pass in a too-small buffer, this is probably
70 * going to be too long to fit. However, even a partial string
71 * starting with "[Buf" should provide enough of a clue to be
74 #define BUF_TOO_SMALL_ERR "[Buffer too small]"
76 /* Routine to convert a sequence of bytes to a hex string, one byte/two hex
77 * digits at at a time, with a specified punctuation character between
80 * If punct is '\0', no punctuation is applied (and thus
81 * the resulting string is (len-1) bytes shorter)
84 bytestring_to_str(const guint8 *ad, guint32 len, char punct) {
87 int i = (int) len - 1;
90 /* At least one version of Apple's C compiler/linker is buggy, causing
91 a complaint from the linker about the "literal C string section"
92 not ending with '\0' if we initialize a 16-element "char" array with
93 a 16-character string, the fact that initializing such an array with
94 such a string is perfectly legitimate ANSI C nonwithstanding, the 17th
95 '\0' byte in the string nonwithstanding. */
96 static const gchar hex_digits[16] =
97 { '0', '1', '2', '3', '4', '5', '6', '7',
98 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
105 if (buflen < 3 || i < 0) {
109 buf=ep_alloc(buflen);
110 p = &buf[buflen - 1];
114 *--p = hex_digits[octet&0xF];
116 *--p = hex_digits[octet&0xF];
126 #define PLURALIZE(n) (((n) > 1) ? "s" : "")
127 #define COMMA(do_it) ((do_it) ? ", " : "")
130 * Maximum length of a string showing days/hours/minutes/seconds.
131 * (Does not include the terminating '\0'.)
132 * Includes space for a '-' sign for any negative components.
133 * -12345 days, 12 hours, 12 minutes, 12.123 seconds
135 #define TIME_SECS_LEN (10+1+4+2+2+5+2+2+7+2+2+7+4)
138 * Convert a value in seconds and fractions of a second to a string,
139 * giving time in days, hours, minutes, and seconds, and put the result
141 * "is_nsecs" says that "frac" is microseconds if true and milliseconds
143 * If time is negative, add a '-' to all non-null components.
146 time_secs_to_str_buf(gint32 time, guint32 frac, gboolean is_nsecs,
149 int hours, mins, secs;
150 const gchar *msign = "";
151 gboolean do_comma = FALSE;
153 if(time == G_MININT32) { /* That Which Shall Not Be Negated */
154 ep_strbuf_append_printf(buf, "Unable to cope with time value %d", time);
171 ep_strbuf_append_printf(buf, "%s%u day%s", msign, time, PLURALIZE(time));
176 ep_strbuf_append_printf(buf, "%s%s%u hour%s", COMMA(do_comma), msign, hours, PLURALIZE(hours));
181 ep_strbuf_append_printf(buf, "%s%s%u minute%s", COMMA(do_comma), msign, mins, PLURALIZE(mins));
185 if (secs != 0 || frac != 0) {
188 ep_strbuf_append_printf(buf, "%s%s%u.%09u seconds", COMMA(do_comma), msign, secs, frac);
190 ep_strbuf_append_printf(buf, "%s%s%u.%03u seconds", COMMA(do_comma), msign, secs, frac);
192 ep_strbuf_append_printf(buf, "%s%s%u second%s", COMMA(do_comma), msign, secs, PLURALIZE(secs));
197 time_secs_to_str(gint32 time)
201 buf=ep_strbuf_sized_new(TIME_SECS_LEN+1, TIME_SECS_LEN+1);
204 ep_strbuf_append(buf, "0 time");
208 time_secs_to_str_buf(time, 0, FALSE, buf);
213 time_secs_to_str_buf_unsigned(guint32 time, guint32 frac, gboolean is_nsecs,
216 int hours, mins, secs;
217 gboolean do_comma = FALSE;
227 ep_strbuf_append_printf(buf, "%u day%s", time, PLURALIZE(time));
231 ep_strbuf_append_printf(buf, "%s%u hour%s", COMMA(do_comma), hours, PLURALIZE(hours));
235 ep_strbuf_append_printf(buf, "%s%u minute%s", COMMA(do_comma), mins, PLURALIZE(mins));
238 if (secs != 0 || frac != 0) {
241 ep_strbuf_append_printf(buf, "%s%u.%09u seconds", COMMA(do_comma), secs, frac);
243 ep_strbuf_append_printf(buf, "%s%u.%03u seconds", COMMA(do_comma), secs, frac);
245 ep_strbuf_append_printf(buf, "%s%u second%s", COMMA(do_comma), secs, PLURALIZE(secs));
250 time_secs_to_str_unsigned(guint32 time)
254 buf=ep_strbuf_sized_new(TIME_SECS_LEN+1, TIME_SECS_LEN+1);
257 ep_strbuf_append(buf, "0 time");
261 time_secs_to_str_buf_unsigned(time, 0, FALSE, buf);
267 time_msecs_to_str(gint32 time)
272 buf=ep_strbuf_sized_new(TIME_SECS_LEN+1+3+1, TIME_SECS_LEN+1+3+1);
275 ep_strbuf_append(buf, "0 time");
280 /* oops we got passed a negative time */
290 time_secs_to_str_buf(time, msecs, FALSE, buf);
294 static const char *mon_names[12] = {
310 abs_time_to_str(nstime_t *abs_time)
316 /* calling localtime() on MSVC 2005 with huge values causes it to crash */
317 /* XXX - find the exact value that still does work */
318 /* XXX - using _USE_32BIT_TIME_T might be another way to circumvent this problem */
319 if(abs_time->secs > 2000000000) {
323 tmp = localtime(&abs_time->secs);
325 buf = ep_strdup_printf("%s %2d, %d %02d:%02d:%02d.%09ld",
326 mon_names[tmp->tm_mon],
332 (long)abs_time->nsecs);
334 buf = ep_strdup("Not representable");
339 abs_time_secs_to_str(time_t abs_time)
344 tmp = localtime(&abs_time);
346 buf = ep_strdup_printf("%s %2d, %d %02d:%02d:%02d",
347 mon_names[tmp->tm_mon],
354 buf = ep_strdup("Not representable");
359 display_signed_time(gchar *buf, int buflen, gint32 sec, gint32 frac,
362 /* If the fractional part of the time stamp is negative,
363 print its absolute value and, if the seconds part isn't
364 (the seconds part should be zero in that case), stick
365 a "-" in front of the entire time stamp. */
380 g_snprintf(buf, buflen, "%d", sec);
384 g_snprintf(buf, buflen, "%d.%01d", sec, frac);
388 g_snprintf(buf, buflen, "%d.%02d", sec, frac);
392 g_snprintf(buf, buflen, "%d.%03d", sec, frac);
396 g_snprintf(buf, buflen, "%d.%06d", sec, frac);
400 g_snprintf(buf, buflen, "%d.%09d", sec, frac);
407 display_epoch_time(gchar *buf, int buflen, time_t sec, gint32 frac,
412 elapsed_secs = difftime(sec,(time_t)0);
414 /* This code copied from display_signed_time; keep it in case anyone
415 is looking at captures from before 1970 (???).
416 If the fractional part of the time stamp is negative,
417 print its absolute value and, if the seconds part isn't
418 (the seconds part should be zero in that case), stick
419 a "-" in front of the entire time stamp. */
422 if (elapsed_secs >= 0) {
434 g_snprintf(buf, buflen, "%0.0f", elapsed_secs);
438 g_snprintf(buf, buflen, "%0.0f.%01d", elapsed_secs, frac);
442 g_snprintf(buf, buflen, "%0.0f.%02d", elapsed_secs, frac);
446 g_snprintf(buf, buflen, "%0.0f.%03d", elapsed_secs, frac);
450 g_snprintf(buf, buflen, "%0.0f.%06d", elapsed_secs, frac);
454 g_snprintf(buf, buflen, "%0.0f.%09d", elapsed_secs, frac);
460 * Display a relative time as days/hours/minutes/seconds.
463 rel_time_to_str(nstime_t *rel_time)
470 buf=ep_strbuf_sized_new(1+TIME_SECS_LEN+1+6+1, 1+TIME_SECS_LEN+1+6+1);
472 /* If the nanoseconds part of the time stamp is negative,
473 print its absolute value and, if the seconds part isn't
474 (the seconds part should be zero in that case), stick
475 a "-" in front of the entire time stamp. */
477 time = (gint) rel_time->secs;
478 nsec = rel_time->nsecs;
479 if (time == 0 && nsec == 0) {
480 ep_strbuf_append(buf, "0.000000000 seconds");
485 ep_strbuf_append_c(buf, '-');
488 * We assume here that "rel_time->secs" is negative
489 * or zero; if it's not, the time stamp is bogus,
490 * with a positive seconds and negative microseconds.
492 time = (gint) -rel_time->secs;
495 time_secs_to_str_buf(time, nsec, TRUE, buf);
499 #define REL_TIME_SECS_LEN (1+10+1+9+1)
502 * Display a relative time as seconds.
505 rel_time_to_secs_str(nstime_t *rel_time)
509 buf=ep_alloc(REL_TIME_SECS_LEN);
511 display_signed_time(buf, REL_TIME_SECS_LEN, (gint32) rel_time->secs,
512 rel_time->nsecs, NSECS);
517 * Generates a string representing the bits in a bitfield at "bit_offset" from an 8 bit boundary
518 * with the length in bits of no_of_bits based on value.
523 decode_bits_in_field(gint bit_offset, gint no_of_bits, guint64 value)
525 guint64 mask = 0,tmp;
531 mask = mask << (no_of_bits-1);
533 /* prepare the string */
536 for(bit=0;bit<((int)(bit_offset&0x07));bit++){
543 /* read the bits for the int */
544 for(i=0;i<no_of_bits;i++){
570 /* Generate, into "buf", a string showing the bits of a bitfield.
571 Return a pointer to the character after that string. */
572 /*XXX this needs a buf_len check */
574 other_decode_bitfield_value(char *buf, guint32 val, guint32 mask, int width)
582 bit = 1 << (width - 1);
585 /* This bit is part of the field. Show its value. */
591 /* This bit is not part of the field. */
606 decode_bitfield_value(char *buf, guint32 val, guint32 mask, int width)
610 p = other_decode_bitfield_value(buf, val, mask, width);
616 /* Generate a string describing a Boolean bitfield (a one-bit field that
617 says something is either true of false). */
619 decode_boolean_bitfield(guint32 val, guint32 mask, int width,
620 const char *truedesc, const char *falsedesc)
625 buf=ep_alloc(1025); /* is this a bit overkill? */
626 p = decode_bitfield_value(buf, val, mask, width);
630 strcpy(p, falsedesc);
634 /* Generate a string describing a numeric bitfield (an N-bit field whose
635 value is just a number). */
637 decode_numeric_bitfield(guint32 val, guint32 mask, int width,
644 buf=ep_alloc(1025); /* isnt this a bit overkill? */
645 /* Compute the number of bits we have to shift the bitfield right
646 to extract its value. */
647 while ((mask & (1<<shift)) == 0)
650 p = decode_bitfield_value(buf, val, mask, width);
651 g_snprintf(p, (gulong) (1025-(p-buf)), fmt, (val & mask) >> shift);
655 /* Wrapper for the most common case of asking
656 * for a string using a colon as the hex-digit separator.
659 remove this one later when every call has been converted to ep_address_to_str()
662 ether_to_str(const guint8 *ad)
664 return bytestring_to_str(ad, 6, ':');
668 This function is very fast and this function is called a lot.
669 XXX update the ep_address_to_str stuff to use this function.
672 ip_to_str(const guint8 *ad) {
675 buf=ep_alloc(MAX_IP_STR_LEN);
676 ip_to_str_buf(ad, buf, MAX_IP_STR_LEN);
681 This function is very fast and this function is called a lot.
682 XXX update the ep_address_to_str stuff to use this function.
684 static const char * const fast_strings[] = {
685 "0", "1", "2", "3", "4", "5", "6", "7",
686 "8", "9", "10", "11", "12", "13", "14", "15",
687 "16", "17", "18", "19", "20", "21", "22", "23",
688 "24", "25", "26", "27", "28", "29", "30", "31",
689 "32", "33", "34", "35", "36", "37", "38", "39",
690 "40", "41", "42", "43", "44", "45", "46", "47",
691 "48", "49", "50", "51", "52", "53", "54", "55",
692 "56", "57", "58", "59", "60", "61", "62", "63",
693 "64", "65", "66", "67", "68", "69", "70", "71",
694 "72", "73", "74", "75", "76", "77", "78", "79",
695 "80", "81", "82", "83", "84", "85", "86", "87",
696 "88", "89", "90", "91", "92", "93", "94", "95",
697 "96", "97", "98", "99", "100", "101", "102", "103",
698 "104", "105", "106", "107", "108", "109", "110", "111",
699 "112", "113", "114", "115", "116", "117", "118", "119",
700 "120", "121", "122", "123", "124", "125", "126", "127",
701 "128", "129", "130", "131", "132", "133", "134", "135",
702 "136", "137", "138", "139", "140", "141", "142", "143",
703 "144", "145", "146", "147", "148", "149", "150", "151",
704 "152", "153", "154", "155", "156", "157", "158", "159",
705 "160", "161", "162", "163", "164", "165", "166", "167",
706 "168", "169", "170", "171", "172", "173", "174", "175",
707 "176", "177", "178", "179", "180", "181", "182", "183",
708 "184", "185", "186", "187", "188", "189", "190", "191",
709 "192", "193", "194", "195", "196", "197", "198", "199",
710 "200", "201", "202", "203", "204", "205", "206", "207",
711 "208", "209", "210", "211", "212", "213", "214", "215",
712 "216", "217", "218", "219", "220", "221", "222", "223",
713 "224", "225", "226", "227", "228", "229", "230", "231",
714 "232", "233", "234", "235", "236", "237", "238", "239",
715 "240", "241", "242", "243", "244", "245", "246", "247",
716 "248", "249", "250", "251", "252", "253", "254", "255"
719 ip_to_str_buf(const guint8 *ad, gchar *buf, int buf_len)
721 register gchar const *p;
722 register gchar *b=buf;
724 if (buf_len < MAX_IP_STR_LEN) {
725 g_snprintf ( buf, buf_len, BUF_TOO_SMALL_ERR ); /* Let the unexpected value alert user */
729 p=fast_strings[*ad++];
736 p=fast_strings[*ad++];
743 p=fast_strings[*ad++];
760 remove this one later when every call has been converted to ep_address_to_str()
763 ip6_to_str(const struct e_in6_addr *ad) {
764 #ifndef INET6_ADDRSTRLEN
765 #define INET6_ADDRSTRLEN 46
769 str=ep_alloc(INET6_ADDRSTRLEN+1);
771 ip6_to_str_buf(ad, str);
776 ip6_to_str_buf(const struct e_in6_addr *ad, gchar *buf)
778 inet_ntop(AF_INET6, (const guchar*)ad, buf, INET6_ADDRSTRLEN);
782 ipx_addr_to_str(guint32 net, const guint8 *ad)
787 name = get_ether_name_if_known(ad);
790 buf = ep_strdup_printf("%s.%s", get_ipxnet_name(net), name);
793 buf = ep_strdup_printf("%s.%s", get_ipxnet_name(net),
794 bytestring_to_str(ad, 6, '\0'));
800 ipxnet_to_string(const guint8 *ad)
802 guint32 addr = pntohl(ad);
803 return ipxnet_to_str_punct(addr, ' ');
807 ipxnet_to_str_punct(const guint32 ad, char punct)
813 /* At least one version of Apple's C compiler/linker is buggy, causing
814 a complaint from the linker about the "literal C string section"
815 not ending with '\0' if we initialize a 16-element "char" array with
816 a 16-character string, the fact that initializing such an array with
817 such a string is perfectly legitimate ANSI C nonwithstanding, the 17th
818 '\0' byte in the string nonwithstanding. */
819 static const gchar hex_digits[16] =
820 { '0', '1', '2', '3', '4', '5', '6', '7',
821 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
822 static const guint32 octet_mask[4] =
823 { 0xff000000 , 0x00ff0000, 0x0000ff00, 0x000000ff };
830 octet = (ad & octet_mask[i]) >> ((3 - i) * 8);
831 *--p = hex_digits[octet&0xF];
833 *--p = hex_digits[octet&0xF];
844 vines_addr_to_str(const guint8 *addrp)
850 vines_addr_to_str_buf(addrp, buf, 214);
855 vines_addr_to_str_buf(const guint8 *addrp, gchar *buf, int buf_len)
857 g_snprintf(buf, buf_len, "%08x.%04x", pntohl(&addrp[0]), pntohs(&addrp[4]));
862 usb_addr_to_str_buf(const guint8 *addrp, gchar *buf, int buf_len)
864 if(pletohl(&addrp[0])==0xffffffff){
865 g_snprintf(buf, buf_len, "host");
867 g_snprintf(buf, buf_len, "%d.%d", pletohl(&addrp[0]), pletohl(&addrp[4]));
872 tipc_addr_to_str_buf( const guint8 *data, gchar *buf, int buf_len){
876 guint32 tipc_address;
878 tipc_address = data[0];
879 tipc_address = (tipc_address << 8) ^ data[1];
880 tipc_address = (tipc_address << 8) ^ data[2];
881 tipc_address = (tipc_address << 8) ^ data[3];
883 processor = tipc_address & 0x0fff;
885 tipc_address = tipc_address >> 12;
886 subnetwork = tipc_address & 0x0fff;
888 tipc_address = tipc_address >> 12;
889 zone = tipc_address & 0xff;
891 g_snprintf(buf,buf_len,"%u.%u.%u",zone,subnetwork,processor);
895 remove this one later when every call has been converted to ep_address_to_str()
898 fc_to_str(const guint8 *ad)
900 return bytestring_to_str (ad, 3, '.');
903 /* FC Network Header Network Address Authority Identifiers */
905 #define FC_NH_NAA_IEEE 1 /* IEEE 802.1a */
906 #define FC_NH_NAA_IEEE_E 2 /* IEEE Exteneded */
907 #define FC_NH_NAA_LOCAL 3
908 #define FC_NH_NAA_IP 4 /* 32-bit IP address */
909 #define FC_NH_NAA_IEEE_R 5 /* IEEE Registered */
910 #define FC_NH_NAA_IEEE_R_E 6 /* IEEE Registered Exteneded */
911 /* according to FC-PH 3 draft these are now reclaimed and reserved */
912 #define FC_NH_NAA_CCITT_INDV 12 /* CCITT 60 bit individual address */
913 #define FC_NH_NAA_CCITT_GRP 14 /* CCITT 60 bit group address */
916 fcwwn_to_str (const guint8 *ad)
922 if (ad == NULL) return NULL;
924 ethstr=ep_alloc(512);
926 fmt = (ad[0] & 0xF0) >> 4;
931 case FC_NH_NAA_IEEE_E:
932 memcpy (oui, &ad[2], 6);
933 g_snprintf (ethstr, 512, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x (%s)", ad[0],
934 ad[1], ad[2], ad[3], ad[4], ad[5], ad[6], ad[7],
935 get_manuf_name (oui));
938 case FC_NH_NAA_IEEE_R:
939 oui[0] = ((ad[0] & 0x0F) << 4) | ((ad[1] & 0xF0) >> 4);
940 oui[1] = ((ad[1] & 0x0F) << 4) | ((ad[2] & 0xF0) >> 4);
941 oui[2] = ((ad[2] & 0x0F) << 4) | ((ad[3] & 0xF0) >> 4);
942 oui[3] = ((ad[3] & 0x0F) << 4) | ((ad[4] & 0xF0) >> 4);
943 oui[4] = ((ad[4] & 0x0F) << 4) | ((ad[5] & 0xF0) >> 4);
944 oui[5] = ((ad[5] & 0x0F) << 4) | ((ad[6] & 0xF0) >> 4);
946 g_snprintf (ethstr, 512, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x (%s)", ad[0],
947 ad[1], ad[2], ad[3], ad[4], ad[5], ad[6], ad[7],
948 get_manuf_name (oui));
952 g_snprintf (ethstr, 512, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", ad[0],
953 ad[1], ad[2], ad[3], ad[4], ad[5], ad[6], ad[7]);
959 /*XXX FIXME the code below may be called very very frequently in the future.
960 optimize it for speed and get rid of the slow sprintfs */
961 /* XXX - perhaps we should have individual address types register
962 a table of routines to do operations such as address-to-name translation,
963 address-to-string translation, and the like, and have this call them,
964 and also have an address-to-string-with-a-name routine */
965 /* XXX - use this, and that future address-to-string-with-a-name routine,
966 in "col_set_addr()"; it might also be useful to have address types
967 export the names of the source and destination address fields, so
968 that "col_set_addr()" need know nothing whatsoever about particular
970 /* convert an address struct into a printable string */
973 ep_address_to_str(const address *addr)
977 str=ep_alloc(MAX_ADDR_STR_LEN);
978 address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
982 /* The called routines use se_alloc'ed memory */
984 se_address_to_str(const address *addr)
988 str=se_alloc(MAX_ADDR_STR_LEN);
989 address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
994 * XXX - see also bytes_to_str() and bytes_to_str_punct() in strutil.c.
995 * They fill in an ep_allocated buffer, rather than a buffer supplied
996 * to them, and put in "..." if the string is "too long".
1000 byte_to_hex(char *out, guint8 octet) {
1001 /* At least one version of Apple's C compiler/linker is buggy, causing
1002 a complaint from the linker about the "literal C string section"
1003 not ending with '\0' if we initialize a 16-element "char" array with
1004 a 16-character string, the fact that initializing such an array with
1005 such a string is perfectly legitimate ANSI C nonwithstanding, the 17th
1006 '\0' byte in the string nonwithstanding. */
1007 static const gchar hex_digits[16] =
1008 { '0', '1', '2', '3', '4', '5', '6', '7',
1009 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
1011 *out++ = hex_digits[octet >> 4];
1012 *out++ = hex_digits[octet & 0xF];
1016 /* buffer need to be at least len * 2 size */
1017 static inline char *
1018 bytes_to_hexstr(char *out, const guint8 *ad, guint32 len) {
1021 for (i = 0; i < len; i++)
1022 out = byte_to_hex(out, ad[i]);
1026 /* buffer need to be at least len * 3 - 1 size */
1027 static inline char *
1028 bytes_to_hexstr_punct(char *out, const guint8 *ad, guint32 len, char punct) {
1031 out = byte_to_hex(out, ad[0]);
1032 for (i = 1; i < len; i++) {
1034 out = byte_to_hex(out, ad[i]);
1040 address_to_str_buf(const address *addr, gchar *buf, int buf_len)
1042 const guint8 *addrdata;
1043 struct atalk_ddp_addr ddp_addr;
1046 char *tempptr = temp;
1048 if (!buf || !buf_len)
1055 case AT_ETHER: /* 18 bytes */
1056 tempptr = bytes_to_hexstr_punct(tempptr, addr->data, 6, ':'); /* 17 bytes */
1059 ip_to_str_buf(addr->data, buf, buf_len);
1062 if ( inet_ntop(AF_INET6, addr->data, buf, buf_len) == NULL ) /* Returns NULL if no space and does not touch buf */
1063 g_snprintf ( buf, buf_len, BUF_TOO_SMALL_ERR ); /* Let the unexpected value alert user */
1065 case AT_IPX: /* 22 bytes */
1066 addrdata = addr->data;
1067 tempptr = bytes_to_hexstr(tempptr, &addrdata[0], 4); /* 8 bytes */
1068 *tempptr++ = '.'; /* 1 byte */
1069 tempptr = bytes_to_hexstr(tempptr, &addrdata[4], 6); /* 12 bytes */
1072 sna_fid_to_str_buf(addr, buf, buf_len);
1075 memcpy(&ddp_addr, addr->data, sizeof ddp_addr);
1076 atalk_addr_to_str_buf(&ddp_addr, buf, buf_len);
1079 vines_addr_to_str_buf(addr->data, buf, buf_len);
1082 usb_addr_to_str_buf(addr->data, buf, buf_len);
1085 print_nsap_net_buf(addr->data, addr->len, buf, buf_len);
1087 case AT_ARCNET: /* 5 bytes */
1088 tempptr = g_stpcpy(tempptr, "0x"); /* 2 bytes */
1089 tempptr = bytes_to_hexstr(tempptr, addr->data, 1); /* 2 bytes */
1091 case AT_FC: /* 9 bytes */
1092 tempptr = bytes_to_hexstr_punct(tempptr, addr->data, 3, '.'); /* 8 bytes */
1095 mtp3_addr_to_str_buf((const mtp3_addr_pc_t *)addr->data, buf, buf_len);
1098 g_strlcpy(buf, addr->data, buf_len);
1100 case AT_EUI64: /* 24 bytes */
1101 tempptr = bytes_to_hexstr_punct(tempptr, addr->data, 8, ':'); /* 23 bytes */
1104 int copy_len = addr->len < (buf_len - 1) ? addr->len : (buf_len - 1);
1105 memcpy(buf, addr->data, copy_len );
1106 buf[copy_len] = '\0';
1110 tipc_addr_to_str_buf(addr->data, buf, buf_len);
1113 g_assert_not_reached();
1116 /* copy to output buffer */
1117 if (tempptr != temp) {
1118 size_t temp_len = (size_t) (tempptr - temp);
1120 if (temp_len < (size_t) buf_len) {
1121 memcpy(buf, temp, temp_len);
1122 buf[temp_len] = '\0';
1124 g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len);/* Let the unexpected value alert user */
1128 gchar* guid_to_str(const e_guid_t *guid) {
1131 buf=ep_alloc(GUID_STR_LEN);
1132 return guid_to_str_buf(guid, buf, GUID_STR_LEN);
1135 gchar* guid_to_str_buf(const e_guid_t *guid, gchar *buf, int buf_len) {
1136 g_snprintf(buf, buf_len, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1137 guid->data1, guid->data2, guid->data3,
1138 guid->data4[0], guid->data4[1], guid->data4[2], guid->data4[3], guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7]);