[SIP] Display tel uri in VoIP calls.
[metze/wireshark/wip.git] / epan / address_types.c
1 /* address_types.c
2  *
3  * Wireshark - Network traffic analyzer
4  * By Gerald Combs <gerald@wireshark.org>
5  * Copyright 1998 Gerald Combs
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include "config.h"
23
24 #include <string.h>     /* for memcmp */
25 #include "packet.h"
26 #include "address_types.h"
27 #include "to_str.h"
28 #include "to_str-int.h"
29 #include "addr_resolv.h"
30 #include "wsutil/pint.h"
31 #include "wsutil/str_util.h"
32 #include "wsutil/inet_addr.h"
33
34 struct _address_type_t {
35     int                     addr_type; /* From address_type enumeration or registered value */
36     const char             *name;
37     const char             *pretty_name;
38     AddrValueToString       addr_to_str;
39     AddrValueToStringLen    addr_str_len;
40     AddrValueToByte         addr_to_byte;
41     AddrColFilterString     addr_col_filter;
42     AddrFixedLen            addr_fixed_len;
43     AddrNameResolutionToString addr_name_res_str;
44     AddrNameResolutionLen   addr_name_res_len;
45
46     /* XXX - Some sort of compare functions (like ftype)? ***/
47 };
48
49 #define MAX_DISSECTOR_ADDR_TYPE     30
50 #define MAX_ADDR_TYPE_VALUE (AT_END_OF_LIST+MAX_DISSECTOR_ADDR_TYPE)
51
52 static int num_dissector_addr_type;
53 static address_type_t dissector_type_addresses[MAX_DISSECTOR_ADDR_TYPE];
54
55 /* Keep track of address_type_t's via their id number */
56 static address_type_t* type_list[MAX_ADDR_TYPE_VALUE + 1];
57
58 /*
59  * If a user _does_ pass in a too-small buffer, this is probably
60  * going to be too long to fit.  However, even a partial string
61  * starting with "[Buf" should provide enough of a clue to be
62  * useful.
63  */
64 #define BUF_TOO_SMALL_ERR "[Buffer too small]"
65
66 static void address_type_register(int addr_type, address_type_t *at)
67 {
68     /* Check input */
69     g_assert(addr_type < MAX_ADDR_TYPE_VALUE);
70     g_assert(addr_type == at->addr_type);
71
72     /* Don't re-register. */
73     g_assert(type_list[addr_type] == NULL);
74
75     /* Sanity check */
76     g_assert(at->name);
77     g_assert(at->pretty_name);
78     g_assert(at->addr_to_str);
79     g_assert(at->addr_str_len);
80     g_assert(((at->addr_name_res_str != NULL) && (at->addr_name_res_len != NULL)) ||
81                      ((at->addr_name_res_str == NULL) && (at->addr_name_res_len == NULL)));
82
83     type_list[addr_type] = at;
84 }
85
86 int address_type_dissector_register(const char* name, const char* pretty_name,
87                                     AddrValueToString to_str_func, AddrValueToStringLen str_len_func,
88                                     AddrValueToByte to_bytes_func, AddrColFilterString col_filter_str_func, AddrFixedLen fixed_len_func,
89                                     AddrNameResolutionToString name_res_str_func, AddrNameResolutionLen name_res_len_func)
90 {
91     int addr_type;
92
93     /* Ensure valid data/functions for required fields */
94     g_assert(name);
95     g_assert(pretty_name);
96     g_assert(to_str_func);
97     g_assert(str_len_func);
98     /* Either have both or neither */
99     g_assert(((name_res_str_func != NULL) && (name_res_len_func != NULL)) ||
100                      ((name_res_str_func == NULL) && (name_res_len_func == NULL)));
101
102     /* This shouldn't happen, so flag it for fixing */
103     g_assert(num_dissector_addr_type < MAX_DISSECTOR_ADDR_TYPE);
104
105     addr_type = AT_END_OF_LIST+num_dissector_addr_type;
106     dissector_type_addresses[num_dissector_addr_type].addr_type = addr_type;
107     dissector_type_addresses[num_dissector_addr_type].name = name;
108     dissector_type_addresses[num_dissector_addr_type].pretty_name = pretty_name;
109     dissector_type_addresses[num_dissector_addr_type].addr_to_str = to_str_func;
110     dissector_type_addresses[num_dissector_addr_type].addr_str_len = str_len_func;
111     dissector_type_addresses[num_dissector_addr_type].addr_to_byte = to_bytes_func;
112     dissector_type_addresses[num_dissector_addr_type].addr_col_filter = col_filter_str_func;
113     dissector_type_addresses[num_dissector_addr_type].addr_fixed_len = fixed_len_func;
114     dissector_type_addresses[num_dissector_addr_type].addr_name_res_str = name_res_str_func;
115     dissector_type_addresses[num_dissector_addr_type].addr_name_res_len = name_res_len_func;
116
117     type_list[addr_type] = &dissector_type_addresses[num_dissector_addr_type];
118
119     num_dissector_addr_type++;
120
121     return addr_type;
122 }
123
124 int address_type_get_by_name(const char* name)
125 {
126     address_type_t** addr;
127
128     for (addr = type_list; *addr != NULL; addr++)
129     {
130         if (!strcmp((*addr)->name, name))
131         {
132             return (*addr)->addr_type;
133         }
134     }
135
136     return -1;
137 }
138
139 /******************************************************************************
140  * AT_NONE
141  ******************************************************************************/
142 int none_addr_to_str(const address* addr _U_, gchar *buf, int buf_len _U_)
143 {
144     buf[0] = '\0';
145     return none_addr_str_len(addr);
146 }
147
148 int none_addr_str_len(const address* addr _U_)
149 {
150     return 1; /* NULL character for empty string */
151 }
152
153 int none_addr_len(void)
154 {
155     return 0;
156 }
157
158 static int none_name_res_len(void)
159 {
160     return 5;
161 }
162
163 static const gchar* none_name_res_str(const address* addr _U_)
164 {
165     return "NONE";
166 }
167
168 /******************************************************************************
169  * AT_ETHER
170  ******************************************************************************/
171 int ether_to_str(const address* addr, gchar *buf, int buf_len _U_)
172 {
173     bytes_to_hexstr_punct(buf, (const guint8*)addr->data, 6, ':');
174     buf[17] = '\0';
175     return ether_str_len(addr);
176 }
177
178 int ether_str_len(const address* addr _U_)
179 {
180     return 18;
181 }
182
183 static const char* ether_col_filter_str(const address* addr _U_, gboolean is_src)
184 {
185     if (is_src)
186         return "eth.src";
187
188     return "eth.dst";
189 }
190
191 int ether_len(void)
192 {
193     return 6;
194 }
195
196 const gchar* ether_name_resolution_str(const address* addr)
197 {
198     return get_ether_name((const guint8 *)addr->data);
199 }
200
201 int ether_name_resolution_len(void)
202 {
203     return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
204 }
205
206 /******************************************************************************
207  * AT_IPv4
208  ******************************************************************************/
209 static int ipv4_to_str(const address* addr, gchar *buf, int buf_len)
210 {
211     ip_to_str_buf((const guint8*)addr->data, buf, buf_len);
212     return (int)(strlen(buf)+1);
213 }
214
215 static int ipv4_str_len(const address* addr _U_)
216 {
217     return WS_INET_ADDRSTRLEN;
218 }
219
220 static const char* ipv4_col_filter_str(const address* addr _U_, gboolean is_src)
221 {
222     if (is_src)
223         return "ip.src";
224
225     return "ip.dst";
226 }
227
228 static int ipv4_len(void)
229 {
230     return 4;
231 }
232
233 static const gchar* ipv4_name_res_str(const address* addr)
234 {
235     guint32 ip4_addr;
236     memcpy(&ip4_addr, addr->data, sizeof ip4_addr);
237     return get_hostname(ip4_addr);
238 }
239
240 static int ipv4_name_res_len(void)
241 {
242     return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
243 }
244
245 /******************************************************************************
246  * AT_IPv6
247  ******************************************************************************/
248 static int ipv6_to_str(const address* addr, gchar *buf, int buf_len)
249 {
250     return ip6_to_str_buf((const ws_in6_addr *)addr->data, buf, buf_len);
251 }
252
253 static int ipv6_str_len(const address* addr _U_)
254 {
255     return WS_INET6_ADDRSTRLEN;
256 }
257
258 static const char* ipv6_col_filter_str(const address* addr _U_, gboolean is_src)
259 {
260     if (is_src)
261         return "ipv6.src";
262
263     return "ipv6.dst";
264 }
265
266 static int ipv6_len(void)
267 {
268     return 16;
269 }
270
271 static const gchar* ipv6_name_res_str(const address* addr)
272 {
273     ws_in6_addr ip6_addr;
274     memcpy(&ip6_addr.bytes, addr->data, sizeof ip6_addr.bytes);
275     return get_hostname6(&ip6_addr);
276 }
277
278 static int ipv6_name_res_len(void)
279 {
280     return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
281 }
282
283 /******************************************************************************
284  * AT_IPX
285  ******************************************************************************/
286 static int ipx_to_str(const address* addr, gchar *buf, int buf_len _U_)
287 {
288     const guint8 *addrdata = (const guint8 *)addr->data;
289     gchar *bufp = buf;
290
291     bufp = bytes_to_hexstr(bufp, &addrdata[0], 4); /* 8 bytes */
292     *bufp++ = '.'; /*1 byte */
293     bufp = bytes_to_hexstr(bufp, &addrdata[4], 6); /* 12 bytes */
294     *bufp++ = '\0'; /* NULL terminate */
295     return (int)(bufp - buf);
296 }
297
298 static int ipx_str_len(const address* addr _U_)
299 {
300     return 22;
301 }
302
303 static int ipx_len(void)
304 {
305     return 10;
306 }
307
308 /******************************************************************************
309  * AT_FC
310  ******************************************************************************/
311 static int fc_to_str(const address* addr, gchar *buf, int buf_len _U_)
312 {
313     gchar *bufp = buf;
314
315     bufp = bytes_to_hexstr_punct(bufp, (const guint8 *)addr->data, 3, '.');
316     *bufp++ = '\0'; /* NULL terminate */
317
318     return (int)(bufp - buf);
319 }
320
321 static int fc_str_len(const address* addr _U_)
322 {
323     return 9;
324 }
325
326 static int fc_len(void)
327 {
328     return 3;
329 }
330
331 /******************************************************************************
332  * AT_FCWWN
333  * XXX - Doubles as a "field type", should it be defined here?
334  ******************************************************************************/
335 /* FC Network Header Network Address Authority Identifiers */
336 #define FC_NH_NAA_IEEE          1   /* IEEE 802.1a */
337 #define FC_NH_NAA_IEEE_E        2   /* IEEE Exteneded */
338 #define FC_NH_NAA_LOCAL         3
339 #define FC_NH_NAA_IP            4   /* 32-bit IP address */
340 #define FC_NH_NAA_IEEE_R        5   /* IEEE Registered */
341 #define FC_NH_NAA_IEEE_R_E      6   /* IEEE Registered Exteneded */
342 /* according to FC-PH 3 draft these are now reclaimed and reserved */
343 #define FC_NH_NAA_CCITT_INDV    12  /* CCITT 60 bit individual address */
344 #define FC_NH_NAA_CCITT_GRP     14  /* CCITT 60 bit group address */
345
346 static int fcwwn_str_len(const address* addr _U_)
347 {
348     return 24;
349 }
350
351 static int fcwwn_to_str(const address* addr, gchar *buf, int buf_len _U_)
352 {
353     const guint8 *addrp = (const guint8*)addr->data;
354
355     buf = bytes_to_hexstr_punct(buf, addrp, 8, ':'); /* 23 bytes */
356     *buf = '\0';
357
358     return fcwwn_str_len(addr);
359 }
360
361 static int fcwwn_len(void)
362 {
363     return FCWWN_ADDR_LEN;
364 }
365
366 static const gchar* fcwwn_name_res_str(const address* addr)
367 {
368     const guint8 *addrp = (const guint8*)addr->data;
369     int fmt;
370     guint8 oui[6];
371
372     fmt = (addrp[0] & 0xF0) >> 4;
373     switch (fmt) {
374
375     case FC_NH_NAA_IEEE:
376     case FC_NH_NAA_IEEE_E:
377
378         memcpy (oui, &addrp[2], 6);
379         return get_manuf_name(oui);
380
381     case FC_NH_NAA_IEEE_R:
382         oui[0] = ((addrp[0] & 0x0F) << 4) | ((addrp[1] & 0xF0) >> 4);
383         oui[1] = ((addrp[1] & 0x0F) << 4) | ((addrp[2] & 0xF0) >> 4);
384         oui[2] = ((addrp[2] & 0x0F) << 4) | ((addrp[3] & 0xF0) >> 4);
385         oui[3] = ((addrp[3] & 0x0F) << 4) | ((addrp[4] & 0xF0) >> 4);
386         oui[4] = ((addrp[4] & 0x0F) << 4) | ((addrp[5] & 0xF0) >> 4);
387         oui[5] = ((addrp[5] & 0x0F) << 4) | ((addrp[6] & 0xF0) >> 4);
388
389         return get_manuf_name(oui);
390     }
391
392     return "";
393 }
394
395 static int fcwwn_name_res_len(void)
396 {
397     return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
398 }
399
400 /******************************************************************************
401  * AT_STRINGZ
402  ******************************************************************************/
403 static int stringz_addr_to_str(const address* addr, gchar *buf, int buf_len)
404 {
405     g_strlcpy(buf, (const gchar *)addr->data, buf_len);
406     return (int)(strlen(buf)+1);
407 }
408
409 static int stringz_addr_str_len(const address* addr)
410 {
411     return addr->len+1;
412 }
413
414 /******************************************************************************
415  * AT_EUI64
416  ******************************************************************************/
417 static int eui64_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
418 {
419     buf = bytes_to_hexstr_punct(buf, (const guint8 *)addr->data, 8, ':');
420     *buf = '\0'; /* NULL terminate */
421     return (int)(strlen(buf)+1);
422 }
423
424 static int eui64_str_len(const address* addr _U_)
425 {
426     return EUI64_STR_LEN;
427 }
428
429 static int eui64_len(void)
430 {
431     return 8;
432 }
433
434 /******************************************************************************
435  * AT_IB
436  ******************************************************************************/
437 static int
438 ib_addr_to_str(const address *addr, gchar *buf, int buf_len)
439 {
440     if (addr->len >= 16) { /* GID is 128bits */
441         return ip6_to_str_buf_with_pfx((const ws_in6_addr *)addr->data, buf, buf_len, "GID: ");
442     }
443
444     /* this is a LID (16 bits) */
445     g_snprintf(buf,buf_len,"LID: %u", *(guint16 *)addr->data);
446
447     return (int)(strlen(buf)+1);
448 }
449
450 static int ib_str_len(const address* addr _U_)
451 {
452     return MAX_ADDR_STR_LEN; /* XXX - This is overkill */
453 }
454
455 /******************************************************************************
456  * AT_AX25
457  ******************************************************************************/
458 static int ax25_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
459 {
460     const guint8 *addrdata = (const guint8 *)addr->data;
461     gchar *bufp = buf;
462
463     *bufp++ = printable_char_or_period(addrdata[0] >> 1);
464     *bufp++ = printable_char_or_period(addrdata[1] >> 1);
465     *bufp++ = printable_char_or_period(addrdata[2] >> 1);
466     *bufp++ = printable_char_or_period(addrdata[3] >> 1);
467     *bufp++ = printable_char_or_period(addrdata[4] >> 1);
468     *bufp++ = printable_char_or_period(addrdata[5] >> 1);
469     *bufp++ = '-';
470     bufp = uint_to_str_back(bufp, (addrdata[6] >> 1) & 0x0f);
471     *bufp++ = '\0'; /* NULL terminate */
472
473     return (int)(bufp - buf);
474 }
475
476 static int ax25_addr_str_len(const address* addr _U_)
477 {
478     return 21; /* Leaves extra space (10 bytes) just for uint_to_str_back() */
479 }
480
481 static const char* ax25_col_filter_str(const address* addr _U_, gboolean is_src)
482 {
483     if (is_src)
484         return "ax25.src";
485
486     return "ax25.dst";
487 }
488
489 static int ax25_len(void)
490 {
491     return AX25_ADDR_LEN;
492 }
493
494 /******************************************************************************
495  * END OF PROVIDED ADDRESS TYPES
496  ******************************************************************************/
497
498
499
500
501 void address_types_initialize(void)
502 {
503     static address_type_t none_address = {
504         AT_NONE,            /* addr_type */
505         "AT_NONE",          /* name */
506         "No address",       /* pretty_name */
507         none_addr_to_str,   /* addr_to_str */
508         none_addr_str_len,  /* addr_str_len */
509         NULL,               /* addr_to_byte */
510         NULL,               /* addr_col_filter */
511         none_addr_len,      /* addr_fixed_len */
512         none_name_res_str, /* addr_name_res_str */
513         none_name_res_len, /* addr_name_res_len */
514     };
515
516     static address_type_t ether_address = {
517         AT_ETHER,           /* addr_type */
518         "AT_ETHER",         /* name */
519         "Ethernet address", /* pretty_name */
520         ether_to_str,       /* addr_to_str */
521         ether_str_len,      /* addr_str_len */
522         NULL,               /* addr_to_byte */
523         ether_col_filter_str, /* addr_col_filter */
524         ether_len,          /* addr_fixed_len */
525         ether_name_resolution_str, /* addr_name_res_str */
526         ether_name_resolution_len, /* addr_name_res_len */
527     };
528
529     static address_type_t ipv4_address = {
530         AT_IPv4,            /* addr_type */
531         "AT_IPv4",          /* name */
532         "IPv4 address",     /* pretty_name */
533         ipv4_to_str,        /* addr_to_str */
534         ipv4_str_len,       /* addr_str_len */
535         NULL,               /* addr_to_byte */
536         ipv4_col_filter_str, /* addr_col_filter */
537         ipv4_len,           /* addr_fixed_len */
538         ipv4_name_res_str, /* addr_name_res_str */
539         ipv4_name_res_len, /* addr_name_res_len */
540     };
541
542     static address_type_t ipv6_address = {
543         AT_IPv6,            /* addr_type */
544         "AT_IPv6",          /* name */
545         "IPv6 address",     /* pretty_name */
546         ipv6_to_str,        /* addr_to_str */
547         ipv6_str_len,       /* addr_str_len */
548         NULL,               /* addr_to_byte */
549         ipv6_col_filter_str, /* addr_col_filter */
550         ipv6_len,            /* addr_fixed_len */
551         ipv6_name_res_str, /* addr_name_res_str */
552         ipv6_name_res_len, /* addr_name_res_len */
553    };
554
555     static address_type_t ipx_address = {
556         AT_IPX,             /* addr_type */
557         "AT_IPX",           /* name */
558         "IPX address",      /* pretty_name */
559         ipx_to_str,         /* addr_to_str */
560         ipx_str_len,        /* addr_str_len */
561         NULL,               /* addr_to_byte */
562         NULL,               /* addr_col_filter */
563         ipx_len,            /* addr_fixed_len */
564         NULL,               /* addr_name_res_str */
565         NULL,               /* addr_name_res_len */
566     };
567
568     static address_type_t fc_address = {
569         AT_FC,          /* addr_type */
570         "AT_FC",        /* name */
571         "FC address",   /* pretty_name */
572         fc_to_str,      /* addr_to_str */
573         fc_str_len,     /* addr_str_len */
574         NULL,           /* addr_to_byte */
575         NULL,           /* addr_col_filter */
576         fc_len,         /* addr_fixed_len */
577         NULL,           /* addr_name_res_str */
578         NULL,           /* addr_name_res_len */
579     };
580
581     static address_type_t fcwwn_address = {
582         AT_FCWWN,       /* addr_type */
583         "AT_FCWWN",     /* name */
584         "Fibre Channel WWN",    /* pretty_name */
585         fcwwn_to_str,   /* addr_to_str */
586         fcwwn_str_len,  /* addr_str_len */
587         NULL,           /* addr_to_byte */
588         NULL,           /* addr_col_filter */
589         fcwwn_len,         /* addr_fixed_len */
590         fcwwn_name_res_str, /* addr_name_res_str */
591         fcwwn_name_res_len, /* addr_name_res_len */
592     };
593
594     static address_type_t stringz_address = {
595         AT_STRINGZ,          /* addr_type */
596         "AT_STRINGZ",        /* name */
597         "String address",   /* pretty_name */
598         stringz_addr_to_str, /* addr_to_str */
599         stringz_addr_str_len, /* addr_str_len */
600         NULL,              /* addr_to_byte */
601         NULL,              /* addr_col_filter */
602         NULL,              /* addr_fixed_len */
603         NULL,              /* addr_name_res_str */
604         NULL,              /* addr_name_res_len */
605     };
606
607     static address_type_t eui64_address = {
608         AT_EUI64,          /* addr_type */
609         "AT_EUI64",        /* name */
610         "IEEE EUI-64",     /* pretty_name */
611         eui64_addr_to_str, /* addr_to_str */
612         eui64_str_len,     /* addr_str_len */
613         NULL,              /* addr_to_byte */
614         NULL,              /* addr_col_filter */
615         eui64_len,         /* addr_fixed_len */
616         NULL,              /* addr_name_res_str */
617         NULL,              /* addr_name_res_len */
618     };
619
620     static address_type_t ib_address = {
621         AT_IB,           /* addr_type */
622         "AT_IB",         /* name */
623         "Infiniband GID/LID",   /* pretty_name */
624         ib_addr_to_str,  /* addr_to_str */
625         ib_str_len,      /* addr_str_len */
626         NULL,              /* addr_to_byte */
627         NULL,              /* addr_col_filter */
628         NULL,              /* addr_fixed_len */
629         NULL,              /* addr_name_res_str */
630         NULL,              /* addr_name_res_len */
631     };
632
633     static address_type_t ax25_address = {
634         AT_AX25,          /* addr_type */
635         "AT_AX25",        /* name */
636         "AX.25 Address",  /* pretty_name */
637         ax25_addr_to_str, /* addr_to_str */
638         ax25_addr_str_len,/* addr_str_len */
639         NULL,             /* addr_to_byte */
640         ax25_col_filter_str, /* addr_col_filter */
641         ax25_len,          /* addr_fixed_len */
642         NULL,              /* addr_name_res_str */
643         NULL,              /* addr_name_res_len */
644     };
645
646     num_dissector_addr_type = 0;
647
648     /* Initialize the type array.  This is mostly for handling
649        "dissector registered" address type range (for NULL checking) */
650     memset(type_list, 0, (MAX_ADDR_TYPE_VALUE + 1)*sizeof(address_type_t*));
651
652     address_type_register(AT_NONE, &none_address );
653     address_type_register(AT_ETHER, &ether_address );
654     address_type_register(AT_IPv4, &ipv4_address );
655     address_type_register(AT_IPv6, &ipv6_address );
656     address_type_register(AT_IPX, &ipx_address );
657     address_type_register(AT_FC, &fc_address );
658     address_type_register(AT_FCWWN, &fcwwn_address );
659     address_type_register(AT_STRINGZ, &stringz_address );
660     address_type_register(AT_EUI64, &eui64_address );
661     address_type_register(AT_IB, &ib_address );
662     address_type_register(AT_AX25, &ax25_address );
663 }
664
665 /* Given an address type id, return an address_type_t* */
666 #define ADDR_TYPE_LOOKUP(addr_type, result)    \
667     /* Check input */                          \
668     g_assert(addr_type < MAX_ADDR_TYPE_VALUE); \
669     result = type_list[addr_type];
670
671 static int address_type_get_length(const address* addr)
672 {
673     address_type_t *at;
674
675     ADDR_TYPE_LOOKUP(addr->type, at);
676
677     if (at == NULL)
678         return 0;
679
680     return at->addr_str_len(addr);
681 }
682
683 gchar*
684 address_to_str(wmem_allocator_t *scope, const address *addr)
685 {
686     gchar *str;
687     int len = address_type_get_length(addr);
688
689     if (len <= 0)
690         len = MAX_ADDR_STR_LEN;
691
692     str=(gchar *)wmem_alloc(scope, len);
693     address_to_str_buf(addr, str, len);
694     return str;
695 }
696
697 void address_to_str_buf(const address* addr, gchar *buf, int buf_len)
698 {
699     address_type_t *at;
700
701     if (!buf || !buf_len)
702         return;
703
704     ADDR_TYPE_LOOKUP(addr->type, at);
705
706     if ((at == NULL) || (at->addr_to_str == NULL))
707     {
708         buf[0] = '\0';
709         return;
710     }
711
712     at->addr_to_str(addr, buf, buf_len);
713 }
714
715
716 guint address_to_bytes(const address *addr, guint8 *buf, guint buf_len)
717 {
718     address_type_t *at;
719     guint copy_len = 0;
720
721     if (!buf || !buf_len)
722         return 0;
723
724     ADDR_TYPE_LOOKUP(addr->type, at);
725
726     if (at == NULL)
727         return 0;
728
729     if (at->addr_to_byte == NULL)
730     {
731         /* If a specific function isn't provided, just do a memcpy */
732         copy_len = MIN(((guint)addr->len), buf_len);
733         memcpy(buf, addr->data, copy_len);
734     }
735     else
736     {
737         copy_len = at->addr_to_byte(addr, buf, buf_len);
738     }
739
740     return copy_len;
741 }
742
743 const gchar *
744 address_to_name(const address *addr)
745 {
746     address_type_t *at;
747
748     ADDR_TYPE_LOOKUP(addr->type, at);
749
750     if (at == NULL)
751     {
752         return NULL;
753     }
754
755     /*
756      * XXX - addr_name_res_str is expected to return a string from
757      * a persistent database, so that it lives a long time, past
758      * the lifetime of addr itself.
759      *
760      * We'd like to avoid copying, so this is what we do here.
761      */
762     switch (addr->type) {
763
764     case AT_STRINGZ:
765         return (const gchar *)addr->data;
766
767     default:
768         if (at->addr_name_res_str != NULL)
769             return at->addr_name_res_str(addr);
770         else
771             return NULL;
772     }
773 }
774
775 gchar *
776 address_to_display(wmem_allocator_t *allocator, const address *addr)
777 {
778     gchar *str = NULL;
779     const gchar *result = address_to_name(addr);
780
781     if (result != NULL) {
782         str = wmem_strdup(allocator, result);
783     }
784     else if (addr->type == AT_NONE) {
785         str = wmem_strdup(allocator, "NONE");
786     }
787     else {
788         str = (gchar *) wmem_alloc(allocator, MAX_ADDR_STR_LEN);
789         address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
790     }
791
792     return str;
793 }
794
795 static void address_with_resolution_to_str_buf(const address* addr, gchar *buf, int buf_len)
796 {
797     address_type_t *at;
798     int addr_len;
799     gsize pos;
800     gboolean empty;
801
802     if (!buf || !buf_len)
803         return;
804
805     ADDR_TYPE_LOOKUP(addr->type, at);
806
807     if (at == NULL)
808     {
809         buf[0] = '\0';
810         return;
811     }
812
813 #if 0 /* XXX - If this remains a static function, we've already made this check in the only
814          function that can call it.  If this function becomes "public", need to put this
815          check back in */
816     /* No name resolution support, just return address string */
817     if (at->addr_name_res_str == NULL)
818         return address_to_str_buf(addr, buf, buf_len);
819 #endif
820
821     /* Copy the resolved name */
822     pos = g_strlcpy(buf, at->addr_name_res_str(addr), buf_len);
823
824     /* Don't wrap "emptyness" in parentheses */
825     if (addr->type == AT_NONE)
826         return;
827
828     /* Make sure there is enough room for the address string wrapped in parentheses */
829     if ((int)(pos + 4 + at->addr_str_len(addr)) >= buf_len)
830         return;
831
832     empty = (pos <= 1) ? TRUE : FALSE;
833
834     if (!empty)
835     {
836         buf[pos++] = ' ';
837         buf[pos++] = '(';
838     }
839
840     addr_len = at->addr_to_str(addr, &buf[pos], (int)(buf_len-pos));
841     pos += addr_len - 1; /* addr_len includes the trailing '\0' */
842
843     if (!empty)
844     {
845         buf[pos++] = ')';
846         buf[pos++] = '\0';
847     }
848 }
849
850 gchar* address_with_resolution_to_str(wmem_allocator_t *scope, const address *addr)
851 {
852     address_type_t *at;
853     int len;
854     gchar *str;
855
856     ADDR_TYPE_LOOKUP(addr->type, at);
857
858     if (at == NULL)
859         return wmem_strdup(scope, "");
860
861     /* No name resolution support, just return address string */
862     if ((at->addr_name_res_str == NULL) ||
863             (ADDR_RESOLV_MACADDR(addr) && !gbl_resolv_flags.mac_name) ||
864             (ADDR_RESOLV_NETADDR(addr) && !gbl_resolv_flags.network_name)) {
865         return address_to_str(scope, addr);
866     }
867
868     len = at->addr_name_res_len() + at->addr_str_len(addr) + 4; /* For format of %s (%s) */
869
870     str=(gchar *)wmem_alloc(scope, len);
871     address_with_resolution_to_str_buf(addr, str, len);
872     return str;
873 }
874
875
876 const char* address_type_column_filter_string(const address* addr, gboolean src)
877 {
878     address_type_t *at;
879
880     ADDR_TYPE_LOOKUP(addr->type, at);
881
882     if ((at == NULL) || (at->addr_col_filter == NULL))
883     {
884         return "";
885     }
886
887     return at->addr_col_filter(addr, src);
888 }
889
890 gchar*
891 tvb_address_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int type, const gint offset)
892 {
893     address addr;
894     address_type_t *at;
895
896     ADDR_TYPE_LOOKUP(type, at);
897
898     if (at == NULL)
899     {
900         return NULL;
901     }
902
903     /* The address type must have a fixed length to use this function */
904     /* For variable length fields, use tvb_address_var_to_str() */
905     if (at->addr_fixed_len == NULL)
906     {
907         g_assert_not_reached();
908         return NULL;
909     }
910
911     set_address_tvb(&addr, type, at->addr_fixed_len(), tvb, offset);
912
913     return address_to_str(scope, &addr);
914 }
915
916 gchar* tvb_address_var_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, address_type type, const gint offset, int length)
917 {
918     address addr;
919
920     set_address_tvb(&addr, type, length, tvb, offset);
921
922     return address_to_str(scope, &addr);
923 }
924
925 gchar*
926 tvb_address_with_resolution_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int type, const gint offset)
927 {
928     address addr;
929     address_type_t *at;
930
931     ADDR_TYPE_LOOKUP(type, at);
932
933     if (at == NULL)
934     {
935         return NULL;
936     }
937
938     /* The address type must have a fixed length to use this function */
939     /* For variable length fields, use tvb_address_var_with_resolution_to_str() */
940     if (at->addr_fixed_len == NULL)
941     {
942         g_assert_not_reached();
943         return NULL;
944     }
945
946     set_address_tvb(&addr, type, at->addr_fixed_len(), tvb, offset);
947
948     return address_with_resolution_to_str(scope, &addr);
949 }
950
951
952 /*
953  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
954  *
955  * Local variables:
956  * c-basic-offset: 4
957  * tab-width: 8
958  * indent-tabs-mode: nil
959  * End:
960  *
961  * vi: set shiftwidth=4 tabstop=8 expandtab:
962  * :indentSize=4:tabSize=8:noTabs=true:
963  */