decrypt drsuapi attributes
[wireshark-sm.git] / epan / address_types.c
blob8da09a89273a82ee028f12a6bf5e89ca645d5c44
1 /* address_types.c
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
10 #include "config.h"
12 #include <string.h> /* for memcmp */
13 #include <stdio.h>
15 #include <glib.h>
17 #include "packet.h"
18 #include "address_types.h"
19 #include "to_str.h"
20 #include "addr_resolv.h"
21 #include "wsutil/pint.h"
22 #include "wsutil/str_util.h"
23 #include "wsutil/inet_addr.h"
24 #include <wsutil/ws_assert.h>
26 struct _address_type_t {
27 int addr_type; /* From address_type enumeration or registered value */
28 const char *name;
29 const char *pretty_name;
30 AddrValueToString addr_to_str;
31 AddrValueToStringLen addr_str_len;
32 AddrValueToByte addr_to_byte;
33 AddrColFilterString addr_col_filter;
34 AddrFixedLen addr_fixed_len;
35 AddrNameResolutionToString addr_name_res_str;
36 AddrNameResolutionLen addr_name_res_len;
38 /* XXX - Some sort of compare functions (like ftype)? ***/
42 * For address types that do have resolution (ETHER, IPv4, IPv6),
43 * addr_name_res_str returns a string that is the same as what
44 * addr_to_str returns even if resolution is off; this ends up
45 * allocating persistent memory for the resolution result even so.
46 * This affects address_to_name, address_to_display, etc.
48 * Perhaps it should return NULL in such cases.
50 * As other address types don't support resolution, callers that use
51 * addr_name_res_str (e.g. address_to_name, address_to_display, etc.)
52 * must be prepared to handle NULL already. Note that the header
53 * documentation for address_to_name() claims that if name resolution
54 * is disabled then it returns NULL for such types, but as a result of
55 * the above it does not.
58 #define MAX_DISSECTOR_ADDR_TYPE 30
59 #define MAX_ADDR_TYPE_VALUE (AT_END_OF_LIST+MAX_DISSECTOR_ADDR_TYPE)
61 static int num_dissector_addr_type;
62 static address_type_t dissector_type_addresses[MAX_DISSECTOR_ADDR_TYPE];
64 /* Keep track of address_type_t's via their id number */
65 static address_type_t* type_list[MAX_ADDR_TYPE_VALUE + 1];
68 * If a user _does_ pass in a too-small buffer, this is probably
69 * going to be too long to fit. However, even a partial string
70 * starting with "[Buf" should provide enough of a clue to be
71 * useful.
73 #define BUF_TOO_SMALL_ERR "[Buffer too small]"
75 #define _addr_return_if_nospace(str_len, buf, buf_len) \
76 do { \
77 if ((str_len) > (buf_len)) { \
78 (void)g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); \
79 return buf_len; \
80 } \
81 } while (0)
83 static void address_type_register(int addr_type, address_type_t *at)
85 /* Check input */
86 ws_assert(addr_type < MAX_ADDR_TYPE_VALUE);
87 ws_assert(addr_type == at->addr_type);
89 /* Don't re-register. */
90 ws_assert(type_list[addr_type] == NULL);
92 /* Sanity check */
93 ws_assert(at->name);
94 ws_assert(at->pretty_name);
95 ws_assert(at->addr_to_str);
96 ws_assert(at->addr_str_len);
97 ws_assert(((at->addr_name_res_str != NULL) && (at->addr_name_res_len != NULL)) ||
98 ((at->addr_name_res_str == NULL) && (at->addr_name_res_len == NULL)));
100 type_list[addr_type] = at;
103 int address_type_dissector_register(const char* name, const char* pretty_name,
104 AddrValueToString to_str_func, AddrValueToStringLen str_len_func,
105 AddrValueToByte to_bytes_func, AddrColFilterString col_filter_str_func, AddrFixedLen fixed_len_func,
106 AddrNameResolutionToString name_res_str_func, AddrNameResolutionLen name_res_len_func)
108 int addr_type;
110 /* Ensure valid data/functions for required fields */
111 ws_assert(name);
112 ws_assert(pretty_name);
113 ws_assert(to_str_func);
114 ws_assert(str_len_func);
115 /* Either have both or neither */
116 ws_assert(((name_res_str_func != NULL) && (name_res_len_func != NULL)) ||
117 ((name_res_str_func == NULL) && (name_res_len_func == NULL)));
119 /* This shouldn't happen, so flag it for fixing */
120 ws_assert(num_dissector_addr_type < MAX_DISSECTOR_ADDR_TYPE);
122 addr_type = AT_END_OF_LIST+num_dissector_addr_type;
123 dissector_type_addresses[num_dissector_addr_type].addr_type = addr_type;
124 dissector_type_addresses[num_dissector_addr_type].name = name;
125 dissector_type_addresses[num_dissector_addr_type].pretty_name = pretty_name;
126 dissector_type_addresses[num_dissector_addr_type].addr_to_str = to_str_func;
127 dissector_type_addresses[num_dissector_addr_type].addr_str_len = str_len_func;
128 dissector_type_addresses[num_dissector_addr_type].addr_to_byte = to_bytes_func;
129 dissector_type_addresses[num_dissector_addr_type].addr_col_filter = col_filter_str_func;
130 dissector_type_addresses[num_dissector_addr_type].addr_fixed_len = fixed_len_func;
131 dissector_type_addresses[num_dissector_addr_type].addr_name_res_str = name_res_str_func;
132 dissector_type_addresses[num_dissector_addr_type].addr_name_res_len = name_res_len_func;
134 type_list[addr_type] = &dissector_type_addresses[num_dissector_addr_type];
136 num_dissector_addr_type++;
138 return addr_type;
141 int address_type_get_by_name(const char* name)
143 address_type_t** addr;
145 for (addr = type_list; *addr != NULL; addr++)
147 if (!strcmp((*addr)->name, name))
149 return (*addr)->addr_type;
153 return -1;
156 /******************************************************************************
157 * AT_NONE
158 ******************************************************************************/
159 int none_addr_to_str(const address* addr _U_, char *buf, int buf_len _U_)
161 buf[0] = '\0';
162 return none_addr_str_len(addr);
165 int none_addr_str_len(const address* addr _U_)
167 return 1; /* NULL character for empty string */
170 int none_addr_len(void)
172 return 0;
175 static int none_name_res_len(void)
177 return 5;
180 static const char* none_name_res_str(const address* addr _U_)
182 return "NONE";
185 /******************************************************************************
186 * AT_ETHER
187 ******************************************************************************/
188 int ether_to_str(const address* addr, char *buf, int buf_len)
190 _addr_return_if_nospace(18, buf, buf_len);
192 bytes_to_hexstr_punct(buf, (const uint8_t*)addr->data, 6, ':');
193 buf[17] = '\0';
194 return ether_str_len(addr);
197 int ether_str_len(const address* addr _U_)
199 return 18;
202 static const char* ether_col_filter_str(const address* addr _U_, bool is_src)
204 if (is_src)
205 return "eth.src";
207 return "eth.dst";
210 int ether_len(void)
212 return 6;
215 const char* ether_name_resolution_str(const address* addr)
217 return get_ether_name((const uint8_t *)addr->data);
220 int ether_name_resolution_len(void)
222 return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
225 /******************************************************************************
226 * AT_IPv4
227 ******************************************************************************/
228 int ipv4_to_str(const address* addr, char *buf, int buf_len)
230 ip_addr_to_str_buf(addr->data, buf, buf_len);
231 return (int)(strlen(buf)+1);
234 static int ipv4_str_len(const address* addr _U_)
236 return WS_INET_ADDRSTRLEN;
239 static const char* ipv4_col_filter_str(const address* addr _U_, bool is_src)
241 if (is_src)
242 return "ip.src";
244 return "ip.dst";
247 static int ipv4_len(void)
249 return 4;
252 static const char* ipv4_name_res_str(const address* addr)
254 uint32_t ip4_addr;
255 memcpy(&ip4_addr, addr->data, sizeof ip4_addr);
256 return get_hostname(ip4_addr);
259 static int ipv4_name_res_len(void)
261 return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
264 /******************************************************************************
265 * AT_IPv6
266 ******************************************************************************/
267 static int ipv6_to_str(const address* addr, char *buf, int buf_len)
269 ip6_to_str_buf((const ws_in6_addr *)addr->data, buf, buf_len);
270 return (int)(strlen(buf) + 1);
273 static int ipv6_str_len(const address* addr _U_)
275 return WS_INET6_ADDRSTRLEN;
278 static const char* ipv6_col_filter_str(const address* addr _U_, bool is_src)
280 if (is_src)
281 return "ipv6.src";
283 return "ipv6.dst";
286 static int ipv6_len(void)
288 return 16;
291 static const char* ipv6_name_res_str(const address* addr)
293 ws_in6_addr ip6_addr;
294 memcpy(&ip6_addr.bytes, addr->data, sizeof ip6_addr.bytes);
295 return get_hostname6(&ip6_addr);
298 static int ipv6_name_res_len(void)
300 return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
303 /******************************************************************************
304 * AT_IPX
305 ******************************************************************************/
306 static int ipx_to_str(const address* addr, char *buf, int buf_len)
308 _addr_return_if_nospace(22, buf, buf_len);
310 const uint8_t *addrdata = (const uint8_t *)addr->data;
311 char *bufp = buf;
313 bufp = bytes_to_hexstr(bufp, &addrdata[0], 4); /* 8 bytes */
314 *bufp++ = '.'; /*1 byte */
315 bufp = bytes_to_hexstr(bufp, &addrdata[4], 6); /* 12 bytes */
316 *bufp++ = '\0'; /* NULL terminate */
317 return (int)(bufp - buf);
320 static int ipx_str_len(const address* addr _U_)
322 return 22;
325 static int ipx_len(void)
327 return 10;
330 /******************************************************************************
331 * AT_FC
332 ******************************************************************************/
333 static int fc_to_str(const address* addr, char *buf, int buf_len)
335 _addr_return_if_nospace(9, buf, buf_len);
337 char *bufp = buf;
339 bufp = bytes_to_hexstr_punct(bufp, (const uint8_t *)addr->data, 3, '.');
340 *bufp++ = '\0'; /* NULL terminate */
342 return (int)(bufp - buf);
345 static int fc_str_len(const address* addr _U_)
347 return 9;
350 static int fc_len(void)
352 return 3;
355 /******************************************************************************
356 * AT_FCWWN
357 * XXX - Doubles as a "field type", should it be defined here?
358 ******************************************************************************/
359 /* FC Network Header Network Address Authority Identifiers */
360 #define FC_NH_NAA_IEEE 1 /* IEEE 802.1a */
361 #define FC_NH_NAA_IEEE_E 2 /* IEEE Extended */
362 #define FC_NH_NAA_LOCAL 3
363 #define FC_NH_NAA_IP 4 /* 32-bit IP address */
364 #define FC_NH_NAA_IEEE_R 5 /* IEEE Registered */
365 #define FC_NH_NAA_IEEE_R_E 6 /* IEEE Registered Extended */
366 /* according to FC-PH 3 draft these are now reclaimed and reserved */
367 #define FC_NH_NAA_CCITT_INDV 12 /* CCITT 60 bit individual address */
368 #define FC_NH_NAA_CCITT_GRP 14 /* CCITT 60 bit group address */
370 static int fcwwn_str_len(const address* addr _U_)
372 return 24;
375 static int fcwwn_to_str(const address* addr, char *buf, int buf_len)
377 _addr_return_if_nospace(24, buf, buf_len);
379 const uint8_t *addrp = (const uint8_t*)addr->data;
381 buf = bytes_to_hexstr_punct(buf, addrp, 8, ':'); /* 23 bytes */
382 *buf = '\0';
384 return fcwwn_str_len(addr);
387 static int fcwwn_len(void)
389 return FCWWN_ADDR_LEN;
392 static const char* fcwwn_name_res_str(const address* addr)
394 const uint8_t *addrp = (const uint8_t*)addr->data;
395 int fmt;
396 uint8_t oui[6];
398 fmt = (addrp[0] & 0xF0) >> 4;
399 switch (fmt) {
401 case FC_NH_NAA_IEEE:
402 case FC_NH_NAA_IEEE_E:
404 memcpy (oui, &addrp[2], 6);
405 return get_manuf_name(oui, sizeof(oui));
407 case FC_NH_NAA_IEEE_R:
408 oui[0] = ((addrp[0] & 0x0F) << 4) | ((addrp[1] & 0xF0) >> 4);
409 oui[1] = ((addrp[1] & 0x0F) << 4) | ((addrp[2] & 0xF0) >> 4);
410 oui[2] = ((addrp[2] & 0x0F) << 4) | ((addrp[3] & 0xF0) >> 4);
411 oui[3] = ((addrp[3] & 0x0F) << 4) | ((addrp[4] & 0xF0) >> 4);
412 oui[4] = ((addrp[4] & 0x0F) << 4) | ((addrp[5] & 0xF0) >> 4);
413 oui[5] = ((addrp[5] & 0x0F) << 4) | ((addrp[6] & 0xF0) >> 4);
415 return get_manuf_name(oui, sizeof(oui));
418 return "";
421 static int fcwwn_name_res_len(void)
423 return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
426 /******************************************************************************
427 * AT_STRINGZ
428 ******************************************************************************/
429 static int stringz_addr_to_str(const address* addr, char *buf, int buf_len)
431 (void) g_strlcpy(buf, (const char *)addr->data, buf_len);
432 return (int)(strlen(buf)+1);
435 static int stringz_addr_str_len(const address* addr)
437 return addr->len+1;
440 /******************************************************************************
441 * AT_EUI64
442 ******************************************************************************/
443 static int eui64_addr_to_str(const address* addr, char *buf, int buf_len)
445 _addr_return_if_nospace(EUI64_STR_LEN, buf, buf_len);
447 buf = bytes_to_hexstr_punct(buf, (const uint8_t *)addr->data, 8, ':');
448 *buf = '\0'; /* NULL terminate */
449 return EUI64_STR_LEN;
452 static int eui64_str_len(const address* addr _U_)
454 return EUI64_STR_LEN;
457 static int eui64_len(void)
459 return 8;
462 /******************************************************************************
463 * AT_IB
464 ******************************************************************************/
465 static int
466 ib_addr_to_str(const address *addr, char *buf, int buf_len)
468 char buf_ip6[WS_INET6_ADDRSTRLEN];
470 if (addr->len >= 16) { /* GID is 128bits */
471 ws_inet_ntop6((const ws_in6_addr *)addr->data, buf_ip6, sizeof(buf_ip6));
472 snprintf(buf, buf_len, "GID: %s", buf_ip6);
474 else {
475 /* this is a LID (16 bits) */
476 snprintf(buf,buf_len,"LID: %u", *(const uint16_t *)addr->data);
479 return (int)(strlen(buf)+1);
482 static int ib_str_len(const address* addr _U_)
484 return MAX_ADDR_STR_LEN; /* XXX - This is overkill */
487 /******************************************************************************
488 * AT_AX25
489 ******************************************************************************/
490 static int ax25_addr_to_str(const address* addr, char *buf, int buf_len)
492 _addr_return_if_nospace(10, buf, buf_len);
494 const uint8_t *addrdata = (const uint8_t *)addr->data;
495 int i, ssid;
496 char *bufp = buf;
498 for (i = 0; i < 6; i++) {
499 if (addrdata[i] == 0x40) {
500 /* end of callsign, start of space-padding */
501 break;
503 *bufp++ = printable_char_or_period(addrdata[i] >> 1);
506 ssid = (addrdata[6] >> 1) & 0x0f;
507 if (ssid != 0) {
508 bufp += snprintf(bufp,buf_len-(int)(bufp-buf),"-%d",ssid);
509 } else {
510 *bufp++ = '\0'; /* NULL terminate */
513 return (int)(bufp - buf);
516 static int ax25_addr_str_len(const address* addr _U_)
518 return 10; /* callsign (6) + dash (1) + ssid (2) + nul (1) = 10 */
521 static const char* ax25_col_filter_str(const address* addr _U_, bool is_src)
523 if (is_src)
524 return "ax25.src";
526 return "ax25.dst";
529 static int ax25_len(void)
531 return AX25_ADDR_LEN;
534 /******************************************************************************
535 * AT_VINES
536 ******************************************************************************/
538 static int vines_addr_to_str(const address* addr, char *buf, int buf_len)
540 _addr_return_if_nospace(14, buf, buf_len);
541 const uint8_t *addr_data = (const uint8_t *)addr->data;
542 char *bufp = buf;
544 bufp = dword_to_hex(bufp, pntoh32(&addr_data[0])); /* 8 bytes */
545 *bufp++ = '.'; /* 1 byte */
546 bufp = word_to_hex(bufp, pntoh16(&addr_data[4])); /* 4 bytes */
547 *bufp++ = '\0'; /* NULL terminate */
549 return (int)(bufp - buf);
552 static int vines_addr_str_len(const address* addr _U_)
554 return 14;
557 static int vines_len(void)
559 return VINES_ADDR_LEN;
562 /******************************************************************************
563 * AT_NUMERIC
564 ******************************************************************************/
566 /* UINT64_MAX is defined as 0xffffffffffffffffU which in itself represents
567 * 18,446,744,073,709,551,615 as decimal, which has 20 characters. Adding 21
568 * as for null-byte termination.
569 * All values are derived from the counterparts defined in glib/basic-types */
570 const size_t MAX_UINT64_WIDTH = 21;
571 const size_t MAX_UINT32_WIDTH = 11;
572 const size_t MAX_UINT16_WIDTH = 6;
573 const size_t MAX_UINT8_WIDTH = 4;
575 static int numeric_addr_str_len(const address* addr)
577 if (addr->len == (int) sizeof(uint64_t)) {
578 return (int) MAX_UINT64_WIDTH;
579 } else if (addr->len == (int) sizeof(uint32_t)) {
580 return (int) MAX_UINT32_WIDTH;
581 } else if (addr->len == (int) sizeof(uint16_t)) {
582 return (int) MAX_UINT16_WIDTH;
585 return (int) MAX_UINT8_WIDTH;
588 static int numeric_addr_to_str(const address* addr, char *buf, int buf_len)
590 int ret;
592 if (addr->len == (int) sizeof(uint64_t)) {
593 ret = snprintf(buf, buf_len, "%"PRIu64, *(uint64_t *)addr->data);
594 } else if (addr->len == (int) sizeof(uint32_t)) {
595 ret = snprintf(buf, buf_len, "%"PRIu32, *(uint32_t *)addr->data);
596 } else if (addr->len == (int) sizeof(uint16_t)) {
597 ret = snprintf(buf, buf_len, "%"PRIu16, *(uint16_t *)addr->data);
598 } else {
599 ret = snprintf(buf, buf_len, "%"PRIu8, *(uint8_t *)addr->data);
602 return ret + 1;
605 /******************************************************************************
606 * AT_MCTP
607 ******************************************************************************/
609 static int mctp_addr_to_str(const address* addr, char *buf, int buf_len _U_)
611 const uint8_t *addr_data = (const uint8_t *)addr->data;
612 char *bufp = buf;
614 return snprintf(bufp, 4, "%d", addr_data[0]);
617 static int mctp_addr_str_len(const address* addr _U_)
619 return 4;
622 static int mctp_len(void)
624 return 1;
627 /******************************************************************************
628 * END OF PROVIDED ADDRESS TYPES
629 ******************************************************************************/
634 void address_types_initialize(void)
636 static address_type_t none_address = {
637 AT_NONE, /* addr_type */
638 "AT_NONE", /* name */
639 "No address", /* pretty_name */
640 none_addr_to_str, /* addr_to_str */
641 none_addr_str_len, /* addr_str_len */
642 NULL, /* addr_to_byte */
643 NULL, /* addr_col_filter */
644 none_addr_len, /* addr_fixed_len */
645 none_name_res_str, /* addr_name_res_str */
646 none_name_res_len, /* addr_name_res_len */
649 static address_type_t ether_address = {
650 AT_ETHER, /* addr_type */
651 "AT_ETHER", /* name */
652 "Ethernet address", /* pretty_name */
653 ether_to_str, /* addr_to_str */
654 ether_str_len, /* addr_str_len */
655 NULL, /* addr_to_byte */
656 ether_col_filter_str, /* addr_col_filter */
657 ether_len, /* addr_fixed_len */
658 ether_name_resolution_str, /* addr_name_res_str */
659 ether_name_resolution_len, /* addr_name_res_len */
662 static address_type_t ipv4_address = {
663 AT_IPv4, /* addr_type */
664 "AT_IPv4", /* name */
665 "IPv4 address", /* pretty_name */
666 ipv4_to_str, /* addr_to_str */
667 ipv4_str_len, /* addr_str_len */
668 NULL, /* addr_to_byte */
669 ipv4_col_filter_str, /* addr_col_filter */
670 ipv4_len, /* addr_fixed_len */
671 ipv4_name_res_str, /* addr_name_res_str */
672 ipv4_name_res_len, /* addr_name_res_len */
675 static address_type_t ipv6_address = {
676 AT_IPv6, /* addr_type */
677 "AT_IPv6", /* name */
678 "IPv6 address", /* pretty_name */
679 ipv6_to_str, /* addr_to_str */
680 ipv6_str_len, /* addr_str_len */
681 NULL, /* addr_to_byte */
682 ipv6_col_filter_str, /* addr_col_filter */
683 ipv6_len, /* addr_fixed_len */
684 ipv6_name_res_str, /* addr_name_res_str */
685 ipv6_name_res_len, /* addr_name_res_len */
688 static address_type_t ipx_address = {
689 AT_IPX, /* addr_type */
690 "AT_IPX", /* name */
691 "IPX address", /* pretty_name */
692 ipx_to_str, /* addr_to_str */
693 ipx_str_len, /* addr_str_len */
694 NULL, /* addr_to_byte */
695 NULL, /* addr_col_filter */
696 ipx_len, /* addr_fixed_len */
697 NULL, /* addr_name_res_str */
698 NULL, /* addr_name_res_len */
701 static address_type_t fc_address = {
702 AT_FC, /* addr_type */
703 "AT_FC", /* name */
704 "FC address", /* pretty_name */
705 fc_to_str, /* addr_to_str */
706 fc_str_len, /* addr_str_len */
707 NULL, /* addr_to_byte */
708 NULL, /* addr_col_filter */
709 fc_len, /* addr_fixed_len */
710 NULL, /* addr_name_res_str */
711 NULL, /* addr_name_res_len */
714 static address_type_t fcwwn_address = {
715 AT_FCWWN, /* addr_type */
716 "AT_FCWWN", /* name */
717 "Fibre Channel WWN", /* pretty_name */
718 fcwwn_to_str, /* addr_to_str */
719 fcwwn_str_len, /* addr_str_len */
720 NULL, /* addr_to_byte */
721 NULL, /* addr_col_filter */
722 fcwwn_len, /* addr_fixed_len */
723 fcwwn_name_res_str, /* addr_name_res_str */
724 fcwwn_name_res_len, /* addr_name_res_len */
727 static address_type_t stringz_address = {
728 AT_STRINGZ, /* addr_type */
729 "AT_STRINGZ", /* name */
730 "String address", /* pretty_name */
731 stringz_addr_to_str, /* addr_to_str */
732 stringz_addr_str_len, /* addr_str_len */
733 NULL, /* addr_to_byte */
734 NULL, /* addr_col_filter */
735 NULL, /* addr_fixed_len */
736 NULL, /* addr_name_res_str */
737 NULL, /* addr_name_res_len */
740 static address_type_t eui64_address = {
741 AT_EUI64, /* addr_type */
742 "AT_EUI64", /* name */
743 "IEEE EUI-64", /* pretty_name */
744 eui64_addr_to_str, /* addr_to_str */
745 eui64_str_len, /* addr_str_len */
746 NULL, /* addr_to_byte */
747 NULL, /* addr_col_filter */
748 eui64_len, /* addr_fixed_len */
749 NULL, /* addr_name_res_str */
750 NULL, /* addr_name_res_len */
753 static address_type_t ib_address = {
754 AT_IB, /* addr_type */
755 "AT_IB", /* name */
756 "Infiniband GID/LID", /* pretty_name */
757 ib_addr_to_str, /* addr_to_str */
758 ib_str_len, /* addr_str_len */
759 NULL, /* addr_to_byte */
760 NULL, /* addr_col_filter */
761 NULL, /* addr_fixed_len */
762 NULL, /* addr_name_res_str */
763 NULL, /* addr_name_res_len */
766 static address_type_t ax25_address = {
767 AT_AX25, /* addr_type */
768 "AT_AX25", /* name */
769 "AX.25 Address", /* pretty_name */
770 ax25_addr_to_str, /* addr_to_str */
771 ax25_addr_str_len,/* addr_str_len */
772 NULL, /* addr_to_byte */
773 ax25_col_filter_str, /* addr_col_filter */
774 ax25_len, /* addr_fixed_len */
775 NULL, /* addr_name_res_str */
776 NULL, /* addr_name_res_len */
778 static address_type_t vines_address = {
779 AT_VINES, /* addr_type */
780 "AT_VINES", /* name */
781 "Banyan Vines Address", /* pretty_name */
782 vines_addr_to_str, /* addr_to_str */
783 vines_addr_str_len,/* addr_str_len */
784 NULL, /* addr_to_byte */
785 NULL, /* addr_col_filter */
786 vines_len, /* addr_fixed_len */
787 NULL, /* addr_name_res_str */
788 NULL, /* addr_name_res_len */
791 static address_type_t numeric_address = {
792 AT_NUMERIC, /* addr_type */
793 "AT_NUMERIC", /* name */
794 "Simple numeric address", /* pretty_name */
795 numeric_addr_to_str, /* addr_to_str */
796 numeric_addr_str_len, /* addr_str_len */
797 NULL, /* addr_to_byte */
798 NULL, /* addr_col_filter */
799 NULL, /* addr_fixed_len */
800 NULL, /* addr_name_res_str */
801 NULL, /* addr_name_res_len */
803 static address_type_t mctp_address = {
804 AT_MCTP, /* addr_type */
805 "AT_MCTP" , /* name */
806 "MCTP Address", /* pretty_name */
807 mctp_addr_to_str, /* addr_to_str */
808 mctp_addr_str_len, /* addr_str_len */
809 NULL, /* addr_to_byte */
810 NULL, /* addr_col_filter */
811 mctp_len, /* addr_fixed_len */
812 NULL, /* addr_name_res_str */
813 NULL, /* addr_name_res_len */
816 num_dissector_addr_type = 0;
818 /* Initialize the type array. This is mostly for handling
819 "dissector registered" address type range (for NULL checking) */
820 memset(type_list, 0, (MAX_ADDR_TYPE_VALUE + 1)*sizeof(address_type_t*));
822 address_type_register(AT_NONE, &none_address );
823 address_type_register(AT_ETHER, &ether_address );
824 address_type_register(AT_IPv4, &ipv4_address );
825 address_type_register(AT_IPv6, &ipv6_address );
826 address_type_register(AT_IPX, &ipx_address );
827 address_type_register(AT_FC, &fc_address );
828 address_type_register(AT_FCWWN, &fcwwn_address );
829 address_type_register(AT_STRINGZ, &stringz_address );
830 address_type_register(AT_EUI64, &eui64_address );
831 address_type_register(AT_IB, &ib_address );
832 address_type_register(AT_AX25, &ax25_address );
833 address_type_register(AT_VINES, &vines_address );
834 address_type_register(AT_NUMERIC, &numeric_address );
835 address_type_register(AT_MCTP, &mctp_address );
838 /* Given an address type id, return an address_type_t* */
839 #define ADDR_TYPE_LOOKUP(addr_type, result) \
840 /* Check input */ \
841 ws_assert(addr_type < MAX_ADDR_TYPE_VALUE); \
842 result = type_list[addr_type];
844 static int address_type_get_length(const address* addr)
846 address_type_t *at;
848 ADDR_TYPE_LOOKUP(addr->type, at);
850 if (at == NULL)
851 return 0;
853 return at->addr_str_len(addr);
856 char*
857 address_to_str(wmem_allocator_t *scope, const address *addr)
859 char *str;
860 int len = address_type_get_length(addr);
862 if (len <= 0)
863 len = MAX_ADDR_STR_LEN;
865 str=(char *)wmem_alloc(scope, len);
866 address_to_str_buf(addr, str, len);
867 return str;
870 void address_to_str_buf(const address* addr, char *buf, int buf_len)
872 address_type_t *at;
874 if (!buf || !buf_len)
875 return;
877 ADDR_TYPE_LOOKUP(addr->type, at);
879 if ((at == NULL) || (at->addr_to_str == NULL))
881 buf[0] = '\0';
882 return;
885 at->addr_to_str(addr, buf, buf_len);
889 unsigned address_to_bytes(const address *addr, uint8_t *buf, unsigned buf_len)
891 address_type_t *at;
892 unsigned copy_len = 0;
894 if (!buf || !buf_len)
895 return 0;
897 ADDR_TYPE_LOOKUP(addr->type, at);
899 if (at == NULL)
900 return 0;
902 if (at->addr_to_byte == NULL)
904 /* If a specific function isn't provided, just do a memcpy */
905 copy_len = MIN(((unsigned)addr->len), buf_len);
906 memcpy(buf, addr->data, copy_len);
908 else
910 copy_len = at->addr_to_byte(addr, buf, buf_len);
913 return copy_len;
916 const char *
917 address_to_name(const address *addr)
919 address_type_t *at;
921 ADDR_TYPE_LOOKUP(addr->type, at);
923 if (at == NULL)
925 return NULL;
929 * XXX - addr_name_res_str is expected to return a string from
930 * a persistent database, so that it lives a long time, past
931 * the lifetime of addr itself. That string is addr_resolv scope,
932 * which is roughly that of file scope, so in unusual circumstances
933 * it can be freed before addr.
935 * We'd like to avoid copying, so this is what we do here.
937 switch (addr->type) {
939 case AT_STRINGZ:
940 return (const char *)addr->data;
942 default:
943 if (at->addr_name_res_str != NULL)
944 return at->addr_name_res_str(addr);
945 else
946 return NULL;
950 char *
951 address_to_display(wmem_allocator_t *allocator, const address *addr)
953 char *str = NULL;
954 const char *result = address_to_name(addr);
956 if (result != NULL) {
957 str = wmem_strdup(allocator, result);
959 else if (addr->type == AT_NONE) {
960 str = wmem_strdup(allocator, "NONE");
962 else {
963 str = (char *) wmem_alloc(allocator, MAX_ADDR_STR_LEN);
964 address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
967 return str;
970 static void address_with_resolution_to_str_buf(const address* addr, char *buf, int buf_len)
972 address_type_t *at;
973 int addr_len;
974 size_t pos;
976 if (!buf || !buf_len)
977 return;
979 ADDR_TYPE_LOOKUP(addr->type, at);
981 if (at == NULL)
983 buf[0] = '\0';
984 return;
987 #if 0 /* XXX - If this remains a static function, we've already made this check in the only
988 function that can call it. If this function becomes "public", need to put this
989 check back in */
990 /* No name resolution support, just return address string */
991 if (at->addr_name_res_str == NULL)
992 return address_to_str_buf(addr, buf, buf_len);
993 #endif
995 /* Copy the resolved name */
996 g_strlcpy(buf, at->addr_name_res_str(addr), buf_len);
998 /* Get the length of the copied resolved name */
999 pos = strlen(buf);
1001 /* Get an upper bound on the length of the address string. */
1002 addr_len = at->addr_str_len(addr);
1004 * That includes the terminating '\0', so we subtract 1
1005 * to get the length prior to the terminator.
1007 addr_len--;
1010 * If the upper bound is 0, that means that the address string is
1011 * empty, so don't add it after the resolved name.
1013 if (addr_len == 0)
1014 return;
1017 * If the resolved name is an empty string, don't wrap parentheses
1018 * around the address string.
1020 if (pos == 0) {
1022 * The resolved name is an empty string.
1023 * Make sure there's room in the buffer for the address string;
1024 * addr_len + 1 includes the terminating '\0', and buf_len
1025 * includes room for the terminating '\0', so if the former
1026 * is greater than the latter, there isn't room.
1028 if (addr_len + 1 > buf_len)
1029 return;
1031 /* There is; just put the address string into the buffer. */
1032 at->addr_to_str(addr, buf, buf_len);
1033 } else {
1035 * Make sure there is enough room for the maximum length of the
1036 * address string wrapped in parentheses. That's pos (the
1037 * length of the resolved name plus 2 (for " (" plus addr_len
1038 * (the length of the address string) plus 2 (for ")\0");
1039 * it must not be greater than the buffer length.
1041 if ((int)(pos + 4 + addr_len) > buf_len)
1042 return;
1044 buf[pos++] = ' ';
1045 buf[pos++] = '(';
1047 addr_len = at->addr_to_str(addr, &buf[pos], (int)(buf_len-pos));
1048 pos += addr_len - 1; /* addr_len includes the trailing '\0' */
1050 buf[pos++] = ')';
1051 buf[pos++] = '\0';
1055 char* address_with_resolution_to_str(wmem_allocator_t *scope, const address *addr)
1057 address_type_t *at;
1058 int len;
1059 char *str;
1061 ADDR_TYPE_LOOKUP(addr->type, at);
1063 if (at == NULL)
1064 return wmem_strdup(scope, "");
1066 /* No name resolution support, just return address string */
1067 if ((at->addr_name_res_str == NULL) ||
1068 (ADDR_RESOLV_MACADDR(addr) && !gbl_resolv_flags.mac_name) ||
1069 (ADDR_RESOLV_NETADDR(addr) && !gbl_resolv_flags.network_name)) {
1070 return address_to_str(scope, addr);
1073 len = at->addr_name_res_len() + at->addr_str_len(addr) + 4; /* For format of %s (%s) */
1075 str=(char *)wmem_alloc(scope, len);
1076 address_with_resolution_to_str_buf(addr, str, len);
1077 return str;
1081 const char* address_type_column_filter_string(const address* addr, bool src)
1083 address_type_t *at;
1085 ADDR_TYPE_LOOKUP(addr->type, at);
1087 if ((at == NULL) || (at->addr_col_filter == NULL))
1089 return "";
1092 return at->addr_col_filter(addr, src);
1095 char*
1096 tvb_address_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int type, const int offset)
1098 address addr;
1099 address_type_t *at;
1101 ADDR_TYPE_LOOKUP(type, at);
1103 if (at == NULL)
1105 return NULL;
1108 /* The address type must have a fixed length to use this function */
1109 /* For variable length fields, use tvb_address_var_to_str() */
1110 if (at->addr_fixed_len == NULL)
1112 ws_assert_not_reached();
1113 return NULL;
1116 set_address_tvb(&addr, type, at->addr_fixed_len(), tvb, offset);
1118 return address_to_str(scope, &addr);
1121 char* tvb_address_var_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, address_type type, const int offset, int length)
1123 address addr;
1125 set_address_tvb(&addr, type, length, tvb, offset);
1127 return address_to_str(scope, &addr);
1130 char*
1131 tvb_address_with_resolution_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int type, const int offset)
1133 address addr;
1134 address_type_t *at;
1136 ADDR_TYPE_LOOKUP(type, at);
1138 if (at == NULL)
1140 return NULL;
1143 /* The address type must have a fixed length to use this function */
1144 /* For variable length fields, use tvb_address_var_with_resolution_to_str() */
1145 if (at->addr_fixed_len == NULL)
1147 ws_assert_not_reached();
1148 return NULL;
1151 set_address_tvb(&addr, type, at->addr_fixed_len(), tvb, offset);
1153 return address_with_resolution_to_str(scope, &addr);
1158 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1160 * Local variables:
1161 * c-basic-offset: 4
1162 * tab-width: 8
1163 * indent-tabs-mode: nil
1164 * End:
1166 * vi: set shiftwidth=4 tabstop=8 expandtab:
1167 * :indentSize=4:tabSize=8:noTabs=true: