1 |
commit: 9cd07a6fa5b7117008a716f774db884cecc55468 |
2 |
Author: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon Nov 21 01:31:57 2011 +0000 |
4 |
Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon Nov 21 01:31:57 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/net-tools.git;a=commit;h=9cd07a6f |
7 |
|
8 |
netstat: unify duplicate addr pretty printing |
9 |
|
10 |
The tcp/udp/raw protocols duplicate the logic for looking up addresses and |
11 |
their ports, and then formatting them nicely. They also duplicate this for |
12 |
local and remote addresses. They also encode a few assumptions about the |
13 |
length of the strings they get back which can cause buffer over and under |
14 |
flows. |
15 |
|
16 |
Add a new helper called addr_do_one that unifies all of this duplicate |
17 |
logic in one place, and handles any string size correctly. |
18 |
|
19 |
Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org> |
20 |
|
21 |
--- |
22 |
netstat.c | 102 ++++++++++++++++++++++-------------------------------------- |
23 |
1 files changed, 38 insertions(+), 64 deletions(-) |
24 |
|
25 |
diff --git a/netstat.c b/netstat.c |
26 |
index 7b45fc8..07d3da3 100644 |
27 |
--- a/netstat.c |
28 |
+++ b/netstat.c |
29 |
@@ -870,11 +870,39 @@ static int sctp_info(void) { |
30 |
return sctp_info_assocs(); |
31 |
} |
32 |
|
33 |
+static void addr_do_one(char *buf, size_t buf_len, size_t short_len, struct aftype *ap, |
34 |
+#if HAVE_AFINET6 |
35 |
+ struct sockaddr_in6 *addr, |
36 |
+#else |
37 |
+ struct sockaddr_in *addr, |
38 |
+#endif |
39 |
+ int port, const char *proto |
40 |
+) |
41 |
+{ |
42 |
+ const char *sport, *saddr; |
43 |
+ size_t port_len, addr_len; |
44 |
+ |
45 |
+ saddr = ap->sprint((struct sockaddr *)addr, flag_not & FLAG_NUM_HOST); |
46 |
+ sport = get_sname(htons(port), proto, flag_not & FLAG_NUM_PORT); |
47 |
+ addr_len = strlen(saddr); |
48 |
+ port_len = strlen(sport); |
49 |
+ if (!flag_wide && (addr_len + port_len > short_len)) { |
50 |
+ /* Assume port name is short */ |
51 |
+ port_len = netmin(port_len, short_len - 4); |
52 |
+ addr_len = short_len - port_len; |
53 |
+ strncpy(buf, saddr, addr_len); |
54 |
+ buf[addr_len] = '\0'; |
55 |
+ strcat(buf, ":"); |
56 |
+ strncat(buf, sport, port_len); |
57 |
+ } else |
58 |
+ snprintf(buf, buf_len, "%s:%s", saddr, sport); |
59 |
+} |
60 |
+ |
61 |
static void tcp_do_one(int lnr, const char *line, const char *prot) |
62 |
{ |
63 |
unsigned long rxq, txq, time_len, retr, inode; |
64 |
int num, local_port, rem_port, d, state, uid, timer_run, timeout; |
65 |
- char rem_addr[128], local_addr[128], timers[64], buffer[1024], more[512]; |
66 |
+ char rem_addr[128], local_addr[128], timers[64], more[512]; |
67 |
struct aftype *ap; |
68 |
#if HAVE_AFINET6 |
69 |
struct sockaddr_in6 localaddr, remaddr; |
70 |
@@ -930,34 +958,11 @@ static void tcp_do_one(int lnr, const char *line, const char *prot) |
71 |
((struct sockaddr *) &localaddr)->sa_family); |
72 |
return; |
73 |
} |
74 |
- safe_strncpy(local_addr, ap->sprint((struct sockaddr *) &localaddr, |
75 |
- flag_not & FLAG_NUM_HOST), sizeof(local_addr)); |
76 |
- safe_strncpy(rem_addr, ap->sprint((struct sockaddr *) &remaddr, flag_not & FLAG_NUM_HOST), |
77 |
- sizeof(rem_addr)); |
78 |
- |
79 |
- snprintf(buffer, sizeof(buffer), "%s", |
80 |
- get_sname(htons(local_port), "tcp", |
81 |
- flag_not & FLAG_NUM_PORT)); |
82 |
- |
83 |
- if (!flag_wide) { |
84 |
- if ((strlen(local_addr) + strlen(buffer)) > 22) |
85 |
- local_addr[22 - strlen(buffer)] = '\0'; |
86 |
- } |
87 |
- |
88 |
- strcat(local_addr, ":"); |
89 |
- strcat(local_addr, buffer); |
90 |
- snprintf(buffer, sizeof(buffer), "%s", |
91 |
- get_sname(htons(rem_port), "tcp", flag_not & FLAG_NUM_PORT)); |
92 |
|
93 |
- if (!flag_wide) { |
94 |
- if ((strlen(rem_addr) + strlen(buffer)) > 22) |
95 |
- rem_addr[22 - strlen(buffer)] = '\0'; |
96 |
- } |
97 |
+ addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "tcp"); |
98 |
+ addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "tcp"); |
99 |
|
100 |
- strcat(rem_addr, ":"); |
101 |
- strcat(rem_addr, buffer); |
102 |
timers[0] = '\0'; |
103 |
- |
104 |
if (flag_opt) |
105 |
switch (timer_run) { |
106 |
case 0: |
107 |
@@ -984,6 +989,7 @@ static void tcp_do_one(int lnr, const char *line, const char *prot) |
108 |
timer_run, (double) time_len / HZ, retr, timeout); |
109 |
break; |
110 |
} |
111 |
+ |
112 |
printf("%-4s %6ld %6ld %-*s %-*s %-11s", |
113 |
prot, rxq, txq, (int)netmax(23,strlen(local_addr)), local_addr, (int)netmax(23,strlen(rem_addr)), rem_addr, _(tcp_state[state])); |
114 |
|
115 |
@@ -998,7 +1004,7 @@ static int tcp_info(void) |
116 |
|
117 |
static void udp_do_one(int lnr, const char *line,const char *prot) |
118 |
{ |
119 |
- char buffer[8192], local_addr[64], rem_addr[64]; |
120 |
+ char local_addr[64], rem_addr[64]; |
121 |
char *udp_state, timers[64], more[512]; |
122 |
int num, local_port, rem_port, d, state, timer_run, uid, timeout; |
123 |
#if HAVE_AFINET6 |
124 |
@@ -1087,24 +1093,8 @@ static void udp_do_one(int lnr, const char *line,const char *prot) |
125 |
|
126 |
if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst)) |
127 |
{ |
128 |
- safe_strncpy(local_addr, ap->sprint((struct sockaddr *) &localaddr, |
129 |
- flag_not & FLAG_NUM_HOST), sizeof(local_addr)); |
130 |
- snprintf(buffer, sizeof(buffer), "%s", |
131 |
- get_sname(htons(local_port), "udp", |
132 |
- flag_not & FLAG_NUM_PORT)); |
133 |
- if ((strlen(local_addr) + strlen(buffer)) > 22) |
134 |
- local_addr[22 - strlen(buffer)] = '\0'; |
135 |
- strcat(local_addr, ":"); |
136 |
- strcat(local_addr, buffer); |
137 |
- |
138 |
- snprintf(buffer, sizeof(buffer), "%s", |
139 |
- get_sname(htons(rem_port), "udp", flag_not & FLAG_NUM_PORT)); |
140 |
- safe_strncpy(rem_addr, ap->sprint((struct sockaddr *) &remaddr, |
141 |
- flag_not & FLAG_NUM_HOST), sizeof(rem_addr)); |
142 |
- if ((strlen(rem_addr) + strlen(buffer)) > 22) |
143 |
- rem_addr[22 - strlen(buffer)] = '\0'; |
144 |
- strcat(rem_addr, ":"); |
145 |
- strcat(rem_addr, buffer); |
146 |
+ addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "udp"); |
147 |
+ addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "udp"); |
148 |
|
149 |
timers[0] = '\0'; |
150 |
if (flag_opt) |
151 |
@@ -1144,7 +1134,7 @@ static int udplite_info(void) |
152 |
|
153 |
static void raw_do_one(int lnr, const char *line,const char *prot) |
154 |
{ |
155 |
- char buffer[8192], local_addr[64], rem_addr[64]; |
156 |
+ char local_addr[64], rem_addr[64]; |
157 |
char timers[64], more[512]; |
158 |
int num, local_port, rem_port, d, state, timer_run, uid, timeout; |
159 |
#if HAVE_AFINET6 |
160 |
@@ -1212,24 +1202,8 @@ static void raw_do_one(int lnr, const char *line,const char *prot) |
161 |
|
162 |
if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst)) |
163 |
{ |
164 |
- snprintf(buffer, sizeof(buffer), "%s", |
165 |
- get_sname(htons(local_port), "raw", |
166 |
- flag_not & FLAG_NUM_PORT)); |
167 |
- safe_strncpy(local_addr, ap->sprint((struct sockaddr *) &localaddr, |
168 |
- flag_not & FLAG_NUM_HOST), sizeof(local_addr)); |
169 |
- if ((strlen(local_addr) + strlen(buffer)) > 22) |
170 |
- local_addr[22 - strlen(buffer)] = '\0'; |
171 |
- strcat(local_addr, ":"); |
172 |
- strcat(local_addr, buffer); |
173 |
- |
174 |
- snprintf(buffer, sizeof(buffer), "%s", |
175 |
- get_sname(htons(rem_port), "raw", flag_not & FLAG_NUM_PORT)); |
176 |
- safe_strncpy(rem_addr, ap->sprint((struct sockaddr *) &remaddr, |
177 |
- flag_not & FLAG_NUM_HOST), sizeof(rem_addr)); |
178 |
- if ((strlen(rem_addr) + strlen(buffer)) > 22) |
179 |
- rem_addr[22 - strlen(buffer)] = '\0'; |
180 |
- strcat(rem_addr, ":"); |
181 |
- strcat(rem_addr, buffer); |
182 |
+ addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "raw"); |
183 |
+ addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "raw"); |
184 |
|
185 |
timers[0] = '\0'; |
186 |
if (flag_opt) |