aboutsummaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2012-03-22 13:56:39 +0000
committerRon Yorston <rmy@pobox.com>2012-03-22 13:56:39 +0000
commit811c449748d5bd0505f8510e5582892f94ac0cda (patch)
tree2640249cb2a9605c7cd59467b9861b205e9bcc8a /networking
parentc0d4367d6b581eb5989c02815880cf0fa2851ae8 (diff)
parent19311bfa7b8e8c6effa9c375de9b0eb4338bee12 (diff)
downloadbusybox-w32-811c449748d5bd0505f8510e5582892f94ac0cda.tar.gz
busybox-w32-811c449748d5bd0505f8510e5582892f94ac0cda.tar.bz2
busybox-w32-811c449748d5bd0505f8510e5582892f94ac0cda.zip
Merge commit '19311bfa7b8e8c6effa9c375de9b0eb4338bee12' into merge
Conflicts: coreutils/ls.c shell/ash.c
Diffstat (limited to 'networking')
-rw-r--r--networking/Config.src64
-rw-r--r--networking/ftpd.c19
-rw-r--r--networking/ifupdown.c16
-rw-r--r--networking/nameif.c115
-rw-r--r--networking/nslookup.c4
-rw-r--r--networking/ping.c2
-rw-r--r--networking/route.c6
-rw-r--r--networking/udhcp/Config.src4
-rw-r--r--networking/udhcp/dhcpc.c142
-rw-r--r--networking/udhcp/dhcpc.h3
-rw-r--r--networking/wget.c36
-rw-r--r--networking/whois.c66
12 files changed, 344 insertions, 133 deletions
diff --git a/networking/Config.src b/networking/Config.src
index 274fcae3a..8aeba0ef9 100644
--- a/networking/Config.src
+++ b/networking/Config.src
@@ -51,21 +51,21 @@ config VERBOSE_RESOLUTION_ERRORS
51config ARP 51config ARP
52 bool "arp" 52 bool "arp"
53 default y 53 default y
54 depends on PLATFORM_LINUX 54 select PLATFORM_LINUX
55 help 55 help
56 Manipulate the system ARP cache. 56 Manipulate the system ARP cache.
57 57
58config ARPING 58config ARPING
59 bool "arping" 59 bool "arping"
60 default y 60 default y
61 depends on PLATFORM_LINUX 61 select PLATFORM_LINUX
62 help 62 help
63 Ping hosts by ARP packets. 63 Ping hosts by ARP packets.
64 64
65config BRCTL 65config BRCTL
66 bool "brctl" 66 bool "brctl"
67 default y 67 default y
68 depends on PLATFORM_LINUX 68 select PLATFORM_LINUX
69 help 69 help
70 Manage ethernet bridges. 70 Manage ethernet bridges.
71 Supports addbr/delbr and addif/delif. 71 Supports addbr/delbr and addif/delif.
@@ -98,7 +98,7 @@ config DNSD
98config ETHER_WAKE 98config ETHER_WAKE
99 bool "ether-wake" 99 bool "ether-wake"
100 default y 100 default y
101 depends on PLATFORM_LINUX 101 select PLATFORM_LINUX
102 help 102 help
103 Send a magic packet to wake up sleeping machines. 103 Send a magic packet to wake up sleeping machines.
104 104
@@ -281,7 +281,7 @@ config FEATURE_HTTPD_GZIP
281config IFCONFIG 281config IFCONFIG
282 bool "ifconfig" 282 bool "ifconfig"
283 default y 283 default y
284 depends on PLATFORM_LINUX 284 select PLATFORM_LINUX
285 help 285 help
286 Ifconfig is used to configure the kernel-resident network interfaces. 286 Ifconfig is used to configure the kernel-resident network interfaces.
287 287
@@ -329,7 +329,7 @@ config FEATURE_IFCONFIG_BROADCAST_PLUS
329config IFENSLAVE 329config IFENSLAVE
330 bool "ifenslave" 330 bool "ifenslave"
331 default y 331 default y
332 depends on PLATFORM_LINUX 332 select PLATFORM_LINUX
333 help 333 help
334 Userspace application to bind several interfaces 334 Userspace application to bind several interfaces
335 to a logical interface (use with kernel bonding driver). 335 to a logical interface (use with kernel bonding driver).
@@ -337,7 +337,7 @@ config IFENSLAVE
337config IFPLUGD 337config IFPLUGD
338 bool "ifplugd" 338 bool "ifplugd"
339 default y 339 default y
340 depends on PLATFORM_LINUX 340 select PLATFORM_LINUX
341 help 341 help
342 Network interface plug detection daemon. 342 Network interface plug detection daemon.
343 343
@@ -379,7 +379,8 @@ config FEATURE_IFUPDOWN_IP
379config FEATURE_IFUPDOWN_IP_BUILTIN 379config FEATURE_IFUPDOWN_IP_BUILTIN
380 bool "Use busybox ip applet" 380 bool "Use busybox ip applet"
381 default y 381 default y
382 depends on FEATURE_IFUPDOWN_IP && PLATFORM_LINUX 382 depends on FEATURE_IFUPDOWN_IP
383 select PLATFORM_LINUX
383 select IP 384 select IP
384 select FEATURE_IP_ADDRESS 385 select FEATURE_IP_ADDRESS
385 select FEATURE_IP_LINK 386 select FEATURE_IP_LINK
@@ -498,7 +499,7 @@ config FEATURE_INETD_RPC
498config IP 499config IP
499 bool "ip" 500 bool "ip"
500 default y 501 default y
501 depends on PLATFORM_LINUX 502 select PLATFORM_LINUX
502 help 503 help
503 The "ip" applet is a TCP/IP interface configuration and routing 504 The "ip" applet is a TCP/IP interface configuration and routing
504 utility. You generally don't need "ip" to use busybox with 505 utility. You generally don't need "ip" to use busybox with
@@ -611,39 +612,10 @@ config FEATURE_IPCALC_LONG_OPTIONS
611 help 612 help
612 Support long options for the ipcalc applet. 613 Support long options for the ipcalc applet.
613 614
614config NAMEIF
615 bool "nameif"
616 default y
617 depends on PLATFORM_LINUX
618 select FEATURE_SYSLOG
619 help
620 nameif is used to rename network interface by its MAC address.
621 Renamed interfaces MUST be in the down state.
622 It is possible to use a file (default: /etc/mactab)
623 with list of new interface names and MACs.
624 Maximum interface name length: IFNAMSIZ = 16
625 File fields are separated by space or tab.
626 File format:
627 # Comment
628 new_interface_name XX:XX:XX:XX:XX:XX
629
630config FEATURE_NAMEIF_EXTENDED
631 bool "Extended nameif"
632 default y
633 depends on NAMEIF
634 help
635 This extends the nameif syntax to support the bus_info and driver
636 checks. The syntax is compatible to the normal nameif.
637 File format:
638 new_interface_name driver=asix bus=usb-0000:00:08.2-3
639 new_interface_name bus=usb-0000:00:08.2-3 00:80:C8:38:91:B5
640 new_interface_name mac=00:80:C8:38:91:B5
641 new_interface_name 00:80:C8:38:91:B5
642
643config NETSTAT 615config NETSTAT
644 bool "netstat" 616 bool "netstat"
645 default y 617 default y
646 depends on PLATFORM_LINUX 618 select PLATFORM_LINUX
647 help 619 help
648 netstat prints information about the Linux networking subsystem. 620 netstat prints information about the Linux networking subsystem.
649 621
@@ -672,7 +644,7 @@ config NSLOOKUP
672config NTPD 644config NTPD
673 bool "ntpd" 645 bool "ntpd"
674 default y 646 default y
675 depends on PLATFORM_LINUX 647 select PLATFORM_LINUX
676 help 648 help
677 The NTP client/server daemon. 649 The NTP client/server daemon.
678 650
@@ -693,14 +665,14 @@ config PSCAN
693config ROUTE 665config ROUTE
694 bool "route" 666 bool "route"
695 default y 667 default y
696 depends on PLATFORM_LINUX 668 select PLATFORM_LINUX
697 help 669 help
698 Route displays or manipulates the kernel's IP routing tables. 670 Route displays or manipulates the kernel's IP routing tables.
699 671
700config SLATTACH 672config SLATTACH
701 bool "slattach" 673 bool "slattach"
702 default y 674 default y
703 depends on PLATFORM_LINUX 675 select PLATFORM_LINUX
704 help 676 help
705 slattach is a small utility to attach network interfaces to serial 677 slattach is a small utility to attach network interfaces to serial
706 lines. 678 lines.
@@ -887,7 +859,7 @@ config TFTP_DEBUG
887config TRACEROUTE 859config TRACEROUTE
888 bool "traceroute" 860 bool "traceroute"
889 default y 861 default y
890 depends on PLATFORM_LINUX 862 select PLATFORM_LINUX
891 help 863 help
892 Utility to trace the route of IP packets. 864 Utility to trace the route of IP packets.
893 865
@@ -924,7 +896,7 @@ config FEATURE_TRACEROUTE_USE_ICMP
924config TUNCTL 896config TUNCTL
925 bool "tunctl" 897 bool "tunctl"
926 default y 898 default y
927 depends on PLATFORM_LINUX 899 select PLATFORM_LINUX
928 help 900 help
929 tunctl creates or deletes tun devices. 901 tunctl creates or deletes tun devices.
930 902
@@ -957,7 +929,7 @@ config UDPSVD
957config VCONFIG 929config VCONFIG
958 bool "vconfig" 930 bool "vconfig"
959 default y 931 default y
960 depends on PLATFORM_LINUX 932 select PLATFORM_LINUX
961 help 933 help
962 Creates, removes, and configures VLAN interfaces 934 Creates, removes, and configures VLAN interfaces
963 935
@@ -1004,7 +976,7 @@ config FEATURE_WGET_TIMEOUT
1004config ZCIP 976config ZCIP
1005 bool "zcip" 977 bool "zcip"
1006 default y 978 default y
1007 depends on PLATFORM_LINUX 979 select PLATFORM_LINUX
1008 select FEATURE_SYSLOG 980 select FEATURE_SYSLOG
1009 help 981 help
1010 ZCIP provides ZeroConf IPv4 address selection, according to RFC 3927. 982 ZCIP provides ZeroConf IPv4 address selection, according to RFC 3927.
diff --git a/networking/ftpd.c b/networking/ftpd.c
index 64068e467..b59135667 100644
--- a/networking/ftpd.c
+++ b/networking/ftpd.c
@@ -12,6 +12,23 @@
12 * You have to run this daemon via inetd. 12 * You have to run this daemon via inetd.
13 */ 13 */
14 14
15//usage:#define ftpd_trivial_usage
16//usage: "[-wvS] [-t N] [-T N] [DIR]"
17//usage:#define ftpd_full_usage "\n\n"
18//usage: "Anonymous FTP server\n"
19//usage: "\n"
20//usage: "ftpd should be used as an inetd service.\n"
21//usage: "ftpd's line for inetd.conf:\n"
22//usage: " 21 stream tcp nowait root ftpd ftpd /files/to/serve\n"
23//usage: "It also can be ran from tcpsvd:\n"
24//usage: " tcpsvd -vE 0.0.0.0 21 ftpd /files/to/serve\n"
25//usage: "\nOptions:"
26//usage: "\n -w Allow upload"
27//usage: "\n -v Log errors to stderr. -vv: verbose log"
28//usage: "\n -S Log errors to syslog. -SS: verbose log"
29//usage: "\n -t,-T Idle and absolute timeouts"
30//usage: "\n DIR Change root to this directory"
31
15#include "libbb.h" 32#include "libbb.h"
16#include <syslog.h> 33#include <syslog.h>
17#include <netinet/tcp.h> 34#include <netinet/tcp.h>
@@ -206,7 +223,7 @@ cmdio_write_error(unsigned status)
206{ 223{
207 *(uint32_t *) G.msg_err = status; 224 *(uint32_t *) G.msg_err = status;
208 xwrite(STDOUT_FILENO, G.msg_err, sizeof("NNN " MSG_ERR) - 1); 225 xwrite(STDOUT_FILENO, G.msg_err, sizeof("NNN " MSG_ERR) - 1);
209 if (G.verbose > 1) 226 if (G.verbose > 0)
210 verbose_log(G.msg_err); 227 verbose_log(G.msg_err);
211} 228}
212#define WRITE_ERR(a) cmdio_write_error(STRNUM32sp(a)) 229#define WRITE_ERR(a) cmdio_write_error(STRNUM32sp(a))
diff --git a/networking/ifupdown.c b/networking/ifupdown.c
index 59df4e80f..7706a84b7 100644
--- a/networking/ifupdown.c
+++ b/networking/ifupdown.c
@@ -106,6 +106,7 @@ enum {
106struct globals { 106struct globals {
107 char **my_environ; 107 char **my_environ;
108 const char *startup_PATH; 108 const char *startup_PATH;
109 char *shell;
109} FIX_ALIASING; 110} FIX_ALIASING;
110#define G (*(struct globals*)&bb_common_bufsiz1) 111#define G (*(struct globals*)&bb_common_bufsiz1)
111#define INIT_G() do { } while (0) 112#define INIT_G() do { } while (0)
@@ -986,11 +987,10 @@ static int doit(char *str)
986 987
987 fflush_all(); 988 fflush_all();
988 child = vfork(); 989 child = vfork();
989 switch (child) { 990 if (child < 0) /* failure */
990 case -1: /* failure */
991 return 0; 991 return 0;
992 case 0: /* child */ 992 if (child == 0) { /* child */
993 execle(DEFAULT_SHELL, DEFAULT_SHELL, "-c", str, (char *) NULL, G.my_environ); 993 execle(G.shell, G.shell, "-c", str, (char *) NULL, G.my_environ);
994 _exit(127); 994 _exit(127);
995 } 995 }
996 safe_waitpid(child, &status, 0); 996 safe_waitpid(child, &status, 0);
@@ -1165,6 +1165,7 @@ int ifupdown_main(int argc UNUSED_PARAM, char **argv)
1165 INIT_G(); 1165 INIT_G();
1166 1166
1167 G.startup_PATH = getenv("PATH"); 1167 G.startup_PATH = getenv("PATH");
1168 G.shell = xstrdup(get_shell_name());
1168 1169
1169 cmds = iface_down; 1170 cmds = iface_down;
1170 if (applet_name[2] == 'u') { 1171 if (applet_name[2] == 'u') {
@@ -1220,13 +1221,13 @@ int ifupdown_main(int argc UNUSED_PARAM, char **argv)
1220 /* ifup */ 1221 /* ifup */
1221 if (iface_state) { 1222 if (iface_state) {
1222 bb_error_msg("interface %s already configured", iface); 1223 bb_error_msg("interface %s already configured", iface);
1223 continue; 1224 goto next;
1224 } 1225 }
1225 } else { 1226 } else {
1226 /* ifdown */ 1227 /* ifdown */
1227 if (!iface_state) { 1228 if (!iface_state) {
1228 bb_error_msg("interface %s not configured", iface); 1229 bb_error_msg("interface %s not configured", iface);
1229 continue; 1230 goto next;
1230 } 1231 }
1231 } 1232 }
1232 llist_free(state_list, free); 1233 llist_free(state_list, free);
@@ -1316,6 +1317,9 @@ int ifupdown_main(int argc UNUSED_PARAM, char **argv)
1316 fclose(state_fp); 1317 fclose(state_fp);
1317 llist_free(state_list, free); 1318 llist_free(state_list, free);
1318 } 1319 }
1320 next:
1321 free(iface);
1322 free(liface);
1319 } 1323 }
1320 1324
1321 return any_failures; 1325 return any_failures;
diff --git a/networking/nameif.c b/networking/nameif.c
index d02c2c11b..78719edac 100644
--- a/networking/nameif.c
+++ b/networking/nameif.c
@@ -10,6 +10,66 @@
10 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 10 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
11 */ 11 */
12 12
13//config:config NAMEIF
14//config: bool "nameif"
15//config: default y
16//config: select PLATFORM_LINUX
17//config: select FEATURE_SYSLOG
18//config: help
19//config: nameif is used to rename network interface by its MAC address.
20//config: Renamed interfaces MUST be in the down state.
21//config: It is possible to use a file (default: /etc/mactab)
22//config: with list of new interface names and MACs.
23//config: Maximum interface name length: IFNAMSIZ = 16
24//config: File fields are separated by space or tab.
25//config: File format:
26//config: # Comment
27//config: new_interface_name XX:XX:XX:XX:XX:XX
28//config:
29//config:config FEATURE_NAMEIF_EXTENDED
30//config: bool "Extended nameif"
31//config: default y
32//config: depends on NAMEIF
33//config: help
34//config: This extends the nameif syntax to support the bus_info, driver,
35//config: phyaddr selectors. The syntax is compatible to the normal nameif.
36//config: File format:
37//config: new_interface_name driver=asix bus=usb-0000:00:08.2-3
38//config: new_interface_name bus=usb-0000:00:08.2-3 00:80:C8:38:91:B5
39//config: new_interface_name phy_address=2 00:80:C8:38:91:B5
40//config: new_interface_name mac=00:80:C8:38:91:B5
41//config: new_interface_name 00:80:C8:38:91:B5
42
43//usage:#define nameif_trivial_usage
44//usage: IF_NOT_FEATURE_NAMEIF_EXTENDED(
45//usage: "[-s] [-c FILE] [IFNAME HWADDR]..."
46//usage: )
47//usage: IF_FEATURE_NAMEIF_EXTENDED(
48//usage: "[-s] [-c FILE] [IFNAME SELECTOR]..."
49//usage: )
50//usage:#define nameif_full_usage "\n\n"
51//usage: "Rename network interface while it in the down state."
52//usage: IF_NOT_FEATURE_NAMEIF_EXTENDED(
53//usage: "\nThe device with address HWADDR is renamed to IFACE."
54//usage: )
55//usage: IF_FEATURE_NAMEIF_EXTENDED(
56//usage: "\nThe device matched by SELECTOR is renamed to IFACE."
57//usage: "\nSELECTOR can be a combination of:"
58//usage: "\n driver=STRING"
59//usage: "\n bus=STRING"
60//usage: "\n phy_address=NUM"
61//usage: "\n [mac=]XX:XX:XX:XX:XX:XX"
62//usage: )
63//usage: "\n"
64//usage: "\nOptions:"
65//usage: "\n -c FILE Configuration file (default: /etc/mactab)"
66//usage: "\n -s Log to syslog"
67//usage:
68//usage:#define nameif_example_usage
69//usage: "$ nameif -s dmz0 00:A0:C9:8C:F6:3F\n"
70//usage: " or\n"
71//usage: "$ nameif -c /etc/my_mactab_file\n"
72
13#include "libbb.h" 73#include "libbb.h"
14#include <syslog.h> 74#include <syslog.h>
15#include <net/if.h> 75#include <net/if.h>
@@ -38,6 +98,7 @@ typedef struct ethtable_s {
38#if ENABLE_FEATURE_NAMEIF_EXTENDED 98#if ENABLE_FEATURE_NAMEIF_EXTENDED
39 char *bus_info; 99 char *bus_info;
40 char *driver; 100 char *driver;
101 int32_t phy_address;
41#endif 102#endif
42} ethtable_t; 103} ethtable_t;
43 104
@@ -59,6 +120,25 @@ struct ethtool_drvinfo {
59 uint32_t eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */ 120 uint32_t eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */
60 uint32_t regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */ 121 uint32_t regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */
61}; 122};
123
124struct ethtool_cmd {
125 __u32 cmd;
126 __u32 supported; /* Features this interface supports */
127 __u32 advertising; /* Features this interface advertises */
128 __u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */
129 __u8 duplex; /* Duplex, half or full */
130 __u8 port; /* Which connector port */
131 __u8 phy_address;
132 __u8 transceiver; /* Which transceiver to use */
133 __u8 autoneg; /* Enable or disable autonegotiation */
134 __u32 maxtxpkt; /* Tx pkts before generating tx int */
135 __u32 maxrxpkt; /* Rx pkts before generating rx int */
136 __u16 speed_hi;
137 __u16 reserved2;
138 __u32 reserved[3];
139};
140
141#define ETHTOOL_GSET 0x00000001 /* Get settings. */
62#define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */ 142#define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */
63#endif 143#endif
64 144
@@ -74,6 +154,7 @@ static void nameif_parse_selector(ethtable_t *ch, char *selector)
74#endif 154#endif
75 selector = skip_whitespace(selector); 155 selector = skip_whitespace(selector);
76#if ENABLE_FEATURE_NAMEIF_EXTENDED 156#if ENABLE_FEATURE_NAMEIF_EXTENDED
157 ch->phy_address = -1;
77 if (*selector == '\0') 158 if (*selector == '\0')
78 break; 159 break;
79 /* Search for the end .... */ 160 /* Search for the end .... */
@@ -87,6 +168,9 @@ static void nameif_parse_selector(ethtable_t *ch, char *selector)
87 } else if (strncmp(selector, "driver=", 7) == 0) { 168 } else if (strncmp(selector, "driver=", 7) == 0) {
88 ch->driver = xstrdup(selector + 7); 169 ch->driver = xstrdup(selector + 7);
89 found_selector++; 170 found_selector++;
171 } else if (strncmp(selector, "phyaddr=", 8) == 0) {
172 ch->phy_address = xatoi_positive(selector + 8);
173 found_selector++;
90 } else { 174 } else {
91#endif 175#endif
92 lmac = xmalloc(ETH_ALEN); 176 lmac = xmalloc(ETH_ALEN);
@@ -133,7 +217,7 @@ void delete_eth_table(ethtable_t *ch);
133#endif 217#endif
134 218
135int nameif_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 219int nameif_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
136int nameif_main(int argc, char **argv) 220int nameif_main(int argc UNUSED_PARAM, char **argv)
137{ 221{
138 ethtable_t *clist = NULL; 222 ethtable_t *clist = NULL;
139 const char *fname = "/etc/mactab"; 223 const char *fname = "/etc/mactab";
@@ -148,17 +232,15 @@ int nameif_main(int argc, char **argv)
148 * can't hurt. 2>/dev/null if you don't like it: */ 232 * can't hurt. 2>/dev/null if you don't like it: */
149 logmode |= LOGMODE_SYSLOG; 233 logmode |= LOGMODE_SYSLOG;
150 } 234 }
151 argc -= optind;
152 argv += optind; 235 argv += optind;
153 236
154 if (argc & 1) 237 if (argv[0]) {
155 bb_show_usage(); 238 do {
156 239 if (!argv[1])
157 if (argc) { 240 bb_show_usage();
158 while (*argv) { 241 prepend_new_eth_table(&clist, argv[0], argv[1]);
159 char *ifname = xstrdup(*argv++); 242 argv += 2;
160 prepend_new_eth_table(&clist, ifname, *argv++); 243 } while (*argv);
161 }
162 } else { 244 } else {
163 parser = config_open(fname); 245 parser = config_open(fname);
164 while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) 246 while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL))
@@ -173,8 +255,9 @@ int nameif_main(int argc, char **argv)
173 struct ifreq ifr; 255 struct ifreq ifr;
174#if ENABLE_FEATURE_NAMEIF_EXTENDED 256#if ENABLE_FEATURE_NAMEIF_EXTENDED
175 struct ethtool_drvinfo drvinfo; 257 struct ethtool_drvinfo drvinfo;
258 struct ethtool_cmd eth_settings;
176#endif 259#endif
177 if (parser->lineno < 2) 260 if (parser->lineno <= 2)
178 continue; /* Skip the first two lines */ 261 continue; /* Skip the first two lines */
179 262
180 /* Find the current interface name and copy it to ifr.ifr_name */ 263 /* Find the current interface name and copy it to ifr.ifr_name */
@@ -182,8 +265,14 @@ int nameif_main(int argc, char **argv)
182 strncpy_IFNAMSIZ(ifr.ifr_name, token[0]); 265 strncpy_IFNAMSIZ(ifr.ifr_name, token[0]);
183 266
184#if ENABLE_FEATURE_NAMEIF_EXTENDED 267#if ENABLE_FEATURE_NAMEIF_EXTENDED
268 /* Check for phy address */
269 memset(&eth_settings, 0, sizeof(eth_settings));
270 eth_settings.cmd = ETHTOOL_GSET;
271 ifr.ifr_data = (caddr_t) &eth_settings;
272 ioctl(ctl_sk, SIOCETHTOOL, &ifr);
273
185 /* Check for driver etc. */ 274 /* Check for driver etc. */
186 memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo)); 275 memset(&drvinfo, 0, sizeof(drvinfo));
187 drvinfo.cmd = ETHTOOL_GDRVINFO; 276 drvinfo.cmd = ETHTOOL_GDRVINFO;
188 ifr.ifr_data = (caddr_t) &drvinfo; 277 ifr.ifr_data = (caddr_t) &drvinfo;
189 /* Get driver and businfo first, so we have it in drvinfo */ 278 /* Get driver and businfo first, so we have it in drvinfo */
@@ -198,6 +287,8 @@ int nameif_main(int argc, char **argv)
198 continue; 287 continue;
199 if (ch->driver && strcmp(ch->driver, drvinfo.driver) != 0) 288 if (ch->driver && strcmp(ch->driver, drvinfo.driver) != 0)
200 continue; 289 continue;
290 if (ch->phy_address != -1 && ch->phy_address != eth_settings.phy_address)
291 continue;
201#endif 292#endif
202 if (ch->mac && memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN) != 0) 293 if (ch->mac && memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN) != 0)
203 continue; 294 continue;
diff --git a/networking/nslookup.c b/networking/nslookup.c
index dcac7379e..67fc01547 100644
--- a/networking/nslookup.c
+++ b/networking/nslookup.c
@@ -66,7 +66,7 @@ static int print_host(const char *hostname, const char *header)
66 // hint.ai_flags = AI_CANONNAME; 66 // hint.ai_flags = AI_CANONNAME;
67 rc = getaddrinfo(hostname, NULL /*service*/, &hint, &result); 67 rc = getaddrinfo(hostname, NULL /*service*/, &hint, &result);
68 68
69 if (!rc) { 69 if (rc == 0) {
70 struct addrinfo *cur = result; 70 struct addrinfo *cur = result;
71 unsigned cnt = 0; 71 unsigned cnt = 0;
72 72
@@ -94,7 +94,7 @@ static int print_host(const char *hostname, const char *header)
94 bb_error_msg("can't resolve '%s'", hostname); 94 bb_error_msg("can't resolve '%s'", hostname);
95#endif 95#endif
96 } 96 }
97 if (ENABLE_FEATURE_CLEAN_UP) 97 if (ENABLE_FEATURE_CLEAN_UP && result)
98 freeaddrinfo(result); 98 freeaddrinfo(result);
99 return (rc != 0); 99 return (rc != 0);
100} 100}
diff --git a/networking/ping.c b/networking/ping.c
index c2ff42e2c..7a9c2d1f0 100644
--- a/networking/ping.c
+++ b/networking/ping.c
@@ -32,7 +32,7 @@
32//config:config PING 32//config:config PING
33//config: bool "ping" 33//config: bool "ping"
34//config: default y 34//config: default y
35//config: depends on PLATFORM_LINUX 35//config: select PLATFORM_LINUX
36//config: help 36//config: help
37//config: ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to 37//config: ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to
38//config: elicit an ICMP ECHO_RESPONSE from a host or gateway. 38//config: elicit an ICMP ECHO_RESPONSE from a host or gateway.
diff --git a/networking/route.c b/networking/route.c
index b7d08dd63..98a03ded7 100644
--- a/networking/route.c
+++ b/networking/route.c
@@ -537,6 +537,7 @@ void FAST_FUNC bb_displayroutes(int noresolve, int netstatfmt)
537 printf("%-6d %-2d %7d %s\n", metric, ref, use, devname); 537 printf("%-6d %-2d %7d %s\n", metric, ref, use, devname);
538 } 538 }
539 } 539 }
540 fclose(fp);
540} 541}
541 542
542#if ENABLE_FEATURE_IPV6 543#if ENABLE_FEATURE_IPV6
@@ -604,7 +605,7 @@ static void INET6_displayroutes(void)
604 set_flags(flags, (iflags & IPV6_MASK)); 605 set_flags(flags, (iflags & IPV6_MASK));
605 606
606 r = 0; 607 r = 0;
607 do { 608 while (1) {
608 inet_pton(AF_INET6, addr6x + r, 609 inet_pton(AF_INET6, addr6x + r,
609 (struct sockaddr *) &snaddr6.sin6_addr); 610 (struct sockaddr *) &snaddr6.sin6_addr);
610 snaddr6.sin6_family = AF_INET6; 611 snaddr6.sin6_family = AF_INET6;
@@ -623,8 +624,9 @@ static void INET6_displayroutes(void)
623 free(naddr6); 624 free(naddr6);
624 break; 625 break;
625 } 626 }
626 } while (1); 627 }
627 } 628 }
629 fclose(fp);
628} 630}
629 631
630#endif 632#endif
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src
index 750a53a32..9cd8cbbae 100644
--- a/networking/udhcp/Config.src
+++ b/networking/udhcp/Config.src
@@ -8,7 +8,7 @@ INSERT
8config UDHCPD 8config UDHCPD
9 bool "udhcp server (udhcpd)" 9 bool "udhcp server (udhcpd)"
10 default y 10 default y
11 depends on PLATFORM_LINUX 11 select PLATFORM_LINUX
12 help 12 help
13 udhcpd is a DHCP server geared primarily toward embedded systems, 13 udhcpd is a DHCP server geared primarily toward embedded systems,
14 while striving to be fully functional and RFC compliant. 14 while striving to be fully functional and RFC compliant.
@@ -66,7 +66,7 @@ config DHCPD_LEASES_FILE
66config UDHCPC 66config UDHCPC
67 bool "udhcp client (udhcpc)" 67 bool "udhcp client (udhcpc)"
68 default y 68 default y
69 depends on PLATFORM_LINUX 69 select PLATFORM_LINUX
70 help 70 help
71 udhcpc is a DHCP client geared primarily toward embedded systems, 71 udhcpc is a DHCP client geared primarily toward embedded systems,
72 while striving to be fully functional and RFC compliant. 72 while striving to be fully functional and RFC compliant.
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index d97a404fa..ca82d37e6 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -38,6 +38,67 @@
38/* struct client_config_t client_config is in bb_common_bufsiz1 */ 38/* struct client_config_t client_config is in bb_common_bufsiz1 */
39 39
40 40
41#if ENABLE_LONG_OPTS
42static const char udhcpc_longopts[] ALIGN1 =
43 "clientid-none\0" No_argument "C"
44 "vendorclass\0" Required_argument "V"
45 "hostname\0" Required_argument "H"
46 "fqdn\0" Required_argument "F"
47 "interface\0" Required_argument "i"
48 "now\0" No_argument "n"
49 "pidfile\0" Required_argument "p"
50 "quit\0" No_argument "q"
51 "release\0" No_argument "R"
52 "request\0" Required_argument "r"
53 "script\0" Required_argument "s"
54 "timeout\0" Required_argument "T"
55 "version\0" No_argument "v"
56 "retries\0" Required_argument "t"
57 "tryagain\0" Required_argument "A"
58 "syslog\0" No_argument "S"
59 "request-option\0" Required_argument "O"
60 "no-default-options\0" No_argument "o"
61 "foreground\0" No_argument "f"
62 "background\0" No_argument "b"
63 "broadcast\0" No_argument "B"
64 IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a")
65 IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P")
66 ;
67#endif
68/* Must match getopt32 option string order */
69enum {
70 OPT_C = 1 << 0,
71 OPT_V = 1 << 1,
72 OPT_H = 1 << 2,
73 OPT_h = 1 << 3,
74 OPT_F = 1 << 4,
75 OPT_i = 1 << 5,
76 OPT_n = 1 << 6,
77 OPT_p = 1 << 7,
78 OPT_q = 1 << 8,
79 OPT_R = 1 << 9,
80 OPT_r = 1 << 10,
81 OPT_s = 1 << 11,
82 OPT_T = 1 << 12,
83 OPT_t = 1 << 13,
84 OPT_S = 1 << 14,
85 OPT_A = 1 << 15,
86 OPT_O = 1 << 16,
87 OPT_o = 1 << 17,
88 OPT_x = 1 << 18,
89 OPT_f = 1 << 19,
90 OPT_B = 1 << 20,
91/* The rest has variable bit positions, need to be clever */
92 OPTBIT_B = 20,
93 USE_FOR_MMU( OPTBIT_b,)
94 IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,)
95 IF_FEATURE_UDHCP_PORT( OPTBIT_P,)
96 USE_FOR_MMU( OPT_b = 1 << OPTBIT_b,)
97 IF_FEATURE_UDHCPC_ARPING(OPT_a = 1 << OPTBIT_a,)
98 IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,)
99};
100
101
41/*** Script execution code ***/ 102/*** Script execution code ***/
42 103
43/* get a rough idea of how long an option will be (rounding up...) */ 104/* get a rough idea of how long an option will be (rounding up...) */
@@ -346,11 +407,19 @@ static ALWAYS_INLINE uint32_t random_xid(void)
346/* Initialize the packet with the proper defaults */ 407/* Initialize the packet with the proper defaults */
347static void init_packet(struct dhcp_packet *packet, char type) 408static void init_packet(struct dhcp_packet *packet, char type)
348{ 409{
410 uint16_t secs;
411
349 /* Fill in: op, htype, hlen, cookie fields; message type option: */ 412 /* Fill in: op, htype, hlen, cookie fields; message type option: */
350 udhcp_init_header(packet, type); 413 udhcp_init_header(packet, type);
351 414
352 packet->xid = random_xid(); 415 packet->xid = random_xid();
353 416
417 client_config.last_secs = monotonic_sec();
418 if (client_config.first_secs == 0)
419 client_config.first_secs = client_config.last_secs;
420 secs = client_config.last_secs - client_config.first_secs;
421 packet->secs = htons(secs);
422
354 memcpy(packet->chaddr, client_config.client_mac, 6); 423 memcpy(packet->chaddr, client_config.client_mac, 6);
355 if (client_config.clientid) 424 if (client_config.clientid)
356 udhcp_add_binary_option(packet, client_config.clientid); 425 udhcp_add_binary_option(packet, client_config.clientid);
@@ -391,6 +460,10 @@ static void add_client_options(struct dhcp_packet *packet)
391 if (client_config.fqdn) 460 if (client_config.fqdn)
392 udhcp_add_binary_option(packet, client_config.fqdn); 461 udhcp_add_binary_option(packet, client_config.fqdn);
393 462
463 /* Request broadcast replies if we have no IP addr */
464 if ((option_mask32 & OPT_B) && packet->ciaddr == 0)
465 packet->flags |= htons(BROADCAST_FLAG);
466
394 /* Add -x options if any */ 467 /* Add -x options if any */
395 { 468 {
396 struct option_set *curr = client_config.options; 469 struct option_set *curr = client_config.options;
@@ -783,6 +856,7 @@ static void change_listen_mode(int new_mode)
783 /* else LISTEN_NONE: sockfd stays closed */ 856 /* else LISTEN_NONE: sockfd stays closed */
784} 857}
785 858
859/* Called only on SIGUSR1 */
786static void perform_renew(void) 860static void perform_renew(void)
787{ 861{
788 bb_info_msg("Performing a DHCP renew"); 862 bb_info_msg("Performing a DHCP renew");
@@ -853,13 +927,14 @@ static void client_background(void)
853//usage:# define IF_UDHCP_VERBOSE(...) 927//usage:# define IF_UDHCP_VERBOSE(...)
854//usage:#endif 928//usage:#endif
855//usage:#define udhcpc_trivial_usage 929//usage:#define udhcpc_trivial_usage
856//usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"oCR] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n" 930//usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"oCRB] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n"
857//usage: " [-H HOSTNAME] [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]") 931//usage: " [-H HOSTNAME] [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]")
858//usage:#define udhcpc_full_usage "\n" 932//usage:#define udhcpc_full_usage "\n"
859//usage: IF_LONG_OPTS( 933//usage: IF_LONG_OPTS(
860//usage: "\n -i,--interface IFACE Interface to use (default eth0)" 934//usage: "\n -i,--interface IFACE Interface to use (default eth0)"
861//usage: "\n -p,--pidfile FILE Create pidfile" 935//usage: "\n -p,--pidfile FILE Create pidfile"
862//usage: "\n -s,--script PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" 936//usage: "\n -s,--script PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"
937//usage: "\n -B,--broadcast Request broadcast replies"
863//usage: "\n -t,--retries N Send up to N discover packets" 938//usage: "\n -t,--retries N Send up to N discover packets"
864//usage: "\n -T,--timeout N Pause between packets (default 3 seconds)" 939//usage: "\n -T,--timeout N Pause between packets (default 3 seconds)"
865//usage: "\n -A,--tryagain N Wait N seconds after failure (default 20)" 940//usage: "\n -A,--tryagain N Wait N seconds after failure (default 20)"
@@ -897,6 +972,7 @@ static void client_background(void)
897//usage: "\n -i IFACE Interface to use (default eth0)" 972//usage: "\n -i IFACE Interface to use (default eth0)"
898//usage: "\n -p FILE Create pidfile" 973//usage: "\n -p FILE Create pidfile"
899//usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" 974//usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"
975//usage: "\n -B Request broadcast replies"
900//usage: "\n -t N Send up to N discover packets" 976//usage: "\n -t N Send up to N discover packets"
901//usage: "\n -T N Pause between packets (default 3 seconds)" 977//usage: "\n -T N Pause between packets (default 3 seconds)"
902//usage: "\n -A N Wait N seconds (default 20) after failure" 978//usage: "\n -A N Wait N seconds (default 20) after failure"
@@ -961,63 +1037,6 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
961 struct dhcp_packet packet; 1037 struct dhcp_packet packet;
962 fd_set rfds; 1038 fd_set rfds;
963 1039
964#if ENABLE_LONG_OPTS
965 static const char udhcpc_longopts[] ALIGN1 =
966 "clientid-none\0" No_argument "C"
967 "vendorclass\0" Required_argument "V"
968 "hostname\0" Required_argument "H"
969 "fqdn\0" Required_argument "F"
970 "interface\0" Required_argument "i"
971 "now\0" No_argument "n"
972 "pidfile\0" Required_argument "p"
973 "quit\0" No_argument "q"
974 "release\0" No_argument "R"
975 "request\0" Required_argument "r"
976 "script\0" Required_argument "s"
977 "timeout\0" Required_argument "T"
978 "version\0" No_argument "v"
979 "retries\0" Required_argument "t"
980 "tryagain\0" Required_argument "A"
981 "syslog\0" No_argument "S"
982 "request-option\0" Required_argument "O"
983 "no-default-options\0" No_argument "o"
984 "foreground\0" No_argument "f"
985 "background\0" No_argument "b"
986 IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a")
987 IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P")
988 ;
989#endif
990 enum {
991 OPT_C = 1 << 0,
992 OPT_V = 1 << 1,
993 OPT_H = 1 << 2,
994 OPT_h = 1 << 3,
995 OPT_F = 1 << 4,
996 OPT_i = 1 << 5,
997 OPT_n = 1 << 6,
998 OPT_p = 1 << 7,
999 OPT_q = 1 << 8,
1000 OPT_R = 1 << 9,
1001 OPT_r = 1 << 10,
1002 OPT_s = 1 << 11,
1003 OPT_T = 1 << 12,
1004 OPT_t = 1 << 13,
1005 OPT_S = 1 << 14,
1006 OPT_A = 1 << 15,
1007 OPT_O = 1 << 16,
1008 OPT_o = 1 << 17,
1009 OPT_x = 1 << 18,
1010 OPT_f = 1 << 19,
1011/* The rest has variable bit positions, need to be clever */
1012 OPTBIT_f = 19,
1013 USE_FOR_MMU( OPTBIT_b,)
1014 IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,)
1015 IF_FEATURE_UDHCP_PORT( OPTBIT_P,)
1016 USE_FOR_MMU( OPT_b = 1 << OPTBIT_b,)
1017 IF_FEATURE_UDHCPC_ARPING(OPT_a = 1 << OPTBIT_a,)
1018 IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,)
1019 };
1020
1021 /* Default options */ 1040 /* Default options */
1022 IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) 1041 IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;)
1023 IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) 1042 IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;)
@@ -1033,7 +1052,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1033#endif 1052#endif
1034 ; 1053 ;
1035 IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) 1054 IF_LONG_OPTS(applet_long_options = udhcpc_longopts;)
1036 opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:f" 1055 opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB"
1037 USE_FOR_MMU("b") 1056 USE_FOR_MMU("b")
1038 IF_FEATURE_UDHCPC_ARPING("a") 1057 IF_FEATURE_UDHCPC_ARPING("a")
1039 IF_FEATURE_UDHCP_PORT("P:") 1058 IF_FEATURE_UDHCP_PORT("P:")
@@ -1250,6 +1269,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1250 case BOUND: 1269 case BOUND:
1251 /* 1/2 lease passed, enter renewing state */ 1270 /* 1/2 lease passed, enter renewing state */
1252 state = RENEWING; 1271 state = RENEWING;
1272 client_config.first_secs = 0; /* make secs field count from 0 */
1253 change_listen_mode(LISTEN_KERNEL); 1273 change_listen_mode(LISTEN_KERNEL);
1254 log1("Entering renew state"); 1274 log1("Entering renew state");
1255 /* fall right through */ 1275 /* fall right through */
@@ -1289,6 +1309,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1289 bb_info_msg("Lease lost, entering init state"); 1309 bb_info_msg("Lease lost, entering init state");
1290 udhcp_run_script(NULL, "deconfig"); 1310 udhcp_run_script(NULL, "deconfig");
1291 state = INIT_SELECTING; 1311 state = INIT_SELECTING;
1312 client_config.first_secs = 0; /* make secs field count from 0 */
1292 /*timeout = 0; - already is */ 1313 /*timeout = 0; - already is */
1293 packet_num = 0; 1314 packet_num = 0;
1294 continue; 1315 continue;
@@ -1305,6 +1326,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1305 /* note: udhcp_sp_read checks FD_ISSET before reading */ 1326 /* note: udhcp_sp_read checks FD_ISSET before reading */
1306 switch (udhcp_sp_read(&rfds)) { 1327 switch (udhcp_sp_read(&rfds)) {
1307 case SIGUSR1: 1328 case SIGUSR1:
1329 client_config.first_secs = 0; /* make secs field count from 0 */
1308 perform_renew(); 1330 perform_renew();
1309 if (state == RENEW_REQUESTED) 1331 if (state == RENEW_REQUESTED)
1310 goto case_RENEW_REQUESTED; 1332 goto case_RENEW_REQUESTED;
@@ -1436,6 +1458,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1436 udhcp_run_script(NULL, "deconfig"); 1458 udhcp_run_script(NULL, "deconfig");
1437 change_listen_mode(LISTEN_RAW); 1459 change_listen_mode(LISTEN_RAW);
1438 state = INIT_SELECTING; 1460 state = INIT_SELECTING;
1461 client_config.first_secs = 0; /* make secs field count from 0 */
1439 requested_ip = 0; 1462 requested_ip = 0;
1440 timeout = tryagain_timeout; 1463 timeout = tryagain_timeout;
1441 packet_num = 0; 1464 packet_num = 0;
@@ -1483,6 +1506,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1483 change_listen_mode(LISTEN_RAW); 1506 change_listen_mode(LISTEN_RAW);
1484 sleep(3); /* avoid excessive network traffic */ 1507 sleep(3); /* avoid excessive network traffic */
1485 state = INIT_SELECTING; 1508 state = INIT_SELECTING;
1509 client_config.first_secs = 0; /* make secs field count from 0 */
1486 requested_ip = 0; 1510 requested_ip = 0;
1487 timeout = 0; 1511 timeout = 0;
1488 packet_num = 0; 1512 packet_num = 0;
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h
index 9ef053a1b..2b3599120 100644
--- a/networking/udhcp/dhcpc.h
+++ b/networking/udhcp/dhcpc.h
@@ -21,6 +21,9 @@ struct client_config_t {
21 uint8_t *vendorclass; /* Optional vendor class-id to use */ 21 uint8_t *vendorclass; /* Optional vendor class-id to use */
22 uint8_t *hostname; /* Optional hostname to use */ 22 uint8_t *hostname; /* Optional hostname to use */
23 uint8_t *fqdn; /* Optional fully qualified domain name to use */ 23 uint8_t *fqdn; /* Optional fully qualified domain name to use */
24
25 uint16_t first_secs;
26 uint16_t last_secs;
24} FIX_ALIASING; 27} FIX_ALIASING;
25 28
26/* server_config sits in 1st half of bb_common_bufsiz1 */ 29/* server_config sits in 1st half of bb_common_bufsiz1 */
diff --git a/networking/wget.c b/networking/wget.c
index bbc161be8..41ec7f6dc 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -8,6 +8,32 @@
8 * Copyright (C) 2010 Bradley M. Kuhn <bkuhn@ebb.org> 8 * Copyright (C) 2010 Bradley M. Kuhn <bkuhn@ebb.org>
9 * Kuhn's copyrights are licensed GPLv2-or-later. File as a whole remains GPLv2. 9 * Kuhn's copyrights are licensed GPLv2-or-later. File as a whole remains GPLv2.
10 */ 10 */
11
12//usage:#define wget_trivial_usage
13//usage: IF_FEATURE_WGET_LONG_OPTIONS(
14//usage: "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n"
15//usage: " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n"
16//usage: " [--no-check-certificate] [-U|--user-agent AGENT]"
17//usage: IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..."
18//usage: )
19//usage: IF_NOT_FEATURE_WGET_LONG_OPTIONS(
20//usage: "[-csq] [-O FILE] [-Y on/off] [-P DIR] [-U AGENT]"
21//usage: IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..."
22//usage: )
23//usage:#define wget_full_usage "\n\n"
24//usage: "Retrieve files via HTTP or FTP\n"
25//usage: "\nOptions:"
26//usage: "\n -s Spider mode - only check file existence"
27//usage: "\n -c Continue retrieval of aborted transfer"
28//usage: "\n -q Quiet"
29//usage: "\n -P DIR Save to DIR (default .)"
30//usage: IF_FEATURE_WGET_TIMEOUT(
31//usage: "\n -T SEC Network read timeout is SEC seconds"
32//usage: )
33//usage: "\n -O FILE Save to FILE ('-' for stdout)"
34//usage: "\n -U STR Use STR for User-Agent header"
35//usage: "\n -Y Use proxy ('on' or 'off')"
36
11#include "libbb.h" 37#include "libbb.h"
12 38
13//#define log_io(...) bb_error_msg(__VA_ARGS__) 39//#define log_io(...) bb_error_msg(__VA_ARGS__)
@@ -604,8 +630,14 @@ static void download_one_url(const char *url)
604 if (G.fname_out[0] == '/' || !G.fname_out[0]) 630 if (G.fname_out[0] == '/' || !G.fname_out[0])
605 G.fname_out = (char*)"index.html"; 631 G.fname_out = (char*)"index.html";
606 /* -P DIR is considered only if there was no -O FILE */ 632 /* -P DIR is considered only if there was no -O FILE */
607 if (G.dir_prefix) 633 else {
608 G.fname_out = fname_out_alloc = concat_path_file(G.dir_prefix, G.fname_out); 634 if (G.dir_prefix)
635 G.fname_out = fname_out_alloc = concat_path_file(G.dir_prefix, G.fname_out);
636 else {
637 /* redirects may free target.path later, need to make a copy */
638 G.fname_out = fname_out_alloc = xstrdup(G.fname_out);
639 }
640 }
609 } 641 }
610#if ENABLE_FEATURE_WGET_STATUSBAR 642#if ENABLE_FEATURE_WGET_STATUSBAR
611 G.curfile = bb_get_last_path_component_nostrip(G.fname_out); 643 G.curfile = bb_get_last_path_component_nostrip(G.fname_out);
diff --git a/networking/whois.c b/networking/whois.c
new file mode 100644
index 000000000..4eab9e5fe
--- /dev/null
+++ b/networking/whois.c
@@ -0,0 +1,66 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * whois - tiny client for the whois directory service
4 *
5 * Copyright (c) 2011 Pere Orga <gotrunks@gmail.com>
6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
7 */
8/* TODO
9 * Add ipv6 support
10 * Add proxy support
11 */
12
13//config:config WHOIS
14//config: bool "whois"
15//config: default y
16//config: help
17//config: whois is a client for the whois directory service
18
19//applet:IF_WHOIS(APPLET(whois, BB_DIR_USR_BIN, BB_SUID_DROP))
20
21//kbuild:lib-$(CONFIG_WHOIS) += whois.o
22
23//usage:#define whois_trivial_usage
24//usage: "[-h SERVER] [-p PORT] NAME..."
25//usage:#define whois_full_usage "\n\n"
26//usage: "Query WHOIS info about NAME\n"
27//usage: "\nOptions:"
28//usage: "\n -h,-p Server to query"
29
30#include "libbb.h"
31
32static void pipe_out(int fd)
33{
34 FILE *fp;
35 char buf[1024];
36
37 fp = xfdopen_for_read(fd);
38 while (fgets(buf, sizeof(buf), fp)) {
39 char *p = strpbrk(buf, "\r\n");
40 if (p)
41 *p = '\0';
42 puts(buf);
43 }
44
45 fclose(fp); /* closes fd too */
46}
47
48int whois_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
49int whois_main(int argc UNUSED_PARAM, char **argv)
50{
51 int port = 43;
52 const char *host = "whois-servers.net";
53
54 opt_complementary = "-1:p+";
55 getopt32(argv, "h:p:", &host, &port);
56
57 argv += optind;
58 do {
59 int fd = create_and_connect_stream_or_die(host, port);
60 fdprintf(fd, "%s\r\n", *argv);
61 pipe_out(fd);
62 }
63 while (*++argv);
64
65 return EXIT_SUCCESS;
66}