aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2011-11-20 20:31:57 -0500
committerMike Frysinger <vapier@gentoo.org>2011-11-20 20:31:57 -0500
commit9cd07a6fa5b7117008a716f774db884cecc55468 (patch)
treeefcdfc5876c9a543d251ad826912632a1973e1d2
parentfix integer/pointer cast warnings (diff)
downloadnet-tools-9cd07a6fa5b7117008a716f774db884cecc55468.tar.gz
net-tools-9cd07a6fa5b7117008a716f774db884cecc55468.tar.bz2
net-tools-9cd07a6fa5b7117008a716f774db884cecc55468.zip
netstat: unify duplicate addr pretty printingHEADmaster
The tcp/udp/raw protocols duplicate the logic for looking up addresses and their ports, and then formatting them nicely. They also duplicate this for local and remote addresses. They also encode a few assumptions about the length of the strings they get back which can cause buffer over and under flows. Add a new helper called addr_do_one that unifies all of this duplicate logic in one place, and handles any string size correctly. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r--netstat.c102
1 files changed, 38 insertions, 64 deletions
diff --git a/netstat.c b/netstat.c
index 7b45fc8..07d3da3 100644
--- a/netstat.c
+++ b/netstat.c
@@ -870,11 +870,39 @@ static int sctp_info(void) {
return sctp_info_assocs();
}
+static void addr_do_one(char *buf, size_t buf_len, size_t short_len, struct aftype *ap,
+#if HAVE_AFINET6
+ struct sockaddr_in6 *addr,
+#else
+ struct sockaddr_in *addr,
+#endif
+ int port, const char *proto
+)
+{
+ const char *sport, *saddr;
+ size_t port_len, addr_len;
+
+ saddr = ap->sprint((struct sockaddr *)addr, flag_not & FLAG_NUM_HOST);
+ sport = get_sname(htons(port), proto, flag_not & FLAG_NUM_PORT);
+ addr_len = strlen(saddr);
+ port_len = strlen(sport);
+ if (!flag_wide && (addr_len + port_len > short_len)) {
+ /* Assume port name is short */
+ port_len = netmin(port_len, short_len - 4);
+ addr_len = short_len - port_len;
+ strncpy(buf, saddr, addr_len);
+ buf[addr_len] = '\0';
+ strcat(buf, ":");
+ strncat(buf, sport, port_len);
+ } else
+ snprintf(buf, buf_len, "%s:%s", saddr, sport);
+}
+
static void tcp_do_one(int lnr, const char *line, const char *prot)
{
unsigned long rxq, txq, time_len, retr, inode;
int num, local_port, rem_port, d, state, uid, timer_run, timeout;
- char rem_addr[128], local_addr[128], timers[64], buffer[1024], more[512];
+ char rem_addr[128], local_addr[128], timers[64], more[512];
struct aftype *ap;
#if HAVE_AFINET6
struct sockaddr_in6 localaddr, remaddr;
@@ -930,34 +958,11 @@ static void tcp_do_one(int lnr, const char *line, const char *prot)
((struct sockaddr *) &localaddr)->sa_family);
return;
}
- safe_strncpy(local_addr, ap->sprint((struct sockaddr *) &localaddr,
- flag_not & FLAG_NUM_HOST), sizeof(local_addr));
- safe_strncpy(rem_addr, ap->sprint((struct sockaddr *) &remaddr, flag_not & FLAG_NUM_HOST),
- sizeof(rem_addr));
-
- snprintf(buffer, sizeof(buffer), "%s",
- get_sname(htons(local_port), "tcp",
- flag_not & FLAG_NUM_PORT));
-
- if (!flag_wide) {
- if ((strlen(local_addr) + strlen(buffer)) > 22)
- local_addr[22 - strlen(buffer)] = '\0';
- }
-
- strcat(local_addr, ":");
- strcat(local_addr, buffer);
- snprintf(buffer, sizeof(buffer), "%s",
- get_sname(htons(rem_port), "tcp", flag_not & FLAG_NUM_PORT));
- if (!flag_wide) {
- if ((strlen(rem_addr) + strlen(buffer)) > 22)
- rem_addr[22 - strlen(buffer)] = '\0';
- }
+ addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "tcp");
+ addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "tcp");
- strcat(rem_addr, ":");
- strcat(rem_addr, buffer);
timers[0] = '\0';
-
if (flag_opt)
switch (timer_run) {
case 0:
@@ -984,6 +989,7 @@ static void tcp_do_one(int lnr, const char *line, const char *prot)
timer_run, (double) time_len / HZ, retr, timeout);
break;
}
+
printf("%-4s %6ld %6ld %-*s %-*s %-11s",
prot, rxq, txq, (int)netmax(23,strlen(local_addr)), local_addr, (int)netmax(23,strlen(rem_addr)), rem_addr, _(tcp_state[state]));
@@ -998,7 +1004,7 @@ static int tcp_info(void)
static void udp_do_one(int lnr, const char *line,const char *prot)
{
- char buffer[8192], local_addr[64], rem_addr[64];
+ char local_addr[64], rem_addr[64];
char *udp_state, timers[64], more[512];
int num, local_port, rem_port, d, state, timer_run, uid, timeout;
#if HAVE_AFINET6
@@ -1087,24 +1093,8 @@ static void udp_do_one(int lnr, const char *line,const char *prot)
if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst))
{
- safe_strncpy(local_addr, ap->sprint((struct sockaddr *) &localaddr,
- flag_not & FLAG_NUM_HOST), sizeof(local_addr));
- snprintf(buffer, sizeof(buffer), "%s",
- get_sname(htons(local_port), "udp",
- flag_not & FLAG_NUM_PORT));
- if ((strlen(local_addr) + strlen(buffer)) > 22)
- local_addr[22 - strlen(buffer)] = '\0';
- strcat(local_addr, ":");
- strcat(local_addr, buffer);
-
- snprintf(buffer, sizeof(buffer), "%s",
- get_sname(htons(rem_port), "udp", flag_not & FLAG_NUM_PORT));
- safe_strncpy(rem_addr, ap->sprint((struct sockaddr *) &remaddr,
- flag_not & FLAG_NUM_HOST), sizeof(rem_addr));
- if ((strlen(rem_addr) + strlen(buffer)) > 22)
- rem_addr[22 - strlen(buffer)] = '\0';
- strcat(rem_addr, ":");
- strcat(rem_addr, buffer);
+ addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "udp");
+ addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "udp");
timers[0] = '\0';
if (flag_opt)
@@ -1144,7 +1134,7 @@ static int udplite_info(void)
static void raw_do_one(int lnr, const char *line,const char *prot)
{
- char buffer[8192], local_addr[64], rem_addr[64];
+ char local_addr[64], rem_addr[64];
char timers[64], more[512];
int num, local_port, rem_port, d, state, timer_run, uid, timeout;
#if HAVE_AFINET6
@@ -1212,24 +1202,8 @@ static void raw_do_one(int lnr, const char *line,const char *prot)
if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst))
{
- snprintf(buffer, sizeof(buffer), "%s",
- get_sname(htons(local_port), "raw",
- flag_not & FLAG_NUM_PORT));
- safe_strncpy(local_addr, ap->sprint((struct sockaddr *) &localaddr,
- flag_not & FLAG_NUM_HOST), sizeof(local_addr));
- if ((strlen(local_addr) + strlen(buffer)) > 22)
- local_addr[22 - strlen(buffer)] = '\0';
- strcat(local_addr, ":");
- strcat(local_addr, buffer);
-
- snprintf(buffer, sizeof(buffer), "%s",
- get_sname(htons(rem_port), "raw", flag_not & FLAG_NUM_PORT));
- safe_strncpy(rem_addr, ap->sprint((struct sockaddr *) &remaddr,
- flag_not & FLAG_NUM_HOST), sizeof(rem_addr));
- if ((strlen(rem_addr) + strlen(buffer)) > 22)
- rem_addr[22 - strlen(buffer)] = '\0';
- strcat(rem_addr, ":");
- strcat(rem_addr, buffer);
+ addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "raw");
+ addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "raw");
timers[0] = '\0';
if (flag_opt)