From 7964fd8324c24679ca2ec85b6e9589f24079e089 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 25 Feb 2010 17:05:45 +0100 Subject: [PATCH] 03_resolve-port-names.diff This patch allows to resolve port numbers into names defined in the services(5) /etc/services database: (a) it provides a standalone function which will fall back to stringifying a port number; (b) it resets the 'numeric service' flag of getnameinfo(3) to analogously consider a lookup in /etc/services. Assuming the following had been added to /etc/services: para_server_control 2990/tcp # para_server control paraslash_http_service 8000/tcp # paraslash http sender paraslash_dccp_service 8000/dccp # paraslash dccp sender paraslash_udp_service 8000/udp # paraslash udp sender, then the output of 'para_client si' would look like: http sender: status: on port: paraslash_http_service ... dccp sender: status: on port: paraslash_dccp_service ... udp sender: status: on port: paraslash_udp_service ... Note: On some systems the service lookup may involve LDAP or NIS lookups, depending on the 'services' configuration in /etc/nsswitch.conf. This does not seem to cause a problem, as it implies a working network connection. --- net.c | 29 +++++++++++++++++++++++++++-- net.h | 1 + send_common.c | 4 ++-- udp_send.c | 4 ++-- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/net.c b/net.c index 126b5140..6ab96215 100644 --- a/net.c +++ b/net.c @@ -187,6 +187,31 @@ failed: return NULL; } +/** + * Stringify port number, resolve into service name where defined. + * \param port 2-byte port number, in host-byte-order. + * \param transport Transport protocol name (e.g. "udp", "tcp"), or NULL. + * \return Pointer to static result buffer. + * + * \sa getservent(3), services(5), nsswitch.conf(5) + */ +const char *stringify_port(int port, const char *transport) +{ + static char service[NI_MAXSERV]; + + if (port < 0 || port > 0xFFFF) { + snprintf(service, sizeof(service), "undefined (%d)", port); + } else { + struct servent *se = getservbyport(htons(port), transport); + + if (se == NULL) + snprintf(service, sizeof(service), "%u", port); + else + snprintf(service, sizeof(service), "%s", se->s_name); + } + return service; +} + /** * Determine the socket type for a given layer-4 protocol. * @@ -412,7 +437,7 @@ normalize_ip_address(const struct sockaddr_storage *ss) * * \param sa The IPv4/IPv6 socket address to use. * - * \sa getnameinfo(3). + * \sa getnameinfo(3), services(5), nsswitch.conf(5) */ static char *host_and_port(const struct sockaddr_storage *ss) { @@ -424,7 +449,7 @@ static char *host_and_port(const struct sockaddr_storage *ss) ret = getnameinfo(sa, salen(sa), hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), - NI_NUMERICHOST | NI_NUMERICSERV); + NI_NUMERICHOST); if (ret == 0) { snprintf(output, sizeof(output), "%s#%s", hbuf, sbuf); } else { diff --git a/net.h b/net.h index 15412586..1f2ebc6b 100644 --- a/net.h +++ b/net.h @@ -33,6 +33,7 @@ extern char *parse_cidr(const char *cidr, char *addr, ssize_t addrlen, int32_t *netmask); extern char *parse_url(const char *url, char *host, ssize_t hostlen, int32_t *port); +extern const char *stringify_port(int port, const char *transport); /** * Ensure that string conforms to the IPv4 address format. * diff --git a/send_common.c b/send_common.c index 2af6a8da..bc6892cc 100644 --- a/send_common.c +++ b/send_common.c @@ -231,14 +231,14 @@ char *get_sender_info(struct sender_status *ss, const char *name) ret = make_message( "%s sender:\n" "\tstatus: %s\n" - "\tport: %d\n" + "\tport: %s\n" "\tnumber of connected clients: %d\n" "\tmaximal number of clients: %d%s\n" "\tconnected clients: %s\n" "\taccess %s list: %s\n", name, (ss->listen_fd >= 0)? "on" : "off", - ss->port, + stringify_port(ss->port, strcmp(name, "http") ? "dccp" : "tcp"), ss->num_clients, ss->max_clients, ss->max_clients > 0? "" : " (unlimited)", diff --git a/udp_send.c b/udp_send.c index 77b5819b..7c4a8403 100644 --- a/udp_send.c +++ b/udp_send.c @@ -303,10 +303,10 @@ static char *udp_info(void) ret = make_message( "udp sender:\n" "\tstatus: %s\n" - "\tport: %d\n" + "\tport: %s\n" "\ttargets: %s\n", (sender_status == SENDER_ON)? "on" : "off", - conf.udp_default_port_arg, + stringify_port(conf.udp_default_port_arg, "udp"), tgts? tgts : "(none)" ); free(tgts); -- 2.39.5