TLS13: update pre_shared_key lengths for draft -19
[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     DISSECTOR_ASSERT(at->name);
77     DISSECTOR_ASSERT(at->pretty_name);
78     DISSECTOR_ASSERT(at->addr_to_str);
79     DISSECTOR_ASSERT(at->addr_str_len);
80     DISSECTOR_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     DISSECTOR_ASSERT(name);
95     DISSECTOR_ASSERT(pretty_name);
96     DISSECTOR_ASSERT(to_str_func);
97     DISSECTOR_ASSERT(str_len_func);
98     /* Either have both or neither */
99     DISSECTOR_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     DISSECTOR_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 MAX_IP_STR_LEN;
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     ip6_to_str_buf((const struct e_in6_addr *)addr->data, buf, buf_len);
251     return (int)(strlen(buf)+1);
252 }
253
254 static int ipv6_str_len(const address* addr _U_)
255 {
256     return MAX_IP6_STR_LEN;
257 }
258
259 static const char* ipv6_col_filter_str(const address* addr _U_, gboolean is_src)
260 {
261     if (is_src)
262         return "ipv6.src";
263
264     return "ipv6.dst";
265 }
266
267 static int ipv6_len(void)
268 {
269     return 16;
270 }
271
272 static const gchar* ipv6_name_res_str(const address* addr)
273 {
274     struct e_in6_addr ip6_addr;
275     memcpy(&ip6_addr.bytes, addr->data, sizeof ip6_addr.bytes);
276     return get_hostname6(&ip6_addr);
277 }
278
279 static int ipv6_name_res_len(void)
280 {
281     return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
282 }
283
284 /******************************************************************************
285  * AT_IPX
286  ******************************************************************************/
287 static int ipx_to_str(const address* addr, gchar *buf, int buf_len _U_)
288 {
289     const guint8 *addrdata = (const guint8 *)addr->data;
290     gchar *bufp = buf;
291
292     bufp = bytes_to_hexstr(bufp, &addrdata[0], 4); /* 8 bytes */
293     *bufp++ = '.'; /*1 byte */
294     bufp = bytes_to_hexstr(bufp, &addrdata[4], 6); /* 12 bytes */
295     *bufp++ = '\0'; /* NULL terminate */
296     return (int)(bufp - buf);
297 }
298
299 static int ipx_str_len(const address* addr _U_)
300 {
301     return 22;
302 }
303
304 static int ipx_len(void)
305 {
306     return 10;
307 }
308
309 /******************************************************************************
310  * AT_FC
311  ******************************************************************************/
312 static int fc_to_str(const address* addr, gchar *buf, int buf_len _U_)
313 {
314     gchar *bufp = buf;
315
316     bufp = bytes_to_hexstr_punct(bufp, (const guint8 *)addr->data, 3, '.');
317     *bufp++ = '\0'; /* NULL terminate */
318
319     return (int)(bufp - buf);
320 }
321
322 static int fc_str_len(const address* addr _U_)
323 {
324     return 9;
325 }
326
327 static int fc_len(void)
328 {
329     return 3;
330 }
331
332 /******************************************************************************
333  * AT_FCWWN
334  * XXX - Doubles as a "field type", should it be defined here?
335  ******************************************************************************/
336 /* FC Network Header Network Address Authority Identifiers */
337 #define FC_NH_NAA_IEEE          1   /* IEEE 802.1a */
338 #define FC_NH_NAA_IEEE_E        2   /* IEEE Exteneded */
339 #define FC_NH_NAA_LOCAL         3
340 #define FC_NH_NAA_IP            4   /* 32-bit IP address */
341 #define FC_NH_NAA_IEEE_R        5   /* IEEE Registered */
342 #define FC_NH_NAA_IEEE_R_E      6   /* IEEE Registered Exteneded */
343 /* according to FC-PH 3 draft these are now reclaimed and reserved */
344 #define FC_NH_NAA_CCITT_INDV    12  /* CCITT 60 bit individual address */
345 #define FC_NH_NAA_CCITT_GRP     14  /* CCITT 60 bit group address */
346
347 static int fcwwn_str_len(const address* addr _U_)
348 {
349     return 24;
350 }
351
352 static int fcwwn_to_str(const address* addr, gchar *buf, int buf_len _U_)
353 {
354     const guint8 *addrp = (const guint8*)addr->data;
355
356     buf = bytes_to_hexstr_punct(buf, addrp, 8, ':'); /* 23 bytes */
357     *buf = '\0';
358
359     return fcwwn_str_len(addr);
360 }
361
362 static int fcwwn_len(void)
363 {
364     return FCWWN_ADDR_LEN;
365 }
366
367 static const gchar* fcwwn_name_res_str(const address* addr)
368 {
369     const guint8 *addrp = (const guint8*)addr->data;
370     int fmt;
371     guint8 oui[6];
372
373     fmt = (addrp[0] & 0xF0) >> 4;
374     switch (fmt) {
375
376     case FC_NH_NAA_IEEE:
377     case FC_NH_NAA_IEEE_E:
378
379         memcpy (oui, &addrp[2], 6);
380         return get_manuf_name(oui);
381
382     case FC_NH_NAA_IEEE_R:
383         oui[0] = ((addrp[0] & 0x0F) << 4) | ((addrp[1] & 0xF0) >> 4);
384         oui[1] = ((addrp[1] & 0x0F) << 4) | ((addrp[2] & 0xF0) >> 4);
385         oui[2] = ((addrp[2] & 0x0F) << 4) | ((addrp[3] & 0xF0) >> 4);
386         oui[3] = ((addrp[3] & 0x0F) << 4) | ((addrp[4] & 0xF0) >> 4);
387         oui[4] = ((addrp[4] & 0x0F) << 4) | ((addrp[5] & 0xF0) >> 4);
388         oui[5] = ((addrp[5] & 0x0F) << 4) | ((addrp[6] & 0xF0) >> 4);
389
390         return get_manuf_name(oui);
391     }
392
393     return "";
394 }
395
396 static int fcwwn_name_res_len(void)
397 {
398     return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
399 }
400
401 /******************************************************************************
402  * AT_STRINGZ
403  ******************************************************************************/
404 static int stringz_addr_to_str(const address* addr, gchar *buf, int buf_len)
405 {
406     g_strlcpy(buf, (const gchar *)addr->data, buf_len);
407     return (int)(strlen(buf)+1);
408 }
409
410 static int stringz_addr_str_len(const address* addr)
411 {
412     return addr->len+1;
413 }
414
415 /******************************************************************************
416  * AT_EUI64
417  ******************************************************************************/
418 static int eui64_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
419 {
420     buf = bytes_to_hexstr_punct(buf, (const guint8 *)addr->data, 8, ':');
421     *buf = '\0'; /* NULL terminate */
422     return sizeof(buf) + 1;
423 }
424
425 static int eui64_str_len(const address* addr _U_)
426 {
427     return EUI64_STR_LEN;
428 }
429
430 static int eui64_len(void)
431 {
432     return 8;
433 }
434
435 /******************************************************************************
436  * AT_IB
437  ******************************************************************************/
438 static int
439 ib_addr_to_str( const address *addr, gchar *buf, int buf_len){
440     if (addr->len >= 16) { /* GID is 128bits */
441         #define PREAMBLE_STR_LEN ((int)(sizeof("GID: ") - 1))
442         g_strlcpy(buf, "GID: ", buf_len);
443         if (buf_len < PREAMBLE_STR_LEN ||
444                 ws_inet_ntop6(addr->data, buf + PREAMBLE_STR_LEN,
445                           buf_len - PREAMBLE_STR_LEN) == NULL ) /* Returns NULL if no space and does not touch buf */
446             g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
447     } else {    /* this is a LID (16 bits) */
448         guint16 lid_number;
449
450         memcpy((void *)&lid_number, addr->data, sizeof lid_number);
451         g_snprintf(buf,buf_len,"LID: %u",lid_number);
452     }
453
454     return sizeof(buf) + 1;
455 }
456
457 static int ib_str_len(const address* addr _U_)
458 {
459     return MAX_ADDR_STR_LEN; /* XXX - This is overkill */
460 }
461
462 /******************************************************************************
463  * AT_AX25
464  ******************************************************************************/
465 static int ax25_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
466 {
467     const guint8 *addrdata = (const guint8 *)addr->data;
468     gchar *bufp = buf;
469
470     *bufp++ = printable_char_or_period(addrdata[0] >> 1);
471     *bufp++ = printable_char_or_period(addrdata[1] >> 1);
472     *bufp++ = printable_char_or_period(addrdata[2] >> 1);
473     *bufp++ = printable_char_or_period(addrdata[3] >> 1);
474     *bufp++ = printable_char_or_period(addrdata[4] >> 1);
475     *bufp++ = printable_char_or_period(addrdata[5] >> 1);
476     *bufp++ = '-';
477     bufp = uint_to_str_back(bufp, (addrdata[6] >> 1) & 0x0f);
478     *bufp++ = '\0'; /* NULL terminate */
479
480     return (int)(bufp - buf);
481 }
482
483 static int ax25_addr_str_len(const address* addr _U_)
484 {
485     return 21; /* Leaves extra space (10 bytes) just for uint_to_str_back() */
486 }
487
488 static const char* ax25_col_filter_str(const address* addr _U_, gboolean is_src)
489 {
490     if (is_src)
491         return "ax25.src";
492
493     return "ax25.dst";
494 }
495
496 static int ax25_len(void)
497 {
498     return AX25_ADDR_LEN;
499 }
500
501 /******************************************************************************
502  * END OF PROVIDED ADDRESS TYPES
503  ******************************************************************************/
504
505
506
507
508 void address_types_initialize(void)
509 {
510     static address_type_t none_address = {
511         AT_NONE,            /* addr_type */
512         "AT_NONE",          /* name */
513         "No address",       /* pretty_name */
514         none_addr_to_str,   /* addr_to_str */
515         none_addr_str_len,  /* addr_str_len */
516         NULL,               /* addr_to_byte */
517         NULL,               /* addr_col_filter */
518         none_addr_len,      /* addr_fixed_len */
519         none_name_res_str, /* addr_name_res_str */
520         none_name_res_len, /* addr_name_res_len */
521     };
522
523     static address_type_t ether_address = {
524         AT_ETHER,           /* addr_type */
525         "AT_ETHER",         /* name */
526         "Ethernet address", /* pretty_name */
527         ether_to_str,       /* addr_to_str */
528         ether_str_len,      /* addr_str_len */
529         NULL,               /* addr_to_byte */
530         ether_col_filter_str, /* addr_col_filter */
531         ether_len,          /* addr_fixed_len */
532         ether_name_resolution_str, /* addr_name_res_str */
533         ether_name_resolution_len, /* addr_name_res_len */
534     };
535
536     static address_type_t ipv4_address = {
537         AT_IPv4,            /* addr_type */
538         "AT_IPv4",          /* name */
539         "IPv4 address",     /* pretty_name */
540         ipv4_to_str,        /* addr_to_str */
541         ipv4_str_len,       /* addr_str_len */
542         NULL,               /* addr_to_byte */
543         ipv4_col_filter_str, /* addr_col_filter */
544         ipv4_len,           /* addr_fixed_len */
545         ipv4_name_res_str, /* addr_name_res_str */
546         ipv4_name_res_len, /* addr_name_res_len */
547     };
548
549     static address_type_t ipv6_address = {
550         AT_IPv6,            /* addr_type */
551         "AT_IPv6",          /* name */
552         "IPv6 address",     /* pretty_name */
553         ipv6_to_str,        /* addr_to_str */
554         ipv6_str_len,       /* addr_str_len */
555         NULL,               /* addr_to_byte */
556         ipv6_col_filter_str, /* addr_col_filter */
557         ipv6_len,            /* addr_fixed_len */
558         ipv6_name_res_str, /* addr_name_res_str */
559         ipv6_name_res_len, /* addr_name_res_len */
560    };
561
562     static address_type_t ipx_address = {
563         AT_IPX,             /* addr_type */
564         "AT_IPX",           /* name */
565         "IPX address",      /* pretty_name */
566         ipx_to_str,         /* addr_to_str */
567         ipx_str_len,        /* addr_str_len */
568         NULL,               /* addr_to_byte */
569         NULL,               /* addr_col_filter */
570         ipx_len,            /* addr_fixed_len */
571         NULL,               /* addr_name_res_str */
572         NULL,               /* addr_name_res_len */
573     };
574
575     static address_type_t fc_address = {
576         AT_FC,          /* addr_type */
577         "AT_FC",        /* name */
578         "FC address",   /* pretty_name */
579         fc_to_str,      /* addr_to_str */
580         fc_str_len,     /* addr_str_len */
581         NULL,           /* addr_to_byte */
582         NULL,           /* addr_col_filter */
583         fc_len,         /* addr_fixed_len */
584         NULL,           /* addr_name_res_str */
585         NULL,           /* addr_name_res_len */
586     };
587
588     static address_type_t fcwwn_address = {
589         AT_FCWWN,       /* addr_type */
590         "AT_FCWWN",     /* name */
591         "Fibre Channel WWN",    /* pretty_name */
592         fcwwn_to_str,   /* addr_to_str */
593         fcwwn_str_len,  /* addr_str_len */
594         NULL,           /* addr_to_byte */
595         NULL,           /* addr_col_filter */
596         fcwwn_len,         /* addr_fixed_len */
597         fcwwn_name_res_str, /* addr_name_res_str */
598         fcwwn_name_res_len, /* addr_name_res_len */
599     };
600
601     static address_type_t stringz_address = {
602         AT_STRINGZ,          /* addr_type */
603         "AT_STRINGZ",        /* name */
604         "String address",   /* pretty_name */
605         stringz_addr_to_str, /* addr_to_str */
606         stringz_addr_str_len, /* addr_str_len */
607         NULL,              /* addr_to_byte */
608         NULL,              /* addr_col_filter */
609         NULL,              /* addr_fixed_len */
610         NULL,              /* addr_name_res_str */
611         NULL,              /* addr_name_res_len */
612     };
613
614     static address_type_t eui64_address = {
615         AT_EUI64,          /* addr_type */
616         "AT_EUI64",        /* name */
617         "IEEE EUI-64",     /* pretty_name */
618         eui64_addr_to_str, /* addr_to_str */
619         eui64_str_len,     /* addr_str_len */
620         NULL,              /* addr_to_byte */
621         NULL,              /* addr_col_filter */
622         eui64_len,         /* addr_fixed_len */
623         NULL,              /* addr_name_res_str */
624         NULL,              /* addr_name_res_len */
625     };
626
627     static address_type_t ib_address = {
628         AT_IB,           /* addr_type */
629         "AT_IB",         /* name */
630         "Infiniband GID/LID",   /* pretty_name */
631         ib_addr_to_str,  /* addr_to_str */
632         ib_str_len,      /* addr_str_len */
633         NULL,              /* addr_to_byte */
634         NULL,              /* addr_col_filter */
635         NULL,              /* addr_fixed_len */
636         NULL,              /* addr_name_res_str */
637         NULL,              /* addr_name_res_len */
638     };
639
640     static address_type_t ax25_address = {
641         AT_AX25,          /* addr_type */
642         "AT_AX25",        /* name */
643         "AX.25 Address",  /* pretty_name */
644         ax25_addr_to_str, /* addr_to_str */
645         ax25_addr_str_len,/* addr_str_len */
646         NULL,             /* addr_to_byte */
647         ax25_col_filter_str, /* addr_col_filter */
648         ax25_len,          /* addr_fixed_len */
649         NULL,              /* addr_name_res_str */
650         NULL,              /* addr_name_res_len */
651     };
652
653     num_dissector_addr_type = 0;
654
655     /* Initialize the type array.  This is mostly for handling
656        "dissector registered" address type range (for NULL checking) */
657     memset(type_list, 0, (MAX_ADDR_TYPE_VALUE + 1)*sizeof(address_type_t*));
658
659     address_type_register(AT_NONE, &none_address );
660     address_type_register(AT_ETHER, &ether_address );
661     address_type_register(AT_IPv4, &ipv4_address );
662     address_type_register(AT_IPv6, &ipv6_address );
663     address_type_register(AT_IPX, &ipx_address );
664     address_type_register(AT_FC, &fc_address );
665     address_type_register(AT_FCWWN, &fcwwn_address );
666     address_type_register(AT_STRINGZ, &stringz_address );
667     address_type_register(AT_EUI64, &eui64_address );
668     address_type_register(AT_IB, &ib_address );
669     address_type_register(AT_AX25, &ax25_address );
670 }
671
672 /* Given an address type id, return an address_type_t* */
673 #define ADDR_TYPE_LOOKUP(addr_type, result)    \
674     /* Check input */                          \
675     g_assert(addr_type < MAX_ADDR_TYPE_VALUE); \
676     result = type_list[addr_type];
677
678 static int address_type_get_length(const address* addr)
679 {
680     address_type_t *at;
681
682     ADDR_TYPE_LOOKUP(addr->type, at);
683
684     if (at == NULL)
685         return 0;
686
687     return at->addr_str_len(addr);
688 }
689
690 gchar*
691 address_to_str(wmem_allocator_t *scope, const address *addr)
692 {
693     gchar *str;
694     int len = address_type_get_length(addr);
695
696     if (len <= 0)
697         len = MAX_ADDR_STR_LEN;
698
699     str=(gchar *)wmem_alloc(scope, len);
700     address_to_str_buf(addr, str, len);
701     return str;
702 }
703
704 void address_to_str_buf(const address* addr, gchar *buf, int buf_len)
705 {
706     address_type_t *at;
707
708     if (!buf || !buf_len)
709         return;
710
711     ADDR_TYPE_LOOKUP(addr->type, at);
712
713     if ((at == NULL) || (at->addr_to_str == NULL))
714     {
715         buf[0] = '\0';
716         return;
717     }
718
719     at->addr_to_str(addr, buf, buf_len);
720 }
721
722
723 guint address_to_bytes(const address *addr, guint8 *buf, guint buf_len)
724 {
725     address_type_t *at;
726     guint copy_len = 0;
727
728     if (!buf || !buf_len)
729         return 0;
730
731     ADDR_TYPE_LOOKUP(addr->type, at);
732
733     if (at == NULL)
734         return 0;
735
736     if (at->addr_to_byte == NULL)
737     {
738         /* If a specific function isn't provided, just do a memcpy */
739         copy_len = MIN(((guint)addr->len), buf_len);
740         memcpy(buf, addr->data, copy_len);
741     }
742     else
743     {
744         copy_len = at->addr_to_byte(addr, buf, buf_len);
745     }
746
747     return copy_len;
748 }
749
750 const gchar *
751 address_to_name(const address *addr)
752 {
753     address_type_t *at;
754
755     ADDR_TYPE_LOOKUP(addr->type, at);
756
757     if (at == NULL)
758     {
759         return NULL;
760     }
761
762     /*
763      * XXX - addr_name_res_str is expected to return a string from
764      * a persistent database, so that it lives a long time, past
765      * the lifetime of addr itself.
766      *
767      * We'd like to avoid copying, so this is what we do here.
768      */
769     switch (addr->type) {
770
771     case AT_STRINGZ:
772         return (const gchar *)addr->data;
773
774     default:
775         if (at->addr_name_res_str != NULL)
776             return at->addr_name_res_str(addr);
777         else
778             return NULL;
779     }
780 }
781
782 gchar *
783 address_to_display(wmem_allocator_t *allocator, const address *addr)
784 {
785     gchar *str = NULL;
786     const gchar *result = address_to_name(addr);
787
788     if (result != NULL) {
789         str = wmem_strdup(allocator, result);
790     }
791     else if (addr->type == AT_NONE) {
792         str = wmem_strdup(allocator, "NONE");
793     }
794     else {
795         str = (gchar *) wmem_alloc(allocator, MAX_ADDR_STR_LEN);
796         address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
797     }
798
799     return str;
800 }
801
802 static void address_with_resolution_to_str_buf(const address* addr, gchar *buf, int buf_len)
803 {
804     address_type_t *at;
805     int addr_len;
806     gsize pos;
807     gboolean empty;
808
809     if (!buf || !buf_len)
810         return;
811
812     ADDR_TYPE_LOOKUP(addr->type, at);
813
814     if (at == NULL)
815     {
816         buf[0] = '\0';
817         return;
818     }
819
820 #if 0 /* XXX - If this remains a static function, we've already made this check in the only
821          function that can call it.  If this function becomes "public", need to put this
822          check back in */
823     /* No name resolution support, just return address string */
824     if (at->addr_name_res_str == NULL)
825         return address_to_str_buf(addr, buf, buf_len);
826 #endif
827
828     /* Copy the resolved name */
829     pos = g_strlcpy(buf, at->addr_name_res_str(addr), buf_len);
830
831     /* Don't wrap "emptyness" in parentheses */
832     if (addr->type == AT_NONE)
833         return;
834
835     /* Make sure there is enough room for the address string wrapped in parentheses */
836     if ((int)(pos + 4 + at->addr_str_len(addr)) >= buf_len)
837         return;
838
839     empty = (pos <= 1) ? TRUE : FALSE;
840
841     if (!empty)
842     {
843         buf[pos++] = ' ';
844         buf[pos++] = '(';
845     }
846
847     addr_len = at->addr_to_str(addr, &buf[pos], (int)(buf_len-pos));
848     pos += addr_len - 1; /* addr_len includes the trailing '\0' */
849
850     if (!empty)
851     {
852         buf[pos++] = ')';
853         buf[pos++] = '\0';
854     }
855 }
856
857 gchar* address_with_resolution_to_str(wmem_allocator_t *scope, const address *addr)
858 {
859     address_type_t *at;
860     int len;
861     gchar *str;
862
863     ADDR_TYPE_LOOKUP(addr->type, at);
864
865     if (at == NULL)
866         return wmem_strdup(scope, "");
867
868     /* No name resolution support, just return address string */
869     if ((at->addr_name_res_str == NULL) ||
870             (ADDR_RESOLV_MACADDR(addr) && !gbl_resolv_flags.mac_name) ||
871             (ADDR_RESOLV_NETADDR(addr) && !gbl_resolv_flags.network_name)) {
872         return address_to_str(scope, addr);
873     }
874
875     len = at->addr_name_res_len() + at->addr_str_len(addr) + 4; /* For format of %s (%s) */
876
877     str=(gchar *)wmem_alloc(scope, len);
878     address_with_resolution_to_str_buf(addr, str, len);
879     return str;
880 }
881
882
883 const char* address_type_column_filter_string(const address* addr, gboolean src)
884 {
885     address_type_t *at;
886
887     ADDR_TYPE_LOOKUP(addr->type, at);
888
889     if ((at == NULL) || (at->addr_col_filter == NULL))
890     {
891         return "";
892     }
893
894     return at->addr_col_filter(addr, src);
895 }
896
897 gchar*
898 tvb_address_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int type, const gint offset)
899 {
900     address addr;
901     address_type_t *at;
902
903     ADDR_TYPE_LOOKUP(type, at);
904
905     if (at == NULL)
906     {
907         return NULL;
908     }
909
910     /* The address type must have a fixed length to use this function */
911     /* For variable length fields, use tvb_address_var_to_str() */
912     if (at->addr_fixed_len == NULL)
913     {
914         g_assert_not_reached();
915         return NULL;
916     }
917
918     set_address_tvb(&addr, type, at->addr_fixed_len(), tvb, offset);
919
920     return address_to_str(scope, &addr);
921 }
922
923 gchar* tvb_address_var_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, address_type type, const gint offset, int length)
924 {
925     address addr;
926
927     set_address_tvb(&addr, type, length, tvb, offset);
928
929     return address_to_str(scope, &addr);
930 }
931
932 gchar*
933 tvb_address_with_resolution_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int type, const gint offset)
934 {
935     address addr;
936     address_type_t *at;
937
938     ADDR_TYPE_LOOKUP(type, at);
939
940     if (at == NULL)
941     {
942         return NULL;
943     }
944
945     /* The address type must have a fixed length to use this function */
946     /* For variable length fields, use tvb_address_var_with_resolution_to_str() */
947     if (at->addr_fixed_len == NULL)
948     {
949         g_assert_not_reached();
950         return NULL;
951     }
952
953     set_address_tvb(&addr, type, at->addr_fixed_len(), tvb, offset);
954
955     return address_with_resolution_to_str(scope, &addr);
956 }
957
958
959 /*
960  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
961  *
962  * Local variables:
963  * c-basic-offset: 4
964  * tab-width: 8
965  * indent-tabs-mode: nil
966  * End:
967  *
968  * vi: set shiftwidth=4 tabstop=8 expandtab:
969  * :indentSize=4:tabSize=8:noTabs=true:
970  */