Add inet_pton/inet_ntop interface to libwsutil
[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 #include <epan/dissectors/packet-mtp3.h>
35
36 struct _address_type_t {
37     int                     addr_type; /* From address_type enumeration or registered value */
38     const char             *name;
39     const char             *pretty_name;
40     AddrValueToString       addr_to_str;
41     AddrValueToStringLen    addr_str_len;
42     AddrColFilterString     addr_col_filter;
43     AddrFixedLen            addr_fixed_len;
44     AddrNameResolutionToString addr_name_res_str;
45     AddrNameResolutionLen   addr_name_res_len;
46
47     /* XXX - Some sort of compare functions (like ftype)? ***/
48 };
49
50 #define MAX_DISSECTOR_ADDR_TYPE     20
51 #define MAX_ADDR_TYPE_VALUE (AT_END_OF_LIST+MAX_DISSECTOR_ADDR_TYPE)
52
53 static int num_dissector_addr_type;
54 static address_type_t dissector_type_addresses[MAX_DISSECTOR_ADDR_TYPE];
55
56 /* Keep track of address_type_t's via their id number */
57 static address_type_t* type_list[MAX_ADDR_TYPE_VALUE];
58
59 /*
60  * If a user _does_ pass in a too-small buffer, this is probably
61  * going to be too long to fit.  However, even a partial string
62  * starting with "[Buf" should provide enough of a clue to be
63  * useful.
64  */
65 #define BUF_TOO_SMALL_ERR "[Buffer too small]"
66
67 static void address_type_register(int addr_type, address_type_t *at)
68 {
69     /* Check input */
70     g_assert(addr_type < MAX_ADDR_TYPE_VALUE);
71     g_assert(addr_type == at->addr_type);
72
73     /* Don't re-register. */
74     g_assert(type_list[addr_type] == NULL);
75
76     /* Sanity check */
77     DISSECTOR_ASSERT(at->name);
78     DISSECTOR_ASSERT(at->pretty_name);
79     DISSECTOR_ASSERT(at->addr_to_str);
80     DISSECTOR_ASSERT(at->addr_str_len);
81     DISSECTOR_ASSERT(((at->addr_name_res_str != NULL) && (at->addr_name_res_len != NULL)) ||
82                      ((at->addr_name_res_str == NULL) && (at->addr_name_res_len == NULL)));
83
84     type_list[addr_type] = at;
85 }
86
87 int address_type_dissector_register(const char* name, const char* pretty_name,
88                                     AddrValueToString to_str_func, AddrValueToStringLen str_len_func,
89                                     AddrColFilterString col_filter_str_func, AddrFixedLen fixed_len_func,
90                                     AddrNameResolutionToString name_res_str_func, AddrNameResolutionLen name_res_len_func)
91 {
92     int addr_type;
93
94     /* Ensure valid data/functions for required fields */
95     DISSECTOR_ASSERT(name);
96     DISSECTOR_ASSERT(pretty_name);
97     DISSECTOR_ASSERT(to_str_func);
98     DISSECTOR_ASSERT(str_len_func);
99     /* Either have both or neither */
100     DISSECTOR_ASSERT(((name_res_str_func != NULL) && (name_res_len_func != NULL)) ||
101                      ((name_res_str_func == NULL) && (name_res_len_func == NULL)));
102
103     /* This shouldn't happen, so flag it for fixing */
104     DISSECTOR_ASSERT(num_dissector_addr_type < MAX_DISSECTOR_ADDR_TYPE);
105
106     addr_type = AT_END_OF_LIST+num_dissector_addr_type;
107     dissector_type_addresses[num_dissector_addr_type].addr_type = addr_type;
108     dissector_type_addresses[num_dissector_addr_type].name = name;
109     dissector_type_addresses[num_dissector_addr_type].pretty_name = pretty_name;
110     dissector_type_addresses[num_dissector_addr_type].addr_to_str = to_str_func;
111     dissector_type_addresses[num_dissector_addr_type].addr_str_len = str_len_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 /******************************************************************************
125  * AT_NONE
126  ******************************************************************************/
127 int none_addr_to_str(const address* addr _U_, gchar *buf, int buf_len _U_)
128 {
129     buf[0] = '\0';
130     return none_addr_str_len(addr);
131 }
132
133 int none_addr_str_len(const address* addr _U_)
134 {
135     return 1; /* NULL character for empty string */
136 }
137
138 int none_addr_len(void)
139 {
140     return 0;
141 }
142
143 static int none_name_res_len(void)
144 {
145     return 5;
146 }
147
148 static const gchar* none_name_res_str(const address* addr _U_)
149 {
150     return "NONE";
151 }
152
153 /******************************************************************************
154  * AT_ETHER
155  ******************************************************************************/
156 int ether_to_str(const address* addr, gchar *buf, int buf_len _U_)
157 {
158     bytes_to_hexstr_punct(buf, (const guint8*)addr->data, 6, ':');
159     buf[17] = '\0';
160     return ether_str_len(addr);
161 }
162
163 int ether_str_len(const address* addr _U_)
164 {
165     return 18;
166 }
167
168 static const char* ether_col_filter_str(const address* addr _U_, gboolean is_src)
169 {
170     if (is_src)
171         return "eth.src";
172
173     return "eth.dst";
174 }
175
176 int ether_len(void)
177 {
178     return 6;
179 }
180
181 const gchar* ether_name_resolution_str(const address* addr)
182 {
183     return get_ether_name((const guint8 *)addr->data);
184 }
185
186 int ether_name_resolution_len(void)
187 {
188     return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
189 }
190
191 /******************************************************************************
192  * AT_IPv4
193  ******************************************************************************/
194 static int ipv4_to_str(const address* addr, gchar *buf, int buf_len)
195 {
196     ip_to_str_buf((const guint8*)addr->data, buf, buf_len);
197     return (int)(strlen(buf)+1);
198 }
199
200 static int ipv4_str_len(const address* addr _U_)
201 {
202     return MAX_IP_STR_LEN;
203 }
204
205 static const char* ipv4_col_filter_str(const address* addr _U_, gboolean is_src)
206 {
207     if (is_src)
208         return "ip.src";
209
210     return "ip.dst";
211 }
212
213 static int ipv4_len(void)
214 {
215     return 4;
216 }
217
218 static const gchar* ipv4_name_res_str(const address* addr)
219 {
220     guint32 ip4_addr;
221     memcpy(&ip4_addr, addr->data, sizeof ip4_addr);
222     return get_hostname(ip4_addr);
223 }
224
225 static int ipv4_name_res_len(void)
226 {
227     return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
228 }
229
230 /******************************************************************************
231  * AT_IPv6
232  ******************************************************************************/
233 /* const char *
234  * inet_ntop6(src, dst, size)
235  *  convert IPv6 binary address into presentation (printable) format
236  * author:
237  *  Paul Vixie, 1996.
238  */
239 static void
240 ip6_to_str_buf_len(const guchar* src, char *buf, int buf_len)
241 {
242     struct { int base, len; } best, cur;
243     guint words[8];
244     int i;
245
246     if (buf_len < MAX_IP6_STR_LEN) { /* buf_len < 40 */
247         g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
248         return;
249     }
250
251     /*
252      * Preprocess:
253      *  Copy the input (bytewise) array into a wordwise array.
254      *  Find the longest run of 0x00's in src[] for :: shorthanding.
255      */
256     for (i = 0; i < 16; i += 2) {
257         words[i / 2] = (src[i+1] << 0);
258         words[i / 2] |= (src[i] << 8);
259     }
260     best.base = -1; best.len = 0;
261     cur.base = -1;  cur.len = 0;
262     for (i = 0; i < 8; i++) {
263         if (words[i] == 0) {
264             if (cur.base == -1) {
265                 cur.base = i;
266                 cur.len = 1;
267             } else
268                 cur.len++;
269         } else {
270             if (cur.base != -1) {
271                 if (best.base == -1 || cur.len > best.len)
272                     best = cur;
273                 cur.base = -1;
274             }
275         }
276     }
277     if (cur.base != -1) {
278         if (best.base == -1 || cur.len > best.len)
279             best = cur;
280     }
281     if (best.base != -1 && best.len < 2)
282         best.base = -1;
283
284     /* Is this address an encapsulated IPv4? */
285     /* XXX,
286      * Orginal code dated 1996 uses ::/96 as a valid IPv4-compatible addresses
287      * but since Feb 2006 ::/96 is deprecated one.
288      * Quoting wikipedia [0]:
289      * > The 96-bit zero-value prefix ::/96, originally known as IPv4-compatible
290      * > addresses, was mentioned in 1995[35] but first described in 1998.[41]
291      * > This class of addresses was used to represent IPv4 addresses within
292      * > an IPv6 transition technology. Such an IPv6 address has its first
293      * > (most significant) 96 bits set to zero, while its last 32 bits are the
294      * > IPv4 address that is represented.
295      * > In February 2006 the Internet Engineering Task Force (IETF) has deprecated
296      * > the use of IPv4-compatible addresses.[1] The only remaining use of this address
297      * > format is to represent an IPv4 address in a table or database with fixed size
298      * > members that must also be able to store an IPv6 address.
299      *
300      * If needed it can be fixed by changing next line:
301      *   if (best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
302      * to:
303      *   if (best.base == 0 && best.len == 5 && words[5] == 0xffff)
304      *
305      * [0] http://en.wikipedia.org/wiki/IPv6_address#Historical_notes
306      */
307
308     if (best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
309     {
310         /* best.len == 6 -> ::IPv4; 5 -> ::ffff:IPv4 */
311         buf = g_stpcpy(buf, "::");
312         if (best.len == 5)
313         buf = g_stpcpy(buf, "ffff:");
314         ip_to_str_buf(src + 12, buf, MAX_IP_STR_LEN);
315         /* max: 2 + 5 + 16 == 23 bytes */
316         return;
317     }
318
319     /*
320      * Format the result.
321      */
322     for (i = 0; i < 8; i++) {
323         /* Are we inside the best run of 0x00's? */
324         if (i == best.base) {
325             *buf++ = ':';
326             i += best.len;
327
328             /* Was it a trailing run of 0x00's? */
329             if (i == 8) {
330                 *buf++ = ':';
331                 break;
332             }
333         }
334         /* Are we following an initial run of 0x00s or any real hex? */
335         if (i != 0)
336             *buf++ = ':';
337
338         buf = word_to_hex_npad(buf, words[i]); /* max: 4B */
339         /* max: 8 * 4 + 7 == 39 bytes */
340     }
341     *buf = '\0'; /* 40 byte */
342 }
343
344 void
345 ip6_to_str_buf(const struct e_in6_addr *ad, gchar *buf)
346 {
347     ip6_to_str_buf_len((const guchar*)ad, buf, MAX_IP6_STR_LEN);
348 }
349
350 static int ipv6_to_str(const address* addr, gchar *buf, int buf_len)
351 {
352     ip6_to_str_buf_len((const guchar*)addr->data, buf, buf_len);
353     return (int)(strlen(buf)+1);
354 }
355
356 static int ipv6_str_len(const address* addr _U_)
357 {
358     return MAX_IP6_STR_LEN;
359 }
360
361 static const char* ipv6_col_filter_str(const address* addr _U_, gboolean is_src)
362 {
363     if (is_src)
364         return "ipv6.src";
365
366     return "ipv6.dst";
367 }
368
369 static int ipv6_len(void)
370 {
371     return 16;
372 }
373
374 static const gchar* ipv6_name_res_str(const address* addr)
375 {
376     struct e_in6_addr ip6_addr;
377     memcpy(&ip6_addr.bytes, addr->data, sizeof ip6_addr.bytes);
378     return get_hostname6(&ip6_addr);
379 }
380
381 static int ipv6_name_res_len(void)
382 {
383     return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
384 }
385
386 /******************************************************************************
387  * AT_IPX
388  ******************************************************************************/
389 static int ipx_to_str(const address* addr, gchar *buf, int buf_len _U_)
390 {
391     const guint8 *addrdata = (const guint8 *)addr->data;
392     gchar *bufp = buf;
393
394     bufp = bytes_to_hexstr(bufp, &addrdata[0], 4); /* 8 bytes */
395     *bufp++ = '.'; /*1 byte */
396     bufp = bytes_to_hexstr(bufp, &addrdata[4], 6); /* 12 bytes */
397     *bufp++ = '\0'; /* NULL terminate */
398     return (int)(bufp - buf);
399 }
400
401 static int ipx_str_len(const address* addr _U_)
402 {
403     return 22;
404 }
405
406 static int ipx_len(void)
407 {
408     return 10;
409 }
410
411 /******************************************************************************
412  * AT_VINES
413  * XXX - This functionality should really be in packet-vines.c as a dissector
414  * address type, but need to resolve "address type" as "field type"
415  ******************************************************************************/
416 static int vines_to_str(const address* addr, gchar *buf, int buf_len _U_)
417 {
418     const guint8 *addr_data = (const guint8 *)addr->data;
419     gchar *bufp = buf;
420
421     bufp = dword_to_hex(bufp, pntoh32(&addr_data[0])); /* 8 bytes */
422     *bufp++ = '.'; /* 1 byte */
423     bufp = word_to_hex(bufp, pntoh16(&addr_data[4])); /* 4 bytes */
424     *bufp++ = '\0'; /* NULL terminate */
425
426     return (int)(bufp - buf);
427 }
428
429 static int vines_str_len(const address* addr _U_)
430 {
431     return 14;
432 }
433
434 static int vines_len(void)
435 {
436     return VINES_ADDR_LEN;
437 }
438
439 /******************************************************************************
440  * AT_FC
441  ******************************************************************************/
442 static int fc_to_str(const address* addr, gchar *buf, int buf_len _U_)
443 {
444     gchar *bufp = buf;
445
446     bufp = bytes_to_hexstr_punct(bufp, (const guint8 *)addr->data, 3, '.');
447     *bufp++ = '\0'; /* NULL terminate */
448
449     return (int)(bufp - buf);
450 }
451
452 static int fc_str_len(const address* addr _U_)
453 {
454     return 9;
455 }
456
457 static int fc_len(void)
458 {
459     return 3;
460 }
461
462 /******************************************************************************
463  * AT_FCWWN
464  * XXX - Doubles as a "field type", should it be defined here?
465  ******************************************************************************/
466 /* FC Network Header Network Address Authority Identifiers */
467 #define FC_NH_NAA_IEEE          1   /* IEEE 802.1a */
468 #define FC_NH_NAA_IEEE_E        2   /* IEEE Exteneded */
469 #define FC_NH_NAA_LOCAL         3
470 #define FC_NH_NAA_IP            4   /* 32-bit IP address */
471 #define FC_NH_NAA_IEEE_R        5   /* IEEE Registered */
472 #define FC_NH_NAA_IEEE_R_E      6   /* IEEE Registered Exteneded */
473 /* according to FC-PH 3 draft these are now reclaimed and reserved */
474 #define FC_NH_NAA_CCITT_INDV    12  /* CCITT 60 bit individual address */
475 #define FC_NH_NAA_CCITT_GRP     14  /* CCITT 60 bit group address */
476
477 static int fcwwn_str_len(const address* addr _U_)
478 {
479     return 24;
480 }
481
482 static int fcwwn_to_str(const address* addr, gchar *buf, int buf_len _U_)
483 {
484     const guint8 *addrp = (const guint8*)addr->data;
485
486     buf = bytes_to_hexstr_punct(buf, addrp, 8, ':'); /* 23 bytes */
487     *buf = '\0';
488
489     return fcwwn_str_len(addr);
490 }
491
492 static int fcwwn_len(void)
493 {
494     return FCWWN_ADDR_LEN;
495 }
496
497 static const gchar* fcwwn_name_res_str(const address* addr)
498 {
499     const guint8 *addrp = (const guint8*)addr->data;
500     int fmt;
501     guint8 oui[6];
502
503     fmt = (addrp[0] & 0xF0) >> 4;
504     switch (fmt) {
505
506     case FC_NH_NAA_IEEE:
507     case FC_NH_NAA_IEEE_E:
508
509         memcpy (oui, &addrp[2], 6);
510         return get_manuf_name(oui);
511
512     case FC_NH_NAA_IEEE_R:
513         oui[0] = ((addrp[0] & 0x0F) << 4) | ((addrp[1] & 0xF0) >> 4);
514         oui[1] = ((addrp[1] & 0x0F) << 4) | ((addrp[2] & 0xF0) >> 4);
515         oui[2] = ((addrp[2] & 0x0F) << 4) | ((addrp[3] & 0xF0) >> 4);
516         oui[3] = ((addrp[3] & 0x0F) << 4) | ((addrp[4] & 0xF0) >> 4);
517         oui[4] = ((addrp[4] & 0x0F) << 4) | ((addrp[5] & 0xF0) >> 4);
518         oui[5] = ((addrp[5] & 0x0F) << 4) | ((addrp[6] & 0xF0) >> 4);
519
520         return get_manuf_name(oui);
521     }
522
523     return "";
524 }
525
526 static int fcwwn_name_res_len(void)
527 {
528     return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
529 }
530
531 /******************************************************************************
532  * AT_SS7PC
533  * XXX - This should really be a dissector address type as its address string
534  * is partially determined by a dissector preference.
535  ******************************************************************************/
536 static int ss7pc_to_str(const address* addr, gchar *buf, int buf_len)
537 {
538     mtp3_addr_to_str_buf((const mtp3_addr_pc_t *)addr->data, buf, buf_len);
539     return (int)(strlen(buf)+1);
540 }
541
542 static int ss7pc_str_len(const address* addr _U_)
543 {
544     return 50;
545 }
546
547 /******************************************************************************
548  * AT_STRINGZ
549  ******************************************************************************/
550 static int stringz_addr_to_str(const address* addr, gchar *buf, int buf_len)
551 {
552     g_strlcpy(buf, (const gchar *)addr->data, buf_len);
553     return (int)(strlen(buf)+1);
554 }
555
556 static int stringz_addr_str_len(const address* addr)
557 {
558     return addr->len+1;
559 }
560
561 /******************************************************************************
562  * AT_EUI64
563  ******************************************************************************/
564 static int eui64_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
565 {
566     buf = bytes_to_hexstr_punct(buf, (const guint8 *)addr->data, 8, ':');
567     *buf = '\0'; /* NULL terminate */
568     return sizeof(buf) + 1;
569 }
570
571 static int eui64_str_len(const address* addr _U_)
572 {
573     return EUI64_STR_LEN;
574 }
575
576 static int eui64_len(void)
577 {
578     return 8;
579 }
580
581 /******************************************************************************
582  * AT_IB
583  ******************************************************************************/
584 static int
585 ib_addr_to_str( const address *addr, gchar *buf, int buf_len){
586     if (addr->len >= 16) { /* GID is 128bits */
587         #define PREAMBLE_STR_LEN ((int)(sizeof("GID: ") - 1))
588         g_strlcpy(buf, "GID: ", buf_len);
589         if (buf_len < PREAMBLE_STR_LEN ||
590                 ws_inet_ntop6(addr->data, buf + PREAMBLE_STR_LEN,
591                           buf_len - PREAMBLE_STR_LEN) == NULL ) /* Returns NULL if no space and does not touch buf */
592             g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
593     } else {    /* this is a LID (16 bits) */
594         guint16 lid_number;
595
596         memcpy((void *)&lid_number, addr->data, sizeof lid_number);
597         g_snprintf(buf,buf_len,"LID: %u",lid_number);
598     }
599
600     return sizeof(buf) + 1;
601 }
602
603 static int ib_str_len(const address* addr _U_)
604 {
605     return MAX_ADDR_STR_LEN; /* XXX - This is overkill */
606 }
607
608 /******************************************************************************
609  * AT_USB
610  * XXX - This functionality should really be in packet-usb.c as a dissector
611  * address type, but currently need support of AT_USB in conversation_table.c
612  ******************************************************************************/
613 static int usb_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
614 {
615     const guint8 *addrp = (const guint8 *)addr->data;
616
617     if(pletoh32(&addrp[0])==0xffffffff){
618         g_strlcpy(buf, "host", buf_len);
619     } else {
620         g_snprintf(buf, buf_len, "%d.%d.%d", pletoh16(&addrp[8]),
621                         pletoh32(&addrp[0]), pletoh32(&addrp[4]));
622     }
623
624     return (int)(strlen(buf)+1);
625 }
626
627 static int usb_addr_str_len(const address* addr _U_)
628 {
629     return 50;
630 }
631
632 /******************************************************************************
633  * AT_AX25
634  ******************************************************************************/
635 static int ax25_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
636 {
637     const guint8 *addrdata = (const guint8 *)addr->data;
638     gchar *bufp = buf;
639
640     *bufp++ = printable_char_or_period(addrdata[0] >> 1);
641     *bufp++ = printable_char_or_period(addrdata[1] >> 1);
642     *bufp++ = printable_char_or_period(addrdata[2] >> 1);
643     *bufp++ = printable_char_or_period(addrdata[3] >> 1);
644     *bufp++ = printable_char_or_period(addrdata[4] >> 1);
645     *bufp++ = printable_char_or_period(addrdata[5] >> 1);
646     *bufp++ = '-';
647     bufp = uint_to_str_back(bufp, (addrdata[6] >> 1) & 0x0f);
648     *bufp++ = '\0'; /* NULL terminate */
649
650     return (int)(bufp - buf);
651 }
652
653 static int ax25_addr_str_len(const address* addr _U_)
654 {
655     return 21; /* Leaves extra space (10 bytes) just for uint_to_str_back() */
656 }
657
658 static const char* ax25_col_filter_str(const address* addr _U_, gboolean is_src)
659 {
660     if (is_src)
661         return "ax25.src";
662
663     return "ax25.dst";
664 }
665
666 static int ax25_len(void)
667 {
668     return AX25_ADDR_LEN;
669 }
670
671 /******************************************************************************
672  * END OF PROVIDED ADDRESS TYPES
673  ******************************************************************************/
674
675
676
677
678 void address_types_initialize(void)
679 {
680     static address_type_t none_address = {
681         AT_NONE,            /* addr_type */
682         "AT_NONE",          /* name */
683         "No address",       /* pretty_name */
684         none_addr_to_str,   /* addr_to_str */
685         none_addr_str_len,  /* addr_str_len */
686         NULL,               /* addr_col_filter */
687         none_addr_len,      /* addr_fixed_len */
688         none_name_res_str, /* addr_name_res_str */
689         none_name_res_len, /* addr_name_res_len */
690     };
691
692     static address_type_t ether_address = {
693         AT_ETHER,           /* addr_type */
694         "AT_ETHER",         /* name */
695         "Ethernet address", /* pretty_name */
696         ether_to_str,       /* addr_to_str */
697         ether_str_len,      /* addr_str_len */
698         ether_col_filter_str, /* addr_col_filter */
699         ether_len,          /* addr_fixed_len */
700         ether_name_resolution_str, /* addr_name_res_str */
701         ether_name_resolution_len, /* addr_name_res_len */
702     };
703
704     static address_type_t ipv4_address = {
705         AT_IPv4,            /* addr_type */
706         "AT_IPv4",          /* name */
707         "IPv4 address",     /* pretty_name */
708         ipv4_to_str,        /* addr_to_str */
709         ipv4_str_len,       /* addr_str_len */
710         ipv4_col_filter_str, /* addr_col_filter */
711         ipv4_len,           /* addr_fixed_len */
712         ipv4_name_res_str, /* addr_name_res_str */
713         ipv4_name_res_len, /* addr_name_res_len */
714     };
715
716     static address_type_t ipv6_address = {
717         AT_IPv6,            /* addr_type */
718         "AT_IPv6",          /* name */
719         "IPv6 address",     /* pretty_name */
720         ipv6_to_str,        /* addr_to_str */
721         ipv6_str_len,       /* addr_str_len */
722         ipv6_col_filter_str, /* addr_col_filter */
723         ipv6_len,            /* addr_fixed_len */
724         ipv6_name_res_str, /* addr_name_res_str */
725         ipv6_name_res_len, /* addr_name_res_len */
726    };
727
728     static address_type_t ipx_address = {
729         AT_IPX,             /* addr_type */
730         "AT_IPX",           /* name */
731         "IPX address",      /* pretty_name */
732         ipx_to_str,         /* addr_to_str */
733         ipx_str_len,        /* addr_str_len */
734         NULL,               /* addr_col_filter */
735         ipx_len,            /* addr_fixed_len */
736         NULL,               /* addr_name_res_str */
737         NULL,               /* addr_name_res_len */
738     };
739
740     static address_type_t vines_address = {
741         AT_VINES,           /* addr_type */
742         "AT_VINES",         /* name */
743         "Banyan Vines address", /* pretty_name */
744         vines_to_str,       /* addr_to_str */
745         vines_str_len,      /* addr_str_len */
746         NULL,               /* addr_col_filter */
747         vines_len,          /* addr_fixed_len */
748         NULL,               /* addr_name_res_str */
749         NULL,               /* addr_name_res_len */
750     };
751
752     static address_type_t fc_address = {
753         AT_FC,          /* addr_type */
754         "AT_FC",        /* name */
755         "FC address",   /* pretty_name */
756         fc_to_str,      /* addr_to_str */
757         fc_str_len,     /* addr_str_len */
758         NULL,           /* addr_col_filter */
759         fc_len,         /* addr_fixed_len */
760         NULL,           /* addr_name_res_str */
761         NULL,           /* addr_name_res_len */
762     };
763
764     static address_type_t fcwwn_address = {
765         AT_FCWWN,       /* addr_type */
766         "AT_FCWWN",     /* name */
767         "Fibre Channel WWN",    /* pretty_name */
768         fcwwn_to_str,   /* addr_to_str */
769         fcwwn_str_len,  /* addr_str_len */
770         NULL,           /* addr_col_filter */
771         fcwwn_len,         /* addr_fixed_len */
772         fcwwn_name_res_str, /* addr_name_res_str */
773         fcwwn_name_res_len, /* addr_name_res_len */
774     };
775
776     static address_type_t ss7pc_address = {
777         AT_SS7PC,          /* addr_type */
778         "AT_SS7PC",        /* name */
779         "SS7 Point Code",  /* pretty_name */
780         ss7pc_to_str,      /* addr_to_str */
781         ss7pc_str_len,     /* addr_str_len */
782         NULL,              /* addr_col_filter */
783         NULL,              /* addr_fixed_len */
784         NULL,              /* addr_name_res_str */
785         NULL,              /* addr_name_res_len */
786     };
787
788     static address_type_t stringz_address = {
789         AT_STRINGZ,          /* addr_type */
790         "AT_STRINGZ",        /* name */
791         "String address",   /* pretty_name */
792         stringz_addr_to_str, /* addr_to_str */
793         stringz_addr_str_len, /* addr_str_len */
794         NULL,              /* addr_col_filter */
795         NULL,              /* addr_fixed_len */
796         NULL,              /* addr_name_res_str */
797         NULL,              /* addr_name_res_len */
798     };
799
800     static address_type_t eui64_address = {
801         AT_EUI64,          /* addr_type */
802         "AT_EUI64",        /* name */
803         "IEEE EUI-64",     /* pretty_name */
804         eui64_addr_to_str, /* addr_to_str */
805         eui64_str_len,     /* addr_str_len */
806         NULL,              /* addr_col_filter */
807         eui64_len,         /* addr_fixed_len */
808         NULL,              /* addr_name_res_str */
809         NULL,              /* addr_name_res_len */
810     };
811
812     static address_type_t ib_address = {
813         AT_IB,           /* addr_type */
814         "AT_IB",         /* name */
815         "Infiniband GID/LID",   /* pretty_name */
816         ib_addr_to_str,  /* addr_to_str */
817         ib_str_len,      /* addr_str_len */
818         NULL,              /* addr_col_filter */
819         NULL,              /* addr_fixed_len */
820         NULL,              /* addr_name_res_str */
821         NULL,              /* addr_name_res_len */
822     };
823
824     static address_type_t usb_address = {
825         AT_USB,          /* addr_type */
826         "AT_USB",        /* name */
827         "USB Address",   /* pretty_name */
828         usb_addr_to_str, /* addr_to_str */
829         usb_addr_str_len, /* addr_str_len */
830         NULL,              /* addr_col_filter */
831         NULL,              /* addr_fixed_len */
832         NULL,              /* addr_name_res_str */
833         NULL,              /* addr_name_res_len */
834     };
835
836     static address_type_t ax25_address = {
837         AT_AX25,          /* addr_type */
838         "AT_AX25",        /* name */
839         "AX.25 Address",  /* pretty_name */
840         ax25_addr_to_str, /* addr_to_str */
841         ax25_addr_str_len,/* addr_str_len */
842         ax25_col_filter_str, /* addr_col_filter */
843         ax25_len,          /* addr_fixed_len */
844         NULL,              /* addr_name_res_str */
845         NULL,              /* addr_name_res_len */
846     };
847
848     num_dissector_addr_type = 0;
849
850     /* Initialize the type array.  This is mostly for handling
851        "dissector registered" address type range (for NULL checking) */
852     memset(type_list, 0, MAX_ADDR_TYPE_VALUE*sizeof(address_type_t*));
853
854     address_type_register(AT_NONE, &none_address );
855     address_type_register(AT_ETHER, &ether_address );
856     address_type_register(AT_IPv4, &ipv4_address );
857     address_type_register(AT_IPv6, &ipv6_address );
858     address_type_register(AT_IPX, &ipx_address );
859     address_type_register(AT_VINES, &vines_address );
860     address_type_register(AT_FC, &fc_address );
861     address_type_register(AT_FCWWN, &fcwwn_address );
862     address_type_register(AT_SS7PC, &ss7pc_address );
863     address_type_register(AT_STRINGZ, &stringz_address );
864     address_type_register(AT_EUI64, &eui64_address );
865     address_type_register(AT_IB, &ib_address );
866     address_type_register(AT_USB, &usb_address );
867     address_type_register(AT_AX25, &ax25_address );
868 }
869
870 /* Given an address type id, return an address_type_t* */
871 #define ADDR_TYPE_LOOKUP(addr_type, result)    \
872     /* Check input */                          \
873     g_assert(addr_type < MAX_ADDR_TYPE_VALUE); \
874     result = type_list[addr_type];
875
876 static int address_type_get_length(const address* addr)
877 {
878     address_type_t *at;
879
880     ADDR_TYPE_LOOKUP(addr->type, at);
881
882     if (at == NULL)
883         return 0;
884
885     return at->addr_str_len(addr);
886 }
887
888 gchar*
889 address_to_str(wmem_allocator_t *scope, const address *addr)
890 {
891     gchar *str;
892     int len = address_type_get_length(addr);
893
894     if (len <= 0)
895         len = MAX_ADDR_STR_LEN;
896
897     str=(gchar *)wmem_alloc(scope, len);
898     address_to_str_buf(addr, str, len);
899     return str;
900 }
901
902 void address_to_str_buf(const address* addr, gchar *buf, int buf_len)
903 {
904     address_type_t *at;
905
906     if (!buf || !buf_len)
907         return;
908
909     ADDR_TYPE_LOOKUP(addr->type, at);
910
911     if ((at == NULL) || (at->addr_to_str == NULL))
912     {
913         buf[0] = '\0';
914         return;
915     }
916
917     at->addr_to_str(addr, buf, buf_len);
918 }
919
920 const gchar *
921 address_to_name(const address *addr)
922 {
923     address_type_t *at;
924
925     ADDR_TYPE_LOOKUP(addr->type, at);
926
927     if (at == NULL)
928     {
929         return NULL;
930     }
931
932     /*
933      * XXX - addr_name_res_str is expected to return a string from
934      * a persistent database, so that it lives a long time, past
935      * the lifetime of addr itself.
936      *
937      * We'd like to avoid copying, so this is what we do here.
938      */
939     switch (addr->type) {
940
941     case AT_STRINGZ:
942         return (const gchar *)addr->data;
943
944     default:
945         if (at->addr_name_res_str != NULL)
946             return at->addr_name_res_str(addr);
947         else
948             return NULL;
949     }
950 }
951
952 gchar *
953 address_to_display(wmem_allocator_t *allocator, const address *addr)
954 {
955     gchar *str = NULL;
956     const gchar *result = address_to_name(addr);
957
958     if (result != NULL) {
959         str = wmem_strdup(allocator, result);
960     }
961     else if (addr->type == AT_NONE) {
962         str = wmem_strdup(allocator, "NONE");
963     }
964     else {
965         str = (gchar *) wmem_alloc(allocator, MAX_ADDR_STR_LEN);
966         address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
967     }
968
969     return str;
970 }
971
972 static void address_with_resolution_to_str_buf(const address* addr, gchar *buf, int buf_len)
973 {
974     address_type_t *at;
975     int addr_len;
976     gsize pos;
977     gboolean empty;
978
979     if (!buf || !buf_len)
980         return;
981
982     ADDR_TYPE_LOOKUP(addr->type, at);
983
984     if (at == NULL)
985     {
986         buf[0] = '\0';
987         return;
988     }
989
990 #if 0 /* XXX - If this remains a static function, we've already made this check in the only
991          function that can call it.  If this function becomes "public", need to put this
992          check back in */
993     /* No name resolution support, just return address string */
994     if (at->addr_name_res_str == NULL)
995         return address_to_str_buf(addr, buf, buf_len);
996 #endif
997
998     /* Copy the resolved name */
999     pos = g_strlcpy(buf, at->addr_name_res_str(addr), buf_len);
1000
1001     /* Don't wrap "emptyness" in parentheses */
1002     if (addr->type == AT_NONE)
1003         return;
1004
1005     /* Make sure there is enough room for the address string wrapped in parentheses */
1006     if ((int)(pos + 4 + at->addr_str_len(addr)) >= buf_len)
1007         return;
1008
1009     empty = (pos <= 1) ? TRUE : FALSE;
1010
1011     if (!empty)
1012     {
1013         buf[pos++] = ' ';
1014         buf[pos++] = '(';
1015     }
1016
1017     addr_len = at->addr_to_str(addr, &buf[pos], (int)(buf_len-pos));
1018     pos += addr_len - 1; /* addr_len includes the trailing '\0' */
1019
1020     if (!empty)
1021     {
1022         buf[pos++] = ')';
1023         buf[pos++] = '\0';
1024     }
1025 }
1026
1027 gchar* address_with_resolution_to_str(wmem_allocator_t *scope, const address *addr)
1028 {
1029     address_type_t *at;
1030     int len;
1031     gchar *str;
1032
1033     ADDR_TYPE_LOOKUP(addr->type, at);
1034
1035     if (at == NULL)
1036         return wmem_strdup(scope, "");
1037
1038     /* No name resolution support, just return address string */
1039     if ((at->addr_name_res_str == NULL) ||
1040             (ADDR_RESOLV_MACADDR(addr) && !gbl_resolv_flags.mac_name) ||
1041             (ADDR_RESOLV_NETADDR(addr) && !gbl_resolv_flags.network_name)) {
1042         return address_to_str(scope, addr);
1043     }
1044
1045     len = at->addr_name_res_len() + at->addr_str_len(addr) + 4; /* For format of %s (%s) */
1046
1047     str=(gchar *)wmem_alloc(scope, len);
1048     address_with_resolution_to_str_buf(addr, str, len);
1049     return str;
1050 }
1051
1052
1053 const char* address_type_column_filter_string(const address* addr, gboolean src)
1054 {
1055     address_type_t *at;
1056
1057     ADDR_TYPE_LOOKUP(addr->type, at);
1058
1059     if ((at == NULL) || (at->addr_col_filter == NULL))
1060     {
1061         return "";
1062     }
1063
1064     return at->addr_col_filter(addr, src);
1065 }
1066
1067 gchar*
1068 tvb_address_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int type, const gint offset)
1069 {
1070     address addr;
1071     address_type_t *at;
1072
1073     ADDR_TYPE_LOOKUP(type, at);
1074
1075     if (at == NULL)
1076     {
1077         return NULL;
1078     }
1079
1080     /* The address type must have a fixed length to use this function */
1081     /* For variable length fields, use tvb_address_var_to_str() */
1082     if (at->addr_fixed_len == NULL)
1083     {
1084         g_assert_not_reached();
1085         return NULL;
1086     }
1087
1088     set_address_tvb(&addr, type, at->addr_fixed_len(), tvb, offset);
1089
1090     return address_to_str(scope, &addr);
1091 }
1092
1093 gchar* tvb_address_var_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, address_type type, const gint offset, int length)
1094 {
1095     address addr;
1096
1097     set_address_tvb(&addr, type, length, tvb, offset);
1098
1099     return address_to_str(scope, &addr);
1100 }
1101
1102 gchar*
1103 tvb_address_with_resolution_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int type, const gint offset)
1104 {
1105     address addr;
1106     address_type_t *at;
1107
1108     ADDR_TYPE_LOOKUP(type, at);
1109
1110     if (at == NULL)
1111     {
1112         return NULL;
1113     }
1114
1115     /* The address type must have a fixed length to use this function */
1116     /* For variable length fields, use tvb_address_var_with_resolution_to_str() */
1117     if (at->addr_fixed_len == NULL)
1118     {
1119         g_assert_not_reached();
1120         return NULL;
1121     }
1122
1123     set_address_tvb(&addr, type, at->addr_fixed_len(), tvb, offset);
1124
1125     return address_with_resolution_to_str(scope, &addr);
1126 }
1127
1128
1129 /*
1130  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
1131  *
1132  * Local variables:
1133  * c-basic-offset: 4
1134  * tab-width: 8
1135  * indent-tabs-mode: nil
1136  * End:
1137  *
1138  * vi: set shiftwidth=4 tabstop=8 expandtab:
1139  * :indentSize=4:tabSize=8:noTabs=true:
1140  */