diff options
author | Ron Yorston <rmy@pobox.com> | 2016-07-07 14:28:08 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2016-07-07 14:58:55 +0100 |
commit | 613f46218c53c8cabdbf0435653e74e0e0e91e1c (patch) | |
tree | ca06a7e7a3e4c861441acb4ea20648d7827fa6ae /networking | |
parent | a0c61c9492723dd31681f878f9c68c92817a476d (diff) | |
parent | 237bedd499c58034a1355484d6d4d906f0180308 (diff) | |
download | busybox-w32-613f46218c53c8cabdbf0435653e74e0e0e91e1c.tar.gz busybox-w32-613f46218c53c8cabdbf0435653e74e0e0e91e1c.tar.bz2 busybox-w32-613f46218c53c8cabdbf0435653e74e0e0e91e1c.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'networking')
-rw-r--r-- | networking/arp.c | 6 | ||||
-rw-r--r-- | networking/arping.c | 15 | ||||
-rw-r--r-- | networking/ftpd.c | 6 | ||||
-rw-r--r-- | networking/ifplugd.c | 5 | ||||
-rw-r--r-- | networking/inetd.c | 4 | ||||
-rw-r--r-- | networking/nc_bloaty.c | 4 | ||||
-rw-r--r-- | networking/ntpd.c | 96 | ||||
-rw-r--r-- | networking/ping.c | 12 | ||||
-rw-r--r-- | networking/tcpudp.c | 4 | ||||
-rw-r--r-- | networking/telnetd.c | 4 | ||||
-rw-r--r-- | networking/traceroute.c | 4 | ||||
-rw-r--r-- | networking/udhcp/d6_dhcpc.c | 10 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 10 | ||||
-rw-r--r-- | networking/wget.c | 3 | ||||
-rw-r--r-- | networking/whois.c | 147 |
15 files changed, 240 insertions, 90 deletions
diff --git a/networking/arp.c b/networking/arp.c index 9381eb53a..69a5816eb 100644 --- a/networking/arp.c +++ b/networking/arp.c | |||
@@ -178,7 +178,7 @@ static int arp_del(char **args) | |||
178 | if (flags == 0) | 178 | if (flags == 0) |
179 | flags = 3; | 179 | flags = 3; |
180 | 180 | ||
181 | strncpy(req.arp_dev, device, sizeof(req.arp_dev)); | 181 | strncpy_IFNAMSIZ(req.arp_dev, device); |
182 | 182 | ||
183 | err = -1; | 183 | err = -1; |
184 | 184 | ||
@@ -219,7 +219,7 @@ static void arp_getdevhw(char *ifname, struct sockaddr *sa) | |||
219 | struct ifreq ifr; | 219 | struct ifreq ifr; |
220 | const struct hwtype *xhw; | 220 | const struct hwtype *xhw; |
221 | 221 | ||
222 | strcpy(ifr.ifr_name, ifname); | 222 | strncpy_IFNAMSIZ(ifr.ifr_name, ifname); |
223 | ioctl_or_perror_and_die(sockfd, SIOCGIFHWADDR, &ifr, | 223 | ioctl_or_perror_and_die(sockfd, SIOCGIFHWADDR, &ifr, |
224 | "can't get HW-Address for '%s'", ifname); | 224 | "can't get HW-Address for '%s'", ifname); |
225 | if (hw_set && (ifr.ifr_hwaddr.sa_family != hw->type)) { | 225 | if (hw_set && (ifr.ifr_hwaddr.sa_family != hw->type)) { |
@@ -332,7 +332,7 @@ static int arp_set(char **args) | |||
332 | /* Fill in the remainder of the request. */ | 332 | /* Fill in the remainder of the request. */ |
333 | req.arp_flags = flags; | 333 | req.arp_flags = flags; |
334 | 334 | ||
335 | strncpy(req.arp_dev, device, sizeof(req.arp_dev)); | 335 | strncpy_IFNAMSIZ(req.arp_dev, device); |
336 | 336 | ||
337 | /* Call the kernel. */ | 337 | /* Call the kernel. */ |
338 | if (option_mask32 & ARP_OPT_v) | 338 | if (option_mask32 & ARP_OPT_v) |
diff --git a/networking/arping.c b/networking/arping.c index 6b0de4de2..46bd65e36 100644 --- a/networking/arping.c +++ b/networking/arping.c | |||
@@ -231,20 +231,23 @@ static void recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
231 | if (!(option_mask32 & QUIET)) { | 231 | if (!(option_mask32 & QUIET)) { |
232 | int s_printed = 0; | 232 | int s_printed = 0; |
233 | 233 | ||
234 | printf("%scast re%s from %s [%s]", | 234 | printf("%scast re%s from %s [%02x:%02x:%02x:%02x:%02x:%02x]", |
235 | FROM->sll_pkttype == PACKET_HOST ? "Uni" : "Broad", | 235 | FROM->sll_pkttype == PACKET_HOST ? "Uni" : "Broad", |
236 | ah->ar_op == htons(ARPOP_REPLY) ? "ply" : "quest", | 236 | ah->ar_op == htons(ARPOP_REPLY) ? "ply" : "quest", |
237 | inet_ntoa(src_ip), | 237 | inet_ntoa(src_ip), |
238 | ether_ntoa((struct ether_addr *) p)); | 238 | p[0], p[1], p[2], p[3], p[4], p[5] |
239 | ); | ||
239 | if (dst_ip.s_addr != src.s_addr) { | 240 | if (dst_ip.s_addr != src.s_addr) { |
240 | printf("for %s ", inet_ntoa(dst_ip)); | 241 | printf("for %s ", inet_ntoa(dst_ip)); |
241 | s_printed = 1; | 242 | s_printed = 1; |
242 | } | 243 | } |
243 | if (memcmp(p + ah->ar_hln + 4, me.sll_addr, ah->ar_hln)) { | 244 | if (memcmp(p + ah->ar_hln + 4, me.sll_addr, ah->ar_hln)) { |
245 | unsigned char *pp = p + ah->ar_hln + 4; | ||
244 | if (!s_printed) | 246 | if (!s_printed) |
245 | printf("for "); | 247 | printf("for "); |
246 | printf("[%s]", | 248 | printf("[%02x:%02x:%02x:%02x:%02x:%02x]", |
247 | ether_ntoa((struct ether_addr *) p + ah->ar_hln + 4)); | 249 | pp[0], pp[1], pp[2], pp[3], pp[4], pp[5] |
250 | ); | ||
248 | } | 251 | } |
249 | 252 | ||
250 | if (last) { | 253 | if (last) { |
@@ -292,8 +295,8 @@ int arping_main(int argc UNUSED_PARAM, char **argv) | |||
292 | /* Dad also sets quit_on_reply. | 295 | /* Dad also sets quit_on_reply. |
293 | * Advert also sets unsolicited. | 296 | * Advert also sets unsolicited. |
294 | */ | 297 | */ |
295 | opt_complementary = "=1:Df:AU:c+"; | 298 | opt_complementary = "=1:Df:AU"; |
296 | opt = getopt32(argv, "DUAqfbc:w:I:s:", | 299 | opt = getopt32(argv, "DUAqfbc:+w:I:s:", |
297 | &count, &str_timeout, &device, &source); | 300 | &count, &str_timeout, &device, &source); |
298 | if (opt & 0x80) /* -w: timeout */ | 301 | if (opt & 0x80) /* -w: timeout */ |
299 | timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000; | 302 | timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000; |
diff --git a/networking/ftpd.c b/networking/ftpd.c index 360d1e6be..4cbb9b6fe 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c | |||
@@ -1130,11 +1130,11 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv) | |||
1130 | abs_timeout = 1 * 60 * 60; | 1130 | abs_timeout = 1 * 60 * 60; |
1131 | verbose_S = 0; | 1131 | verbose_S = 0; |
1132 | G.timeout = 2 * 60; | 1132 | G.timeout = 2 * 60; |
1133 | opt_complementary = "t+:T+:vv:SS"; | 1133 | opt_complementary = "vv:SS"; |
1134 | #if BB_MMU | 1134 | #if BB_MMU |
1135 | opts = getopt32(argv, "vS" IF_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose, &verbose_S); | 1135 | opts = getopt32(argv, "vS" IF_FEATURE_FTP_WRITE("w") "t:+T:+", &G.timeout, &abs_timeout, &G.verbose, &verbose_S); |
1136 | #else | 1136 | #else |
1137 | opts = getopt32(argv, "l1AvS" IF_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose, &verbose_S); | 1137 | opts = getopt32(argv, "l1AvS" IF_FEATURE_FTP_WRITE("w") "t:+T:+", &G.timeout, &abs_timeout, &G.verbose, &verbose_S); |
1138 | if (opts & (OPT_l|OPT_1)) { | 1138 | if (opts & (OPT_l|OPT_1)) { |
1139 | /* Our secret backdoor to ls */ | 1139 | /* Our secret backdoor to ls */ |
1140 | /* TODO: pass --group-directories-first? would be nice, but ls doesn't do that yet */ | 1140 | /* TODO: pass --group-directories-first? would be nice, but ls doesn't do that yet */ |
diff --git a/networking/ifplugd.c b/networking/ifplugd.c index f0defb5c8..28c49e218 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c | |||
@@ -107,9 +107,9 @@ enum { | |||
107 | #endif | 107 | #endif |
108 | }; | 108 | }; |
109 | #if ENABLE_FEATURE_PIDFILE | 109 | #if ENABLE_FEATURE_PIDFILE |
110 | # define OPTION_STR "+ansfFi:r:It:u:d:m:pqlx:Mk" | 110 | # define OPTION_STR "+ansfFi:r:It:+u:+d:+m:pqlx:Mk" |
111 | #else | 111 | #else |
112 | # define OPTION_STR "+ansfFi:r:It:u:d:m:pqlx:M" | 112 | # define OPTION_STR "+ansfFi:r:It:+u:+d:+m:pqlx:M" |
113 | #endif | 113 | #endif |
114 | 114 | ||
115 | enum { // interface status | 115 | enum { // interface status |
@@ -560,7 +560,6 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) | |||
560 | 560 | ||
561 | INIT_G(); | 561 | INIT_G(); |
562 | 562 | ||
563 | opt_complementary = "t+:u+:d+"; | ||
564 | opts = getopt32(argv, OPTION_STR, | 563 | opts = getopt32(argv, OPTION_STR, |
565 | &G.iface, &G.script_name, &G.poll_time, &G.delay_up, | 564 | &G.iface, &G.script_name, &G.poll_time, &G.delay_up, |
566 | &G.delay_down, &G.api_mode, &G.extra_arg); | 565 | &G.delay_down, &G.api_mode, &G.extra_arg); |
diff --git a/networking/inetd.c b/networking/inetd.c index 8d44b5198..f9295e38b 100644 --- a/networking/inetd.c +++ b/networking/inetd.c | |||
@@ -1153,8 +1153,8 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1153 | if (real_uid != 0) /* run by non-root user */ | 1153 | if (real_uid != 0) /* run by non-root user */ |
1154 | config_filename = NULL; | 1154 | config_filename = NULL; |
1155 | 1155 | ||
1156 | opt_complementary = "R+:q+"; /* -q N, -R N */ | 1156 | /* -q N, -R N */ |
1157 | opt = getopt32(argv, "R:feq:", &max_concurrency, &global_queuelen); | 1157 | opt = getopt32(argv, "R:+feq:+", &max_concurrency, &global_queuelen); |
1158 | argv += optind; | 1158 | argv += optind; |
1159 | //argc -= optind; | 1159 | //argc -= optind; |
1160 | if (argv[0]) | 1160 | if (argv[0]) |
diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c index 471ae1a12..192e42fe5 100644 --- a/networking/nc_bloaty.c +++ b/networking/nc_bloaty.c | |||
@@ -794,8 +794,8 @@ int nc_main(int argc UNUSED_PARAM, char **argv) | |||
794 | e_found: | 794 | e_found: |
795 | 795 | ||
796 | // -g -G -t -r deleted, unimplemented -a deleted too | 796 | // -g -G -t -r deleted, unimplemented -a deleted too |
797 | opt_complementary = "?2:vv:ll:w+"; /* max 2 params; -v and -l are counters; -w N */ | 797 | opt_complementary = "?2:vv:ll"; /* max 2 params; -v and -l are counters; -w N */ |
798 | getopt32(argv, "np:s:uvw:" IF_NC_SERVER("lk") | 798 | getopt32(argv, "np:s:uvw:+" IF_NC_SERVER("lk") |
799 | IF_NC_EXTRA("i:o:z"), | 799 | IF_NC_EXTRA("i:o:z"), |
800 | &str_p, &str_s, &o_wait | 800 | &str_p, &str_s, &o_wait |
801 | IF_NC_EXTRA(, &str_i, &str_o), &o_verbose IF_NC_SERVER(, &cnt_l)); | 801 | IF_NC_EXTRA(, &str_i, &str_o), &o_verbose IF_NC_SERVER(, &cnt_l)); |
diff --git a/networking/ntpd.c b/networking/ntpd.c index 410318979..130cef0af 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -267,7 +267,6 @@ typedef struct { | |||
267 | 267 | ||
268 | typedef struct { | 268 | typedef struct { |
269 | len_and_sockaddr *p_lsa; | 269 | len_and_sockaddr *p_lsa; |
270 | char *p_hostname; | ||
271 | char *p_dotted; | 270 | char *p_dotted; |
272 | int p_fd; | 271 | int p_fd; |
273 | int datapoint_idx; | 272 | int datapoint_idx; |
@@ -293,6 +292,7 @@ typedef struct { | |||
293 | datapoint_t filter_datapoint[NUM_DATAPOINTS]; | 292 | datapoint_t filter_datapoint[NUM_DATAPOINTS]; |
294 | /* last sent packet: */ | 293 | /* last sent packet: */ |
295 | msg_t p_xmt_msg; | 294 | msg_t p_xmt_msg; |
295 | char p_hostname[1]; | ||
296 | } peer_t; | 296 | } peer_t; |
297 | 297 | ||
298 | 298 | ||
@@ -765,14 +765,38 @@ reset_peer_stats(peer_t *p, double offset) | |||
765 | } | 765 | } |
766 | 766 | ||
767 | static void | 767 | static void |
768 | resolve_peer_hostname(peer_t *p, int loop_on_fail) | ||
769 | { | ||
770 | len_and_sockaddr *lsa; | ||
771 | |||
772 | again: | ||
773 | lsa = host2sockaddr(p->p_hostname, 123); | ||
774 | if (!lsa) { | ||
775 | /* error message already emitted by host2sockaddr() */ | ||
776 | if (!loop_on_fail) | ||
777 | return; | ||
778 | //FIXME: do this to avoid infinite looping on typo in a hostname? | ||
779 | //well... in which case, what is a good value for loop_on_fail? | ||
780 | //if (--loop_on_fail == 0) | ||
781 | // xfunc_die(); | ||
782 | sleep(5); | ||
783 | goto again; | ||
784 | } | ||
785 | free(p->p_lsa); | ||
786 | free(p->p_dotted); | ||
787 | p->p_lsa = lsa; | ||
788 | p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); | ||
789 | } | ||
790 | |||
791 | static void | ||
768 | add_peers(const char *s) | 792 | add_peers(const char *s) |
769 | { | 793 | { |
770 | llist_t *item; | 794 | llist_t *item; |
771 | peer_t *p; | 795 | peer_t *p; |
772 | 796 | ||
773 | p = xzalloc(sizeof(*p)); | 797 | p = xzalloc(sizeof(*p) + strlen(s)); |
774 | p->p_lsa = xhost2sockaddr(s, 123); | 798 | strcpy(p->p_hostname, s); |
775 | p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa); | 799 | resolve_peer_hostname(p, /*loop_on_fail=*/ 1); |
776 | 800 | ||
777 | /* Names like N.<country2chars>.pool.ntp.org are randomly resolved | 801 | /* Names like N.<country2chars>.pool.ntp.org are randomly resolved |
778 | * to a pool of machines. Sometimes different N's resolve to the same IP. | 802 | * to a pool of machines. Sometimes different N's resolve to the same IP. |
@@ -789,7 +813,6 @@ add_peers(const char *s) | |||
789 | } | 813 | } |
790 | } | 814 | } |
791 | 815 | ||
792 | p->p_hostname = xstrdup(s); | ||
793 | p->p_fd = -1; | 816 | p->p_fd = -1; |
794 | p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); | 817 | p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); |
795 | p->next_action_time = G.cur_time; /* = set_next(p, 0); */ | 818 | p->next_action_time = G.cur_time; /* = set_next(p, 0); */ |
@@ -2174,11 +2197,11 @@ static NOINLINE void ntp_init(char **argv) | |||
2174 | 2197 | ||
2175 | /* Parse options */ | 2198 | /* Parse options */ |
2176 | peers = NULL; | 2199 | peers = NULL; |
2177 | opt_complementary = "dd:p::wn" /* -d: counter; -p: list; -w implies -n */ | 2200 | opt_complementary = "dd:wn" /* -d: counter; -p: list; -w implies -n */ |
2178 | IF_FEATURE_NTPD_SERVER(":Il"); /* -I implies -l */ | 2201 | IF_FEATURE_NTPD_SERVER(":Il"); /* -I implies -l */ |
2179 | opts = getopt32(argv, | 2202 | opts = getopt32(argv, |
2180 | "nqNx" /* compat */ | 2203 | "nqNx" /* compat */ |
2181 | "wp:S:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */ | 2204 | "wp:*S:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */ |
2182 | IF_FEATURE_NTPD_SERVER("I:") /* compat */ | 2205 | IF_FEATURE_NTPD_SERVER("I:") /* compat */ |
2183 | "d" /* compat */ | 2206 | "d" /* compat */ |
2184 | "46aAbgL", /* compat, ignored */ | 2207 | "46aAbgL", /* compat, ignored */ |
@@ -2190,6 +2213,31 @@ static NOINLINE void ntp_init(char **argv) | |||
2190 | 2213 | ||
2191 | // if (opts & OPT_x) /* disable stepping, only slew is allowed */ | 2214 | // if (opts & OPT_x) /* disable stepping, only slew is allowed */ |
2192 | // G.time_was_stepped = 1; | 2215 | // G.time_was_stepped = 1; |
2216 | |||
2217 | #if ENABLE_FEATURE_NTPD_SERVER | ||
2218 | G_listen_fd = -1; | ||
2219 | if (opts & OPT_l) { | ||
2220 | G_listen_fd = create_and_bind_dgram_or_die(NULL, 123); | ||
2221 | if (G.if_name) { | ||
2222 | if (setsockopt_bindtodevice(G_listen_fd, G.if_name)) | ||
2223 | xfunc_die(); | ||
2224 | } | ||
2225 | socket_want_pktinfo(G_listen_fd); | ||
2226 | setsockopt_int(G_listen_fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); | ||
2227 | } | ||
2228 | #endif | ||
2229 | /* I hesitate to set -20 prio. -15 should be high enough for timekeeping */ | ||
2230 | if (opts & OPT_N) | ||
2231 | setpriority(PRIO_PROCESS, 0, -15); | ||
2232 | |||
2233 | /* add_peers() calls can retry DNS resolution (possibly forever). | ||
2234 | * Daemonize before them, or else boot can stall forever. | ||
2235 | */ | ||
2236 | if (!(opts & OPT_n)) { | ||
2237 | bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv); | ||
2238 | logmode = LOGMODE_NONE; | ||
2239 | } | ||
2240 | |||
2193 | if (peers) { | 2241 | if (peers) { |
2194 | while (peers) | 2242 | while (peers) |
2195 | add_peers(llist_pop(&peers)); | 2243 | add_peers(llist_pop(&peers)); |
@@ -2218,26 +2266,6 @@ static NOINLINE void ntp_init(char **argv) | |||
2218 | /* -l but no peers: "stratum 1 server" mode */ | 2266 | /* -l but no peers: "stratum 1 server" mode */ |
2219 | G.stratum = 1; | 2267 | G.stratum = 1; |
2220 | } | 2268 | } |
2221 | #if ENABLE_FEATURE_NTPD_SERVER | ||
2222 | G_listen_fd = -1; | ||
2223 | if (opts & OPT_l) { | ||
2224 | G_listen_fd = create_and_bind_dgram_or_die(NULL, 123); | ||
2225 | if (opts & OPT_I) { | ||
2226 | if (setsockopt_bindtodevice(G_listen_fd, G.if_name)) | ||
2227 | xfunc_die(); | ||
2228 | } | ||
2229 | socket_want_pktinfo(G_listen_fd); | ||
2230 | setsockopt_int(G_listen_fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); | ||
2231 | } | ||
2232 | #endif | ||
2233 | if (!(opts & OPT_n)) { | ||
2234 | bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv); | ||
2235 | logmode = LOGMODE_NONE; | ||
2236 | } | ||
2237 | /* I hesitate to set -20 prio. -15 should be high enough for timekeeping */ | ||
2238 | if (opts & OPT_N) | ||
2239 | setpriority(PRIO_PROCESS, 0, -15); | ||
2240 | |||
2241 | /* If network is up, syncronization occurs in ~10 seconds. | 2269 | /* If network is up, syncronization occurs in ~10 seconds. |
2242 | * We give "ntpd -q" 10 seconds to get first reply, | 2270 | * We give "ntpd -q" 10 seconds to get first reply, |
2243 | * then another 50 seconds to finish syncing. | 2271 | * then another 50 seconds to finish syncing. |
@@ -2338,18 +2366,8 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
2338 | p->p_dotted, p->reachable_bits, timeout); | 2366 | p->p_dotted, p->reachable_bits, timeout); |
2339 | 2367 | ||
2340 | /* What if don't see it because it changed its IP? */ | 2368 | /* What if don't see it because it changed its IP? */ |
2341 | if (p->reachable_bits == 0) { | 2369 | if (p->reachable_bits == 0) |
2342 | len_and_sockaddr *lsa = host2sockaddr(p->p_hostname, 123); | 2370 | resolve_peer_hostname(p, /*loop_on_fail=*/ 0); |
2343 | if (lsa) { | ||
2344 | char *dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); | ||
2345 | //if (strcmp(dotted, p->p_dotted) != 0) | ||
2346 | // bb_error_msg("peer IP changed"); | ||
2347 | free(p->p_lsa); | ||
2348 | free(p->p_dotted); | ||
2349 | p->p_lsa = lsa; | ||
2350 | p->p_dotted = dotted; | ||
2351 | } | ||
2352 | } | ||
2353 | 2371 | ||
2354 | set_next(p, timeout); | 2372 | set_next(p, timeout); |
2355 | } | 2373 | } |
diff --git a/networking/ping.c b/networking/ping.c index cfe682646..82d5b7a85 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -186,6 +186,7 @@ create_icmp_socket(void) | |||
186 | struct globals { | 186 | struct globals { |
187 | char *hostname; | 187 | char *hostname; |
188 | char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; | 188 | char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; |
189 | uint16_t myid; | ||
189 | } FIX_ALIASING; | 190 | } FIX_ALIASING; |
190 | #define G (*(struct globals*)bb_common_bufsiz1) | 191 | #define G (*(struct globals*)bb_common_bufsiz1) |
191 | #define INIT_G() do { setup_common_bufsiz(); } while (0) | 192 | #define INIT_G() do { setup_common_bufsiz(); } while (0) |
@@ -204,6 +205,7 @@ static void ping4(len_and_sockaddr *lsa) | |||
204 | pkt = (struct icmp *) G.packet; | 205 | pkt = (struct icmp *) G.packet; |
205 | /*memset(pkt, 0, sizeof(G.packet)); already is */ | 206 | /*memset(pkt, 0, sizeof(G.packet)); already is */ |
206 | pkt->icmp_type = ICMP_ECHO; | 207 | pkt->icmp_type = ICMP_ECHO; |
208 | pkt->icmp_id = G.myid; | ||
207 | pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, sizeof(G.packet)); | 209 | pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, sizeof(G.packet)); |
208 | 210 | ||
209 | xsendto(pingsock, G.packet, DEFDATALEN + ICMP_MINLEN, &lsa->u.sa, lsa->len); | 211 | xsendto(pingsock, G.packet, DEFDATALEN + ICMP_MINLEN, &lsa->u.sa, lsa->len); |
@@ -228,6 +230,8 @@ static void ping4(len_and_sockaddr *lsa) | |||
228 | struct iphdr *iphdr = (struct iphdr *) G.packet; | 230 | struct iphdr *iphdr = (struct iphdr *) G.packet; |
229 | 231 | ||
230 | pkt = (struct icmp *) (G.packet + (iphdr->ihl << 2)); /* skip ip hdr */ | 232 | pkt = (struct icmp *) (G.packet + (iphdr->ihl << 2)); /* skip ip hdr */ |
233 | if (pkt->icmp_id != G.myid) | ||
234 | continue; /* not our ping */ | ||
231 | if (pkt->icmp_type == ICMP_ECHOREPLY) | 235 | if (pkt->icmp_type == ICMP_ECHOREPLY) |
232 | break; | 236 | break; |
233 | } | 237 | } |
@@ -246,6 +250,7 @@ static void ping6(len_and_sockaddr *lsa) | |||
246 | pkt = (struct icmp6_hdr *) G.packet; | 250 | pkt = (struct icmp6_hdr *) G.packet; |
247 | /*memset(pkt, 0, sizeof(G.packet)); already is */ | 251 | /*memset(pkt, 0, sizeof(G.packet)); already is */ |
248 | pkt->icmp6_type = ICMP6_ECHO_REQUEST; | 252 | pkt->icmp6_type = ICMP6_ECHO_REQUEST; |
253 | pkt->icmp6_id = G.myid; | ||
249 | 254 | ||
250 | sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); | 255 | sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); |
251 | setsockopt_int(pingsock, SOL_RAW, IPV6_CHECKSUM, sockopt); | 256 | setsockopt_int(pingsock, SOL_RAW, IPV6_CHECKSUM, sockopt); |
@@ -269,6 +274,8 @@ static void ping6(len_and_sockaddr *lsa) | |||
269 | continue; | 274 | continue; |
270 | } | 275 | } |
271 | if (c >= ICMP_MINLEN) { /* icmp6_hdr */ | 276 | if (c >= ICMP_MINLEN) { /* icmp6_hdr */ |
277 | if (pkt->icmp6_id != G.myid) | ||
278 | continue; /* not our ping */ | ||
272 | if (pkt->icmp6_type == ICMP6_ECHO_REPLY) | 279 | if (pkt->icmp6_type == ICMP6_ECHO_REPLY) |
273 | break; | 280 | break; |
274 | } | 281 | } |
@@ -317,6 +324,7 @@ static int common_ping_main(sa_family_t af, char **argv) | |||
317 | alarm(5); /* give the host 5000ms to respond */ | 324 | alarm(5); /* give the host 5000ms to respond */ |
318 | 325 | ||
319 | create_icmp_socket(lsa); | 326 | create_icmp_socket(lsa); |
327 | G.myid = (uint16_t) getpid(); | ||
320 | #if ENABLE_PING6 | 328 | #if ENABLE_PING6 |
321 | if (lsa->u.sa.sa_family == AF_INET6) | 329 | if (lsa->u.sa.sa_family == AF_INET6) |
322 | ping6(lsa); | 330 | ping6(lsa); |
@@ -333,7 +341,7 @@ static int common_ping_main(sa_family_t af, char **argv) | |||
333 | 341 | ||
334 | /* Full(er) version */ | 342 | /* Full(er) version */ |
335 | 343 | ||
336 | #define OPT_STRING ("qvc:s:t:w:W:I:np:4" IF_PING6("6")) | 344 | #define OPT_STRING ("qvc:+s:t:+w:+W:+I:np:4" IF_PING6("6")) |
337 | enum { | 345 | enum { |
338 | OPT_QUIET = 1 << 0, | 346 | OPT_QUIET = 1 << 0, |
339 | OPT_VERBOSE = 1 << 1, | 347 | OPT_VERBOSE = 1 << 1, |
@@ -857,7 +865,7 @@ static int common_ping_main(int opt, char **argv) | |||
857 | INIT_G(); | 865 | INIT_G(); |
858 | 866 | ||
859 | /* exactly one argument needed; -v and -q don't mix; -c NUM, -t NUM, -w NUM, -W NUM */ | 867 | /* exactly one argument needed; -v and -q don't mix; -c NUM, -t NUM, -w NUM, -W NUM */ |
860 | opt_complementary = "=1:q--v:v--q:c+:t+:w+:W+"; | 868 | opt_complementary = "=1:q--v:v--q"; |
861 | opt |= getopt32(argv, OPT_STRING, &pingcount, &str_s, &opt_ttl, &deadline, &timeout, &str_I, &str_p); | 869 | opt |= getopt32(argv, OPT_STRING, &pingcount, &str_s, &opt_ttl, &deadline, &timeout, &str_I, &str_p); |
862 | if (opt & OPT_s) | 870 | if (opt & OPT_s) |
863 | datalen = xatou16(str_s); // -s | 871 | datalen = xatou16(str_s); // -s |
diff --git a/networking/tcpudp.c b/networking/tcpudp.c index 31bc70459..fbd1f1c45 100644 --- a/networking/tcpudp.c +++ b/networking/tcpudp.c | |||
@@ -232,9 +232,9 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv) | |||
232 | tcp = (applet_name[0] == 't'); | 232 | tcp = (applet_name[0] == 't'); |
233 | 233 | ||
234 | /* 3+ args, -i at most once, -p implies -h, -v is counter, -b N, -c N */ | 234 | /* 3+ args, -i at most once, -p implies -h, -v is counter, -b N, -c N */ |
235 | opt_complementary = "-3:i--i:ph:vv:b+:c+"; | 235 | opt_complementary = "-3:i--i:ph:vv"; |
236 | #ifdef SSLSVD | 236 | #ifdef SSLSVD |
237 | opts = getopt32(argv, "+c:C:i:x:u:l:Eb:hpt:vU:/:Z:K:", | 237 | opts = getopt32(argv, "+c:+C:i:x:u:l:Eb:+hpt:vU:/:Z:K:", |
238 | &cmax, &str_C, &instructs, &instructs, &user, &preset_local_hostname, | 238 | &cmax, &str_C, &instructs, &instructs, &user, &preset_local_hostname, |
239 | &backlog, &str_t, &ssluser, &root, &cert, &key, &verbose | 239 | &backlog, &str_t, &ssluser, &root, &cert, &key, &verbose |
240 | ); | 240 | ); |
diff --git a/networking/telnetd.c b/networking/telnetd.c index 13c36aa46..2fbdc3bb3 100644 --- a/networking/telnetd.c +++ b/networking/telnetd.c | |||
@@ -496,12 +496,12 @@ int telnetd_main(int argc UNUSED_PARAM, char **argv) | |||
496 | INIT_G(); | 496 | INIT_G(); |
497 | 497 | ||
498 | /* -w NUM, and implies -F. -w and -i don't mix */ | 498 | /* -w NUM, and implies -F. -w and -i don't mix */ |
499 | IF_FEATURE_TELNETD_INETD_WAIT(opt_complementary = "wF:w+:i--w:w--i";) | 499 | IF_FEATURE_TELNETD_INETD_WAIT(opt_complementary = "wF:i--w:w--i";) |
500 | /* Even if !STANDALONE, we accept (and ignore) -i, thus people | 500 | /* Even if !STANDALONE, we accept (and ignore) -i, thus people |
501 | * don't need to guess whether it's ok to pass -i to us */ | 501 | * don't need to guess whether it's ok to pass -i to us */ |
502 | opt = getopt32(argv, "f:l:Ki" | 502 | opt = getopt32(argv, "f:l:Ki" |
503 | IF_FEATURE_TELNETD_STANDALONE("p:b:F") | 503 | IF_FEATURE_TELNETD_STANDALONE("p:b:F") |
504 | IF_FEATURE_TELNETD_INETD_WAIT("Sw:"), | 504 | IF_FEATURE_TELNETD_INETD_WAIT("Sw:+"), |
505 | &G.issuefile, &G.loginpath | 505 | &G.issuefile, &G.loginpath |
506 | IF_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr) | 506 | IF_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr) |
507 | IF_FEATURE_TELNETD_INETD_WAIT(, &sec_linger) | 507 | IF_FEATURE_TELNETD_INETD_WAIT(, &sec_linger) |
diff --git a/networking/traceroute.c b/networking/traceroute.c index eee4f8873..e43a36dc7 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -294,7 +294,7 @@ | |||
294 | 294 | ||
295 | #define OPT_STRING \ | 295 | #define OPT_STRING \ |
296 | "FIlnrdvxt:i:m:p:q:s:w:z:f:" \ | 296 | "FIlnrdvxt:i:m:p:q:s:w:z:f:" \ |
297 | IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:") \ | 297 | IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:*") \ |
298 | "4" IF_TRACEROUTE6("6") | 298 | "4" IF_TRACEROUTE6("6") |
299 | enum { | 299 | enum { |
300 | OPT_DONT_FRAGMNT = (1 << 0), /* F */ | 300 | OPT_DONT_FRAGMNT = (1 << 0), /* F */ |
@@ -819,7 +819,7 @@ common_traceroute_main(int op, char **argv) | |||
819 | INIT_G(); | 819 | INIT_G(); |
820 | 820 | ||
821 | /* minimum 1 arg */ | 821 | /* minimum 1 arg */ |
822 | opt_complementary = "-1:x-x" IF_FEATURE_TRACEROUTE_SOURCE_ROUTE(":g::"); | 822 | opt_complementary = "-1:x-x"; |
823 | op |= getopt32(argv, OPT_STRING | 823 | op |= getopt32(argv, OPT_STRING |
824 | , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str | 824 | , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str |
825 | , &source, &waittime_str, &pausemsecs_str, &first_ttl_str | 825 | , &source, &waittime_str, &pausemsecs_str, &first_ttl_str |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index c77669a31..6ff040d9e 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c | |||
@@ -793,7 +793,11 @@ static void perform_renew(void) | |||
793 | static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6) | 793 | static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6) |
794 | { | 794 | { |
795 | /* send release packet */ | 795 | /* send release packet */ |
796 | if (state == BOUND || state == RENEWING || state == REBINDING) { | 796 | if (state == BOUND |
797 | || state == RENEWING | ||
798 | || state == REBINDING | ||
799 | || state == RENEW_REQUESTED | ||
800 | ) { | ||
797 | bb_error_msg("unicasting a release"); | 801 | bb_error_msg("unicasting a release"); |
798 | send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */ | 802 | send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */ |
799 | d6_run_script(NULL, "deconfig"); | 803 | d6_run_script(NULL, "deconfig"); |
@@ -940,9 +944,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
940 | 944 | ||
941 | /* Parse command line */ | 945 | /* Parse command line */ |
942 | /* O,x: list; -T,-t,-A take numeric param */ | 946 | /* O,x: list; -T,-t,-A take numeric param */ |
943 | opt_complementary = "O::x::T+:t+:A+" IF_UDHCP_VERBOSE(":vv") ; | 947 | IF_UDHCP_VERBOSE(opt_complementary = "vv";) |
944 | IF_LONG_OPTS(applet_long_options = udhcpc6_longopts;) | 948 | IF_LONG_OPTS(applet_long_options = udhcpc6_longopts;) |
945 | opt = getopt32(argv, "i:np:qRr:s:T:t:SA:O:ox:f" | 949 | opt = getopt32(argv, "i:np:qRr:s:T:+t:+SA:+O:*ox:*f" |
946 | USE_FOR_MMU("b") | 950 | USE_FOR_MMU("b") |
947 | ///IF_FEATURE_UDHCPC_ARPING("a") | 951 | ///IF_FEATURE_UDHCPC_ARPING("a") |
948 | IF_FEATURE_UDHCP_PORT("P:") | 952 | IF_FEATURE_UDHCP_PORT("P:") |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index fc7b6216d..8a16e987d 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -1118,7 +1118,11 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip) | |||
1118 | struct in_addr temp_addr; | 1118 | struct in_addr temp_addr; |
1119 | 1119 | ||
1120 | /* send release packet */ | 1120 | /* send release packet */ |
1121 | if (state == BOUND || state == RENEWING || state == REBINDING) { | 1121 | if (state == BOUND |
1122 | || state == RENEWING | ||
1123 | || state == REBINDING | ||
1124 | || state == RENEW_REQUESTED | ||
1125 | ) { | ||
1122 | temp_addr.s_addr = server_addr; | 1126 | temp_addr.s_addr = server_addr; |
1123 | strcpy(buffer, inet_ntoa(temp_addr)); | 1127 | strcpy(buffer, inet_ntoa(temp_addr)); |
1124 | temp_addr.s_addr = requested_ip; | 1128 | temp_addr.s_addr = requested_ip; |
@@ -1279,9 +1283,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1279 | 1283 | ||
1280 | /* Parse command line */ | 1284 | /* Parse command line */ |
1281 | /* O,x: list; -T,-t,-A take numeric param */ | 1285 | /* O,x: list; -T,-t,-A take numeric param */ |
1282 | opt_complementary = "O::x::T+:t+:A+" IF_UDHCP_VERBOSE(":vv") ; | 1286 | IF_UDHCP_VERBOSE(opt_complementary = "vv";) |
1283 | IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) | 1287 | IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) |
1284 | opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB" | 1288 | opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:+t:+SA:+O:*ox:*fB" |
1285 | USE_FOR_MMU("b") | 1289 | USE_FOR_MMU("b") |
1286 | IF_FEATURE_UDHCPC_ARPING("a::") | 1290 | IF_FEATURE_UDHCPC_ARPING("a::") |
1287 | IF_FEATURE_UDHCP_PORT("P:") | 1291 | IF_FEATURE_UDHCP_PORT("P:") |
diff --git a/networking/wget.c b/networking/wget.c index c725edb5b..c886dd391 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -1274,9 +1274,8 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") | |||
1274 | applet_long_options = wget_longopts; | 1274 | applet_long_options = wget_longopts; |
1275 | #endif | 1275 | #endif |
1276 | opt_complementary = "-1" /* at least one URL */ | 1276 | opt_complementary = "-1" /* at least one URL */ |
1277 | IF_FEATURE_WGET_TIMEOUT(":T+") /* -T NUM */ | ||
1278 | IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */ | 1277 | IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */ |
1279 | getopt32(argv, "csqO:P:Y:U:T:" | 1278 | getopt32(argv, "csqO:P:Y:U:T:+" |
1280 | /*ignored:*/ "t:" | 1279 | /*ignored:*/ "t:" |
1281 | /*ignored:*/ "n::" | 1280 | /*ignored:*/ "n::" |
1282 | /* wget has exactly four -n<letter> opts, all of which we can ignore: | 1281 | /* wget has exactly four -n<letter> opts, all of which we can ignore: |
diff --git a/networking/whois.c b/networking/whois.c index bf330334a..c9dfcf5ee 100644 --- a/networking/whois.c +++ b/networking/whois.c | |||
@@ -21,43 +21,158 @@ | |||
21 | //kbuild:lib-$(CONFIG_WHOIS) += whois.o | 21 | //kbuild:lib-$(CONFIG_WHOIS) += whois.o |
22 | 22 | ||
23 | //usage:#define whois_trivial_usage | 23 | //usage:#define whois_trivial_usage |
24 | //usage: "[-h SERVER] [-p PORT] NAME..." | 24 | //usage: "[-i] [-h SERVER] [-p PORT] NAME..." |
25 | //usage:#define whois_full_usage "\n\n" | 25 | //usage:#define whois_full_usage "\n\n" |
26 | //usage: "Query WHOIS info about NAME\n" | 26 | //usage: "Query WHOIS info about NAME\n" |
27 | //usage: "\n -i Show redirect results too" | ||
27 | //usage: "\n -h,-p Server to query" | 28 | //usage: "\n -h,-p Server to query" |
28 | 29 | ||
29 | #include "libbb.h" | 30 | #include "libbb.h" |
30 | 31 | ||
31 | static void pipe_out(int fd) | 32 | enum { |
33 | OPT_i = (1 << 0), | ||
34 | }; | ||
35 | |||
36 | static char *query(const char *host, int port, const char *domain) | ||
32 | { | 37 | { |
38 | int fd; | ||
33 | FILE *fp; | 39 | FILE *fp; |
34 | char buf[1024]; | 40 | bool success; |
41 | char *redir = NULL; | ||
42 | const char *pfx = ""; | ||
43 | char linebuf[1024]; | ||
44 | char *buf = NULL; | ||
45 | unsigned bufpos = 0; | ||
35 | 46 | ||
47 | again: | ||
48 | printf("[Querying %s:%d '%s%s']\n", host, port, pfx, domain); | ||
49 | fd = create_and_connect_stream_or_die(host, port); | ||
50 | success = 0; | ||
51 | fdprintf(fd, "%s%s\r\n", pfx, domain); | ||
36 | fp = xfdopen_for_read(fd); | 52 | fp = xfdopen_for_read(fd); |
37 | while (fgets(buf, sizeof(buf), fp)) { | ||
38 | char *p = strpbrk(buf, "\r\n"); | ||
39 | if (p) | ||
40 | *p = '\0'; | ||
41 | puts(buf); | ||
42 | } | ||
43 | 53 | ||
54 | while (fgets(linebuf, sizeof(linebuf), fp)) { | ||
55 | unsigned len = strcspn(linebuf, "\r\n"); | ||
56 | linebuf[len++] = '\n'; | ||
57 | |||
58 | buf = xrealloc(buf, bufpos + len + 1); | ||
59 | memcpy(buf + bufpos, linebuf, len); | ||
60 | bufpos += len; | ||
61 | buf[bufpos] = '\0'; | ||
62 | |||
63 | if (!redir || !success) { | ||
64 | trim(linebuf); | ||
65 | str_tolower(linebuf); | ||
66 | if (!success) { | ||
67 | success = is_prefixed_with(linebuf, "domain:") | ||
68 | || is_prefixed_with(linebuf, "domain name:"); | ||
69 | } | ||
70 | else if (!redir) { | ||
71 | char *p = is_prefixed_with(linebuf, "whois server:"); | ||
72 | if (!p) | ||
73 | p = is_prefixed_with(linebuf, "whois:"); | ||
74 | if (p) | ||
75 | redir = xstrdup(skip_whitespace(p)); | ||
76 | } | ||
77 | } | ||
78 | } | ||
44 | fclose(fp); /* closes fd too */ | 79 | fclose(fp); /* closes fd too */ |
80 | if (!success && !pfx[0]) { | ||
81 | /* | ||
82 | * Looking at /etc/jwhois.conf, some whois servers use | ||
83 | * "domain = DOMAIN", "DOMAIN ID <DOMAIN>" | ||
84 | * and "domain=DOMAIN_WITHOUT_LAST_COMPONENT" | ||
85 | * formats, but those are rare. | ||
86 | * (There are a few even more contrived ones.) | ||
87 | * We are trying only "domain DOMAIN", the typical one. | ||
88 | */ | ||
89 | pfx = "domain "; | ||
90 | bufpos = 0; | ||
91 | goto again; | ||
92 | } | ||
93 | |||
94 | /* Success */ | ||
95 | if (redir && strcmp(redir, host) == 0) { | ||
96 | /* Redirect to self does not count */ | ||
97 | free(redir); | ||
98 | redir = NULL; | ||
99 | } | ||
100 | if (!redir || (option_mask32 & OPT_i)) { | ||
101 | /* Output saved text */ | ||
102 | printf("[%s]\n%s", host, buf ? buf : ""); | ||
103 | } | ||
104 | free(buf); | ||
105 | return redir; | ||
106 | } | ||
107 | |||
108 | static void recursive_query(const char *host, int port, const char *domain) | ||
109 | { | ||
110 | char *free_me = NULL; | ||
111 | char *redir; | ||
112 | again: | ||
113 | redir = query(host, port, domain); | ||
114 | free(free_me); | ||
115 | if (redir) { | ||
116 | printf("[Redirected to %s]\n", redir); | ||
117 | host = free_me = redir; | ||
118 | port = 43; | ||
119 | goto again; | ||
120 | } | ||
45 | } | 121 | } |
46 | 122 | ||
123 | /* One of "big" whois implementations has these options: | ||
124 | * | ||
125 | * $ whois --help | ||
126 | * jwhois version 4.0, Copyright (C) 1999-2007 Free Software Foundation, Inc. | ||
127 | * -v, --verbose verbose debug output | ||
128 | * -c FILE, --config=FILE use FILE as configuration file | ||
129 | * -h HOST, --host=HOST explicitly query HOST | ||
130 | * -n, --no-redirect disable content redirection | ||
131 | * -s, --no-whoisservers disable whois-servers.net service support | ||
132 | * -a, --raw disable reformatting of the query | ||
133 | * -i, --display-redirections display all redirects instead of hiding them | ||
134 | * -p PORT, --port=PORT use port number PORT (in conjunction with HOST) | ||
135 | * -r, --rwhois force an rwhois query to be made | ||
136 | * --rwhois-display=DISPLAY sets the display option in rwhois queries | ||
137 | * --rwhois-limit=LIMIT sets the maximum number of matches to return | ||
138 | * | ||
139 | * Example of its output: | ||
140 | * $ whois cnn.com | ||
141 | * [Querying whois.verisign-grs.com] | ||
142 | * [Redirected to whois.corporatedomains.com] | ||
143 | * [Querying whois.corporatedomains.com] | ||
144 | * [whois.corporatedomains.com] | ||
145 | * ...text of the reply... | ||
146 | * | ||
147 | * With -i, reply from each server is printed, after all redirects are done: | ||
148 | * [Querying whois.verisign-grs.com] | ||
149 | * [Redirected to whois.corporatedomains.com] | ||
150 | * [Querying whois.corporatedomains.com] | ||
151 | * [whois.verisign-grs.com] | ||
152 | * ...text of the reply... | ||
153 | * [whois.corporatedomains.com] | ||
154 | * ...text of the reply... | ||
155 | * | ||
156 | * With -a, no "DOMAIN" -> "domain DOMAIN" transformation is attempted. | ||
157 | |||
158 | * With -n, the first reply is shown, redirects are not followed: | ||
159 | * [Querying whois.verisign-grs.com] | ||
160 | * [whois.verisign-grs.com] | ||
161 | * ...text of the reply... | ||
162 | */ | ||
163 | |||
47 | int whois_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 164 | int whois_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
48 | int whois_main(int argc UNUSED_PARAM, char **argv) | 165 | int whois_main(int argc UNUSED_PARAM, char **argv) |
49 | { | 166 | { |
50 | int port = 43; | 167 | int port = 43; |
51 | const char *host = "whois-servers.net"; | 168 | const char *host = "whois.iana.org"; |
52 | |||
53 | opt_complementary = "-1:p+"; | ||
54 | getopt32(argv, "h:p:", &host, &port); | ||
55 | 169 | ||
170 | opt_complementary = "-1"; | ||
171 | getopt32(argv, "ih:p:+", &host, &port); | ||
56 | argv += optind; | 172 | argv += optind; |
173 | |||
57 | do { | 174 | do { |
58 | int fd = create_and_connect_stream_or_die(host, port); | 175 | recursive_query(host, port, *argv); |
59 | fdprintf(fd, "%s\r\n", *argv); | ||
60 | pipe_out(fd); | ||
61 | } | 176 | } |
62 | while (*++argv); | 177 | while (*++argv); |
63 | 178 | ||