aboutsummaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-09-10 14:37:07 +0100
committerRon Yorston <rmy@pobox.com>2018-09-10 14:59:33 +0100
commitd89ced75b204f0eb5611f522864beb81d1b393f5 (patch)
tree5daa31427e287fe079a0ef551097753773fdb266 /networking
parentf72845d9332fa6311a46dbcad3180d5008182982 (diff)
parent05b18065ab9c375f6185b65a3631d4c6cc1a4be9 (diff)
downloadbusybox-w32-d89ced75b204f0eb5611f522864beb81d1b393f5.tar.gz
busybox-w32-d89ced75b204f0eb5611f522864beb81d1b393f5.tar.bz2
busybox-w32-d89ced75b204f0eb5611f522864beb81d1b393f5.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'networking')
-rw-r--r--networking/ip.c6
-rw-r--r--networking/nslookup.c104
-rw-r--r--networking/ntpd.c37
-rw-r--r--networking/ping.c28
-rw-r--r--networking/udhcp/dhcpc.c16
-rw-r--r--networking/whois.c14
6 files changed, 148 insertions, 57 deletions
diff --git a/networking/ip.c b/networking/ip.c
index 9ecb99abb..97d618cd9 100644
--- a/networking/ip.c
+++ b/networking/ip.c
@@ -267,8 +267,7 @@
267//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79 267//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79
268//usage:#define iptunnel_trivial_usage 268//usage:#define iptunnel_trivial_usage
269//usage: "add|change|del|show [NAME]\n" 269//usage: "add|change|del|show [NAME]\n"
270//usage: " [mode ipip|gre|sit]\n" 270//usage: " [mode ipip|gre|sit] [remote ADDR] [local ADDR] [ttl TTL]"
271//usage: " [remote ADDR] [local ADDR] [ttl TTL]"
272//usage:#define iptunnel_full_usage "\n\n" 271//usage:#define iptunnel_full_usage "\n\n"
273//usage: "iptunnel add|change|del|show [NAME]\n" 272//usage: "iptunnel add|change|del|show [NAME]\n"
274//usage: " [mode ipip|gre|sit] [remote ADDR] [local ADDR]\n" 273//usage: " [mode ipip|gre|sit] [remote ADDR] [local ADDR]\n"
@@ -308,10 +307,9 @@
308//usage: IF_FEATURE_IP_TUNNEL( IP_BAR_TUNNEL"tunnel") 307//usage: IF_FEATURE_IP_TUNNEL( IP_BAR_TUNNEL"tunnel")
309//usage: IF_FEATURE_IP_NEIGH( IP_BAR_NEIGH "neigh") 308//usage: IF_FEATURE_IP_NEIGH( IP_BAR_NEIGH "neigh")
310//usage: IF_FEATURE_IP_RULE( IP_BAR_RULE "rule") 309//usage: IF_FEATURE_IP_RULE( IP_BAR_RULE "rule")
311//usage: " [COMMAND]" 310//usage: " [ARGS]"
312//usage:#define ip_full_usage "\n\n" 311//usage:#define ip_full_usage "\n\n"
313//usage: "OPTIONS := -f[amily] inet|inet6|link | -o[neline]\n" 312//usage: "OPTIONS := -f[amily] inet|inet6|link | -o[neline]\n"
314//usage: "COMMAND :="
315//usage: IF_FEATURE_IP_ADDRESS("\n" 313//usage: IF_FEATURE_IP_ADDRESS("\n"
316//usage: "ip addr "ipaddr_trivial_usage) 314//usage: "ip addr "ipaddr_trivial_usage)
317//usage: IF_FEATURE_IP_ROUTE("\n" 315//usage: IF_FEATURE_IP_ROUTE("\n"
diff --git a/networking/nslookup.c b/networking/nslookup.c
index 3a614b0c6..e153eb585 100644
--- a/networking/nslookup.c
+++ b/networking/nslookup.c
@@ -318,6 +318,8 @@ struct globals {
318 unsigned serv_count; 318 unsigned serv_count;
319 struct ns *server; 319 struct ns *server;
320 struct query *query; 320 struct query *query;
321 char *search;
322 smalluint have_search_directive;
321} FIX_ALIASING; 323} FIX_ALIASING;
322#define G (*(struct globals*)bb_common_bufsiz1) 324#define G (*(struct globals*)bb_common_bufsiz1)
323#define INIT_G() do { \ 325#define INIT_G() do { \
@@ -667,24 +669,60 @@ static void parse_resolvconf(void)
667 669
668 resolv = fopen("/etc/resolv.conf", "r"); 670 resolv = fopen("/etc/resolv.conf", "r");
669 if (resolv) { 671 if (resolv) {
670 char line[128], *p; 672 char line[512]; /* "search" is defined to be up to 256 chars */
671 673
672 while (fgets(line, sizeof(line), resolv)) { 674 while (fgets(line, sizeof(line), resolv)) {
673 p = strtok(line, " \t\n"); 675 char *p, *arg;
674 676
675 if (!p || strcmp(p, "nameserver") != 0) 677 p = strtok(line, " \t\n");
678 if (!p)
679 continue;
680 dbg("resolv_key:'%s'\n", p);
681 arg = strtok(NULL, "\n");
682 dbg("resolv_arg:'%s'\n", arg);
683 if (!arg)
676 continue; 684 continue;
677 685
678 p = strtok(NULL, " \t\n"); 686 if (strcmp(p, "domain") == 0) {
687 /* domain DOM */
688 if (!G.have_search_directive)
689 goto set_search;
690 continue;
691 }
692 if (strcmp(p, "search") == 0) {
693 /* search DOM1 DOM2... */
694 G.have_search_directive = 1;
695 set_search:
696 free(G.search);
697 G.search = xstrdup(arg);
698 dbg("search='%s'\n", G.search);
699 continue;
700 }
679 701
680 if (!p) 702 if (strcmp(p, "nameserver") != 0)
681 continue; 703 continue;
682 704
683 add_ns(xstrdup(p)); 705 /* nameserver DNS */
706 add_ns(xstrdup(arg));
684 } 707 }
685 708
686 fclose(resolv); 709 fclose(resolv);
687 } 710 }
711
712 if (!G.search) {
713 /* default search domain is domain part of hostname */
714 char *h = safe_gethostname();
715 char *d = strchr(h, '.');
716 if (d) {
717 G.search = d + 1;
718 dbg("search='%s' (from hostname)\n", G.search);
719 }
720 /* else free(h); */
721 }
722
723 /* Cater for case of "domain ." in resolv.conf */
724 if (G.search && LONE_CHAR(G.search, '.'))
725 G.search = NULL;
688} 726}
689 727
690static void add_query(int type, const char *dname) 728static void add_query(int type, const char *dname)
@@ -695,7 +733,7 @@ static void add_query(int type, const char *dname)
695 733
696 count = G.query_count++; 734 count = G.query_count++;
697 735
698 G.query = xrealloc_vector(G.query, /*2=2^1:*/ 1, count); 736 G.query = xrealloc_vector(G.query, /*4=2^2:*/ 2, count);
699 new_q = &G.query[count]; 737 new_q = &G.query[count];
700 738
701 dbg("new query#%u type %u for '%s'\n", count, type, dname); 739 dbg("new query#%u type %u for '%s'\n", count, type, dname);
@@ -709,6 +747,28 @@ static void add_query(int type, const char *dname)
709 new_q->qlen = qlen; 747 new_q->qlen = qlen;
710} 748}
711 749
750static void add_query_with_search(int type, const char *dname)
751{
752 char *s;
753
754 if (type == T_PTR || !G.search || strchr(dname, '.')) {
755 add_query(type, dname);
756 return;
757 }
758
759 s = G.search;
760 for (;;) {
761 char *fullname, *e;
762
763 e = skip_non_whitespace(s);
764 fullname = xasprintf("%s.%.*s", dname, (int)(e - s), s);
765 add_query(type, fullname);
766 s = skip_whitespace(e);
767 if (!*s)
768 break;
769 }
770}
771
712static char *make_ptr(const char *addrstr) 772static char *make_ptr(const char *addrstr)
713{ 773{
714 unsigned char addr[16]; 774 unsigned char addr[16];
@@ -833,6 +893,18 @@ int nslookup_main(int argc UNUSED_PARAM, char **argv)
833 } 893 }
834 } 894 }
835 895
896 /* Use given DNS server if present */
897 if (argv[1]) {
898 if (argv[2])
899 bb_show_usage();
900 add_ns(argv[1]);
901 } else {
902 parse_resolvconf();
903 /* Fall back to localhost if we could not find NS in resolv.conf */
904 if (G.serv_count == 0)
905 add_ns("127.0.0.1");
906 }
907
836 if (types == 0) { 908 if (types == 0) {
837 /* No explicit type given, guess query type. 909 /* No explicit type given, guess query type.
838 * If we can convert the domain argument into a ptr (means that 910 * If we can convert the domain argument into a ptr (means that
@@ -846,31 +918,19 @@ int nslookup_main(int argc UNUSED_PARAM, char **argv)
846 if (ptr) { 918 if (ptr) {
847 add_query(T_PTR, ptr); 919 add_query(T_PTR, ptr);
848 } else { 920 } else {
849 add_query(T_A, argv[0]); 921 add_query_with_search(T_A, argv[0]);
850#if ENABLE_FEATURE_IPV6 922#if ENABLE_FEATURE_IPV6
851 add_query(T_AAAA, argv[0]); 923 add_query_with_search(T_AAAA, argv[0]);
852#endif 924#endif
853 } 925 }
854 } else { 926 } else {
855 int c; 927 int c;
856 for (c = 0; c < ARRAY_SIZE(qtypes); c++) { 928 for (c = 0; c < ARRAY_SIZE(qtypes); c++) {
857 if (types & (1 << c)) 929 if (types & (1 << c))
858 add_query(qtypes[c].type, argv[0]); 930 add_query_with_search(qtypes[c].type, argv[0]);
859 } 931 }
860 } 932 }
861 933
862 /* Use given DNS server if present */
863 if (argv[1]) {
864 if (argv[2])
865 bb_show_usage();
866 add_ns(argv[1]);
867 } else {
868 parse_resolvconf();
869 /* Fall back to localhost if we could not find NS in resolv.conf */
870 if (G.serv_count == 0)
871 add_ns("127.0.0.1");
872 }
873
874 for (rc = 0; rc < G.serv_count;) { 934 for (rc = 0; rc < G.serv_count;) {
875 int c; 935 int c;
876 936
diff --git a/networking/ntpd.c b/networking/ntpd.c
index 7b800369e..991c518f6 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -149,8 +149,8 @@
149 */ 149 */
150 150
151#define INITIAL_SAMPLES 4 /* how many samples do we want for init */ 151#define INITIAL_SAMPLES 4 /* how many samples do we want for init */
152#define MIN_FREQHOLD 10 /* adjust offset, but not freq in this many first adjustments */ 152#define MIN_FREQHOLD 12 /* adjust offset, but not freq in this many first adjustments */
153#define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this */ 153#define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this factor */
154 154
155#define RETRY_INTERVAL 32 /* on send/recv error, retry in N secs (need to be power of 2) */ 155#define RETRY_INTERVAL 32 /* on send/recv error, retry in N secs (need to be power of 2) */
156#define NOREPLY_INTERVAL 512 /* sent, but got no reply: cap next query by this many seconds */ 156#define NOREPLY_INTERVAL 512 /* sent, but got no reply: cap next query by this many seconds */
@@ -1777,9 +1777,9 @@ update_local_clock(peer_t *p)
1777//15:31:53.473 update from:<IP> offset:+0.000007 delay:0.158142 jitter:0.010922 clock drift:+9.343ppm tc:6 1777//15:31:53.473 update from:<IP> offset:+0.000007 delay:0.158142 jitter:0.010922 clock drift:+9.343ppm tc:6
1778//15:32:58.902 update from:<IP> offset:-0.000728 delay:0.158222 jitter:0.009454 clock drift:+9.298ppm tc:6 1778//15:32:58.902 update from:<IP> offset:-0.000728 delay:0.158222 jitter:0.009454 clock drift:+9.298ppm tc:6
1779 /* 1779 /*
1780 * This expression would choose MIN_FREQHOLD + 7 in the above example. 1780 * This expression would choose MIN_FREQHOLD + 8 in the above example.
1781 */ 1781 */
1782 G.FREQHOLD_cnt = MIN_FREQHOLD + ((unsigned)(abs(tmx.offset)) >> 16); 1782 G.FREQHOLD_cnt = 1 + MIN_FREQHOLD + ((unsigned)(abs(tmx.offset)) >> 16);
1783 } 1783 }
1784 G.FREQHOLD_cnt--; 1784 G.FREQHOLD_cnt--;
1785 tmx.status |= STA_FREQHOLD; 1785 tmx.status |= STA_FREQHOLD;
@@ -1819,7 +1819,7 @@ update_local_clock(peer_t *p)
1819 VERB2 bb_error_msg("update from:%s offset:%+f delay:%f jitter:%f clock drift:%+.3fppm tc:%d", 1819 VERB2 bb_error_msg("update from:%s offset:%+f delay:%f jitter:%f clock drift:%+.3fppm tc:%d",
1820 p->p_dotted, 1820 p->p_dotted,
1821 offset, 1821 offset,
1822 p->lastpkt_delay, 1822 p->p_raw_delay,
1823 G.discipline_jitter, 1823 G.discipline_jitter,
1824 (double)tmx.freq / 65536, 1824 (double)tmx.freq / 65536,
1825 (int)tmx.constant 1825 (int)tmx.constant
@@ -1976,27 +1976,30 @@ recv_and_process_peer_pkt(peer_t *p)
1976 T2 = lfp_to_d(msg.m_rectime); 1976 T2 = lfp_to_d(msg.m_rectime);
1977 T3 = lfp_to_d(msg.m_xmttime); 1977 T3 = lfp_to_d(msg.m_xmttime);
1978 T4 = G.cur_time; 1978 T4 = G.cur_time;
1979
1980 /* The delay calculation is a special case. In cases where the
1981 * server and client clocks are running at different rates and
1982 * with very fast networks, the delay can appear negative. In
1983 * order to avoid violating the Principle of Least Astonishment,
1984 * the delay is clamped not less than the system precision.
1985 */
1986 delay = (T4 - T1) - (T3 - T2); 1979 delay = (T4 - T1) - (T3 - T2);
1987 if (delay < G_precision_sec) 1980
1988 delay = G_precision_sec;
1989 /* 1981 /*
1990 * If this packet's delay is much bigger than the last one, 1982 * If this packet's delay is much bigger than the last one,
1991 * it's better to just ignore it than use its much less precise value. 1983 * it's better to just ignore it than use its much less precise value.
1992 */ 1984 */
1993 prev_delay = p->p_raw_delay; 1985 prev_delay = p->p_raw_delay;
1994 p->p_raw_delay = delay; 1986 p->p_raw_delay = (delay < 0 ? 0.0 : delay);
1995 if (p->reachable_bits && delay > prev_delay * BAD_DELAY_GROWTH) { 1987 if (p->reachable_bits
1988 && delay > prev_delay * BAD_DELAY_GROWTH
1989 && delay > 1.0 / (8 * 1024) /* larger than ~0.000122 */
1990 ) {
1996 bb_error_msg("reply from %s: delay %f is too high, ignoring", p->p_dotted, delay); 1991 bb_error_msg("reply from %s: delay %f is too high, ignoring", p->p_dotted, delay);
1997 goto pick_normal_interval; 1992 goto pick_normal_interval;
1998 } 1993 }
1999 1994
1995 /* The delay calculation is a special case. In cases where the
1996 * server and client clocks are running at different rates and
1997 * with very fast networks, the delay can appear negative. In
1998 * order to avoid violating the Principle of Least Astonishment,
1999 * the delay is clamped not less than the system precision.
2000 */
2001 if (delay < G_precision_sec)
2002 delay = G_precision_sec;
2000 p->lastpkt_delay = delay; 2003 p->lastpkt_delay = delay;
2001 p->lastpkt_recv_time = T4; 2004 p->lastpkt_recv_time = T4;
2002 VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); 2005 VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time);
@@ -2024,7 +2027,7 @@ recv_and_process_peer_pkt(peer_t *p)
2024 bb_error_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x", 2027 bb_error_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x",
2025 p->p_dotted, 2028 p->p_dotted,
2026 offset, 2029 offset,
2027 p->lastpkt_delay, 2030 p->p_raw_delay,
2028 p->lastpkt_status, 2031 p->lastpkt_status,
2029 p->lastpkt_stratum, 2032 p->lastpkt_stratum,
2030 p->lastpkt_refid, 2033 p->lastpkt_refid,
diff --git a/networking/ping.c b/networking/ping.c
index 8f85d3ec2..570184fee 100644
--- a/networking/ping.c
+++ b/networking/ping.c
@@ -74,6 +74,7 @@
74//usage: ) 74//usage: )
75//usage: "\n -c CNT Send only CNT pings" 75//usage: "\n -c CNT Send only CNT pings"
76//usage: "\n -s SIZE Send SIZE data bytes in packets (default 56)" 76//usage: "\n -s SIZE Send SIZE data bytes in packets (default 56)"
77//usage: "\n -i SECS Interval"
77//usage: "\n -A Ping as soon as reply is recevied" 78//usage: "\n -A Ping as soon as reply is recevied"
78//usage: "\n -t TTL Set TTL" 79//usage: "\n -t TTL Set TTL"
79//usage: "\n -I IFACE/IP Source interface or IP address" 80//usage: "\n -I IFACE/IP Source interface or IP address"
@@ -91,6 +92,7 @@
91//usage: "Send ICMP ECHO_REQUEST packets to network hosts\n" 92//usage: "Send ICMP ECHO_REQUEST packets to network hosts\n"
92//usage: "\n -c CNT Send only CNT pings" 93//usage: "\n -c CNT Send only CNT pings"
93//usage: "\n -s SIZE Send SIZE data bytes in packets (default 56)" 94//usage: "\n -s SIZE Send SIZE data bytes in packets (default 56)"
95//usage: "\n -i SECS Interval"
94//usage: "\n -A Ping as soon as reply is recevied" 96//usage: "\n -A Ping as soon as reply is recevied"
95//usage: "\n -I IFACE/IP Source interface or IP address" 97//usage: "\n -I IFACE/IP Source interface or IP address"
96//usage: "\n -q Quiet, only display output at start" 98//usage: "\n -q Quiet, only display output at start"
@@ -350,7 +352,7 @@ static int common_ping_main(sa_family_t af, char **argv)
350/* Full(er) version */ 352/* Full(er) version */
351 353
352/* -c NUM, -t NUM, -w NUM, -W NUM */ 354/* -c NUM, -t NUM, -w NUM, -W NUM */
353#define OPT_STRING "qvAc:+s:t:+w:+W:+I:np:4"IF_PING6("6") 355#define OPT_STRING "qvAc:+s:t:+w:+W:+I:np:i:4"IF_PING6("6")
354enum { 356enum {
355 OPT_QUIET = 1 << 0, 357 OPT_QUIET = 1 << 0,
356 OPT_VERBOSE = 1 << 1, 358 OPT_VERBOSE = 1 << 1,
@@ -363,8 +365,9 @@ enum {
363 OPT_I = 1 << 8, 365 OPT_I = 1 << 8,
364 /*OPT_n = 1 << 9, - ignored */ 366 /*OPT_n = 1 << 9, - ignored */
365 OPT_p = 1 << 10, 367 OPT_p = 1 << 10,
366 OPT_IPV4 = 1 << 11, 368 OPT_i = 1 << 11,
367 OPT_IPV6 = (1 << 12) * ENABLE_PING6, 369 OPT_IPV4 = 1 << 12,
370 OPT_IPV6 = (1 << 13) * ENABLE_PING6,
368}; 371};
369 372
370 373
@@ -382,6 +385,7 @@ struct globals {
382 unsigned long long tsum; /* in us, sum of all times */ 385 unsigned long long tsum; /* in us, sum of all times */
383 unsigned cur_us; /* low word only, we don't need more */ 386 unsigned cur_us; /* low word only, we don't need more */
384 unsigned deadline_us; 387 unsigned deadline_us;
388 unsigned interval_us;
385 unsigned timeout; 389 unsigned timeout;
386 unsigned sizeof_rcv_packet; 390 unsigned sizeof_rcv_packet;
387 char *rcv_packet; /* [datalen + MAXIPLEN + MAXICMPLEN] */ 391 char *rcv_packet; /* [datalen + MAXIPLEN + MAXICMPLEN] */
@@ -481,9 +485,15 @@ static void sendping_tail(void (*sp)(int), int size_pkt)
481 bb_error_msg_and_die(bb_msg_write_error); 485 bb_error_msg_and_die(bb_msg_write_error);
482 486
483 if (pingcount == 0 || G.ntransmitted < pingcount) { 487 if (pingcount == 0 || G.ntransmitted < pingcount) {
484 /* Didn't send all pings yet - schedule next in 1s */ 488 /* Didn't send all pings yet - schedule next in -i SEC interval */
489 struct itimerval i;
485 signal(SIGALRM, sp); 490 signal(SIGALRM, sp);
486 alarm(PINGINTERVAL); 491 /*ualarm(G.interval_us, 0); - does not work for >=1sec on some libc */
492 i.it_interval.tv_sec = 0;
493 i.it_interval.tv_usec = 0;
494 i.it_value.tv_sec = G.interval_us / 1000000;
495 i.it_value.tv_usec = G.interval_us % 1000000;
496 setitimer(ITIMER_REAL, &i, NULL);
487 } else { /* -c NN, and all NN are sent */ 497 } else { /* -c NN, and all NN are sent */
488 /* Wait for the last ping to come back. 498 /* Wait for the last ping to come back.
489 * -W timeout: wait for a response in seconds. 499 * -W timeout: wait for a response in seconds.
@@ -885,6 +895,8 @@ static int common_ping_main(int opt, char **argv)
885{ 895{
886 len_and_sockaddr *lsa; 896 len_and_sockaddr *lsa;
887 char *str_s, *str_p; 897 char *str_s, *str_p;
898 char *str_i = (char*)"1";
899 duration_t interval;
888 900
889 INIT_G(); 901 INIT_G();
890 902
@@ -892,7 +904,7 @@ static int common_ping_main(int opt, char **argv)
892 OPT_STRING 904 OPT_STRING
893 /* exactly one arg; -v and -q don't mix */ 905 /* exactly one arg; -v and -q don't mix */
894 "\0" "=1:q--v:v--q", 906 "\0" "=1:q--v:v--q",
895 &pingcount, &str_s, &opt_ttl, &G.deadline_us, &timeout, &str_I, &str_p 907 &pingcount, &str_s, &opt_ttl, &G.deadline_us, &timeout, &str_I, &str_p, &str_i
896 ); 908 );
897 if (opt & OPT_s) 909 if (opt & OPT_s)
898 datalen = xatou16(str_s); // -s 910 datalen = xatou16(str_s); // -s
@@ -910,6 +922,10 @@ static int common_ping_main(int opt, char **argv)
910 unsigned d = G.deadline_us < INT_MAX/1000000 ? G.deadline_us : INT_MAX/1000000; 922 unsigned d = G.deadline_us < INT_MAX/1000000 ? G.deadline_us : INT_MAX/1000000;
911 G.deadline_us = 1 | ((d * 1000000) + monotonic_us()); 923 G.deadline_us = 1 | ((d * 1000000) + monotonic_us());
912 } 924 }
925 interval = parse_duration_str(str_i);
926 if (interval > INT_MAX/1000000)
927 interval = INT_MAX/1000000;
928 G.interval_us = interval * 1000000;
913 929
914 myid = (uint16_t) getpid(); 930 myid = (uint16_t) getpid();
915 hostname = argv[optind]; 931 hostname = argv[optind];
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index c2805a009..0310663e0 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -160,8 +160,8 @@ static int mton(uint32_t mask)
160 160
161#if ENABLE_FEATURE_UDHCPC_SANITIZEOPT 161#if ENABLE_FEATURE_UDHCPC_SANITIZEOPT
162/* Check if a given label represents a valid DNS label 162/* Check if a given label represents a valid DNS label
163 * Return pointer to the first character after the label upon success, 163 * Return pointer to the first character after the label
164 * NULL otherwise. 164 * (NUL or dot) upon success, NULL otherwise.
165 * See RFC1035, 2.3.1 165 * See RFC1035, 2.3.1
166 */ 166 */
167/* We don't need to be particularly anal. For example, allowing _, hyphen 167/* We don't need to be particularly anal. For example, allowing _, hyphen
@@ -173,8 +173,10 @@ static int mton(uint32_t mask)
173static const char *valid_domain_label(const char *label) 173static const char *valid_domain_label(const char *label)
174{ 174{
175 unsigned char ch; 175 unsigned char ch;
176 unsigned pos = 0; 176 //unsigned pos = 0;
177 177
178 if (label[0] == '-')
179 return NULL;
178 for (;;) { 180 for (;;) {
179 ch = *label; 181 ch = *label;
180 if ((ch|0x20) < 'a' || (ch|0x20) > 'z') { 182 if ((ch|0x20) < 'a' || (ch|0x20) > 'z') {
@@ -187,7 +189,7 @@ static const char *valid_domain_label(const char *label)
187 } 189 }
188 } 190 }
189 label++; 191 label++;
190 pos++; 192 //pos++;
191 //Do we want this? 193 //Do we want this?
192 //if (pos > 63) /* NS_MAXLABEL; labels must be 63 chars or less */ 194 //if (pos > 63) /* NS_MAXLABEL; labels must be 63 chars or less */
193 // return NULL; 195 // return NULL;
@@ -272,6 +274,12 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
272 case OPTION_STRING_HOST: 274 case OPTION_STRING_HOST:
273 memcpy(dest, option, len); 275 memcpy(dest, option, len);
274 dest[len] = '\0'; 276 dest[len] = '\0';
277//TODO: it appears option 15 DHCP_DOMAIN_NAME is often abused
278//by DHCP admins to contain a space-separated list of domains,
279//not one domain name (presumably, to work as list of search domains,
280//instead of using proper option 119 DHCP_DOMAIN_SEARCH).
281//Currently, good_hostname() balks on strings containing spaces.
282//Do we need to allow it? Only for DHCP_DOMAIN_NAME option?
275 if (type == OPTION_STRING_HOST && !good_hostname(dest)) 283 if (type == OPTION_STRING_HOST && !good_hostname(dest))
276 safe_strncpy(dest, "bad", len); 284 safe_strncpy(dest, "bad", len);
277 return ret; 285 return ret;
diff --git a/networking/whois.c b/networking/whois.c
index f0ec86301..f3da32b4e 100644
--- a/networking/whois.c
+++ b/networking/whois.c
@@ -39,20 +39,26 @@ static char *query(const char *host, int port, const char *domain)
39 bool success; 39 bool success;
40 char *redir = NULL; 40 char *redir = NULL;
41 const char *pfx = ""; 41 const char *pfx = "";
42 char linebuf[1024]; 42 /* some .io domains reported to have very long strings in whois
43 * responses, 1k was not enough:
44 */
45 char linebuf[2 * 1024];
43 char *buf = NULL; 46 char *buf = NULL;
44 unsigned bufpos = 0; 47 unsigned bufpos = 0;
45 48
46 again: 49 again:
47 printf("[Querying %s:%d '%s%s']\n", host, port, pfx, domain); 50 printf("[Querying %s:%d '%s%s']\n", host, port, pfx, domain);
48 fd = create_and_connect_stream_or_die(host, port); 51 fd = create_and_connect_stream_or_die(host, port);
49 success = 0;
50 fdprintf(fd, "%s%s\r\n", pfx, domain); 52 fdprintf(fd, "%s%s\r\n", pfx, domain);
51 fp = xfdopen_for_read(fd); 53 fp = xfdopen_for_read(fd);
52 54
53 while (fgets(linebuf, sizeof(linebuf), fp)) { 55 success = 0;
54 unsigned len = strcspn(linebuf, "\r\n"); 56 while (fgets(linebuf, sizeof(linebuf)-1, fp)) {
57 unsigned len;
58
59 len = strcspn(linebuf, "\r\n");
55 linebuf[len++] = '\n'; 60 linebuf[len++] = '\n';
61 linebuf[len] = '\0';
56 62
57 buf = xrealloc(buf, bufpos + len + 1); 63 buf = xrealloc(buf, bufpos + len + 1);
58 memcpy(buf + bufpos, linebuf, len); 64 memcpy(buf + bufpos, linebuf, len);