diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-19 11:12:46 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-19 11:12:46 +0000 |
commit | 6d9ea24611090f06b74e0e5b038b6c5b4bbe1063 (patch) | |
tree | 7fbefb532c3412b0264a9faf7d0ad3f42254b86e /libbb | |
parent | 1b16bdaebf7d0e543e048dfec9f34f06e983336c (diff) | |
download | busybox-w32-6d9ea24611090f06b74e0e5b038b6c5b4bbe1063.tar.gz busybox-w32-6d9ea24611090f06b74e0e5b038b6c5b4bbe1063.tar.bz2 busybox-w32-6d9ea24611090f06b74e0e5b038b6c5b4bbe1063.zip |
networking/interface.c: huke remaining big statics; use malloc for INET[6]_rresolve
return value. Went thru callers and adjusted them - code got smaller too.
function old new delta
ip_port_str - 126 +126
INET6_rresolve 165 182 +17
static.cache 20 24 +4
route_main 2092 2091 -1
INET_sprint 61 59 -2
INET_nn 4 - -4
INET6_sprint 59 53 -6
udp_do_one 518 508 -10
tcp_do_one 433 423 -10
raw_do_one 494 484 -10
traceroute_main 4117 4105 -12
INET_rresolve 334 321 -13
bb_displayroutes 494 456 -38
snprint_ip_port 244 - -244
static.buff 264 16 -248
------------------------------------------------------------------------------
(add/remove: 1/2 grow/shrink: 2/10 up/down: 147/-598) Total: -451 bytes
size busybox_old busybox_unstripped
text data bss dec hex filename
751073 3048 14688 768809 bbb29 busybox_old
750873 3048 14440 768361 bb969 busybox_unstripped
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/inet_common.c | 104 |
1 files changed, 47 insertions, 57 deletions
diff --git a/libbb/inet_common.c b/libbb/inet_common.c index 44b44a4cc..8449201ab 100644 --- a/libbb/inet_common.c +++ b/libbb/inet_common.c | |||
@@ -72,26 +72,24 @@ int INET_resolve(const char *name, struct sockaddr_in *s_in, int hostfirst) | |||
72 | return 0; | 72 | return 0; |
73 | } | 73 | } |
74 | 74 | ||
75 | /* cache */ | ||
76 | struct addr { | ||
77 | struct sockaddr_in addr; | ||
78 | char *name; | ||
79 | int host; | ||
80 | struct addr *next; | ||
81 | }; | ||
82 | |||
83 | static struct addr *INET_nn = NULL; /* addr-to-name cache */ | ||
84 | 75 | ||
85 | /* numeric: & 0x8000: default instead of *, | 76 | /* numeric: & 0x8000: default instead of *, |
86 | * & 0x4000: host instead of net, | 77 | * & 0x4000: host instead of net, |
87 | * & 0x0fff: don't resolve | 78 | * & 0x0fff: don't resolve |
88 | */ | 79 | */ |
89 | int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in, | 80 | char *INET_rresolve(struct sockaddr_in *s_in, int numeric, uint32_t netmask) |
90 | int numeric, unsigned int netmask) | ||
91 | { | 81 | { |
92 | struct hostent *ent; | 82 | /* addr-to-name cache */ |
93 | struct netent *np; | 83 | struct addr { |
84 | struct addr *next; | ||
85 | struct sockaddr_in addr; | ||
86 | int host; | ||
87 | char name[1]; | ||
88 | }; | ||
89 | static struct addr *cache = NULL; | ||
90 | |||
94 | struct addr *pn; | 91 | struct addr *pn; |
92 | char *name; | ||
95 | uint32_t ad, host_ad; | 93 | uint32_t ad, host_ad; |
96 | int host = 0; | 94 | int host = 0; |
97 | 95 | ||
@@ -102,7 +100,7 @@ int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in, | |||
102 | s_in->sin_family); | 100 | s_in->sin_family); |
103 | #endif | 101 | #endif |
104 | errno = EAFNOSUPPORT; | 102 | errno = EAFNOSUPPORT; |
105 | return -1; | 103 | return NULL; |
106 | } | 104 | } |
107 | ad = s_in->sin_addr.s_addr; | 105 | ad = s_in->sin_addr.s_addr; |
108 | #ifdef DEBUG | 106 | #ifdef DEBUG |
@@ -111,62 +109,58 @@ int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in, | |||
111 | if (ad == INADDR_ANY) { | 109 | if (ad == INADDR_ANY) { |
112 | if ((numeric & 0x0FFF) == 0) { | 110 | if ((numeric & 0x0FFF) == 0) { |
113 | if (numeric & 0x8000) | 111 | if (numeric & 0x8000) |
114 | safe_strncpy(name, bb_str_default, len); | 112 | return xstrdup(bb_str_default); |
115 | else | 113 | return xstrdup("*"); |
116 | safe_strncpy(name, "*", len); | ||
117 | return 0; | ||
118 | } | 114 | } |
119 | } | 115 | } |
120 | if (numeric & 0x0FFF) { | 116 | if (numeric & 0x0FFF) |
121 | safe_strncpy(name, inet_ntoa(s_in->sin_addr), len); | 117 | return xstrdup(inet_ntoa(s_in->sin_addr)); |
122 | return 0; | ||
123 | } | ||
124 | 118 | ||
125 | if ((ad & (~netmask)) != 0 || (numeric & 0x4000)) | 119 | if ((ad & (~netmask)) != 0 || (numeric & 0x4000)) |
126 | host = 1; | 120 | host = 1; |
127 | pn = INET_nn; | 121 | pn = cache; |
128 | while (pn != NULL) { | 122 | while (pn) { |
129 | if (pn->addr.sin_addr.s_addr == ad && pn->host == host) { | 123 | if (pn->addr.sin_addr.s_addr == ad && pn->host == host) { |
130 | safe_strncpy(name, pn->name, len); | ||
131 | #ifdef DEBUG | 124 | #ifdef DEBUG |
132 | bb_error_msg("rresolve: found %s %08x in cache", | 125 | bb_error_msg("rresolve: found %s %08x in cache", |
133 | (host ? "host" : "net"), (unsigned)ad); | 126 | (host ? "host" : "net"), (unsigned)ad); |
134 | #endif | 127 | #endif |
135 | return 0; | 128 | return xstrdup(pn->name); |
136 | } | 129 | } |
137 | pn = pn->next; | 130 | pn = pn->next; |
138 | } | 131 | } |
139 | 132 | ||
140 | host_ad = ntohl(ad); | 133 | host_ad = ntohl(ad); |
141 | np = NULL; | 134 | name = NULL; |
142 | ent = NULL; | ||
143 | if (host) { | 135 | if (host) { |
136 | struct hostent *ent; | ||
144 | #ifdef DEBUG | 137 | #ifdef DEBUG |
145 | bb_error_msg("gethostbyaddr (%08x)", (unsigned)ad); | 138 | bb_error_msg("gethostbyaddr (%08x)", (unsigned)ad); |
146 | #endif | 139 | #endif |
147 | ent = gethostbyaddr((char *) &ad, 4, AF_INET); | 140 | ent = gethostbyaddr((char *) &ad, 4, AF_INET); |
148 | if (ent != NULL) { | 141 | if (ent) |
149 | safe_strncpy(name, ent->h_name, len); | 142 | name = xstrdup(ent->h_name); |
150 | } | ||
151 | } else { | 143 | } else { |
144 | /* Hmmm... this is very rare to have named nets, | ||
145 | * and this getnetbyaddr() call is the only one in bbox. | ||
146 | * Maybe get rid of or make configurable? */ | ||
147 | struct netent *np; | ||
152 | #ifdef DEBUG | 148 | #ifdef DEBUG |
153 | bb_error_msg("getnetbyaddr (%08x)", (unsigned)host_ad); | 149 | bb_error_msg("getnetbyaddr (%08x)", (unsigned)host_ad); |
154 | #endif | 150 | #endif |
155 | np = getnetbyaddr(host_ad, AF_INET); | 151 | np = getnetbyaddr(host_ad, AF_INET); |
156 | if (np != NULL) { | 152 | if (np) |
157 | safe_strncpy(name, np->n_name, len); | 153 | name = xstrdup(np->n_name); |
158 | } | ||
159 | } | ||
160 | if (!ent && !np) { | ||
161 | safe_strncpy(name, inet_ntoa(s_in->sin_addr), len); | ||
162 | } | 154 | } |
163 | pn = xmalloc(sizeof(struct addr)); | 155 | if (!name) |
156 | name = xstrdup(inet_ntoa(s_in->sin_addr)); | ||
157 | pn = xmalloc(sizeof(*pn) + strlen(name)); /* no '+ 1', it's already accounted for */ | ||
158 | pn->next = cache; | ||
164 | pn->addr = *s_in; | 159 | pn->addr = *s_in; |
165 | pn->next = INET_nn; | ||
166 | pn->host = host; | 160 | pn->host = host; |
167 | pn->name = xstrdup(name); | 161 | strcpy(pn->name, name); |
168 | INET_nn = pn; | 162 | cache = pn; |
169 | return 0; | 163 | return name; |
170 | } | 164 | } |
171 | 165 | ||
172 | #ifdef CONFIG_FEATURE_IPV6 | 166 | #ifdef CONFIG_FEATURE_IPV6 |
@@ -195,9 +189,9 @@ int INET6_resolve(const char *name, struct sockaddr_in6 *sin6) | |||
195 | #endif | 189 | #endif |
196 | 190 | ||
197 | 191 | ||
198 | int INET6_rresolve(char *name, size_t len, struct sockaddr_in6 *sin6, | 192 | char *INET6_rresolve(struct sockaddr_in6 *sin6, int numeric) |
199 | int numeric) | ||
200 | { | 193 | { |
194 | char name[128]; | ||
201 | int s; | 195 | int s; |
202 | 196 | ||
203 | /* Grmpf. -FvK */ | 197 | /* Grmpf. -FvK */ |
@@ -207,29 +201,25 @@ int INET6_rresolve(char *name, size_t len, struct sockaddr_in6 *sin6, | |||
207 | sin6->sin6_family); | 201 | sin6->sin6_family); |
208 | #endif | 202 | #endif |
209 | errno = EAFNOSUPPORT; | 203 | errno = EAFNOSUPPORT; |
210 | return -1; | 204 | return NULL; |
211 | } | 205 | } |
212 | if (numeric & 0x7FFF) { | 206 | if (numeric & 0x7FFF) { |
213 | inet_ntop(AF_INET6, &sin6->sin6_addr, name, len); | 207 | inet_ntop(AF_INET6, &sin6->sin6_addr, name, sizeof(name)); |
214 | return 0; | 208 | return xstrdup(name); |
215 | } | 209 | } |
216 | if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { | 210 | if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { |
217 | if (numeric & 0x8000) { | 211 | if (numeric & 0x8000) |
218 | strcpy(name, bb_str_default); | 212 | return xstrdup(bb_str_default); |
219 | } else { | 213 | return xstrdup("*"); |
220 | name[0] = '*'; | ||
221 | name[1] = '\0'; | ||
222 | } | ||
223 | return 0; | ||
224 | } | 214 | } |
225 | 215 | ||
226 | s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6), | 216 | s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6), |
227 | name, len, NULL, 0, 0); | 217 | name, sizeof(name), NULL, 0, 0); |
228 | if (s) { | 218 | if (s) { |
229 | bb_error_msg("getnameinfo failed"); | 219 | bb_error_msg("getnameinfo failed"); |
230 | return -1; | 220 | return NULL; |
231 | } | 221 | } |
232 | return 0; | 222 | return xstrdup(name); |
233 | } | 223 | } |
234 | 224 | ||
235 | #endif /* CONFIG_FEATURE_IPV6 */ | 225 | #endif /* CONFIG_FEATURE_IPV6 */ |