diff options
author | Roland Knall <rknall@gmail.com> | 2022-07-20 13:39:28 +0200 |
---|---|---|
committer | Roland Knall <rknall@gmail.com> | 2022-07-20 13:46:15 +0000 |
commit | bf89153aa0a29ded302bd42db3dfd13687842b3c (patch) | |
tree | 659c96b24d5f6784fc700da391b89ed0ea9b2012 /epan/addr_resolv.c | |
parent | 6699b33276db0356c1ca93c765725aea94673f6a (diff) |
addr_resolve: Allow for port to be configured
If nameservers use a different default port than 53, Wireshark
is not able to resolve, as it always assumes the default port.
This allows to configure both tcp/udp ports for name resolutions,
with the udp port being asked first and tcp only used for fallback
Implements #18214
Diffstat (limited to 'epan/addr_resolv.c')
-rw-r--r-- | epan/addr_resolv.c | 67 |
1 files changed, 61 insertions, 6 deletions
diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c index c892e42a78..3a82722936 100644 --- a/epan/addr_resolv.c +++ b/epan/addr_resolv.c @@ -354,9 +354,13 @@ static wmem_list_t *async_dns_queue_head = NULL; gboolean use_custom_dns_server_list = FALSE; struct dns_server_data { char *ipaddr; + char *udp_port; + char *tcp_port; }; UAT_CSTRING_CB_DEF(dnsserverlist_uats, ipaddr, struct dns_server_data) +UAT_CSTRING_CB_DEF(dnsserverlist_uats, tcp_port, struct dns_server_data) +UAT_CSTRING_CB_DEF(dnsserverlist_uats, udp_port, struct dns_server_data) static uat_t *dnsserver_uat = NULL; static struct dns_server_data *dnsserverlist_uats = NULL; @@ -368,6 +372,31 @@ dns_server_free_cb(void *data) struct dns_server_data *h = (struct dns_server_data*)data; g_free(h->ipaddr); + g_free(h->tcp_port); + g_free(h->udp_port); +} + +static char * +copy_port(char *p) +{ + if (!p || strlen(p) == 0u) + return g_strdup("53"); + return g_strdup(p); +} + +static int +get_port_to_int(char *p) +{ + guint16 port; + + if (!p || strlen(p) == 0u) + return 53; + + if (!ws_strtou16(p, NULL, &port)) { + return 53; + } + + return port; } static void* @@ -377,6 +406,8 @@ dns_server_copy_cb(void *dst_, const void *src_, size_t len _U_) struct dns_server_data *dst = (struct dns_server_data *)dst_; dst->ipaddr = g_strdup(src->ipaddr); + dst->udp_port = copy_port(src->udp_port); + dst->tcp_port = copy_port(src->tcp_port); return dst; } @@ -394,7 +425,26 @@ dnsserver_uat_fld_ip_chk_cb(void* r _U_, const char* ipaddr, guint len _U_, cons return FALSE; } +static gboolean +dnsserver_uat_fld_port_chk_cb(void* r _U_, const char* p, guint len _U_, const void* u1 _U_, const void* u2 _U_, char** err) +{ + if (!p || strlen(p) == 0u) { + // This should be removed in favor of Decode As. Make it optional. + *err = NULL; + return TRUE; + } + if (strcmp(p, "53") != 0){ + guint16 port; + if (!ws_strtou16(p, NULL, &port)) { + *err = g_strdup("Invalid port given."); + return FALSE; + } + } + + *err = NULL; + return TRUE; +} static void c_ares_ghba_sync_cb(void *arg, int status, int timeouts _U_, struct hostent *he) { @@ -545,14 +595,14 @@ c_ares_set_dns_servers(void) if (ndnsservers == 0) { //clear the list of servers. This may effectively disable name resolution - ares_set_servers(ghba_chan, NULL); - ares_set_servers(ghbn_chan, NULL); + ares_set_servers_ports(ghba_chan, NULL); + ares_set_servers_ports(ghbn_chan, NULL); } else { - struct ares_addr_node* servers = wmem_alloc_array(NULL, struct ares_addr_node, ndnsservers); + struct ares_addr_port_node* servers = wmem_alloc_array(NULL, struct ares_addr_port_node, ndnsservers); ws_in4_addr ipv4addr; ws_in6_addr ipv6addr; gboolean invalid_IP_found = FALSE; - struct ares_addr_node* server; + struct ares_addr_port_node* server; guint i; for (i = 0, server = servers; i < ndnsservers-1; i++, server++) { if (ws_inet_pton6(dnsserverlist_uats[i].ipaddr, &ipv6addr)) { @@ -569,6 +619,9 @@ c_ares_set_dns_servers(void) break; } + server->udp_port = get_port_to_int(dnsserverlist_uats[i].udp_port); + server->tcp_port = get_port_to_int(dnsserverlist_uats[i].tcp_port); + server->next = (server+1); } if (!invalid_IP_found) { @@ -587,8 +640,8 @@ c_ares_set_dns_servers(void) } server->next = NULL; - ares_set_servers(ghba_chan, servers); - ares_set_servers(ghbn_chan, servers); + ares_set_servers_ports(ghba_chan, servers); + ares_set_servers_ports(ghbn_chan, servers); wmem_free(NULL, servers); } } @@ -2844,6 +2897,8 @@ addr_resolve_pref_init(module_t *nameres) static uat_field_t dns_server_uats_flds[] = { UAT_FLD_CSTRING_OTHER(dnsserverlist_uats, ipaddr, "IP address", dnsserver_uat_fld_ip_chk_cb, "IPv4 or IPv6 address"), + UAT_FLD_CSTRING_OTHER(dnsserverlist_uats, tcp_port, "TCP Port", dnsserver_uat_fld_port_chk_cb, "Port Number (TCP)"), + UAT_FLD_CSTRING_OTHER(dnsserverlist_uats, udp_port, "UDP Port", dnsserver_uat_fld_port_chk_cb, "Port Number (UDP)"), UAT_END_FIELDS }; |