Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/networking
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (7 years ago)
- Location:
- branches/3.3
- Files:
-
- 16 added
- 8 deleted
- 78 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/networking/Config.src
r3232 r3621 135 135 Most other ftp servers seem to behave similar to this. 136 136 137 config FEATURE_FTP_AUTHENTICATION 138 bool "Enable authentication" 139 default y 140 depends on FTPD 141 help 142 Enable basic system login as seen in telnet etc. 143 137 144 config FTPGET 138 145 bool "ftpget" … … 174 181 "Range: bytes=NNN-[MMM]" header. Allows for resuming interrupted 175 182 downloads, seeking in multimedia players etc. 176 177 config FEATURE_HTTPD_USE_SENDFILE178 bool "Use sendfile system call"179 default y180 depends on HTTPD181 help182 When enabled, httpd will use the kernel sendfile() function183 instead of read/write loop.184 183 185 184 config FEATURE_HTTPD_SETUID … … 499 498 config FEATURE_INETD_RPC 500 499 bool "Support RPC services" 501 default y500 default n # very rarely used, and needs Sun RPC support in libc 502 501 depends on INETD 503 502 select FEATURE_HAVE_RPC … … 535 534 Add support for routing table management to "ip". 536 535 536 config FEATURE_IP_ROUTE_DIR 537 string "ip route configuration directory" 538 default "/etc/iproute2" 539 depends on FEATURE_IP_ROUTE 540 help 541 Location of the "ip" applet routing configuration. 542 537 543 config FEATURE_IP_TUNNEL 538 544 bool "ip tunnel" … … 548 554 help 549 555 Add support for rule commands to "ip". 556 557 config FEATURE_IP_NEIGH 558 bool "ip neighbor" 559 default y 560 depends on IP 561 help 562 Add support for neighbor commands to "ip". 550 563 551 564 config FEATURE_IP_SHORT_FORMS … … 560 573 ip tunnel -> iptunnel 561 574 ip rule -> iprule 575 ip neigh -> ipneigh 562 576 563 577 Say N unless you desparately need the short form of the ip … … 599 613 depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_RULE 600 614 615 config IPNEIGH 616 bool 617 default y 618 depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_NEIGH 619 601 620 config IPCALC 602 621 bool "ipcalc" … … 664 683 Make ntpd usable as a NTP server. If you disable this option 665 684 ntpd will be usable only as a NTP client. 685 686 config FEATURE_NTPD_CONF 687 bool "Make ntpd understand /etc/ntp.conf" 688 default y 689 depends on NTPD 690 help 691 Make ntpd look in /etc/ntp.conf for peers. Only "server address" 692 is supported. 666 693 667 694 config PSCAN … … 744 771 Note that for busybox telnetd to work you need several things: 745 772 First of all, your kernel needs: 746 UNIX98_PTYS=y 747 DEVPTS_FS=y 773 CONFIG_UNIX98_PTYS=y 748 774 749 775 Next, you need a /dev/pts directory on your root filesystem: … … 942 968 Creates, removes, and configures VLAN interfaces 943 969 944 config WGET945 bool "wget"946 default y947 help948 wget is a utility for non-interactive download of files from HTTP949 and FTP servers.950 951 config FEATURE_WGET_STATUSBAR952 bool "Enable a nifty process meter (+2k)"953 default y954 depends on WGET955 help956 Enable the transfer progress bar for wget transfers.957 958 config FEATURE_WGET_AUTHENTICATION959 bool "Enable HTTP authentication"960 default y961 depends on WGET962 help963 Support authenticated HTTP transfers.964 965 config FEATURE_WGET_LONG_OPTIONS966 bool "Enable long options"967 default y968 depends on WGET && LONG_OPTS969 help970 Support long options for the wget applet.971 972 config FEATURE_WGET_TIMEOUT973 bool "Enable read timeout option -T SEC"974 default y975 depends on WGET976 help977 Supports network read timeout for wget, so that wget will give978 up and timeout when reading network data, through the -T command979 line option. Currently only network data read timeout is980 supported (i.e., timeout is not applied to the DNS nor TCP981 connection initialization). When FEATURE_WGET_LONG_OPTIONS is982 also enabled, the --timeout option will work in addition to -T.983 984 970 config ZCIP 985 971 bool "zcip" -
branches/3.3/mindi-busybox/networking/Kbuild.src
r3232 r3621 42 42 lib-$(CONFIG_TUNCTL) += tunctl.o 43 43 lib-$(CONFIG_VCONFIG) += vconfig.o 44 lib-$(CONFIG_WGET) += wget.o45 44 lib-$(CONFIG_ZCIP) += zcip.o 46 45 -
branches/3.3/mindi-busybox/networking/arp.c
r3232 r3621 23 23 //usage: "Manipulate ARP cache\n" 24 24 //usage: "\n -a Display (all) hosts" 25 //usage: "\n - s Set newARP entry"26 //usage: "\n - d Delete a specifiedentry"25 //usage: "\n -d Delete ARP entry" 26 //usage: "\n -s Set new entry" 27 27 //usage: "\n -v Verbose" 28 28 //usage: "\n -n Don't resolve names" 29 29 //usage: "\n -i IF Network interface" 30 //usage: "\n -D Read <hwaddr> from given device"30 //usage: "\n -D Read HWADDR from IFACE" 31 31 //usage: "\n -A,-p AF Protocol family" 32 32 //usage: "\n -H HWTYPE Hardware address type" 33 33 34 34 #include "libbb.h" 35 #include "common_bufsiz.h" 35 36 #include "inet_common.h" 36 37 … … 69 70 const char *device; /* current device */ 70 71 smallint hw_set; /* flag if hw-type was set (-H) */ 71 72 72 } FIX_ALIASING; 73 #define G (*(struct globals*) &bb_common_bufsiz1)73 #define G (*(struct globals*)bb_common_bufsiz1) 74 74 #define ap (G.ap ) 75 75 #define hw (G.hw ) … … 77 77 #define hw_set (G.hw_set ) 78 78 #define INIT_G() do { \ 79 setup_common_bufsiz(); \ 79 80 device = ""; \ 80 81 } while (0) … … 214 215 215 216 /* Get the hardware address to a specified interface name */ 216 static void arp_getdevhw(char *ifname, struct sockaddr *sa, 217 const struct hwtype *hwt) 217 static void arp_getdevhw(char *ifname, struct sockaddr *sa) 218 218 { 219 219 struct ifreq ifr; … … 222 222 strcpy(ifr.ifr_name, ifname); 223 223 ioctl_or_perror_and_die(sockfd, SIOCGIFHWADDR, &ifr, 224 "can t get HW-Address for '%s'", ifname);225 if (hw t && (ifr.ifr_hwaddr.sa_family != hw->type)) {224 "can't get HW-Address for '%s'", ifname); 225 if (hw_set && (ifr.ifr_hwaddr.sa_family != hw->type)) { 226 226 bb_error_msg_and_die("protocol type mismatch"); 227 227 } … … 234 234 } 235 235 bb_error_msg("device '%s' has HW address %s '%s'", 236 237 236 ifname, xhw->name, 237 xhw->print((unsigned char *) &ifr.ifr_hwaddr.sa_data)); 238 238 } 239 239 } … … 262 262 } 263 263 if (option_mask32 & ARP_OPT_D) { 264 arp_getdevhw(*args++, &req.arp_ha , hw_set ? hw : NULL);264 arp_getdevhw(*args++, &req.arp_ha); 265 265 } else { 266 266 if (hw->input(*args++, &req.arp_ha) < 0) { … … 461 461 } 462 462 if (option_mask32 & ARP_OPT_v) 463 printf("Entries: % d\tSkipped: %d\tFound: %d\n",463 printf("Entries: %u\tSkipped: %u\tFound: %u\n", 464 464 entries, entries - shown, shown); 465 465 466 466 if (!shown) { 467 467 if (hw_set || host || device[0]) 468 printf("No match found in % dentries\n", entries);468 printf("No match found in %u entries\n", entries); 469 469 } 470 470 if (ENABLE_FEATURE_CLEAN_UP) { … … 478 478 int arp_main(int argc UNUSED_PARAM, char **argv) 479 479 { 480 const char *hw_type = "ether";480 const char *hw_type; 481 481 const char *protocol; 482 482 unsigned opts; … … 485 485 486 486 xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sockfd); 487 487 488 ap = get_aftype(DFLT_AF); 488 if (!ap) 489 bb_error_msg_and_die("%s: %s not supported", DFLT_AF, "address family"); 489 /* Defaults are always supported */ 490 //if (!ap) 491 // bb_error_msg_and_die("%s: %s not supported", DFLT_AF, "address family"); 492 hw = get_hwtype(DFLT_HW); 493 //if (!hw) 494 // bb_error_msg_and_die("%s: %s not supported", DFLT_HW, "hardware type"); 490 495 491 496 opts = getopt32(argv, "A:p:H:t:i:adnDsv", &protocol, &protocol, … … 494 499 if (opts & (ARP_OPT_A | ARP_OPT_p)) { 495 500 ap = get_aftype(protocol); 496 if ( ap == NULL)501 if (!ap) 497 502 bb_error_msg_and_die("%s: unknown %s", protocol, "address family"); 498 503 } 499 if (opts & (ARP_OPT_ A | ARP_OPT_p)) {504 if (opts & (ARP_OPT_H | ARP_OPT_t)) { 500 505 hw = get_hwtype(hw_type); 501 if ( hw == NULL)506 if (!hw) 502 507 bb_error_msg_and_die("%s: unknown %s", hw_type, "hardware type"); 503 508 hw_set = 1; … … 508 513 bb_error_msg_and_die("%s: kernel only supports 'inet'", ap->name); 509 514 } 510 511 /* If no hw type specified get default */512 if (!hw) {513 hw = get_hwtype(DFLT_HW);514 if (!hw)515 bb_error_msg_and_die("%s: %s not supported", DFLT_HW, "hardware type");516 }517 518 515 if (hw->alen <= 0) { 519 516 bb_error_msg_and_die("%s: %s without ARP support", … … 529 526 return arp_del(argv); 530 527 } 528 531 529 //if (opts & ARP_OPT_a) - default 532 530 return arp_show(argv[0]); -
branches/3.3/mindi-busybox/networking/arping.c
r3232 r3621 14 14 //usage: "\n -q Quiet" 15 15 //usage: "\n -b Keep broadcasting, don't go unicast" 16 //usage: "\n -D Duplicated address detection mode"16 //usage: "\n -D Exit with 1 if DST_IP replies" 17 17 //usage: "\n -U Unsolicited ARP mode, update your neighbors" 18 18 //usage: "\n -A ARP answer mode, update your neighbors" 19 19 //usage: "\n -c N Stop after sending N ARP requests" 20 //usage: "\n -w TIMEOUT Time to wait for ARP reply, seconds"20 //usage: "\n -w TIMEOUT Seconds to wait for ARP reply" 21 21 //usage: "\n -I IFACE Interface to use (default eth0)" 22 22 //usage: "\n -s SRC_IP Sender IP address" … … 29 29 30 30 #include "libbb.h" 31 #include "common_bufsiz.h" 31 32 32 33 /* We don't expect to see 1000+ seconds delay, unsigned is enough */ … … 61 62 unsigned req_recv; 62 63 } FIX_ALIASING; 63 #define G (*(struct globals*) &bb_common_bufsiz1)64 #define G (*(struct globals*)bb_common_bufsiz1) 64 65 #define src (G.src ) 65 66 #define dst (G.dst ) … … 77 78 #define req_recv (G.req_recv ) 78 79 #define INIT_G() do { \ 80 setup_common_bufsiz(); \ 79 81 count = -1; \ 80 82 } while (0) … … 163 165 } 164 166 165 static boolrecv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)167 static void recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) 166 168 { 167 169 struct arphdr *ah = (struct arphdr *) buf; … … 182 184 && FROM->sll_pkttype != PACKET_BROADCAST 183 185 && FROM->sll_pkttype != PACKET_MULTICAST) 184 return false;186 return; 185 187 186 188 /* Only these types are recognized */ 187 189 if (ah->ar_op != htons(ARPOP_REQUEST) && ah->ar_op != htons(ARPOP_REPLY)) 188 return false;190 return; 189 191 190 192 /* ARPHRD check and this darned FDDI hack here :-( */ 191 193 if (ah->ar_hrd != htons(FROM->sll_hatype) 192 194 && (FROM->sll_hatype != ARPHRD_FDDI || ah->ar_hrd != htons(ARPHRD_ETHER))) 193 return false;195 return; 194 196 195 197 /* Protocol must be IP. */ … … 198 200 || (ah->ar_hln != me.sll_halen) 199 201 || (len < (int)(sizeof(*ah) + 2 * (4 + ah->ar_hln)))) 200 return false;202 return; 201 203 202 204 move_from_unaligned32(src_ip.s_addr, p + ah->ar_hln); … … 204 206 205 207 if (dst.s_addr != src_ip.s_addr) 206 return false;208 return; 207 209 if (!(option_mask32 & DAD)) { 208 210 if ((src.s_addr != dst_ip.s_addr) 209 210 return false;211 || (memcmp(p + ah->ar_hln + 4, &me.sll_addr, ah->ar_hln))) 212 return; 211 213 } else { 212 214 /* DAD packet was: … … 225 227 if ((memcmp(p, &me.sll_addr, me.sll_halen) == 0) 226 228 || (src.s_addr && src.s_addr != dst_ip.s_addr)) 227 return false;229 return; 228 230 } 229 231 if (!(option_mask32 & QUIET)) { 230 232 int s_printed = 0; 231 233 232 printf("%scast re%s from %s [% s]",234 printf("%scast re%s from %s [%02x:%02x:%02x:%02x:%02x:%02x]", 233 235 FROM->sll_pkttype == PACKET_HOST ? "Uni" : "Broad", 234 236 ah->ar_op == htons(ARPOP_REPLY) ? "ply" : "quest", 235 237 inet_ntoa(src_ip), 236 ether_ntoa((struct ether_addr *) p)); 238 p[0], p[1], p[2], p[3], p[4], p[5] 239 ); 237 240 if (dst_ip.s_addr != src.s_addr) { 238 241 printf("for %s ", inet_ntoa(dst_ip)); … … 240 243 } 241 244 if (memcmp(p + ah->ar_hln + 4, me.sll_addr, ah->ar_hln)) { 245 unsigned char *pp = p + ah->ar_hln + 4; 242 246 if (!s_printed) 243 247 printf("for "); 244 printf("[%s]", 245 ether_ntoa((struct ether_addr *) p + ah->ar_hln + 4)); 248 printf("[%02x:%02x:%02x:%02x:%02x:%02x]", 249 pp[0], pp[1], pp[2], pp[3], pp[4], pp[5] 250 ); 246 251 } 247 252 … … 250 255 printf(" %u.%03ums\n", diff / 1000, diff % 1000); 251 256 } else { 252 p rintf(" UNSOLICITED?\n");257 puts(" UNSOLICITED?"); 253 258 } 254 259 fflush_all(); … … 265 270 option_mask32 |= UNICASTING; 266 271 } 267 return true;268 272 } 269 273 … … 285 289 //xsetuid(getuid()); 286 290 287 err_str = xasprintf("interface %s %%s", device);288 291 { 289 292 unsigned opt; … … 303 306 304 307 target = argv[optind]; 305 308 err_str = xasprintf("interface %s %%s", device); 306 309 xfunc_error_retval = 2; 307 310 … … 360 363 saddr.sin_addr = dst; 361 364 362 if (setsockopt (probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1)363 bb_perror_msg("setsockopt( SO_DONTROUTE)");365 if (setsockopt_SOL_SOCKET_1(probe_fd, SO_DONTROUTE) != 0) 366 bb_perror_msg("setsockopt(%s)", "SO_DONTROUTE"); 364 367 xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); 365 368 getsockname(probe_fd, (struct sockaddr *) &saddr, &alen); -
branches/3.3/mindi-busybox/networking/brctl.c
r3232 r3621 65 65 66 66 #if ENABLE_FEATURE_BRCTL_FANCY 67 # include <linux/if_bridge.h> 67 /* #include <linux/if_bridge.h> 68 * breaks on musl: we already included netinet/in.h in libbb.h, 69 * if we include <linux/if_bridge.h> here, we get this: 70 * In file included from /usr/include/linux/if_bridge.h:18, 71 * from networking/brctl.c:67: 72 * /usr/include/linux/in6.h:32: error: redefinition of 'struct in6_addr' 73 * /usr/include/linux/in6.h:49: error: redefinition of 'struct sockaddr_in6' 74 * /usr/include/linux/in6.h:59: error: redefinition of 'struct ipv6_mreq' 75 */ 76 /* From <linux/if_bridge.h> */ 77 #define BRCTL_GET_VERSION 0 78 #define BRCTL_GET_BRIDGES 1 79 #define BRCTL_ADD_BRIDGE 2 80 #define BRCTL_DEL_BRIDGE 3 81 #define BRCTL_ADD_IF 4 82 #define BRCTL_DEL_IF 5 83 #define BRCTL_GET_BRIDGE_INFO 6 84 #define BRCTL_GET_PORT_LIST 7 85 #define BRCTL_SET_BRIDGE_FORWARD_DELAY 8 86 #define BRCTL_SET_BRIDGE_HELLO_TIME 9 87 #define BRCTL_SET_BRIDGE_MAX_AGE 10 88 #define BRCTL_SET_AGEING_TIME 11 89 #define BRCTL_SET_GC_INTERVAL 12 90 #define BRCTL_GET_PORT_INFO 13 91 #define BRCTL_SET_BRIDGE_STP_STATE 14 92 #define BRCTL_SET_BRIDGE_PRIORITY 15 93 #define BRCTL_SET_PORT_PRIORITY 16 94 #define BRCTL_SET_PATH_COST 17 95 #define BRCTL_GET_FDB_ENTRIES 18 96 struct __bridge_info { 97 uint64_t designated_root; 98 uint64_t bridge_id; 99 uint32_t root_path_cost; 100 uint32_t max_age; 101 uint32_t hello_time; 102 uint32_t forward_delay; 103 uint32_t bridge_max_age; 104 uint32_t bridge_hello_time; 105 uint32_t bridge_forward_delay; 106 uint8_t topology_change; 107 uint8_t topology_change_detected; 108 uint8_t root_port; 109 uint8_t stp_enabled; 110 uint32_t ageing_time; 111 uint32_t gc_interval; 112 uint32_t hello_timer_value; 113 uint32_t tcn_timer_value; 114 uint32_t topology_change_timer_value; 115 uint32_t gc_timer_value; 116 }; 117 /* end <linux/if_bridge.h> */ 68 118 69 119 /* FIXME: These 4 funcs are not really clean and could be improved */ … … 79 129 if (sscanf(time_str, "%lf", &secs) != 1) 80 130 # endif 81 bb_error_msg_and_die(bb_msg_invalid_arg , time_str, "timespec");131 bb_error_msg_and_die(bb_msg_invalid_arg_to, time_str, "timespec"); 82 132 tv->tv_sec = secs; 83 133 tv->tv_usec = 1000000 * (secs - tv->tv_sec); … … 156 206 key = index_in_strings(keywords, *argv); 157 207 if (key == -1) /* no match found in keywords array, bail out. */ 158 bb_error_msg_and_die(bb_msg_invalid_arg , *argv, applet_name);208 bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name); 159 209 argv++; 160 210 fd = xsocket(AF_INET, SOCK_STREAM, 0); … … 168 218 (unsigned long) bridx, MAX_PORTS); 169 219 num = xioctl(fd, SIOCGIFBR, args); 170 p rintf("bridge name\tbridge id\t\tSTP enabled\tinterfaces\n");220 puts("bridge name\tbridge id\t\tSTP enabled\tinterfaces"); 171 221 for (i = 0; i < num; i++) { 172 222 char ifname[IFNAMSIZ]; … … 187 237 x = (unsigned char *) &bi.bridge_id; 188 238 for (j = 0; j < 8; j++) { 189 printf("% .2x", x[j]);239 printf("%02x", x[j]); 190 240 if (j == 1) 191 241 bb_putchar('.'); … … 250 300 int onoff = index_in_strings(no_yes, *argv); 251 301 if (onoff < 0) 252 bb_error_msg_and_die(bb_msg_invalid_arg , *argv, applet_name);302 bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name); 253 303 onoff = (unsigned)onoff / 4; 254 304 arm_ioctl(args, BRCTL_SET_BRIDGE_STP_STATE, onoff, 0); … … 283 333 port = if_nametoindex(*argv++); 284 334 if (!port) 285 bb_error_msg_and_die(bb_msg_invalid_arg , *argv, "port");335 bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, "port"); 286 336 memset(ifidx, 0, sizeof ifidx); 287 337 arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long)ifidx, -
branches/3.3/mindi-busybox/networking/dnsd.c
r3232 r3621 195 195 /* we assume (do not check) that query_string 196 196 * ends in ".in-addr.arpa" */ 197 && strncmp(d->rip, query_string, strlen(d->rip)) == 0197 && is_prefixed_with(query_string, d->rip) 198 198 ) { 199 199 #if DEBUG -
branches/3.3/mindi-busybox/networking/ether-wake.c
r3232 r3621 63 63 * doing so only works with adapters configured for unicast+broadcast Rx 64 64 * filter. That configuration consumes more power. 65 */65 */ 66 66 67 67 //usage:#define ether_wake_trivial_usage 68 //usage: "[-b] [-i iface] [-p aa:bb:cc:dd[:ee:ff]] MAC"68 //usage: "[-b] [-i IFACE] [-p aa:bb:cc:dd[:ee:ff]/a.b.c.d] MAC" 69 69 //usage:#define ether_wake_full_usage "\n\n" 70 70 //usage: "Send a magic packet to wake up sleeping machines.\n" 71 71 //usage: "MAC must be a station address (00:11:22:33:44:55) or\n" 72 72 //usage: "a hostname with a known 'ethers' entry.\n" 73 //usage: "\n -b Send wake-up packet to the broadcast address"74 //usage: "\n -i ifaceInterface to use (default eth0)"75 //usage: "\n -p pass Append four or six byte password PWto the packet"73 //usage: "\n -b Broadcast the packet" 74 //usage: "\n -i IFACE Interface to use (default eth0)" 75 //usage: "\n -p PASSWORD Append four or six byte PASSWORD to the packet" 76 76 77 77 #include "libbb.h" … … 122 122 if (eap) { 123 123 bb_debug_msg("The target station address is %s\n\n", ether_ntoa(eap)); 124 #if !defined(__UCLIBC_MAJOR__) \ 125 || __UCLIBC_MAJOR__ > 0 \ 126 || __UCLIBC_MINOR__ > 9 \ 127 || (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ >= 30) 124 #if !defined(__UCLIBC__) || UCLIBC_VERSION >= KERNEL_VERSION(0, 9, 30) 128 125 } else if (ether_hostton(hostid, eaddr) == 0) { 129 126 bb_debug_msg("Station address for hostname %s is %s\n\n", hostid, ether_ntoa(eaddr)); … … 134 131 } 135 132 136 static int get_fill(unsigned char *pkt, struct ether_addr *eaddr, int broadcast) 133 #define PKT_HEADER_SIZE (20 + 16*6) 134 static int fill_pkt_header(unsigned char *pkt, struct ether_addr *eaddr, int broadcast) 137 135 { 138 136 int i; … … 157 155 } 158 156 159 return 20 + 16*6; /* length of packet */157 return PKT_HEADER_SIZE; /* length of packet */ 160 158 } 161 159 … … 199 197 int s; /* Raw socket */ 200 198 int pktsize; 201 unsigned char outpack[ 1000];199 unsigned char outpack[PKT_HEADER_SIZE + 6 /* max passwd size */ + 16 /* paranoia */]; 202 200 203 201 struct ether_addr eaddr; … … 221 219 222 220 /* fill out the header of the packet */ 223 pktsize = get_fill(outpack, &eaddr, flags /* & 1 OPT_BROADCAST */);221 pktsize = fill_pkt_header(outpack, &eaddr, flags /* & 1 OPT_BROADCAST */); 224 222 225 223 bb_debug_dump_packet(outpack, pktsize); -
branches/3.3/mindi-busybox/networking/ftpd.c
r3232 r3621 30 30 31 31 #include "libbb.h" 32 #include "common_bufsiz.h" 32 33 #include <syslog.h> 33 34 #include <netinet/tcp.h> … … 124 125 char msg_err[(sizeof("NNN " MSG_ERR) + 3) & 0xfffc]; 125 126 } FIX_ALIASING; 126 #define G (*(struct globals*) &bb_common_bufsiz1)127 #define G (*(struct globals*)bb_common_bufsiz1) 127 128 #define INIT_G() do { \ 129 setup_common_bufsiz(); \ 128 130 /* Moved to main */ \ 129 131 /*strcpy(G.msg_ok + 4, MSG_OK );*/ \ … … 378 380 } 379 381 380 setsockopt (remote_fd, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));382 setsockopt_keepalive(remote_fd); 381 383 return remote_fd; 382 384 } … … 623 625 624 626 argv[0] = "ftpd"; 625 argv[1] = opt; /* "-l" or "-1" */ 626 #if BB_MMU 627 argv[1] = opt; /* "-lA" or "-1A" */ 627 628 argv[2] = "--"; 628 #else629 /* NOMMU ftpd ls helper chdirs to argv[2],630 * preventing peer from seeing real root. */631 argv[2] = xrealloc_getcwd_or_warn(NULL);632 #endif633 629 argv[3] = G.ftp_arg; 634 630 argv[4] = NULL; … … 651 647 pid = BB_MMU ? xfork() : xvfork(); 652 648 if (pid == 0) { 649 #if !BB_MMU 650 int cur_fd; 651 #endif 653 652 /* child */ 654 #if !BB_MMU655 /* On NOMMU, we want to execute a child - copy of ourself.656 * In chroot we usually can't do it. Thus we chdir657 * out of the chroot back to original root,658 * and (see later below) execute bb_busybox_exec_path659 * relative to current directory */660 if (fchdir(G.root_fd) != 0)661 _exit(127);662 /*close(G.root_fd); - close_on_exec_on() took care of this */663 #endif664 653 /* NB: close _first_, then move fd! */ 665 654 close(outfd.rd); … … 675 664 exit(ls_main(ARRAY_SIZE(argv) - 1, (char**) argv)); 676 665 #else 677 /* + 1: we must use relative path here if in chroot. 678 * For example, execv("/proc/self/exe") will fail, since 679 * it looks for "/proc/self/exe" _relative to chroot!_ */ 680 execv(bb_busybox_exec_path + 1, (char**) argv); 666 cur_fd = xopen(".", O_RDONLY | O_DIRECTORY); 667 /* On NOMMU, we want to execute a child - copy of ourself 668 * in order to unblock parent after vfork. 669 * In chroot we usually can't re-exec. Thus we escape 670 * out of the chroot back to original root. 671 */ 672 if (G.root_fd >= 0) { 673 if (fchdir(G.root_fd) != 0 || chroot(".") != 0) 674 _exit(127); 675 /*close(G.root_fd); - close_on_exec_on() took care of this */ 676 } 677 /* Child expects directory to list on fd #3 */ 678 xmove_fd(cur_fd, 3); 679 execv(bb_busybox_exec_path, (char**) argv); 681 680 _exit(127); 682 681 #endif … … 685 684 /* parent */ 686 685 close(outfd.wr); 687 #if !BB_MMU688 free((char*)argv[2]);689 #endif690 686 return outfd.rd; 691 687 } … … 706 702 return; /* port_or_pasv_was_seen emitted error response */ 707 703 708 /* -n prevents user/groupname display, 709 * which can be problematic in chroot */ 710 ls_fd = popen_ls((opts & LONG_LISTING) ? "-l" : "-1"); 704 ls_fd = popen_ls((opts & LONG_LISTING) ? "-lA" : "-1A"); 711 705 ls_fp = xfdopen_for_read(ls_fd); 706 /* FIXME: filenames with embedded newlines are mishandled */ 712 707 713 708 if (opts & USE_CTRL_CONN) { … … 730 725 if (remote_fd >= 0) { 731 726 while (1) { 732 line = xmalloc_fgetline(ls_fp); 727 unsigned len; 728 729 line = xmalloc_fgets(ls_fp); 733 730 if (!line) 734 731 break; 735 732 /* I've seen clients complaining when they 736 733 * are fed with ls output with bare '\n'. 737 * Pity... that would be much simpler.734 * Replace trailing "\n\0" with "\r\n". 738 735 */ 739 /* TODO: need to s/LF/NUL/g here */ 740 xwrite_str(remote_fd, line); 741 xwrite(remote_fd, "\r\n", 2); 736 len = strlen(line); 737 if (len != 0) /* paranoia check */ 738 line[len - 1] = '\r'; 739 line[len] = '\n'; 740 xwrite(remote_fd, line, len + 1); 742 741 free(line); 743 742 } … … 1086 1085 const_PORT = mk_const4('P', 'O', 'R', 'T'), 1087 1086 const_PWD = mk_const3('P', 'W', 'D'), 1087 /* Same as PWD. Reportedly used by windows ftp client */ 1088 const_XPWD = mk_const4('X', 'P', 'W', 'D'), 1088 1089 const_QUIT = mk_const4('Q', 'U', 'I', 'T'), 1089 1090 const_REST = mk_const4('R', 'E', 'S', 'T'), … … 1104 1105 OPT_l = (1 << 0), 1105 1106 OPT_1 = (1 << 1), 1106 #endif 1107 OPT_v = (1 << ((!BB_MMU) * 2 + 0)), 1108 OPT_S = (1 << ((!BB_MMU) * 2 + 1)), 1109 OPT_w = (1 << ((!BB_MMU) * 2 + 2)) * ENABLE_FEATURE_FTP_WRITE, 1107 OPT_A = (1 << 2), 1108 #endif 1109 OPT_v = (1 << ((!BB_MMU) * 3 + 0)), 1110 OPT_S = (1 << ((!BB_MMU) * 3 + 1)), 1111 OPT_w = (1 << ((!BB_MMU) * 3 + 2)) * ENABLE_FEATURE_FTP_WRITE, 1110 1112 }; 1111 1113 … … 1117 1119 #endif 1118 1120 { 1121 #if ENABLE_FEATURE_FTP_AUTHENTICATION 1122 struct passwd *pw = NULL; 1123 #endif 1119 1124 unsigned abs_timeout; 1120 1125 unsigned verbose_S; … … 1128 1133 opt_complementary = "t+:T+:vv:SS"; 1129 1134 #if BB_MMU 1130 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); 1131 1136 #else 1132 opts = getopt32(argv, "l1 vS" 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); 1133 1138 if (opts & (OPT_l|OPT_1)) { 1134 1139 /* Our secret backdoor to ls */ 1135 /* TODO: pass -n? It prevents user/group resolution, which may not work in chroot anyway */1136 /* TODO: pass -A? It shows dot files */1137 1140 /* TODO: pass --group-directories-first? would be nice, but ls doesn't do that yet */ 1138 xchdir(argv[2]);1139 argv[2] = (char*)"--";1141 if (fchdir(3) != 0) 1142 _exit(127); 1140 1143 /* memset(&G, 0, sizeof(G)); - ls_main does it */ 1141 1144 return ls_main(argc, argv); … … 1175 1178 applet_name = xasprintf("%s[%u]", applet_name, (int)getpid()); 1176 1179 1177 #if !BB_MMU1178 G.root_fd = xopen("/", O_RDONLY | O_DIRECTORY);1179 close_on_exec_on(G.root_fd);1180 #endif1181 1182 if (argv[optind]) {1183 xchroot(argv[optind]);1184 }1185 1186 1180 //umask(077); - admin can set umask before starting us 1187 1181 1188 /* Signals. We'll always take -EPIPE rather than a rude signal, thanks */ 1189 signal(SIGPIPE, SIG_IGN); 1182 /* Signals */ 1183 bb_signals(0 1184 /* We'll always take EPIPE rather than a rude signal, thanks */ 1185 + (1 << SIGPIPE) 1186 /* LIST command spawns chilren. Prevent zombies */ 1187 + (1 << SIGCHLD) 1188 , SIG_IGN); 1190 1189 1191 1190 /* Set up options on the command socket (do we need these all? why?) */ 1192 setsockopt (STDIN_FILENO, IPPROTO_TCP, TCP_NODELAY, &const_int_1, sizeof(const_int_1));1193 setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));1191 setsockopt_1(STDIN_FILENO, IPPROTO_TCP, TCP_NODELAY); 1192 setsockopt_keepalive(STDIN_FILENO); 1194 1193 /* Telnet protocol over command link may send "urgent" data, 1195 1194 * we prefer it to be received in the "normal" data stream: */ 1196 setsockopt (STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &const_int_1, sizeof(const_int_1));1195 setsockopt_1(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE); 1197 1196 1198 1197 WRITE_OK(FTP_GREET); 1199 1198 signal(SIGALRM, timeout_handler); 1200 1199 1201 #ifdef IF_WE_WANT_TO_REQUIRE_LOGIN 1202 { 1203 smallint user_was_specified = 0; 1204 while (1) { 1205 uint32_t cmdval = cmdio_get_cmd_and_arg(); 1206 1200 #if ENABLE_FEATURE_FTP_AUTHENTICATION 1201 while (1) { 1202 uint32_t cmdval = cmdio_get_cmd_and_arg(); 1207 1203 if (cmdval == const_USER) { 1208 if (G.ftp_arg == NULL || strcasecmp(G.ftp_arg, "anonymous") != 0) 1209 cmdio_write_raw(STR(FTP_LOGINERR)" Server is anonymous only\r\n"); 1210 else { 1211 user_was_specified = 1; 1212 cmdio_write_raw(STR(FTP_GIVEPWORD)" Please specify the password\r\n"); 1213 } 1214 } else if (cmdval == const_PASS) { 1215 if (user_was_specified) 1216 break; 1217 cmdio_write_raw(STR(FTP_NEEDUSER)" Login with USER\r\n"); 1218 } else if (cmdval == const_QUIT) { 1219 WRITE_OK(FTP_GOODBYE); 1220 return 0; 1221 } else { 1222 cmdio_write_raw(STR(FTP_LOGINERR)" Login with USER and PASS\r\n"); 1204 pw = getpwnam(G.ftp_arg); 1205 cmdio_write_raw(STR(FTP_GIVEPWORD)" Please specify password\r\n"); 1206 } else if (cmdval == const_PASS) { 1207 if (check_password(pw, G.ftp_arg) > 0) { 1208 break; /* login success */ 1223 1209 } 1210 cmdio_write_raw(STR(FTP_LOGINERR)" Login failed\r\n"); 1211 pw = NULL; 1212 } else if (cmdval == const_QUIT) { 1213 WRITE_OK(FTP_GOODBYE); 1214 return 0; 1215 } else { 1216 cmdio_write_raw(STR(FTP_LOGINERR)" Login with USER and PASS\r\n"); 1224 1217 } 1225 1218 } 1226 1219 WRITE_OK(FTP_LOGINOK); 1220 #endif 1221 1222 /* Do this after auth, else /etc/passwd is not accessible */ 1223 #if !BB_MMU 1224 G.root_fd = -1; 1225 #endif 1226 argv += optind; 1227 if (argv[0]) { 1228 const char *basedir = argv[0]; 1229 #if !BB_MMU 1230 G.root_fd = xopen("/", O_RDONLY | O_DIRECTORY); 1231 close_on_exec_on(G.root_fd); 1232 #endif 1233 if (chroot(basedir) == 0) 1234 basedir = "/"; 1235 #if !BB_MMU 1236 else { 1237 close(G.root_fd); 1238 G.root_fd = -1; 1239 } 1240 #endif 1241 /* 1242 * If chroot failed, assume that we aren't root, 1243 * and at least chdir to the specified DIR 1244 * (older versions were dying with error message). 1245 * If chroot worked, move current dir to new "/": 1246 */ 1247 xchdir(basedir); 1248 } 1249 1250 #if ENABLE_FEATURE_FTP_AUTHENTICATION 1251 change_identity(pw); 1227 1252 #endif 1228 1253 … … 1293 1318 else if (cmdval == const_SYST) 1294 1319 cmdio_write_raw(STR(FTP_SYSTOK)" UNIX Type: L8\r\n"); 1295 else if (cmdval == const_PWD )1320 else if (cmdval == const_PWD || cmdval == const_XPWD) 1296 1321 handle_pwd(); 1297 1322 else if (cmdval == const_CWD) -
branches/3.3/mindi-busybox/networking/ftpgetput.c
r3232 r3621 51 51 52 52 #include "libbb.h" 53 #include "common_bufsiz.h" 53 54 54 55 struct globals { … … 61 62 char buf[4]; /* actually [BUFSZ] */ 62 63 } FIX_ALIASING; 63 #define G (*(struct globals*) &bb_common_bufsiz1)64 #define G (*(struct globals*)bb_common_bufsiz1) 64 65 enum { BUFSZ = COMMON_BUFSIZE - offsetof(struct globals, buf) }; 65 struct BUG_G_too_big {66 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];67 };68 66 #define user (G.user ) 69 67 #define password (G.password ) … … 73 71 #define do_continue (G.do_continue ) 74 72 #define buf (G.buf ) 75 #define INIT_G() do { } while (0) 73 #define INIT_G() do { \ 74 setup_common_bufsiz(); \ 75 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ 76 } while (0) 76 77 77 78 -
branches/3.3/mindi-busybox/networking/hostname.c
r3232 r3621 107 107 OPT_s = 0x8, 108 108 OPT_F = 0x10, 109 OPT_dfi s = 0xf,109 OPT_dfi = 0x7, 110 110 }; 111 111 … … 135 135 opts = OPT_d; 136 136 137 if (opts & OPT_dfi s) {137 if (opts & OPT_dfi) { 138 138 /* Cases when we need full hostname (or its part) */ 139 139 struct hostent *hp; … … 160 160 } 161 161 } 162 } else if (opts & OPT_s) { 163 strchrnul(buf, '.')[0] = '\0'; 164 puts(buf); 162 165 } else if (opts & OPT_F) { 163 166 /* Set the hostname */ -
branches/3.3/mindi-busybox/networking/httpd.c
r3232 r3621 126 126 127 127 #include "libbb.h" 128 #include "common_bufsiz.h" 128 129 #if ENABLE_PAM 129 130 /* PAM may include <locale.h>. We may need to undefine bbox's stub define: */ … … 134 135 # include <security/pam_misc.h> 135 136 #endif 136 #if ENABLE_FEATURE_ HTTPD_USE_SENDFILE137 #if ENABLE_FEATURE_USE_SENDFILE 137 138 # include <sys/sendfile.h> 138 139 #endif … … 308 309 #endif 309 310 char *iobuf; /* [IOBUF_SIZE] */ 310 #define hdr_buf bb_common_bufsiz1 311 #define hdr_buf bb_common_bufsiz1 312 #define sizeof_hdr_buf COMMON_BUFSIZE 311 313 char *hdr_ptr; 312 314 int hdr_cnt; … … 369 371 #endif 370 372 #define INIT_G() do { \ 373 setup_common_bufsiz(); \ 371 374 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 372 375 IF_FEATURE_HTTPD_BASIC_AUTH(g_realm = "Web Server Authentication";) \ … … 698 701 } 699 702 *host_port++ = '\0'; 700 if ( strncmp(host_port, "http://", 7) == 0)703 if (is_prefixed_with(host_port, "http://")) 701 704 host_port += 7; 702 705 if (*host_port == '\0') { … … 968 971 #endif 969 972 if (responseNum == HTTP_MOVED_TEMPORARILY) { 970 len += sprintf(iobuf + len, "Location: %s/%s%s\r\n", 973 /* Responding to "GET /dir" with 974 * "HTTP/1.0 302 Found" "Location: /dir/" 975 * - IOW, asking them to repeat with a slash. 976 * Here, overflow IS possible, can't use sprintf: 977 * mkdir test 978 * python -c 'print("get /test?" + ("x" * 8192))' | busybox httpd -i -h . 979 */ 980 len += snprintf(iobuf + len, IOBUF_SIZE-3 - len, 981 "Location: %s/%s%s\r\n", 971 982 found_moved_temporarily, 972 983 (g_query ? "?" : ""), 973 984 (g_query ? g_query : "")); 985 if (len > IOBUF_SIZE-3) 986 len = IOBUF_SIZE-3; 974 987 } 975 988 976 989 #if ENABLE_FEATURE_HTTPD_ERROR_PAGES 977 990 if (error_page && access(error_page, R_OK) == 0) { 978 strcat(iobuf, "\r\n");979 len += 2;980 981 if (DEBUG)991 iobuf[len++] = '\r'; 992 iobuf[len++] = '\n'; 993 if (DEBUG) { 994 iobuf[len] = '\0'; 982 995 fprintf(stderr, "headers: '%s'\n", iobuf); 996 } 983 997 full_write(STDOUT_FILENO, iobuf, len); 984 998 if (DEBUG) … … 1022 1036 responseNum, responseString, infoString); 1023 1037 } 1024 if (DEBUG) 1038 if (DEBUG) { 1039 iobuf[len] = '\0'; 1025 1040 fprintf(stderr, "headers: '%s'\n", iobuf); 1041 } 1026 1042 if (full_write(STDOUT_FILENO, iobuf, len) != len) { 1027 1043 if (verbose > 1) … … 1054 1070 while (1) { 1055 1071 if (hdr_cnt <= 0) { 1056 hdr_cnt = safe_read(STDIN_FILENO, hdr_buf, sizeof (hdr_buf));1072 hdr_cnt = safe_read(STDIN_FILENO, hdr_buf, sizeof_hdr_buf); 1057 1073 if (hdr_cnt <= 0) 1058 1074 break; … … 1105 1121 /* NB: breaking out of this loop jumps to log_and_exit() */ 1106 1122 out_cnt = 0; 1123 pfd[FROM_CGI].fd = fromCgi_rd; 1124 pfd[FROM_CGI].events = POLLIN; 1125 pfd[TO_CGI].fd = toCgi_wr; 1107 1126 while (1) { 1108 memset(pfd, 0, sizeof(pfd)); 1109 1110 pfd[FROM_CGI].fd = fromCgi_rd; 1111 pfd[FROM_CGI].events = POLLIN; 1112 1113 if (toCgi_wr) { 1114 pfd[TO_CGI].fd = toCgi_wr; 1115 if (hdr_cnt > 0) { 1116 pfd[TO_CGI].events = POLLOUT; 1117 } else if (post_len > 0) { 1118 pfd[0].events = POLLIN; 1127 /* Note: even pfd[0].events == 0 won't prevent 1128 * revents == POLLHUP|POLLERR reports from closed stdin. 1129 * Setting fd to -1 works: */ 1130 pfd[0].fd = -1; 1131 pfd[0].events = POLLIN; 1132 pfd[0].revents = 0; /* probably not needed, paranoia */ 1133 1134 /* We always poll this fd, thus kernel always sets revents: */ 1135 /*pfd[FROM_CGI].events = POLLIN; - moved out of loop */ 1136 /*pfd[FROM_CGI].revents = 0; - not needed */ 1137 1138 /* gcc-4.8.0 still doesnt fill two shorts with one insn :( */ 1139 /* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47059 */ 1140 /* hopefully one day it will... */ 1141 pfd[TO_CGI].events = POLLOUT; 1142 pfd[TO_CGI].revents = 0; /* needed! */ 1143 1144 if (toCgi_wr && hdr_cnt <= 0) { 1145 if (post_len > 0) { 1146 /* Expect more POST data from network */ 1147 pfd[0].fd = 0; 1119 1148 } else { 1120 1149 /* post_len <= 0 && hdr_cnt <= 0: … … 1128 1157 1129 1158 /* Now wait on the set of sockets */ 1130 count = safe_poll(pfd, toCgi_wr? TO_CGI+1 : FROM_CGI+1, -1);1159 count = safe_poll(pfd, hdr_cnt > 0 ? TO_CGI+1 : FROM_CGI+1, -1); 1131 1160 if (count <= 0) { 1132 1161 #if 0 … … 1145 1174 1146 1175 if (pfd[TO_CGI].revents) { 1147 /* hdr_cnt > 0 here due to the way p fd[TO_CGI].events set*/1176 /* hdr_cnt > 0 here due to the way poll() called */ 1148 1177 /* Have data from peer and can write to CGI */ 1149 1178 count = safe_write(toCgi_wr, hdr_ptr, hdr_cnt); … … 1166 1195 * and there *is* data to read from the peer 1167 1196 * (POSTDATA) */ 1168 //count = post_len > (int)sizeof (hdr_buf) ? (int)sizeof(hdr_buf): post_len;1197 //count = post_len > (int)sizeof_hdr_buf ? (int)sizeof_hdr_buf : post_len; 1169 1198 //count = safe_read(STDIN_FILENO, hdr_buf, count); 1170 count = safe_read(STDIN_FILENO, hdr_buf, sizeof (hdr_buf));1199 count = safe_read(STDIN_FILENO, hdr_buf, sizeof_hdr_buf); 1171 1200 if (count > 0) { 1172 1201 hdr_cnt = count; … … 1210 1239 count = 0; 1211 1240 /* "Status" header format is: "Status: 302 Redirected\r\n" */ 1212 if (out_cnt >= 8 && memcmp(rbuf, "Status: ", 8) == 0) {1241 if (out_cnt >= 7 && memcmp(rbuf, "Status:", 7) == 0) { 1213 1242 /* send "HTTP/1.0 " */ 1214 1243 if (full_write(STDOUT_FILENO, HTTP_200, 9) != 9) 1215 1244 break; 1216 rbuf += 8; /* skip "Status:" */1217 count = out_cnt - 8;1245 rbuf += 7; /* skip "Status:" */ 1246 count = out_cnt - 7; 1218 1247 out_cnt = -1; /* buffering off */ 1219 1248 } else if (out_cnt >= 4) { … … 1612 1641 if (what & SEND_HEADERS) 1613 1642 send_headers(HTTP_OK); 1614 #if ENABLE_FEATURE_ HTTPD_USE_SENDFILE1643 #if ENABLE_FEATURE_USE_SENDFILE 1615 1644 { 1616 1645 off_t offset = range_start; … … 1642 1671 } 1643 1672 if (count < 0) { 1644 IF_FEATURE_ HTTPD_USE_SENDFILE(fin:)1673 IF_FEATURE_USE_SENDFILE(fin:) 1645 1674 if (verbose > 1) 1646 1675 bb_perror_msg("error"); … … 1710 1739 break; 1711 1740 case PAM_ERROR_MSG: 1712 1713 1741 case PAM_TEXT_INFO: 1742 s = ""; 1714 1743 break; 1715 1744 default: … … 1882 1911 Htaccess_Proxy *p; 1883 1912 for (p = proxy; p; p = p->next) { 1884 if ( strncmp(url, p->url_from, strlen(p->url_from)) == 0)1913 if (is_prefixed_with(url, p->url_from)) 1885 1914 return p; 1886 1915 } … … 1965 1994 1966 1995 /* Determine type of request (GET/POST) */ 1967 urlp = strpbrk(iobuf, " \t"); 1996 // rfc2616: method and URI is separated by exactly one space 1997 //urlp = strpbrk(iobuf, " \t"); - no, tab isn't allowed 1998 urlp = strchr(iobuf, ' '); 1968 1999 if (urlp == NULL) 1969 2000 send_headers_and_exit(HTTP_BAD_REQUEST); … … 1983 2014 send_headers_and_exit(HTTP_NOT_IMPLEMENTED); 1984 2015 #endif 1985 urlp = skip_whitespace(urlp); 2016 // rfc2616: method and URI is separated by exactly one space 2017 //urlp = skip_whitespace(urlp); - should not be necessary 1986 2018 if (urlp[0] != '/') 1987 2019 send_headers_and_exit(HTTP_BAD_REQUEST); … … 2168 2200 /* We know only bytes=NNN-[MMM] */ 2169 2201 char *s = skip_whitespace(iobuf + sizeof("Range:")-1); 2170 if ( strncmp(s, "bytes=", 6) == 0) {2202 if (is_prefixed_with(s, "bytes=") == 0) { 2171 2203 s += sizeof("bytes=")-1; 2172 2204 range_start = BB_STRTOOFF(s, &s, 10); … … 2254 2286 2255 2287 #if ENABLE_FEATURE_HTTPD_CGI 2256 if ( strncmp(tptr, "cgi-bin/", 8) == 0) {2288 if (is_prefixed_with(tptr, "cgi-bin/")) { 2257 2289 if (tptr[8] == '\0') { 2258 2290 /* protect listing "cgi-bin/" */ … … 2337 2369 2338 2370 /* set the KEEPALIVE option to cull dead connections */ 2339 setsockopt (n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));2371 setsockopt_keepalive(n); 2340 2372 2341 2373 if (fork() == 0) { … … 2380 2412 2381 2413 /* set the KEEPALIVE option to cull dead connections */ 2382 setsockopt (n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));2414 setsockopt_keepalive(n); 2383 2415 2384 2416 if (vfork() == 0) { -
branches/3.3/mindi-busybox/networking/ifconfig.c
r3232 r3621 57 57 58 58 #if ENABLE_FEATURE_IFCONFIG_SLIP 59 # include < net/if_slip.h>59 # include <linux/if_slip.h> 60 60 #endif 61 61 … … 265 265 { NULL, 0, ARG_HOSTNAME, (IFF_UP | IFF_RUNNING) } 266 266 }; 267 268 #if ENABLE_FEATURE_IFCONFIG_HW269 /* Input an Ethernet address and convert to binary. */270 static int in_ether(const char *bufp, struct sockaddr *sap)271 {272 char *ptr;273 int i, j;274 unsigned char val;275 unsigned char c;276 277 sap->sa_family = ARPHRD_ETHER;278 ptr = (char *) sap->sa_data;279 280 i = 0;281 do {282 j = val = 0;283 284 /* We might get a semicolon here - not required. */285 if (i && (*bufp == ':')) {286 bufp++;287 }288 289 do {290 c = *bufp;291 if (((unsigned char)(c - '0')) <= 9) {292 c -= '0';293 } else if ((unsigned char)((c|0x20) - 'a') <= 5) {294 c = (unsigned char)((c|0x20) - 'a') + 10;295 } else if (j && (c == ':' || c == 0)) {296 break;297 } else {298 return -1;299 }300 ++bufp;301 val <<= 4;302 val += c;303 } while (++j < 2);304 *ptr++ = val;305 } while (++i < ETH_ALEN);306 307 return *bufp; /* Error if we don't end at end of string. */308 }309 #endif310 267 311 268 int ifconfig_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -
branches/3.3/mindi-busybox/networking/ifenslave.c
r3232 r3621 578 578 /* remember the error and skip it */ 579 579 bb_perror_msg( 580 "skipping %s: can't get flags",581 slave_ifname );580 "skipping %s: can't get %s", 581 slave_ifname, "flags"); 582 582 res = rv; 583 583 continue; … … 596 596 /* remember the error and skip it */ 597 597 bb_perror_msg( 598 "skipping %s: can't get settings",599 slave_ifname );598 "skipping %s: can't get %s", 599 slave_ifname, "settings"); 600 600 res = rv; 601 601 continue; -
branches/3.3/mindi-busybox/networking/ifplugd.c
r3232 r3621 39 39 #include <linux/ethtool.h> 40 40 #ifdef HAVE_NET_ETHERNET_H 41 # include <net/ethernet.h> 41 /* musl breakage: 42 * In file included from /usr/include/net/ethernet.h:10, 43 * from networking/ifplugd.c:41: 44 * /usr/include/netinet/if_ether.h:96: error: redefinition of 'struct ethhdr' 45 * 46 * Build succeeds without it on musl. Commented it out. 47 * If on your system you need it, consider removing <linux/ethtool.h> 48 * and copy-pasting its definitions here (<linux/ethtool.h> is what pulls in 49 * conflicting definition of struct ethhdr on musl). 50 */ 51 /* # include <net/ethernet.h> */ 42 52 #endif 43 53 #include <linux/netlink.h> … … 48 58 #define __user 49 59 #include <linux/wireless.h> 60 61 #ifndef ETH_ALEN 62 # define ETH_ALEN 6 63 #endif 50 64 51 65 /* … … 290 304 }; 291 305 292 293 294 306 static const char *strstatus(int status) 295 307 { … … 452 464 { 453 465 int iface_len; 454 char replybuf[1024]; 466 /* Buffer was 1K, but on linux-3.9.9 it was reported to be too small. 467 * netlink.h: "limit to 8K to avoid MSG_TRUNC when PAGE_SIZE is very large". 468 * Note: on error returns (-1) we exit, no need to free replybuf. 469 */ 470 enum { BUF_SIZE = 8 * 1024 }; 471 char *replybuf = xmalloc(BUF_SIZE); 455 472 456 473 iface_len = strlen(G.iface); … … 459 476 ssize_t bytes; 460 477 461 bytes = recv(netlink_fd, &replybuf, sizeof(replybuf), MSG_DONTWAIT);478 bytes = recv(netlink_fd, replybuf, BUF_SIZE, MSG_DONTWAIT); 462 479 if (bytes < 0) { 463 480 if (errno == EAGAIN) 464 return G.iface_exists;481 goto ret; 465 482 if (errno == EINTR) 466 483 continue; 467 468 484 bb_perror_msg("netlink: recv"); 469 485 return -1; … … 508 524 } 509 525 526 ret: 527 free(replybuf); 510 528 return G.iface_exists; 511 529 } … … 557 575 if (opts & FLAG_KILL) { 558 576 if (pid_from_pidfile > 0) 559 kill(pid_from_pidfile, SIGQUIT); 577 /* Upstream tool use SIGINT for -k */ 578 kill(pid_from_pidfile, SIGINT); 560 579 return EXIT_SUCCESS; 561 580 } … … 646 665 while (1) { 647 666 int iface_status_old; 648 int iface_exists_old;649 667 650 668 switch (bb_got_signal) { … … 672 690 } 673 691 674 iface_status_old = iface_status;675 iface_exists_old = G.iface_exists;676 677 692 if ((opts & FLAG_MONITOR) 678 693 && (netlink_pollfd[0].revents & POLLIN) 679 694 ) { 695 int iface_exists_old; 696 697 iface_exists_old = G.iface_exists; 680 698 G.iface_exists = check_existence_through_netlink(); 681 699 if (G.iface_exists < 0) /* error */ … … 690 708 691 709 /* note: if !G.iface_exists, returns DOWN */ 710 iface_status_old = iface_status; 692 711 iface_status = detect_link(); 693 712 if (iface_status == IFSTATUS_ERR) { … … 703 722 if (delay_time) { 704 723 /* link restored its old status before 705 * we r un script. don't run the script: */724 * we ran script. don't run the script: */ 706 725 delay_time = 0; 707 726 } else { … … 711 730 if (iface_status == IFSTATUS_DOWN) 712 731 delay_time += G.delay_down; 713 if (delay_time == 0) 714 delay_time++; 732 #if 0 /* if you are back in 1970... */ 733 if (delay_time == 0) { 734 sleep(1); 735 delay_time = 1; 736 } 737 #endif 715 738 } 716 739 } 717 740 718 741 if (delay_time && (int)(monotonic_sec() - delay_time) >= 0) { 719 delay_time = 0;720 742 if (run_script(iface_status_str) != 0) 721 743 goto exiting; 744 delay_time = 0; 722 745 } 723 746 } /* while (1) */ -
branches/3.3/mindi-busybox/networking/ifupdown.c
r3232 r3621 45 45 46 46 #include "libbb.h" 47 #include "common_bufsiz.h" 47 48 /* After libbb.h, since it needs sys/types.h on some systems */ 48 49 #include <sys/utsname.h> … … 130 131 char *shell; 131 132 } FIX_ALIASING; 132 #define G (*(struct globals*) &bb_common_bufsiz1)133 #define INIT_G() do { } while (0)133 #define G (*(struct globals*)bb_common_bufsiz1) 134 #define INIT_G() do { setup_common_bufsiz(); } while (0) 134 135 135 136 … … 290 291 * unlike ifconfig, ip doesnt want <class> 291 292 * (usually "ether" keyword). Skip it. */ 292 if ( strncmp(command, "hwaddress", 9) == 0) {293 if (is_prefixed_with(command, "hwaddress")) { 293 294 varvalue = skip_whitespace(skip_non_whitespace(varvalue)); 294 295 } … … 299 300 /* Sigh... Add a special case for 'ip' to convert from 300 301 * dotted quad to bit count style netmasks. */ 301 if ( strncmp(command, "bnmask", 6) == 0) {302 if (is_prefixed_with(command, "bnmask")) { 302 303 unsigned res; 303 304 varvalue = get_var("netmask", 7, ifd); … … 395 396 result = execute("ip addr add %address%/%netmask% dev %iface%[[ label %label%]]", ifd, exec); 396 397 result += execute("ip link set[[ mtu %mtu%]][[ addr %hwaddress%]] %iface% up", ifd, exec); 397 /* Was: "[[ ip ....%gateway% ]]". Removed extra spaces w/o checking*/398 result += execute("[[ip route add ::/0 via %gateway% ]][[ prio%metric%]]", ifd, exec);398 /* Reportedly, IPv6 needs "dev %iface%", but IPv4 does not: */ 399 result += execute("[[ip route add ::/0 via %gateway% dev %iface%]][[ metric %metric%]]", ifd, exec); 399 400 # else 400 401 result = execute("ifconfig %iface%[[ media %media%]][[ hw %hwaddress%]][[ mtu %mtu%]] up", ifd, exec); … … 422 423 result += execute("ip link set %iface% up", ifd, exec); 423 424 result += execute("ip addr add %address%/%netmask% dev %iface%", ifd, exec); 424 result += execute("[[ip route add ::/0 via %gateway%]]", ifd, exec); 425 /* Reportedly, IPv6 needs "dev %iface%", but IPv4 does not: */ 426 result += execute("[[ip route add ::/0 via %gateway% dev %iface%]]", ifd, exec); 425 427 return ((result == 4) ? 4 : 0); 426 428 } … … 483 485 "dev %iface%[[ peer %pointopoint%]][[ label %label%]]", ifd, exec); 484 486 result += execute("ip link set[[ mtu %mtu%]][[ addr %hwaddress%]] %iface% up", ifd, exec); 485 result += execute("[[ip route add default via %gateway% dev %iface%[[ prio%metric%]]]]", ifd, exec);487 result += execute("[[ip route add default via %gateway% dev %iface%[[ metric %metric%]]]]", ifd, exec); 486 488 return ((result == 3) ? 3 : 0); 487 489 # else … … 535 537 }, 536 538 { "udhcpc", 537 "udhcpc " UDHCPC_CMD_OPTIONS " -p /var/run/udhcpc.%iface%.pid -i %iface%[[ - H%hostname%]][[ -c %client%]]"539 "udhcpc " UDHCPC_CMD_OPTIONS " -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -x hostname:%hostname%]][[ -c %client%]]" 538 540 "[[ -s %script%]][[ %udhcpc_opts%]]", 539 541 "kill `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", … … 556 558 # endif 557 559 for (i = 0; i < ARRAY_SIZE(ext_dhcp_clients); i++) { 558 if (ex ists_execable(ext_dhcp_clients[i].name))560 if (executable_exists(ext_dhcp_clients[i].name)) 559 561 return execute(ext_dhcp_clients[i].startcmd, ifd, exec); 560 562 } … … 575 577 # endif 576 578 return execute("udhcpc " UDHCPC_CMD_OPTIONS " -p /var/run/udhcpc.%iface%.pid " 577 "-i %iface%[[ - H%hostname%]][[ -c %client%]][[ -s %script%]][[ %udhcpc_opts%]]",579 "-i %iface%[[ -x hostname:%hostname%]][[ -c %client%]][[ -s %script%]][[ %udhcpc_opts%]]", 578 580 ifd, exec); 579 581 } … … 593 595 594 596 for (i = 0; i < ARRAY_SIZE(ext_dhcp_clients); i++) { 595 if (ex ists_execable(ext_dhcp_clients[i].name)) {597 if (executable_exists(ext_dhcp_clients[i].name)) { 596 598 result = execute(ext_dhcp_clients[i].stopcmd, ifd, exec); 597 599 if (result) … … 686 688 #endif /* FEATURE_IFUPDOWN_IPV4 */ 687 689 690 static int FAST_FUNC link_up_down(struct interface_defn_t *ifd UNUSED_PARAM, execfn *exec UNUSED_PARAM) 691 { 692 return 1; 693 } 694 695 static const struct method_t link_methods[] = { 696 { "none", link_up_down, link_up_down } 697 }; 698 699 static const struct address_family_t addr_link = { 700 "link", ARRAY_SIZE(link_methods), link_methods 701 }; 688 702 689 703 /* Returns pointer to the next word, or NULL. … … 744 758 } 745 759 746 static struct interfaces_file_t *read_interfaces(const char *filename )760 static struct interfaces_file_t *read_interfaces(const char *filename, struct interfaces_file_t *defn) 747 761 { 748 762 /* Let's try to be compatible. … … 759 773 * A "\" character at the very end of the line indicates the next line 760 774 * should be treated as a continuation of the current one. 775 * 776 * Lines beginning with "source" are used to include stanzas from 777 * other files, so configuration can be split into many files. 778 * The word "source" is followed by the path of file to be sourced. 761 779 */ 762 780 #if ENABLE_FEATURE_IFUPDOWN_MAPPING … … 764 782 #endif 765 783 struct interface_defn_t *currif = NULL; 766 struct interfaces_file_t *defn;767 784 FILE *f; 768 785 char *buf; … … 771 788 enum { NONE, IFACE, MAPPING } currently_processing = NONE; 772 789 773 defn = xzalloc(sizeof(*defn)); 790 if (!defn) 791 defn = xzalloc(sizeof(*defn)); 792 793 debug_noise("reading %s file:\n", filename); 774 794 f = xfopen_for_read(filename); 775 795 … … 826 846 &addr_inet6, 827 847 #endif 848 &addr_link, 828 849 NULL 829 850 }; … … 831 852 char *address_family_name; 832 853 char *method_name; 833 llist_t *iface_list;834 854 835 855 currif = xzalloc(sizeof(*currif)); … … 856 876 if (!currif->method) 857 877 bb_error_msg_and_die("unknown method \"%s\"", method_name); 858 878 #if 0 879 // Allegedly, Debian allows a duplicate definition: 880 // iface eth0 inet static 881 // address 192.168.0.15 882 // netmask 255.255.0.0 883 // gateway 192.168.0.1 884 // 885 // iface eth0 inet static 886 // address 10.0.0.1 887 // netmask 255.255.255.0 888 // 889 // This adds *two* addresses to eth0 (probably requires use of "ip", not "ifconfig" 890 // 891 llist_t *iface_list; 859 892 for (iface_list = defn->ifaces; iface_list; iface_list = iface_list->link) { 860 893 struct interface_defn_t *tmp = (struct interface_defn_t *) iface_list->data; … … 865 898 } 866 899 } 900 #endif 867 901 llist_add_to_end(&(defn->ifaces), (char*)currif); 868 902 … … 882 916 } 883 917 currently_processing = NONE; 918 } else if (strcmp(first_word, "source") == 0) { 919 read_interfaces(next_word(&rest_of_line), defn); 884 920 } else { 885 921 switch (currently_processing) { … … 935 971 } 936 972 fclose(f); 973 debug_noise("\ndone reading %s\n\n", filename); 937 974 938 975 return defn; … … 1138 1175 static llist_t *find_iface_state(llist_t *state_list, const char *iface) 1139 1176 { 1140 unsigned iface_len = strlen(iface);1141 1177 llist_t *search = state_list; 1142 1178 1143 1179 while (search) { 1144 if ((strncmp(search->data, iface, iface_len) == 0) 1145 && (search->data[iface_len] == '=') 1180 char *after_iface = is_prefixed_with(search->data, iface); 1181 if (after_iface 1182 && *after_iface == '=' 1146 1183 ) { 1147 1184 return search; … … 1200 1237 } 1201 1238 1202 debug_noise("reading %s file:\n", interfaces); 1203 defn = read_interfaces(interfaces); 1204 debug_noise("\ndone reading %s\n\n", interfaces); 1239 defn = read_interfaces(interfaces, NULL); 1205 1240 1206 1241 /* Create a list of interfaces to work on */ … … 1220 1255 bool okay = 0; 1221 1256 int cmds_ret; 1257 bool curr_failure = 0; 1222 1258 1223 1259 iface = xstrdup(target_list->data); … … 1285 1321 cmds_ret = cmds(currif); 1286 1322 if (cmds_ret == -1) { 1287 bb_error_msg("don't seem to have all thevariables for %s/%s",1323 bb_error_msg("don't have all variables for %s/%s", 1288 1324 liface, currif->address_family->name); 1289 any_failures = 1;1325 any_failures = curr_failure = 1; 1290 1326 } else if (cmds_ret == 0) { 1291 any_failures = 1;1327 any_failures = curr_failure = 1; 1292 1328 } 1293 1329 … … 1310 1346 llist_t *iface_state = find_iface_state(state_list, iface); 1311 1347 1312 if (cmds == iface_up && ! any_failures) {1348 if (cmds == iface_up && !curr_failure) { 1313 1349 char *newiface = xasprintf("%s=%s", iface, liface); 1314 1350 if (!iface_state) { -
branches/3.3/mindi-busybox/networking/inetd.c
r3232 r3621 171 171 172 172 #include "libbb.h" 173 #include "common_bufsiz.h" 173 174 174 175 #if ENABLE_FEATURE_INETD_RPC … … 328 329 char line[256]; /* _at least_ 256, see LINE_SIZE */ 329 330 } FIX_ALIASING; 330 #define G (*(struct globals*) &bb_common_bufsiz1)331 #define G (*(struct globals*)bb_common_bufsiz1) 331 332 enum { LINE_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line) }; 332 struct BUG_G_too_big {333 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];334 };335 333 #define rlim_ofile_cur (G.rlim_ofile_cur ) 336 334 #define rlim_ofile (G.rlim_ofile ) … … 353 351 #define line (G.line ) 354 352 #define INIT_G() do { \ 353 setup_common_bufsiz(); \ 354 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ 355 355 rlim_ofile_cur = OPEN_MAX; \ 356 356 global_queuelen = 128; \ … … 646 646 647 647 /* gcc generates much more code if this is inlined */ 648 static servtab_t *parse_one_line(void)648 static NOINLINE servtab_t *parse_one_line(void) 649 649 { 650 650 int argc; … … 676 676 free(default_local_hostname); 677 677 default_local_hostname = sep->se_local_hostname; 678 /*sep->se_local_hostname = NULL; - redundant */ 679 /* (we'll overwrite this field anyway) */ 678 680 goto more; 679 681 } … … 689 691 bb_error_msg("parse error on line %u, line is ignored", 690 692 parser->lineno); 691 free_servtab_strings(sep);692 693 /* Just "goto more" can make sep to carry over e.g. 693 694 * "rpc"-ness (by having se_rpcver_lo != 0). 694 695 * We will be more paranoid: */ 696 free_servtab_strings(sep); 695 697 free(sep); 696 698 goto new; … … 726 728 #endif 727 729 } 728 if ( strncmp(arg, "rpc/", 4) == 0) {730 if (is_prefixed_with(arg, "rpc/")) { 729 731 #if ENABLE_FEATURE_INETD_RPC 730 732 unsigned n; … … 816 818 #endif 817 819 argc = 0; 818 while ( (arg = token[6+argc]) != NULL && argc < MAXARGV)820 while (argc < MAXARGV && (arg = token[6+argc]) != NULL) 819 821 sep->se_argv[argc++] = xstrdup(arg); 820 822 /* Some inetd.conf files have no argv's, not even argv[0]. … … 835 837 } 836 838 837 // bb_info_msg(838 //"ENTRY[%s][%s][%s][%d][%d][%d][%d][%d][%s][%s][%s]",839 //sep->se_local_hostname, sep->se_service, sep->se_proto, sep->se_wait, sep->se_proto_no,840 //sep->se_max, sep->se_count, sep->se_time, sep->se_user, sep->se_group, sep->se_program);839 //bb_error_msg( 840 // "ENTRY[%s][%s][%s][%d][%d][%d][%d][%d][%s][%s][%s]", 841 // sep->se_local_hostname, sep->se_service, sep->se_proto, sep->se_wait, sep->se_proto_no, 842 // sep->se_max, sep->se_count, sep->se_time, sep->se_user, sep->se_group, sep->se_program); 841 843 842 844 /* check if the hostname specifier is a comma separated list … … 1655 1657 time_t t; 1656 1658 1657 t = time(NULL);1659 time(&t); 1658 1660 fdprintf(s, "%.24s\r\n", ctime(&t)); 1659 1661 } -
branches/3.3/mindi-busybox/networking/interface.c
r3232 r3621 90 90 static const char* FAST_FUNC INET_sprint(struct sockaddr *sap, int numeric) 91 91 { 92 static char *buff; /* defaults to NULL */93 94 free(buff);95 92 if (sap->sa_family == 0xFFFF || sap->sa_family == 0) 96 93 return "[NONE SET]"; 97 buff = INET_rresolve((struct sockaddr_in *) sap, numeric, 0xffffff00); 98 return buff; 94 return auto_string(INET_rresolve((struct sockaddr_in *) sap, numeric, 0xffffff00)); 99 95 } 100 96 … … 172 168 static const char* FAST_FUNC INET6_sprint(struct sockaddr *sap, int numeric) 173 169 { 174 static char *buff;175 176 free(buff);177 170 if (sap->sa_family == 0xFFFF || sap->sa_family == 0) 178 171 return "[NONE SET]"; 179 buff = INET6_rresolve((struct sockaddr_in6 *) sap, numeric); 180 return buff; 172 return auto_string(INET6_rresolve((struct sockaddr_in6 *) sap, numeric)); 181 173 } 182 174 … … 224 216 static char* FAST_FUNC UNSPEC_print(unsigned char *ptr) 225 217 { 226 static char *buff; 227 218 char *buff; 228 219 char *pos; 229 220 unsigned int i; 230 221 231 if (!buff) 232 buff = xmalloc(sizeof(struct sockaddr) * 3 + 1); 222 buff = auto_string(xmalloc(sizeof(struct sockaddr) * 3 + 1)); 233 223 pos = buff; 234 224 for (i = 0; i < sizeof(struct sockaddr); i++) { … … 713 703 static char* FAST_FUNC ether_print(unsigned char *ptr) 714 704 { 715 static char *buff; 716 717 free(buff); 705 char *buff; 718 706 buff = xasprintf("%02X:%02X:%02X:%02X:%02X:%02X", 719 707 (ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377), 720 708 (ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377) 721 709 ); 722 return buff; 723 } 724 725 static int FAST_FUNC ether_input(const char *bufp, struct sockaddr *sap); 710 return auto_string(buff); 711 } 726 712 727 713 static const struct hwtype ether_hwtype = { … … 731 717 .alen = ETH_ALEN, 732 718 .print = ether_print, 733 .input = ether_input 734 }; 735 736 static unsigned hexchar2int(char c) 737 { 738 if (isdigit(c)) 739 return c - '0'; 740 c &= ~0x20; /* a -> A */ 741 if ((unsigned)(c - 'A') <= 5) 742 return c - ('A' - 10); 743 return ~0U; 744 } 745 746 /* Input an Ethernet address and convert to binary. */ 747 static int FAST_FUNC ether_input(const char *bufp, struct sockaddr *sap) 748 { 749 unsigned char *ptr; 750 char c; 751 int i; 752 unsigned val; 753 754 sap->sa_family = ether_hwtype.type; 755 ptr = (unsigned char*) sap->sa_data; 756 757 i = 0; 758 while ((*bufp != '\0') && (i < ETH_ALEN)) { 759 val = hexchar2int(*bufp++) * 0x10; 760 if (val > 0xff) { 761 errno = EINVAL; 762 return -1; 763 } 764 c = *bufp; 765 if (c == ':' || c == 0) 766 val >>= 4; 767 else { 768 val |= hexchar2int(c); 769 if (val > 0xff) { 770 errno = EINVAL; 771 return -1; 772 } 773 } 774 if (c != 0) 775 bufp++; 776 *ptr++ = (unsigned char) val; 777 i++; 778 779 /* We might get a semicolon here - not required. */ 780 if (*bufp == ':') { 781 bufp++; 782 } 783 } 784 return 0; 785 } 719 .input = in_ether 720 }; 786 721 787 722 static const struct hwtype ppp_hwtype = { … … 928 863 { 929 864 FILE *f; 930 char addr6[40], devname[2 0];865 char addr6[40], devname[21]; 931 866 struct sockaddr_in6 sap; 932 867 int plen, scope, dad_status, if_idx; … … 947 882 addr6p[0], addr6p[1], addr6p[2], addr6p[3], 948 883 addr6p[4], addr6p[5], addr6p[6], addr6p[7]); 884 memset(&sap, 0, sizeof(sap)); 949 885 inet_pton(AF_INET6, addr6, 950 886 (struct sockaddr *) &sap.sin6_addr); -
branches/3.3/mindi-busybox/networking/ip.c
r3232 r3621 17 17 //usage: IF_FEATURE_IP_LINK("link | ") 18 18 //usage: IF_FEATURE_IP_TUNNEL("tunnel | ") 19 //usage: IF_FEATURE_IP_NEIGH("neigh | ") 19 20 //usage: IF_FEATURE_IP_RULE("rule") 20 21 //usage: "} {COMMAND}" … … 26 27 //usage: IF_FEATURE_IP_LINK("link | ") 27 28 //usage: IF_FEATURE_IP_TUNNEL("tunnel | ") 29 //usage: IF_FEATURE_IP_NEIGH("neigh | ") 28 30 //usage: IF_FEATURE_IP_RULE("rule") 29 31 //usage: "}\n" … … 34 36 //usage: " [dev STRING] [to PREFIX] }" 35 37 //usage:#define ipaddr_full_usage "\n\n" 36 //usage: "ipaddr {add| delete} IFADDR dev STRING\n"38 //usage: "ipaddr {add|change|replace|delete} IFADDR dev STRING\n" 37 39 //usage: "ipaddr {show|flush} [dev STRING] [scope SCOPE-ID]\n" 38 40 //usage: " [to PREFIX] [label PATTERN]\n" … … 81 83 //usage: " [[i|o]seq] [[i|o]key KEY] [[i|o]csum]\n" 82 84 //usage: " [ttl TTL] [tos TOS] [[no]pmtudisc] [dev PHYS_DEV]" 85 //usage: 86 //usage:#define ipneigh_trivial_usage 87 //usage: "{ show | flush} [ to PREFIX ] [ dev DEV ] [ nud STATE ]" 88 //usage:#define ipneigh_full_usage "\n\n" 89 //usage: "ipneigh { show | flush} [ to PREFIX ] [ dev DEV ] [ nud STATE ]" 83 90 84 91 #include "libbb.h" … … 91 98 || ENABLE_FEATURE_IP_LINK \ 92 99 || ENABLE_FEATURE_IP_TUNNEL \ 93 || ENABLE_FEATURE_IP_RULE 100 || ENABLE_FEATURE_IP_RULE \ 101 || ENABLE_FEATURE_IP_NEIGH 94 102 95 103 static int FAST_FUNC ip_print_help(char **argv UNUSED_PARAM) … … 141 149 } 142 150 #endif 151 #if ENABLE_FEATURE_IP_NEIGH 152 int ipneigh_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 153 int ipneigh_main(int argc UNUSED_PARAM, char **argv) 154 { 155 return ip_do(do_ipneigh, argv); 156 } 157 #endif 143 158 144 159 … … 154 169 IF_FEATURE_IP_TUNNEL("tunl\0") 155 170 IF_FEATURE_IP_RULE("rule\0") 171 IF_FEATURE_IP_NEIGH("neigh\0") 156 172 ; 157 173 static const ip_func_ptr_t ip_func_ptrs[] = { … … 164 180 IF_FEATURE_IP_TUNNEL(do_iptunnel,) 165 181 IF_FEATURE_IP_RULE(do_iprule,) 182 IF_FEATURE_IP_NEIGH(do_ipneigh,) 166 183 }; 167 184 ip_func_ptr_t ip_func; -
branches/3.3/mindi-busybox/networking/ipcalc.c
r3232 r3621 14 14 15 15 //usage:#define ipcalc_trivial_usage 16 //usage: "[OPTIONS] ADDRESS[[/]NETMASK] [NETMASK]" 16 //usage: "[OPTIONS] ADDRESS" 17 //usage: IF_FEATURE_IPCALC_FANCY("[/PREFIX]") " [NETMASK]" 17 18 //usage:#define ipcalc_full_usage "\n\n" 18 19 //usage: "Calculate IP network settings from a IP address\n" -
branches/3.3/mindi-busybox/networking/isrv.c
r2725 r3621 195 195 } 196 196 197 void BUG_sizeof_fd_set_is_strange(void);198 197 static void handle_fd_set(isrv_state_t *state, fd_set *fds, int (*h)(int, void **)) 199 198 { … … 204 203 int fd_cnt = FD_COUNT; 205 204 206 if (LONG_CNT * sizeof(long) != sizeof(fd_set)) 207 BUG_sizeof_fd_set_is_strange(); 205 BUILD_BUG_ON(LONG_CNT * sizeof(long) != sizeof(fd_set)); 208 206 209 207 fds_pos = 0; -
branches/3.3/mindi-busybox/networking/isrv.h
r2725 r3621 24 24 int isrv_register_peer(isrv_state_t *state, void *param); 25 25 26 /* driver */ 26 /* Driver: 27 * 28 * Select on listen_fd for <linger_timeout> (or forever if 0). 29 * 30 * If we time out and we have no peers, exit. 31 * If we have peers, call do_timeout(peer_param), 32 * if it returns !0, peer is removed. 33 * 34 * If listen_fd is active, accept new connection ("peer"), 35 * call new_peer() on it, and if it returns 0, 36 * add it to fds to select on. 37 * Now, select will wait for <timeout>, not <linger_timeout> 38 * (as long as we have more than zero peers). 39 * 40 * If a peer's fd is active, we call do_rd() on it if read 41 * bit was set, and then do_wr() if write bit was also set. 42 * If either returns !0, peer is removed. 43 * Reaching this place also resets timeout counter for this peer. 44 * 45 * Note that peer must indicate that he wants to be selected 46 * for read and/or write using isrv_want_rd()/isrv_want_wr() 47 * [can be called in new_peer() or in do_rd()/do_wr()]. 48 * If it never wants to be selected for write, do_wr() 49 * will never be called (can be NULL). 50 */ 27 51 void isrv_run( 28 52 int listen_fd, -
branches/3.3/mindi-busybox/networking/isrv_identd.c
r3232 r3621 19 19 20 20 #include "libbb.h" 21 #include "common_bufsiz.h" 21 22 #include <syslog.h> 22 23 #include "isrv.h" … … 26 27 typedef struct identd_buf_t { 27 28 int pos; 28 int fd_flag; 29 char buf[64 - 2*sizeof(int)]; 29 char buf[64 - sizeof(int)]; 30 30 } identd_buf_t; 31 31 … … 43 43 return peer; /* failure, unregister peer */ 44 44 45 buf->fd_flag = fcntl(fd, F_GETFL) | O_NONBLOCK;45 ndelay_on(fd); 46 46 isrv_want_rd(state, fd); 47 47 return 0; … … 52 52 identd_buf_t *buf = *paramp; 53 53 char *cur, *p; 54 int retval = 0; /* session is ok (so far) */55 54 int sz; 56 55 57 56 cur = buf->buf + buf->pos; 58 57 59 if (buf->fd_flag & O_NONBLOCK) 60 fcntl(fd, F_SETFL, buf->fd_flag); 61 sz = safe_read(fd, cur, sizeof(buf->buf) - buf->pos); 58 sz = safe_read(fd, cur, sizeof(buf->buf) - 1 - buf->pos); 62 59 63 60 if (sz < 0) { 64 61 if (errno != EAGAIN) 65 goto term; /* terminate this session if !EAGAIN */66 goto ok;62 goto term; 63 return 0; /* "session is ok" */ 67 64 } 68 65 … … 72 69 if (p) 73 70 *p = '\0'; 74 if (!p && sz && buf->pos <= (int)sizeof(buf->buf)) 75 goto ok; 71 if (!p && sz) 72 return 0; /* "session is ok" */ 73 76 74 /* Terminate session. If we are in server mode, then 77 75 * fd is still in nonblocking mode - we never block here */ 78 if (fd == 0) fd++; /* inetd mode? then write to fd 1 */ 76 if (fd == 0) 77 fd++; /* inetd mode? then write to fd 1 */ 79 78 fdprintf(fd, "%s : USERID : UNIX : %s\r\n", buf->buf, bogouser); 79 /* 80 * Why bother if we are going to close fd now anyway? 81 * if (server) 82 * ndelay_off(fd); 83 */ 80 84 term: 81 85 free(buf); 82 retval = 1; /* terminate */ 83 ok: 84 if (buf->fd_flag & O_NONBLOCK) 85 fcntl(fd, F_SETFL, buf->fd_flag & ~O_NONBLOCK); 86 return retval; 86 return 1; /* "terminate" */ 87 87 } 88 88 … … 96 96 identd_buf_t *buf = xzalloc(sizeof(*buf)); 97 97 /* buf->pos = 0; - xzalloc did it */ 98 /* We do NOT want nonblocking I/O here! */99 /* buf->fd_flag = 0; - xzalloc did it */100 98 do 101 99 alarm(TIMEOUT); 100 /* Note: we do NOT want nonblocking I/O here! */ 102 101 while (do_rd(0, (void*)&buf) == 0); 103 102 } … … 118 117 int fd; 119 118 119 setup_common_bufsiz(); 120 120 121 opt = getopt32(argv, "fiwb:", &bind_address); 121 122 strcpy(bogouser, "nobody"); 122 123 if (argv[optind]) 123 strncpy(bogouser, argv[optind], sizeof(bogouser));124 strncpy(bogouser, argv[optind], COMMON_BUFSIZE - 1); 124 125 125 126 /* Daemonize if no -f and no -i and no -w */ -
branches/3.3/mindi-busybox/networking/libiproute/Kbuild.src
r2725 r3621 65 65 rt_names.o \ 66 66 utils.o 67 68 lib-$(CONFIG_FEATURE_IP_NEIGH) += \ 69 ip_parse_common_args.o \ 70 ipneigh.o \ 71 libnetlink.o \ 72 ll_map.o \ 73 rt_names.o \ 74 utils.o -
branches/3.3/mindi-busybox/networking/libiproute/ip_common.h
r2725 r3621 25 25 int FAST_FUNC do_iproute(char **argv); 26 26 int FAST_FUNC do_iprule(char **argv); 27 //int FAST_FUNC do_ipneigh(char **argv);27 int FAST_FUNC do_ipneigh(char **argv); 28 28 int FAST_FUNC do_iptunnel(char **argv); 29 29 int FAST_FUNC do_iplink(char **argv); -
branches/3.3/mindi-busybox/networking/libiproute/ip_parse_common_args.c
r2725 r3621 68 68 arg = index_in_strings(families, *argv); 69 69 if (arg < 0) 70 invarg (*argv, "protocolfamily");70 invarg_1_to_2(*argv, "family"); 71 71 /* now arg == 0, 1 or 2 */ 72 72 } else { -
branches/3.3/mindi-busybox/networking/libiproute/ipaddress.c
r3232 r3621 14 14 15 15 #include "ip_common.h" /* #include "libbb.h" is inside */ 16 #include "common_bufsiz.h" 16 17 #include "rt_names.h" 17 18 #include "utils.h" … … 40 41 typedef struct filter_t filter_t; 41 42 42 #define G_filter (*(filter_t*) &bb_common_bufsiz1)43 43 #define G_filter (*(filter_t*)bb_common_bufsiz1) 44 #define INIT_G() do { setup_common_bufsiz(); } while (0) 44 45 45 46 static void print_link_flags(unsigned flags, unsigned mdown) … … 138 139 unsigned m_flag = 0; 139 140 if (tb[IFLA_LINK]) { 140 SPRINT_BUF(b1);141 141 int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); 142 142 if (iflink == 0) 143 143 printf("@NONE: "); 144 144 else { 145 printf("@%s: ", ll_i dx_n2a(iflink, b1));145 printf("@%s: ", ll_index_to_name(iflink)); 146 146 m_flag = ll_index_to_flags(iflink); 147 147 m_flag = !(m_flag & IFF_UP); … … 159 159 #ifdef IFLA_MASTER 160 160 if (tb[IFLA_MASTER]) { 161 SPRINT_BUF(b1); 162 printf("master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); 161 printf("master %s ", ll_index_to_name(*(int*)RTA_DATA(tb[IFLA_MASTER]))); 163 162 } 164 163 #endif … … 217 216 struct ifaddrmsg *ifa = NLMSG_DATA(n); 218 217 int len = n->nlmsg_len; 219 struct rtattr * rta_tb[IFA_MAX+1]; 220 char abuf[256]; 221 SPRINT_BUF(b1); 218 struct rtattr *rta_tb[IFA_MAX+1]; 222 219 223 220 if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) … … 251 248 label = RTA_DATA(rta_tb[IFA_LABEL]); 252 249 else 253 label = ll_i dx_n2a(ifa->ifa_index, b1);250 label = ll_index_to_name(ifa->ifa_index); 254 251 if (fnmatch(G_filter.label, label, 0) != 0) 255 252 return 0; … … 295 292 296 293 if (rta_tb[IFA_LOCAL]) { 297 fputs(rt_addr_n2a(ifa->ifa_family, 298 RTA_DATA(rta_tb[IFA_LOCAL]),299 abuf, sizeof(abuf)), stdout);294 fputs(rt_addr_n2a(ifa->ifa_family, RTA_DATA(rta_tb[IFA_LOCAL])), 295 stdout 296 ); 300 297 301 298 if (rta_tb[IFA_ADDRESS] == NULL … … 305 302 } else { 306 303 printf(" peer %s/%d ", 307 rt_addr_n2a(ifa->ifa_family, 308 RTA_DATA(rta_tb[IFA_ADDRESS]), 309 abuf, sizeof(abuf)), 310 ifa->ifa_prefixlen); 304 rt_addr_n2a(ifa->ifa_family, RTA_DATA(rta_tb[IFA_ADDRESS])), 305 ifa->ifa_prefixlen 306 ); 311 307 } 312 308 } … … 315 311 printf("brd %s ", 316 312 rt_addr_n2a(ifa->ifa_family, 317 RTA_DATA(rta_tb[IFA_BROADCAST]), 318 abuf, sizeof(abuf)) 313 RTA_DATA(rta_tb[IFA_BROADCAST])) 319 314 ); 320 315 } … … 322 317 printf("any %s ", 323 318 rt_addr_n2a(ifa->ifa_family, 324 RTA_DATA(rta_tb[IFA_ANYCAST]), 325 abuf, sizeof(abuf)) 319 RTA_DATA(rta_tb[IFA_ANYCAST])) 326 320 ); 327 321 } 328 printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope , b1));322 printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope)); 329 323 if (ifa->ifa_flags & IFA_F_SECONDARY) { 330 324 ifa->ifa_flags &= ~IFA_F_SECONDARY; … … 459 453 if (rtnl_rtscope_a2n(&scope, *argv)) { 460 454 if (strcmp(*argv, "all") != 0) { 461 invarg (*argv, "scope");455 invarg_1_to_2(*argv, "scope"); 462 456 } 463 457 scope = RT_SCOPE_NOWHERE; … … 557 551 } 558 552 if (G_filter.label) { 559 SPRINT_BUF(b1);560 553 const char *label; 561 554 if (tb[IFA_LABEL]) 562 555 label = RTA_DATA(tb[IFA_LABEL]); 563 556 else 564 label = ll_i dx_n2a(ifa->ifa_index, b1);557 label = ll_index_to_name(ifa->ifa_index); 565 558 if (fnmatch(G_filter.label, label, 0) != 0) 566 559 continue; … … 599 592 600 593 /* Return value becomes exitcode. It's okay to not return at all */ 601 static int ipaddr_modify(int cmd, char **argv)594 static int ipaddr_modify(int cmd, int flags, char **argv) 602 595 { 603 596 static const char option[] ALIGN1 = … … 623 616 624 617 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); 625 req.n.nlmsg_flags = NLM_F_REQUEST ;618 req.n.nlmsg_flags = NLM_F_REQUEST | flags; 626 619 req.n.nlmsg_type = cmd; 627 620 req.ifa.ifa_family = preferred_family; 628 621 629 622 while (*argv) { 630 const smalluint arg = index_in_strings(option, *argv); 623 unsigned arg = index_in_strings(option, *argv); 624 /* if search fails, "local" is assumed */ 625 if ((int)arg >= 0) 626 NEXT_ARG(); 627 631 628 if (arg <= 1) { /* peer, remote */ 632 NEXT_ARG();633 634 629 if (peer_len) { 635 630 duparg("peer", *argv); … … 644 639 } else if (arg <= 3) { /* broadcast, brd */ 645 640 inet_prefix addr; 646 NEXT_ARG();647 641 if (brd_len) { 648 642 duparg("broadcast", *argv); … … 661 655 } else if (arg == 4) { /* anycast */ 662 656 inet_prefix addr; 663 NEXT_ARG();664 657 if (any_len) { 665 658 duparg("anycast", *argv); … … 673 666 } else if (arg == 5) { /* scope */ 674 667 uint32_t scope = 0; 675 NEXT_ARG();676 668 if (rtnl_rtscope_a2n(&scope, *argv)) { 677 invarg (*argv, "scope");669 invarg_1_to_2(*argv, "scope"); 678 670 } 679 671 req.ifa.ifa_scope = scope; 680 672 scoped = 1; 681 673 } else if (arg == 6) { /* dev */ 682 NEXT_ARG();683 674 d = *argv; 684 675 } else if (arg == 7) { /* label */ 685 NEXT_ARG();686 676 l = *argv; 687 677 addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1); 688 678 } else { 689 if (arg == 8) /* local */ 690 NEXT_ARG(); 679 /* local (specified or assumed) */ 691 680 if (local_len) { 692 681 duparg2("local", *argv); … … 706 695 bb_error_msg_and_die("need \"dev IFACE\""); 707 696 } 708 if (l && strncmp(d, l, strlen(d)) != 0) {697 if (l && !is_prefixed_with(l, d)) { 709 698 bb_error_msg_and_die("\"dev\" (%s) must match \"label\" (%s)", d, l); 710 699 } … … 725 714 brd = peer; 726 715 if (brd.bitlen <= 30) { 727 for (i =31; i>=brd.bitlen; i--) {716 for (i = 31; i >= brd.bitlen; i--) { 728 717 if (brd_len == -1) 729 718 brd.data[0] |= htonl(1<<(31-i)); … … 754 743 { 755 744 static const char commands[] ALIGN1 = 756 "add\0""delete\0""list\0""show\0""lst\0""flush\0"; 757 smalluint cmd = 2; 745 /* 0 1 2 3 4 5 6 7 8 */ 746 "add\0""change\0""chg\0""replace\0""delete\0""list\0""show\0""lst\0""flush\0"; 747 int cmd = 2; 748 749 INIT_G(); 750 758 751 if (*argv) { 759 752 cmd = index_in_substrings(commands, *argv); 760 if (cmd > 5)761 bb_error_msg_and_die(bb_msg_invalid_arg,*argv, applet_name);753 if (cmd < 0) 754 invarg_1_to_2(*argv, applet_name); 762 755 argv++; 763 if (cmd <= 1) 764 return ipaddr_modify((cmd == 0) ? RTM_NEWADDR : RTM_DELADDR, argv); 765 } 766 /* 2 == list, 3 == show, 4 == lst */ 767 return ipaddr_list_or_flush(argv, cmd == 5); 768 } 756 if (cmd <= 4) { 757 return ipaddr_modify( 758 /*cmd:*/ cmd == 4 ? RTM_DELADDR : RTM_NEWADDR, 759 /*flags:*/ 760 cmd == 0 ? NLM_F_CREATE|NLM_F_EXCL : /* add */ 761 cmd == 1 || cmd == 2 ? NLM_F_REPLACE : /* change */ 762 cmd == 3 ? NLM_F_CREATE|NLM_F_REPLACE : /* replace */ 763 0 /* delete */ 764 , argv); 765 } 766 } 767 return ipaddr_list_or_flush(argv, cmd == 8); 768 } -
branches/3.3/mindi-busybox/networking/libiproute/iplink.c
r3232 r3621 2 2 /* 3 3 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 4 * Patrick McHardy <kaber@trash.net> 4 5 * 5 6 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 6 7 */ 7 8 #include <net/if.h> 8 #include <net/if_packet.h> 9 /*#include <net/if_packet.h> - not needed? */ 9 10 #include <netpacket/packet.h> 10 11 #include <netinet/if_ether.h> 11 12 13 #include <linux/if_vlan.h> 12 14 #include "ip_common.h" /* #include "libbb.h" is inside */ 13 15 #include "rt_names.h" 14 16 #include "utils.h" 15 17 18 #undef ETH_P_8021AD 19 #define ETH_P_8021AD 0x88A8 20 #undef VLAN_FLAG_REORDER_HDR 21 #define VLAN_FLAG_REORDER_HDR 0x1 22 #undef VLAN_FLAG_GVRP 23 #define VLAN_FLAG_GVRP 0x2 24 #undef VLAN_FLAG_LOOSE_BINDING 25 #define VLAN_FLAG_LOOSE_BINDING 0x4 26 #undef VLAN_FLAG_MVRP 27 #define VLAN_FLAG_MVRP 0x8 28 #undef IFLA_VLAN_PROTOCOL 29 #define IFLA_VLAN_PROTOCOL 5 30 16 31 #ifndef IFLA_LINKINFO 17 32 # define IFLA_LINKINFO 18 18 33 # define IFLA_INFO_KIND 1 34 # define IFLA_INFO_DATA 2 35 #endif 36 37 #ifndef IFLA_VLAN_MAX 38 # define IFLA_VLAN_ID 1 39 # define IFLA_VLAN_FLAGS 2 40 struct ifla_vlan_flags { 41 uint32_t flags; 42 uint32_t mask; 43 }; 19 44 #endif 20 45 21 46 /* taken from linux/sockios.h */ 22 47 #define SIOCSIFNAME 0x8923 /* set interface name */ 48 49 #if 0 50 # define dbg(...) bb_error_msg(__VA_ARGS__) 51 #else 52 # define dbg(...) ((void)0) 53 #endif 23 54 24 55 /* Exits on error */ … … 278 309 } 279 310 311 static void vlan_parse_opt(char **argv, struct nlmsghdr *n, unsigned int size) 312 { 313 static const char keywords[] ALIGN1 = 314 "id\0" 315 "protocol\0" 316 "reorder_hdr\0" 317 "gvrp\0" 318 "mvrp\0" 319 "loose_binding\0" 320 ; 321 static const char protocols[] ALIGN1 = 322 "802.1q\0" 323 "802.1ad\0" 324 ; 325 static const char str_on_off[] ALIGN1 = 326 "on\0" 327 "off\0" 328 ; 329 enum { 330 ARG_id = 0, 331 ARG_reorder_hdr, 332 ARG_gvrp, 333 ARG_mvrp, 334 ARG_loose_binding, 335 ARG_protocol, 336 }; 337 enum { 338 PROTO_8021Q = 0, 339 PROTO_8021AD, 340 }; 341 enum { 342 PARM_on = 0, 343 PARM_off 344 }; 345 int arg; 346 uint16_t id, proto; 347 struct ifla_vlan_flags flags = {}; 348 349 while (*argv) { 350 arg = index_in_substrings(keywords, *argv); 351 if (arg < 0) 352 invarg_1_to_2(*argv, "type vlan"); 353 354 NEXT_ARG(); 355 if (arg == ARG_id) { 356 id = get_u16(*argv, "id"); 357 addattr_l(n, size, IFLA_VLAN_ID, &id, sizeof(id)); 358 } else if (arg == ARG_protocol) { 359 arg = index_in_substrings(protocols, *argv); 360 if (arg == PROTO_8021Q) 361 proto = ETH_P_8021Q; 362 else if (arg == PROTO_8021AD) 363 proto = ETH_P_8021AD; 364 else 365 bb_error_msg_and_die("unknown VLAN encapsulation protocol '%s'", 366 *argv); 367 addattr_l(n, size, IFLA_VLAN_PROTOCOL, &proto, sizeof(proto)); 368 } else { 369 int param = index_in_strings(str_on_off, *argv); 370 if (param < 0) 371 die_must_be_on_off(nth_string(keywords, arg)); 372 373 if (arg == ARG_reorder_hdr) { 374 flags.mask |= VLAN_FLAG_REORDER_HDR; 375 flags.flags &= ~VLAN_FLAG_REORDER_HDR; 376 if (param == PARM_on) 377 flags.flags |= VLAN_FLAG_REORDER_HDR; 378 } else if (arg == ARG_gvrp) { 379 flags.mask |= VLAN_FLAG_GVRP; 380 flags.flags &= ~VLAN_FLAG_GVRP; 381 if (param == PARM_on) 382 flags.flags |= VLAN_FLAG_GVRP; 383 } else if (arg == ARG_mvrp) { 384 flags.mask |= VLAN_FLAG_MVRP; 385 flags.flags &= ~VLAN_FLAG_MVRP; 386 if (param == PARM_on) 387 flags.flags |= VLAN_FLAG_MVRP; 388 } else { /*if (arg == ARG_loose_binding) */ 389 flags.mask |= VLAN_FLAG_LOOSE_BINDING; 390 flags.flags &= ~VLAN_FLAG_LOOSE_BINDING; 391 if (param == PARM_on) 392 flags.flags |= VLAN_FLAG_LOOSE_BINDING; 393 } 394 } 395 argv++; 396 } 397 398 if (flags.mask) 399 addattr_l(n, size, IFLA_VLAN_FLAGS, &flags, sizeof(flags)); 400 } 401 280 402 #ifndef NLMSG_TAIL 281 403 #define NLMSG_TAIL(nmsg) \ … … 283 405 #endif 284 406 /* Return value becomes exitcode. It's okay to not return at all */ 285 static int do_ change(char **argv, const unsigned rtm)407 static int do_add_or_delete(char **argv, const unsigned rtm) 286 408 { 287 409 static const char keywords[] ALIGN1 = 288 "link\0""name\0""type\0""dev\0" ;410 "link\0""name\0""type\0""dev\0""address\0"; 289 411 enum { 290 412 ARG_link, … … 292 414 ARG_type, 293 415 ARG_dev, 416 ARG_address, 294 417 }; 295 418 struct rtnl_handle rth; … … 300 423 } req; 301 424 smalluint arg; 302 char *name_str = NULL, *link_str = NULL, *type_str = NULL, *dev_str = NULL; 425 char *name_str = NULL; 426 char *link_str = NULL; 427 char *type_str = NULL; 428 char *dev_str = NULL; 429 char *address_str = NULL; 303 430 304 431 memset(&req, 0, sizeof(req)); … … 313 440 while (*argv) { 314 441 arg = index_in_substrings(keywords, *argv); 442 if (arg == ARG_type) { 443 NEXT_ARG(); 444 type_str = *argv++; 445 dbg("type_str:'%s'", type_str); 446 break; 447 } 315 448 if (arg == ARG_link) { 316 449 NEXT_ARG(); 317 450 link_str = *argv; 451 dbg("link_str:'%s'", link_str); 318 452 } else if (arg == ARG_name) { 319 453 NEXT_ARG(); 320 454 name_str = *argv; 321 } else if (arg == ARG_type) { 322 NEXT_ARG(); 323 type_str = *argv; 455 dbg("name_str:'%s'", name_str); 456 } else if (arg == ARG_address) { 457 NEXT_ARG(); 458 address_str = *argv; 459 dbg("address_str:'%s'", name_str); 324 460 } else { 325 461 if (arg == ARG_dev) { … … 329 465 } 330 466 dev_str = *argv; 467 dbg("dev_str:'%s'", dev_str); 331 468 } 332 469 argv++; … … 340 477 addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type_str, 341 478 strlen(type_str)); 479 480 if (*argv) { 481 struct rtattr *data = NLMSG_TAIL(&req.n); 482 addattr_l(&req.n, sizeof(req), IFLA_INFO_DATA, NULL, 0); 483 484 if (strcmp(type_str, "vlan") == 0) 485 vlan_parse_opt(argv, &req.n, sizeof(req)); 486 487 data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; 488 } 489 342 490 linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo; 343 491 } … … 353 501 addattr_l(&req.n, sizeof(req), IFLA_LINK, &idx, 4); 354 502 } 503 if (address_str) { 504 unsigned char abuf[32]; 505 int len = ll_addr_a2n(abuf, sizeof(abuf), address_str); 506 dbg("address len:%d", len); 507 if (len < 0) 508 return -1; 509 addattr_l(&req.n, sizeof(req), IFLA_ADDRESS, abuf, len); 510 } 355 511 } 356 512 if (name_str) { 357 513 const size_t name_len = strlen(name_str) + 1; 358 514 if (name_len < 2 || name_len > IFNAMSIZ) 359 invarg (name_str, "name");515 invarg_1_to_2(name_str, "name"); 360 516 addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name_str, name_len); 361 517 } … … 365 521 } 366 522 523 /* Other keywords recognized by iproute2-3.12.0: */ 524 #if 0 525 } else if (matches(*argv, "broadcast") == 0 || 526 strcmp(*argv, "brd") == 0) { 527 NEXT_ARG(); 528 len = ll_addr_a2n(abuf, sizeof(abuf), *argv); 529 if (len < 0) 530 return -1; 531 addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len); 532 } else if (matches(*argv, "txqueuelen") == 0 || 533 strcmp(*argv, "qlen") == 0 || 534 matches(*argv, "txqlen") == 0) { 535 NEXT_ARG(); 536 if (qlen != -1) 537 duparg("txqueuelen", *argv); 538 if (get_integer(&qlen, *argv, 0)) 539 invarg_1_to_2(*argv, "txqueuelen"); 540 addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4); 541 } else if (strcmp(*argv, "mtu") == 0) { 542 NEXT_ARG(); 543 if (mtu != -1) 544 duparg("mtu", *argv); 545 if (get_integer(&mtu, *argv, 0)) 546 invarg_1_to_2(*argv, "mtu"); 547 addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4); 548 } else if (strcmp(*argv, "netns") == 0) { 549 NEXT_ARG(); 550 if (netns != -1) 551 duparg("netns", *argv); 552 if ((netns = get_netns_fd(*argv)) >= 0) 553 addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD, &netns, 4); 554 else if (get_integer(&netns, *argv, 0) == 0) 555 addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4); 556 else 557 invarg_1_to_2(*argv, "netns"); 558 } else if (strcmp(*argv, "multicast") == 0) { 559 NEXT_ARG(); 560 req->i.ifi_change |= IFF_MULTICAST; 561 if (strcmp(*argv, "on") == 0) { 562 req->i.ifi_flags |= IFF_MULTICAST; 563 } else if (strcmp(*argv, "off") == 0) { 564 req->i.ifi_flags &= ~IFF_MULTICAST; 565 } else 566 return on_off("multicast", *argv); 567 } else if (strcmp(*argv, "allmulticast") == 0) { 568 NEXT_ARG(); 569 req->i.ifi_change |= IFF_ALLMULTI; 570 if (strcmp(*argv, "on") == 0) { 571 req->i.ifi_flags |= IFF_ALLMULTI; 572 } else if (strcmp(*argv, "off") == 0) { 573 req->i.ifi_flags &= ~IFF_ALLMULTI; 574 } else 575 return on_off("allmulticast", *argv); 576 } else if (strcmp(*argv, "promisc") == 0) { 577 NEXT_ARG(); 578 req->i.ifi_change |= IFF_PROMISC; 579 if (strcmp(*argv, "on") == 0) { 580 req->i.ifi_flags |= IFF_PROMISC; 581 } else if (strcmp(*argv, "off") == 0) { 582 req->i.ifi_flags &= ~IFF_PROMISC; 583 } else 584 return on_off("promisc", *argv); 585 } else if (strcmp(*argv, "trailers") == 0) { 586 NEXT_ARG(); 587 req->i.ifi_change |= IFF_NOTRAILERS; 588 if (strcmp(*argv, "off") == 0) { 589 req->i.ifi_flags |= IFF_NOTRAILERS; 590 } else if (strcmp(*argv, "on") == 0) { 591 req->i.ifi_flags &= ~IFF_NOTRAILERS; 592 } else 593 return on_off("trailers", *argv); 594 } else if (strcmp(*argv, "arp") == 0) { 595 NEXT_ARG(); 596 req->i.ifi_change |= IFF_NOARP; 597 if (strcmp(*argv, "on") == 0) { 598 req->i.ifi_flags &= ~IFF_NOARP; 599 } else if (strcmp(*argv, "off") == 0) { 600 req->i.ifi_flags |= IFF_NOARP; 601 } else 602 return on_off("noarp", *argv); 603 } else if (strcmp(*argv, "vf") == 0) { 604 struct rtattr *vflist; 605 NEXT_ARG(); 606 if (get_integer(&vf, *argv, 0)) { 607 invarg_1_to_2(*argv, "vf"); 608 } 609 vflist = addattr_nest(&req->n, sizeof(*req), 610 IFLA_VFINFO_LIST); 611 len = iplink_parse_vf(vf, &argc, &argv, req); 612 if (len < 0) 613 return -1; 614 addattr_nest_end(&req->n, vflist); 615 } else if (matches(*argv, "master") == 0) { 616 int ifindex; 617 NEXT_ARG(); 618 ifindex = ll_name_to_index(*argv); 619 if (!ifindex) 620 invarg_1_to_2(*argv, "master"); 621 addattr_l(&req->n, sizeof(*req), IFLA_MASTER, 622 &ifindex, 4); 623 } else if (matches(*argv, "nomaster") == 0) { 624 int ifindex = 0; 625 addattr_l(&req->n, sizeof(*req), IFLA_MASTER, 626 &ifindex, 4); 627 } else if (matches(*argv, "dynamic") == 0) { 628 NEXT_ARG(); 629 req->i.ifi_change |= IFF_DYNAMIC; 630 if (strcmp(*argv, "on") == 0) { 631 req->i.ifi_flags |= IFF_DYNAMIC; 632 } else if (strcmp(*argv, "off") == 0) { 633 req->i.ifi_flags &= ~IFF_DYNAMIC; 634 } else 635 return on_off("dynamic", *argv); 636 } else if (matches(*argv, "alias") == 0) { 637 NEXT_ARG(); 638 addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS, 639 *argv, strlen(*argv)); 640 argc--; argv++; 641 break; 642 } else if (strcmp(*argv, "group") == 0) { 643 NEXT_ARG(); 644 if (*group != -1) 645 duparg("group", *argv); 646 if (rtnl_group_a2n(group, *argv)) 647 invarg_1_to_2(*argv, "group"); 648 } else if (strcmp(*argv, "mode") == 0) { 649 int mode; 650 NEXT_ARG(); 651 mode = get_link_mode(*argv); 652 if (mode < 0) 653 invarg_1_to_2(*argv, "mode"); 654 addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode); 655 } else if (strcmp(*argv, "state") == 0) { 656 int state; 657 NEXT_ARG(); 658 state = get_operstate(*argv); 659 if (state < 0) 660 invarg_1_to_2(*argv, "state"); 661 addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state); 662 } else if (matches(*argv, "numtxqueues") == 0) { 663 NEXT_ARG(); 664 if (numtxqueues != -1) 665 duparg("numtxqueues", *argv); 666 if (get_integer(&numtxqueues, *argv, 0)) 667 invarg_1_to_2(*argv, "numtxqueues"); 668 addattr_l(&req->n, sizeof(*req), IFLA_NUM_TX_QUEUES, 669 &numtxqueues, 4); 670 } else if (matches(*argv, "numrxqueues") == 0) { 671 NEXT_ARG(); 672 if (numrxqueues != -1) 673 duparg("numrxqueues", *argv); 674 if (get_integer(&numrxqueues, *argv, 0)) 675 invarg_1_to_2(*argv, "numrxqueues"); 676 addattr_l(&req->n, sizeof(*req), IFLA_NUM_RX_QUEUES, 677 &numrxqueues, 4); 678 } 679 #endif 680 367 681 /* Return value becomes exitcode. It's okay to not return at all */ 368 682 int FAST_FUNC do_iplink(char **argv) … … 371 685 "add\0""delete\0""set\0""show\0""lst\0""list\0"; 372 686 if (*argv) { 373 smalluint key = index_in_substrings(keywords, *argv);374 if (key > 5) /* invalid argument */375 bb_error_msg_and_die(bb_msg_invalid_arg,*argv, applet_name);687 int key = index_in_substrings(keywords, *argv); 688 if (key < 0) /* invalid argument */ 689 invarg_1_to_2(*argv, applet_name); 376 690 argv++; 377 691 if (key <= 1) /* add/delete */ 378 return do_ change(argv, key ? RTM_DELLINK : RTM_NEWLINK);379 elseif (key == 2) /* set */692 return do_add_or_delete(argv, key ? RTM_DELLINK : RTM_NEWLINK); 693 if (key == 2) /* set */ 380 694 return do_set(argv); 381 695 } -
branches/3.3/mindi-busybox/networking/libiproute/iproute.c
r3232 r3621 12 12 13 13 #include "ip_common.h" /* #include "libbb.h" is inside */ 14 #include "common_bufsiz.h" 14 15 #include "rt_names.h" 15 16 #include "utils.h" … … 44 45 typedef struct filter_t filter_t; 45 46 46 #define G_filter (*(filter_t*)&bb_common_bufsiz1) 47 #define G_filter (*(filter_t*)bb_common_bufsiz1) 48 #define INIT_G() do { setup_common_bufsiz(); } while (0) 47 49 48 50 static int flush_update(void) … … 54 56 G_filter.flushp = 0; 55 57 return 0; 56 }57 58 static unsigned get_hz(void)59 {60 static unsigned hz_internal;61 FILE *fp;62 63 if (hz_internal)64 return hz_internal;65 66 fp = fopen_for_read("/proc/net/psched");67 if (fp) {68 unsigned nom, denom;69 70 if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2)71 if (nom == 1000000)72 hz_internal = denom;73 fclose(fp);74 }75 if (!hz_internal)76 hz_internal = sysconf(_SC_CLK_TCK);77 return hz_internal;78 58 } 79 59 … … 84 64 int len = n->nlmsg_len; 85 65 struct rtattr *tb[RTA_MAX+1]; 86 char abuf[256];87 66 inet_prefix dst; 88 67 inet_prefix src; 89 68 int host_len = -1; 90 SPRINT_BUF(b1);91 69 92 70 if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) { … … 219 197 if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) { 220 198 if (flush_update()) 221 bb_error_msg_and_die("flush");199 xfunc_die(); 222 200 } 223 201 fn = (void*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp)); … … 237 215 } 238 216 if (r->rtm_type != RTN_UNICAST /* && !G_filter.type - always 0 */) { 239 printf("%s ", rtnl_rtntype_n2a(r->rtm_type , b1));217 printf("%s ", rtnl_rtntype_n2a(r->rtm_type)); 240 218 } 241 219 242 220 if (tb[RTA_DST]) { 243 221 if (r->rtm_dst_len != host_len) { 244 printf("%s/%u ", rt_addr_n2a(r->rtm_family, 245 RTA_DATA(tb[RTA_DST]), 246 abuf, sizeof(abuf)), 247 r->rtm_dst_len 248 ); 222 printf("%s/%u ", 223 rt_addr_n2a(r->rtm_family, RTA_DATA(tb[RTA_DST])), 224 r->rtm_dst_len 225 ); 249 226 } else { 250 227 printf("%s ", format_host(r->rtm_family, 251 228 RTA_PAYLOAD(tb[RTA_DST]), 252 RTA_DATA(tb[RTA_DST]), 253 abuf, sizeof(abuf)) 254 ); 229 RTA_DATA(tb[RTA_DST])) 230 ); 255 231 } 256 232 } else if (r->rtm_dst_len) { … … 261 237 if (tb[RTA_SRC]) { 262 238 if (r->rtm_src_len != host_len) { 263 printf("from %s/%u ", rt_addr_n2a(r->rtm_family, 264 RTA_DATA(tb[RTA_SRC]), 265 abuf, sizeof(abuf)), 266 r->rtm_src_len 267 ); 239 printf("from %s/%u ", 240 rt_addr_n2a(r->rtm_family, RTA_DATA(tb[RTA_SRC])), 241 r->rtm_src_len 242 ); 268 243 } else { 269 244 printf("from %s ", format_host(r->rtm_family, 270 245 RTA_PAYLOAD(tb[RTA_SRC]), 271 RTA_DATA(tb[RTA_SRC]), 272 abuf, sizeof(abuf)) 273 ); 246 RTA_DATA(tb[RTA_SRC])) 247 ); 274 248 } 275 249 } else if (r->rtm_src_len) { … … 279 253 printf("via %s ", format_host(r->rtm_family, 280 254 RTA_PAYLOAD(tb[RTA_GATEWAY]), 281 RTA_DATA(tb[RTA_GATEWAY]) ,282 abuf, sizeof(abuf)));255 RTA_DATA(tb[RTA_GATEWAY])) 256 ); 283 257 } 284 258 if (tb[RTA_OIF]) { … … 293 267 */ 294 268 printf(" src %s ", rt_addr_n2a(r->rtm_family, 295 RTA_DATA(tb[RTA_PREFSRC]), 296 abuf, sizeof(abuf))); 269 RTA_DATA(tb[RTA_PREFSRC]))); 297 270 } 298 271 if (tb[RTA_PRIORITY]) { 299 272 printf(" metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY])); 300 273 } 274 if (r->rtm_flags & RTNH_F_DEAD) { 275 printf("dead "); 276 } 277 if (r->rtm_flags & RTNH_F_ONLINK) { 278 printf("onlink "); 279 } 280 if (r->rtm_flags & RTNH_F_PERVASIVE) { 281 printf("pervasive "); 282 } 283 if (r->rtm_flags & RTM_F_NOTIFY) { 284 printf("notify "); 285 } 286 301 287 if (r->rtm_family == AF_INET6) { 302 288 struct rta_cacheinfo *ci = NULL; … … 330 316 { 331 317 static const char keywords[] ALIGN1 = 332 "src\0""via\0""mtu\0""lock\0"" protocol\0"IF_FEATURE_IP_RULE("table\0")333 "dev\0""oif\0""to\0""metric\0" ;318 "src\0""via\0""mtu\0""lock\0""scope\0""protocol\0"IF_FEATURE_IP_RULE("table\0") 319 "dev\0""oif\0""to\0""metric\0""onlink\0"; 334 320 enum { 335 321 ARG_src, 336 322 ARG_via, 337 323 ARG_mtu, PARM_lock, 324 ARG_scope, 338 325 ARG_protocol, 339 326 IF_FEATURE_IP_RULE(ARG_table,) … … 342 329 ARG_to, 343 330 ARG_metric, 331 ARG_onlink, 344 332 }; 345 333 enum { … … 360 348 char *d = NULL; 361 349 smalluint ok = 0; 350 smalluint scope_ok = 0; 362 351 int arg; 363 352 … … 368 357 req.n.nlmsg_type = cmd; 369 358 req.r.rtm_family = preferred_family; 370 if (RT_TABLE_MAIN ) /* if it is zero, memset already did it */359 if (RT_TABLE_MAIN != 0) /* if it is zero, memset already did it */ 371 360 req.r.rtm_table = RT_TABLE_MAIN; 372 if (RT_SCOPE_NOWHERE )361 if (RT_SCOPE_NOWHERE != 0) 373 362 req.r.rtm_scope = RT_SCOPE_NOWHERE; 374 363 375 364 if (cmd != RTM_DELROUTE) { 376 req.r.rtm_protocol = RTPROT_BOOT;377 365 req.r.rtm_scope = RT_SCOPE_UNIVERSE; 378 req.r.rtm_type = RTN_UNICAST; 366 if (RTPROT_BOOT != 0) 367 req.r.rtm_protocol = RTPROT_BOOT; 368 if (RTN_UNICAST != 0) 369 req.r.rtm_type = RTN_UNICAST; 379 370 } 380 371 … … 409 400 mtu = get_unsigned(*argv, "mtu"); 410 401 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu); 402 } else if (arg == ARG_scope) { 403 uint32_t scope; 404 NEXT_ARG(); 405 if (rtnl_rtscope_a2n(&scope, *argv)) 406 invarg_1_to_2(*argv, "scope"); 407 req.r.rtm_scope = scope; 408 scope_ok = 1; 411 409 } else if (arg == ARG_protocol) { 412 410 uint32_t prot; 413 411 NEXT_ARG(); 414 412 if (rtnl_rtprot_a2n(&prot, *argv)) 415 invarg (*argv, "protocol");413 invarg_1_to_2(*argv, "protocol"); 416 414 req.r.rtm_protocol = prot; 417 415 ok |= proto_ok; … … 421 419 NEXT_ARG(); 422 420 if (rtnl_rttable_a2n(&tid, *argv)) 423 invarg (*argv, "table");421 invarg_1_to_2(*argv, "table"); 424 422 req.r.rtm_table = tid; 425 423 #endif … … 432 430 metric = get_u32(*argv, "metric"); 433 431 addattr32(&req.n, sizeof(req), RTA_PRIORITY, metric); 432 } else if (arg == ARG_onlink) { 433 req.r.rtm_flags |= RTNH_F_ONLINK; 434 434 } else { 435 435 int type; … … 483 483 } 484 484 485 if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT) 486 req.r.rtm_scope = RT_SCOPE_HOST; 487 else 488 if (req.r.rtm_type == RTN_BROADCAST 489 || req.r.rtm_type == RTN_MULTICAST 490 || req.r.rtm_type == RTN_ANYCAST 491 ) { 492 req.r.rtm_scope = RT_SCOPE_LINK; 493 } 494 else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) { 495 if (cmd == RTM_DELROUTE) 496 req.r.rtm_scope = RT_SCOPE_NOWHERE; 497 else if (!(ok & gw_ok)) 485 if (!scope_ok) { 486 if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT) 487 req.r.rtm_scope = RT_SCOPE_HOST; 488 else 489 if (req.r.rtm_type == RTN_BROADCAST 490 || req.r.rtm_type == RTN_MULTICAST 491 || req.r.rtm_type == RTN_ANYCAST 492 ) { 498 493 req.r.rtm_scope = RT_SCOPE_LINK; 494 } 495 else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) { 496 if (cmd == RTM_DELROUTE) 497 req.r.rtm_scope = RT_SCOPE_NOWHERE; 498 else if (!(ok & gw_ok)) 499 req.r.rtm_scope = RT_SCOPE_LINK; 500 } 499 501 } 500 502 … … 605 607 if (rtnl_rtprot_a2n(&prot, *argv)) { 606 608 if (index_in_strings(keywords, *argv) != KW_all) 607 invarg (*argv, "protocol");609 invarg_1_to_2(*argv, "protocol"); 608 610 prot = 0; 609 611 //G_filter.protocolmask = 0; … … 630 632 uint32_t tid; 631 633 if (rtnl_rttable_a2n(&tid, *argv)) 632 invarg (*argv, "table");634 invarg_1_to_2(*argv, "table"); 633 635 G_filter.tb = tid; 634 636 #else 635 invarg (*argv, "table");637 invarg_1_to_2(*argv, "table"); 636 638 #endif 637 639 } … … 901 903 unsigned flags = 0; 902 904 int cmd = RTM_NEWROUTE; 905 906 INIT_G(); 903 907 904 908 if (!*argv) … … 940 944 return iproute_list_or_flush(argv+1, 1); 941 945 default: 942 bb_error_msg_and_die("unknown command %s", *argv);946 invarg_1_to_2(*argv, applet_name); 943 947 } 944 948 -
branches/3.3/mindi-busybox/networking/libiproute/iprule.c
r3232 r3621 45 45 int host_len = -1; 46 46 struct rtattr * tb[RTA_MAX+1]; 47 char abuf[256];48 SPRINT_BUF(b1);49 47 50 48 if (n->nlmsg_type != RTM_NEWRULE) … … 73 71 if (tb[RTA_SRC]) { 74 72 if (r->rtm_src_len != host_len) { 75 printf("%s/%u", rt_addr_n2a(r->rtm_family, 76 RTA_DATA(tb[RTA_SRC]), 77 abuf, sizeof(abuf)), 73 printf("%s/%u", 74 rt_addr_n2a(r->rtm_family, RTA_DATA(tb[RTA_SRC])), 78 75 r->rtm_src_len 79 76 ); … … 81 78 fputs(format_host(r->rtm_family, 82 79 RTA_PAYLOAD(tb[RTA_SRC]), 83 RTA_DATA(tb[RTA_SRC]), 84 abuf, sizeof(abuf)), 80 RTA_DATA(tb[RTA_SRC])), 85 81 stdout 86 82 ); … … 96 92 if (r->rtm_dst_len != host_len) { 97 93 printf("to %s/%u ", rt_addr_n2a(r->rtm_family, 98 RTA_DATA(tb[RTA_DST]), 99 abuf, sizeof(abuf)), 94 RTA_DATA(tb[RTA_DST])), 100 95 r->rtm_dst_len 101 96 ); … … 103 98 printf("to %s ", format_host(r->rtm_family, 104 99 RTA_PAYLOAD(tb[RTA_DST]), 105 RTA_DATA(tb[RTA_DST]), 106 abuf, sizeof(abuf))); 100 RTA_DATA(tb[RTA_DST]))); 107 101 } 108 102 } else if (r->rtm_dst_len) { … … 111 105 112 106 if (r->rtm_tos) { 113 printf("tos %s ", rtnl_dsfield_n2a(r->rtm_tos , b1));107 printf("tos %s ", rtnl_dsfield_n2a(r->rtm_tos)); 114 108 } 115 109 if (tb[RTA_PROTOINFO]) { … … 122 116 123 117 if (r->rtm_table) 124 printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table , b1));118 printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table)); 125 119 126 120 if (tb[RTA_FLOW]) { … … 130 124 if (from) { 131 125 printf("realms %s/", 132 rtnl_rtrealm_n2a(from , b1));126 rtnl_rtrealm_n2a(from)); 133 127 } 134 128 printf("%s ", 135 rtnl_rtrealm_n2a(to , b1));129 rtnl_rtrealm_n2a(to)); 136 130 } 137 131 … … 141 135 format_host(r->rtm_family, 142 136 RTA_PAYLOAD(tb[RTA_GATEWAY]), 143 RTA_DATA(tb[RTA_GATEWAY]) ,144 abuf, sizeof(abuf)));137 RTA_DATA(tb[RTA_GATEWAY])) 138 ); 145 139 } else 146 140 printf("masquerade"); 147 141 } else if (r->rtm_type != RTN_UNICAST) 148 fputs(rtnl_rtntype_n2a(r->rtm_type , b1), stdout);142 fputs(rtnl_rtntype_n2a(r->rtm_type), stdout); 149 143 150 144 bb_putchar('\n'); … … 216 210 key = index_in_substrings(keywords, *argv) + 1; 217 211 if (key == 0) /* no match found in keywords array, bail out. */ 218 bb_error_msg_and_die(bb_msg_invalid_arg,*argv, applet_name);212 invarg_1_to_2(*argv, applet_name); 219 213 if (key == ARG_from) { 220 214 inet_prefix dst; … … 241 235 NEXT_ARG(); 242 236 if (rtnl_dsfield_a2n(&tos, *argv)) 243 invarg (*argv, "TOS");237 invarg_1_to_2(*argv, "TOS"); 244 238 req.r.rtm_tos = tos; 245 239 } else if (key == ARG_fwmark) { … … 252 246 NEXT_ARG(); 253 247 if (get_rt_realms(&realm, *argv)) 254 invarg (*argv, "realms");248 invarg_1_to_2(*argv, "realms"); 255 249 addattr32(&req.n, sizeof(req), RTA_FLOW, realm); 256 250 } else if (key == ARG_table || … … 260 254 NEXT_ARG(); 261 255 if (rtnl_rttable_a2n(&tid, *argv)) 262 invarg (*argv, "table ID");256 invarg_1_to_2(*argv, "table ID"); 263 257 req.r.rtm_table = tid; 264 258 table_ok = 1; … … 283 277 bb_show_usage(); 284 278 if (rtnl_rtntype_a2n(&type, *argv)) 285 invarg (*argv, "type");279 invarg_1_to_2(*argv, "type"); 286 280 req.r.rtm_type = type; 287 281 } … … 309 303 "add\0""delete\0""list\0""show\0"; 310 304 if (*argv) { 311 smalluint cmd = index_in_substrings(ip_rule_commands, *argv);312 if (cmd > 3)313 bb_error_msg_and_die(bb_msg_invalid_arg,*argv, applet_name);305 int cmd = index_in_substrings(ip_rule_commands, *argv); 306 if (cmd < 0) 307 invarg_1_to_2(*argv, applet_name); 314 308 argv++; 315 309 if (cmd < 2) -
branches/3.3/mindi-busybox/networking/libiproute/iptunnel.c
r3232 r3621 295 295 uval = get_unsigned(*argv, "TTL"); 296 296 if (uval > 255) 297 invarg (*argv, "TTL must be <=255");297 invarg_1_to_2(*argv, "TTL"); 298 298 p->iph.ttl = uval; 299 299 } … … 306 306 if (key != ARG_inherit) { 307 307 if (rtnl_dsfield_a2n(&uval, *argv)) 308 invarg (*argv, "TOS");308 invarg_1_to_2(*argv, "TOS"); 309 309 p->iph.tos = uval; 310 310 } else … … 405 405 static void print_tunnel(struct ip_tunnel_parm *p) 406 406 { 407 char s1[256]; 408 char s2[256]; 409 char s3[64]; 410 char s4[64]; 411 412 format_host(AF_INET, 4, &p->iph.daddr, s1, sizeof(s1)); 413 format_host(AF_INET, 4, &p->iph.saddr, s2, sizeof(s2)); 414 inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3)); 415 inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4)); 407 char s3[INET_ADDRSTRLEN]; 408 char s4[INET_ADDRSTRLEN]; 416 409 417 410 printf("%s: %s/ip remote %s local %s ", 418 p->name, 419 p->iph.protocol == IPPROTO_IPIP ? "ip" : 420 (p->iph.protocol == IPPROTO_GRE ? "gre" : 421 (p->iph.protocol == IPPROTO_IPV6 ? "ipv6" : "unknown")), 422 p->iph.daddr ? s1 : "any", p->iph.saddr ? s2 : "any"); 411 p->name, 412 p->iph.protocol == IPPROTO_IPIP ? "ip" : 413 p->iph.protocol == IPPROTO_GRE ? "gre" : 414 p->iph.protocol == IPPROTO_IPV6 ? "ipv6" : 415 "unknown", 416 p->iph.daddr ? format_host(AF_INET, 4, &p->iph.daddr) : "any", 417 p->iph.saddr ? format_host(AF_INET, 4, &p->iph.saddr) : "any" 418 ); 423 419 if (p->link) { 424 420 char *n = do_ioctl_get_ifname(p->link); … … 433 429 printf(" ttl inherit "); 434 430 if (p->iph.tos) { 435 SPRINT_BUF(b1);436 431 printf(" tos"); 437 432 if (p->iph.tos & 1) … … 439 434 if (p->iph.tos & ~1) 440 435 printf("%c%s ", p->iph.tos & 1 ? '/' : ' ', 441 rtnl_dsfield_n2a(p->iph.tos & ~1 , b1));436 rtnl_dsfield_n2a(p->iph.tos & ~1)); 442 437 } 443 438 if (!(p->iph.frag_off & htons(IP_DF))) 444 439 printf(" nopmtudisc"); 445 440 441 inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3)); 442 inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4)); 446 443 if ((p->i_flags & GRE_KEY) && (p->o_flags & GRE_KEY) && p->o_key == p->i_key) 447 444 printf(" key %s", s3); 448 else if ((p->i_flags | p->o_flags) & GRE_KEY){445 else { 449 446 if (p->i_flags & GRE_KEY) 450 447 printf(" ikey %s ", s3); … … 562 559 563 560 if (*argv) { 564 smalluint key = index_in_substrings(keywords, *argv);565 if (key > 5)566 bb_error_msg_and_die(bb_msg_invalid_arg,*argv, applet_name);561 int key = index_in_substrings(keywords, *argv); 562 if (key < 0) 563 invarg_1_to_2(*argv, applet_name); 567 564 argv++; 568 565 if (key == ARG_add) -
branches/3.3/mindi-busybox/networking/libiproute/libnetlink.c
r3232 r3621 72 72 struct sockaddr_nl nladdr; 73 73 struct iovec iov[2] = { { &nlh, sizeof(nlh) }, { req, len } }; 74 /* Use designated initializers, struct layout is non-portable */ 74 75 struct msghdr msg = { 75 (void*)&nladdr, sizeof(nladdr), 76 iov, 2, 77 NULL, 0, 78 0 76 .msg_name = (void*)&nladdr, 77 .msg_namelen = sizeof(nladdr), 78 .msg_iov = iov, 79 .msg_iovlen = 2, 80 .msg_control = NULL, 81 .msg_controllen = 0, 82 .msg_flags = 0 79 83 }; 80 84 … … 105 109 int status; 106 110 struct nlmsghdr *h; 107 111 /* Use designated initializers, struct layout is non-portable */ 108 112 struct msghdr msg = { 109 (void*)&nladdr, sizeof(nladdr), 110 &iov, 1, 111 NULL, 0, 112 0 113 .msg_name = (void*)&nladdr, 114 .msg_namelen = sizeof(nladdr), 115 .msg_iov = &iov, 116 .msg_iovlen = 1, 117 .msg_control = NULL, 118 .msg_controllen = 0, 119 .msg_flags = 0 113 120 }; 114 121 … … 212 219 struct iovec iov = { (void*)n, n->nlmsg_len }; 213 220 char *buf = xmalloc(8*1024); /* avoid big stack buffer */ 221 /* Use designated initializers, struct layout is non-portable */ 214 222 struct msghdr msg = { 215 (void*)&nladdr, sizeof(nladdr), 216 &iov, 1, 217 NULL, 0, 218 0 223 .msg_name = (void*)&nladdr, 224 .msg_namelen = sizeof(nladdr), 225 .msg_iov = &iov, 226 .msg_iovlen = 1, 227 .msg_control = NULL, 228 .msg_controllen = 0, 229 .msg_flags = 0 219 230 }; 220 231 -
branches/3.3/mindi-busybox/networking/libiproute/ll_map.c
r2725 r3621 87 87 } 88 88 89 const char FAST_FUNC *ll_idx_n2a(int idx, char *buf) 89 static 90 const char FAST_FUNC *ll_idx_n2a(int idx/*, char *buf*/) 90 91 { 91 92 struct idxmap *im; … … 96 97 if (im) 97 98 return im->name; 98 snprintf(buf, 16, "if%d", idx); 99 return buf; 99 //snprintf(buf, 16, "if%d", idx); 100 //return buf; 101 return auto_string(xasprintf("if%d", idx)); 100 102 } 101 102 103 103 104 const char FAST_FUNC *ll_index_to_name(int idx) 104 105 { 105 static char nbuf[16]; 106 107 return ll_idx_n2a(idx, nbuf); 106 //static char nbuf[16]; 107 return ll_idx_n2a(idx/*, nbuf*/); 108 108 } 109 109 … … 137 137 { 138 138 int ret = 0; 139 int sock_fd;140 139 141 140 /* caching is not warranted - no users which repeatedly call it */ … … 165 164 } 166 165 } 167 /* We have not found the interface in our cache, but the kernel168 * may still know about it. One reason is that we may be using169 * module on-demand loading, which means that the kernel will170 * load the module and make the interface exist only when171 * we explicitely request it (check for dev_load() in net/core/dev.c).172 * I can think of other similar scenario, but they are less common...173 * Jean II */174 166 #endif 175 176 sock_fd = socket(AF_INET, SOCK_DGRAM, 0); 177 if (sock_fd >= 0) { 178 struct ifreq ifr; 179 int tmp; 180 181 strncpy_IFNAMSIZ(ifr.ifr_name, name); 182 ifr.ifr_ifindex = -1; 183 tmp = ioctl(sock_fd, SIOCGIFINDEX, &ifr); 184 close(sock_fd); 185 if (tmp >= 0) 186 /* In theory, we should redump the interface list 187 * to update our cache, this is left as an exercise 188 * to the reader... Jean II */ 189 ret = ifr.ifr_ifindex; 190 } 167 ret = if_nametoindex(name); 191 168 /* out:*/ 192 169 if (ret <= 0) -
branches/3.3/mindi-busybox/networking/libiproute/ll_map.h
r2725 r3621 8 8 int ll_init_map(struct rtnl_handle *rth) FAST_FUNC; 9 9 int xll_name_to_index(const char *name) FAST_FUNC; 10 //static: const char *ll_idx_n2a(int idx, char *buf) FAST_FUNC; 10 11 const char *ll_index_to_name(int idx) FAST_FUNC; 11 const char *ll_idx_n2a(int idx, char *buf) FAST_FUNC;12 12 /* int ll_index_to_type(int idx); */ 13 13 unsigned ll_index_to_flags(int idx) FAST_FUNC; -
branches/3.3/mindi-busybox/networking/libiproute/ll_proto.c
r3232 r3621 85 85 /* Keep declarations above and below in sync! */ 86 86 87 static const char llproto_names[] =87 static const char llproto_names[] ALIGN1 = 88 88 #define __PF(f,n) #n "\0" 89 89 __PF(LOOP,loop) -
branches/3.3/mindi-busybox/networking/libiproute/ll_types.c
r3232 r3621 17 17 const char* FAST_FUNC ll_type_n2a(int type, char *buf) 18 18 { 19 static const char arphrd_name[] =19 static const char arphrd_name[] ALIGN1 = 20 20 /* 0, */ "generic" "\0" 21 21 /* ARPHRD_LOOPBACK, */ "loopback" "\0" … … 106 106 /* Keep these arrays in sync! */ 107 107 108 static const uint16_t arphrd_type[] = {108 static const uint16_t arphrd_type[] ALIGN2 = { 109 109 0, /* "generic" "\0" */ 110 110 ARPHRD_LOOPBACK, /* "loopback" "\0" */ -
branches/3.3/mindi-busybox/networking/libiproute/rt_names.c
r2725 r3621 11 11 #include "rt_names.h" 12 12 13 #define CONFDIR CONFIG_FEATURE_IP_ROUTE_DIR 14 13 15 typedef struct rtnl_tab_t { 14 16 const char *cached_str; 15 17 unsigned cached_result; 16 const char *tab[256]; 18 /* upstream version switched to a hash table and removed 19 * id < 256 limit. For now bbox bumps this array size from 256 20 * to 1024. If you plan to change this to a hash table, 21 * consider merging several hash tables we have (for example, 22 * awk has resizable one! 23 */ 24 #define RT_TABLE_MAX 1023 25 const char *tab[RT_TABLE_MAX+1]; 17 26 } rtnl_tab_t; 18 27 … … 20 29 { 21 30 char *token[2]; 22 parser_t *parser = config_open2(file, fopen_for_read); 23 31 char fullname[sizeof(CONFDIR"/rt_dsfield") + 8]; 32 parser_t *parser; 33 34 sprintf(fullname, CONFDIR"/rt_%s", file); 35 parser = config_open2(fullname, fopen_for_read); 24 36 while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { 25 37 unsigned id = bb_strtou(token[0], NULL, 0); 26 if (id > 256) {38 if (id > RT_TABLE_MAX) { 27 39 bb_error_msg("database %s is corrupted at line %d", 28 40 file, parser->lineno); … … 43 55 } 44 56 45 for (i = 0; i < 256; i++) {57 for (i = 0; i <= RT_TABLE_MAX; i++) { 46 58 if (tab->tab[i] 47 59 && strcmp(tab->tab[i], arg) == 0 … … 55 67 56 68 i = bb_strtou(arg, NULL, base); 57 if (i > 255)69 if (i > RT_TABLE_MAX) 58 70 return -1; 59 71 *id = i; … … 86 98 rtnl_rtprot_tab = xzalloc(sizeof(*rtnl_rtprot_tab)); 87 99 memcpy(rtnl_rtprot_tab->tab, init_tab, sizeof(init_tab)); 88 rtnl_tab_initialize(" /etc/iproute2/rt_protos", rtnl_rtprot_tab->tab);89 } 90 91 const char* FAST_FUNC rtnl_rtprot_n2a(int id, char *buf) 92 { 93 if (id < 0 || id >= 256){94 sprintf(buf, "%d", id);95 return buf;100 rtnl_tab_initialize("protos", rtnl_rtprot_tab->tab); 101 } 102 103 #if 0 /* UNUSED */ 104 const char* FAST_FUNC rtnl_rtprot_n2a(int id) 105 { 106 if (id < 0 || id > RT_TABLE_MAX) { 107 return itoa(id); 96 108 } 97 109 … … 100 112 if (rtnl_rtprot_tab->tab[id]) 101 113 return rtnl_rtprot_tab->tab[id]; 102 /* buf is SPRINT_BSIZE big */ 103 sprintf(buf, "%d", id); 104 return buf; 105 } 114 return itoa(id); 115 } 116 #endif 106 117 107 118 int FAST_FUNC rtnl_rtprot_a2n(uint32_t *id, char *arg) … … 124 135 rtnl_rtscope_tab->tab[253] = "link"; 125 136 rtnl_rtscope_tab->tab[200] = "site"; 126 rtnl_tab_initialize("/etc/iproute2/rt_scopes", rtnl_rtscope_tab->tab); 127 } 128 129 const char* FAST_FUNC rtnl_rtscope_n2a(int id, char *buf) 130 { 131 if (id < 0 || id >= 256) { 132 sprintf(buf, "%d", id); 133 return buf; 137 rtnl_tab_initialize("scopes", rtnl_rtscope_tab->tab); 138 } 139 140 const char* FAST_FUNC rtnl_rtscope_n2a(int id) 141 { 142 if (id < 0 || id > RT_TABLE_MAX) { 143 return itoa(id); 134 144 } 135 145 … … 138 148 if (rtnl_rtscope_tab->tab[id]) 139 149 return rtnl_rtscope_tab->tab[id]; 140 /* buf is SPRINT_BSIZE big */ 141 sprintf(buf, "%d", id); 142 return buf; 150 return itoa(id); 143 151 } 144 152 … … 157 165 rtnl_rtrealm_tab = xzalloc(sizeof(*rtnl_rtrealm_tab)); 158 166 rtnl_rtrealm_tab->tab[0] = "unknown"; 159 rtnl_tab_initialize(" /etc/iproute2/rt_realms", rtnl_rtrealm_tab->tab);167 rtnl_tab_initialize("realms", rtnl_rtrealm_tab->tab); 160 168 } 161 169 … … 167 175 168 176 #if ENABLE_FEATURE_IP_RULE 169 const char* FAST_FUNC rtnl_rtrealm_n2a(int id, char *buf) 170 { 171 if (id < 0 || id >= 256) { 172 sprintf(buf, "%d", id); 173 return buf; 177 const char* FAST_FUNC rtnl_rtrealm_n2a(int id) 178 { 179 if (id < 0 || id > RT_TABLE_MAX) { 180 return itoa(id); 174 181 } 175 182 … … 178 185 if (rtnl_rtrealm_tab->tab[id]) 179 186 return rtnl_rtrealm_tab->tab[id]; 180 /* buf is SPRINT_BSIZE big */ 181 sprintf(buf, "%d", id); 182 return buf; 187 return itoa(id); 183 188 } 184 189 #endif … … 192 197 rtnl_rtdsfield_tab = xzalloc(sizeof(*rtnl_rtdsfield_tab)); 193 198 rtnl_rtdsfield_tab->tab[0] = "0"; 194 rtnl_tab_initialize("/etc/iproute2/rt_dsfield", rtnl_rtdsfield_tab->tab); 195 } 196 197 const char* FAST_FUNC rtnl_dsfield_n2a(int id, char *buf) 198 { 199 if (id < 0 || id >= 256) { 200 sprintf(buf, "%d", id); 201 return buf; 199 rtnl_tab_initialize("dsfield", rtnl_rtdsfield_tab->tab); 200 } 201 202 const char* FAST_FUNC rtnl_dsfield_n2a(int id) 203 { 204 if (id < 0 || id > RT_TABLE_MAX) { 205 return itoa(id); 202 206 } 203 207 … … 206 210 if (rtnl_rtdsfield_tab->tab[id]) 207 211 return rtnl_rtdsfield_tab->tab[id]; 208 /* buf is SPRINT_BSIZE big */ 209 sprintf(buf, "0x%02x", id); 210 return buf; 212 return itoa(id); 211 213 } 212 214 … … 223 225 static void rtnl_rttable_initialize(void) 224 226 { 225 if (rtnl_rtdsfield_tab) return; 227 if (rtnl_rttable_tab) 228 return; 229 226 230 rtnl_rttable_tab = xzalloc(sizeof(*rtnl_rttable_tab)); 227 231 rtnl_rttable_tab->tab[0] = "unspec"; … … 229 233 rtnl_rttable_tab->tab[254] = "main"; 230 234 rtnl_rttable_tab->tab[253] = "default"; 231 rtnl_tab_initialize("/etc/iproute2/rt_tables", rtnl_rttable_tab->tab); 232 } 233 234 const char* FAST_FUNC rtnl_rttable_n2a(int id, char *buf) 235 { 236 if (id < 0 || id >= 256) { 237 sprintf(buf, "%d", id); 238 return buf; 235 rtnl_tab_initialize("tables", rtnl_rttable_tab->tab); 236 } 237 238 const char* FAST_FUNC rtnl_rttable_n2a(int id) 239 { 240 if (id < 0 || id > RT_TABLE_MAX) { 241 return itoa(id); 239 242 } 240 243 … … 243 246 if (rtnl_rttable_tab->tab[id]) 244 247 return rtnl_rttable_tab->tab[id]; 245 /* buf is SPRINT_BSIZE big */ 246 sprintf(buf, "%d", id); 247 return buf; 248 return itoa(id); 248 249 } 249 250 -
branches/3.3/mindi-busybox/networking/libiproute/rt_names.h
r2725 r3621 5 5 PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 6 6 7 /* buf is SPRINT_BSIZE big */ 8 extern const char* rtnl_rtprot_n2a(int id, char *buf) FAST_FUNC; 9 extern const char* rtnl_rtscope_n2a(int id, char *buf) FAST_FUNC; 10 extern const char* rtnl_rtrealm_n2a(int id, char *buf) FAST_FUNC; 11 extern const char* rtnl_dsfield_n2a(int id, char *buf) FAST_FUNC; 12 extern const char* rtnl_rttable_n2a(int id, char *buf) FAST_FUNC; 7 extern const char* rtnl_rtprot_n2a(int id) FAST_FUNC; 8 extern const char* rtnl_rtscope_n2a(int id) FAST_FUNC; 9 extern const char* rtnl_rtrealm_n2a(int id) FAST_FUNC; 10 extern const char* rtnl_dsfield_n2a(int id) FAST_FUNC; 11 extern const char* rtnl_rttable_n2a(int id) FAST_FUNC; 13 12 extern int rtnl_rtprot_a2n(uint32_t *id, char *arg) FAST_FUNC; 14 13 extern int rtnl_rtscope_a2n(uint32_t *id, char *arg) FAST_FUNC; -
branches/3.3/mindi-busybox/networking/libiproute/rtm_map.c
r2725 r3621 13 13 #include "utils.h" 14 14 15 const char* FAST_FUNC rtnl_rtntype_n2a(int id , char *buf)15 const char* FAST_FUNC rtnl_rtntype_n2a(int id) 16 16 { 17 17 switch (id) { … … 41 41 return "xresolve"; 42 42 default: 43 /* buf is SPRINT_BSIZE big */ 44 sprintf(buf, "%d", id); 45 return buf; 43 return itoa(id); 46 44 } 47 45 } -
branches/3.3/mindi-busybox/networking/libiproute/rtm_map.h
r2725 r3621 5 5 PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 6 6 7 const char *rtnl_rtntype_n2a(int id , char *buf) FAST_FUNC;7 const char *rtnl_rtntype_n2a(int id) FAST_FUNC; 8 8 int rtnl_rtntype_a2n(int *id, char *arg) FAST_FUNC; 9 9 -
branches/3.3/mindi-busybox/networking/libiproute/utils.c
r3232 r3621 14 14 #include "inet_common.h" 15 15 16 unsigned get_hz(void) 17 { 18 static unsigned hz_internal; 19 FILE *fp; 20 21 if (hz_internal) 22 return hz_internal; 23 24 fp = fopen_for_read("/proc/net/psched"); 25 if (fp) { 26 unsigned nom, denom; 27 28 if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2) 29 if (nom == 1000000) 30 hz_internal = denom; 31 fclose(fp); 32 } 33 if (!hz_internal) 34 hz_internal = bb_clk_tck(); 35 return hz_internal; 36 } 37 16 38 unsigned get_unsigned(char *arg, const char *errmsg) 17 39 { … … 26 48 } 27 49 } 28 invarg (arg, errmsg); /* does not return */50 invarg_1_to_2(arg, errmsg); /* does not return */ 29 51 } 30 52 … … 41 63 } 42 64 } 43 invarg (arg, errmsg); /* does not return */65 invarg_1_to_2(arg, errmsg); /* does not return */ 44 66 } 45 67 … … 56 78 } 57 79 } 58 invarg (arg, errmsg); /* does not return */80 invarg_1_to_2(arg, errmsg); /* does not return */ 59 81 } 60 82 … … 209 231 void incomplete_command(void) 210 232 { 211 bb_error_msg_and_die("command line is not complete, try option\"help\"");212 } 213 214 void invarg (const char *arg, const char *opt)215 { 216 bb_error_msg_and_die(bb_msg_invalid_arg , arg, opt);233 bb_error_msg_and_die("command line is not complete, try \"help\""); 234 } 235 236 void invarg_1_to_2(const char *arg, const char *opt) 237 { 238 bb_error_msg_and_die(bb_msg_invalid_arg_to, arg, opt); 217 239 } 218 240 … … 255 277 } 256 278 257 const char *rt_addr_n2a(int af, 258 void *addr, char *buf, int buflen) 279 const char *rt_addr_n2a(int af, void *addr) 259 280 { 260 281 switch (af) { 261 282 case AF_INET: 262 283 case AF_INET6: 263 return inet_ntop(af, addr, buf, buflen); 284 return inet_ntop(af, addr, 285 auto_string(xzalloc(INET6_ADDRSTRLEN)), INET6_ADDRSTRLEN 286 ); 264 287 default: 265 288 return "???"; … … 268 291 269 292 #ifdef RESOLVE_HOSTNAMES 270 const char *format_host(int af, int len, void *addr , char *buf, int buflen)293 const char *format_host(int af, int len, void *addr) 271 294 { 272 295 if (resolve_hosts) { … … 287 310 h_ent = gethostbyaddr(addr, len, af); 288 311 if (h_ent != NULL) { 289 safe_strncpy(buf, h_ent->h_name, buflen); 290 return buf; 291 } 292 } 293 } 294 return rt_addr_n2a(af, addr, buf, buflen); 312 return auto_string(xstrdup(h_ent->h_name)); 313 } 314 } 315 } 316 return rt_addr_n2a(af, addr); 295 317 } 296 318 #endif -
branches/3.3/mindi-busybox/networking/libiproute/utils.h
r3232 r3621 67 67 extern uint16_t get_u16(char *arg, const char *errmsg); 68 68 69 extern const char *rt_addr_n2a(int af, void *addr , char *buf, int buflen);69 extern const char *rt_addr_n2a(int af, void *addr); 70 70 #ifdef RESOLVE_HOSTNAMES 71 extern const char *format_host(int af, int len, void *addr , char *buf, int buflen);71 extern const char *format_host(int af, int len, void *addr); 72 72 #else 73 #define format_host(af, len, addr , buf, buflen) \74 rt_addr_n2a(af, addr , buf, buflen)73 #define format_host(af, len, addr) \ 74 rt_addr_n2a(af, addr) 75 75 #endif 76 76 77 void invarg (const char *, const char *) NORETURN;77 void invarg_1_to_2(const char *, const char *) NORETURN; 78 78 void duparg(const char *, const char *) NORETURN; 79 79 void duparg2(const char *, const char *) NORETURN; … … 86 86 int ipx_pton(int af, const char *src, void *addr); 87 87 88 unsigned get_hz(void); 89 88 90 POP_SAVED_FUNCTION_VISIBILITY 89 91 -
branches/3.3/mindi-busybox/networking/nameif.c
r3232 r3621 162 162 *next++ = '\0'; 163 163 /* Check for selectors, mac= is assumed */ 164 if ( strncmp(selector, "bus=", 4) == 0) {164 if (is_prefixed_with(selector, "bus=")) { 165 165 ch->bus_info = xstrdup(selector + 4); 166 166 found_selector++; 167 } else if ( strncmp(selector, "driver=", 7) == 0) {167 } else if (is_prefixed_with(selector, "driver=")) { 168 168 ch->driver = xstrdup(selector + 7); 169 169 found_selector++; 170 } else if ( strncmp(selector, "phyaddr=", 8) == 0) {170 } else if (is_prefixed_with(selector, "phyaddr=")) { 171 171 ch->phy_address = xatoi_positive(selector + 8); 172 172 found_selector++; … … 174 174 #endif 175 175 lmac = xmalloc(ETH_ALEN); 176 ch->mac = ether_aton_r(selector + ( strncmp(selector, "mac=", 4) != 0 ? 0 : 4), lmac);176 ch->mac = ether_aton_r(selector + (is_prefixed_with(selector, "mac=") ? 4 : 0), lmac); 177 177 if (ch->mac == NULL) 178 178 bb_error_msg_and_die("can't parse %s", selector); … … 293 293 continue; 294 294 /* if we came here, all selectors have matched */ 295 break;295 goto found; 296 296 } 297 297 /* Nothing found for current interface */ 298 if (!ch) 299 continue; 300 298 continue; 299 found: 301 300 if (strcmp(ifr.ifr_name, ch->ifname) != 0) { 302 301 strcpy(ifr.ifr_newname, ch->ifname); … … 314 313 if (ENABLE_FEATURE_CLEAN_UP) 315 314 delete_eth_table(ch); 316 } 315 } /* while */ 316 317 317 if (ENABLE_FEATURE_CLEAN_UP) { 318 for (ch = clist; ch; ch = ch->next) 318 ethtable_t *next; 319 for (ch = clist; ch; ch = next) { 320 next = ch->next; 319 321 delete_eth_table(ch); 322 } 320 323 config_close(parser); 321 324 }; -
branches/3.3/mindi-busybox/networking/nbd-client.c
r3232 r3621 58 58 char data[124]; 59 59 } nbd_header; 60 struct bug_check { 61 char c[offsetof(struct nbd_header_t, data) == 8+8+8+4 ? 1 : -1]; 62 }; 60 61 BUILD_BUG_ON(offsetof(struct nbd_header_t, data) != 8+8+8+4); 63 62 64 63 // Parse command line stuff (just a stub now) … … 84 83 // Find and connect to server 85 84 sock = create_and_connect_stream_or_die(host, xatou16(port)); 86 setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &const_int_1, sizeof(const_int_1));85 setsockopt_1(sock, IPPROTO_TCP, TCP_NODELAY); 87 86 88 87 // Log on to the server -
branches/3.3/mindi-busybox/networking/nc.c
r3232 r3621 9 9 10 10 #include "libbb.h" 11 #include "common_bufsiz.h" 11 12 12 13 //config:config NC … … 25 26 //config: 26 27 //config:config NC_EXTRA 27 //config: bool "Netcat extensions (-eiw and filename)"28 //config: bool "Netcat extensions (-eiw and -f FILE)" 28 29 //config: default y 29 30 //config: depends on NC … … 41 42 //config: The code is about 2.5k bigger. It enables 42 43 //config: -s ADDR, -n, -u, -v, -o FILE, -z options, but loses 43 //config: busybox-specific extensions: -f FILE and -ll.44 //config: busybox-specific extensions: -f FILE. 44 45 45 46 #if ENABLE_NC_110_COMPAT … … 61 62 //usage: "Open a pipe to IP:PORT" IF_NC_EXTRA(" or FILE") 62 63 //usage: NC_OPTIONS_STR 63 //usage: IF_NC_EXTRA(64 //usage: "\n -e PROG Run PROG after connect"65 64 //usage: IF_NC_SERVER( 66 65 //usage: "\n -l Listen mode, for inbound connects" 67 66 //usage: IF_NC_EXTRA( 68 //usage: "\n (use -l twice with -e for persistent server)") 67 //usage: "\n (use -ll with -e for persistent server)" 68 //usage: ) 69 69 //usage: "\n -p PORT Local port" 70 70 //usage: ) 71 //usage: "\n -w SEC Timeout for connect" 71 //usage: IF_NC_EXTRA( 72 //usage: "\n -w SEC Connect timeout" 72 73 //usage: "\n -i SEC Delay interval for lines sent" 73 74 //usage: "\n -f FILE Use file (ala /dev/ttyS0) instead of network" 75 //usage: "\n -e PROG Run PROG after connect" 74 76 //usage: ) 75 77 //usage: … … 148 150 } 149 151 ) 150 /* optind points to argv[ar vc] (NULL) now.152 /* optind points to argv[argc] (NULL) now. 151 153 ** FIXME: we assume that getopt will not count options 152 154 ** possibly present on "-e PROG ARGS" and will not … … 227 229 xmove_fd(cfd, 0); 228 230 xdup2(0, 1); 229 xdup2(0, 2);231 /*xdup2(0, 2); - original nc 1.10 does this, we don't */ 230 232 IF_NC_EXTRA(BB_EXECVP(execparam[0], execparam);) 231 /* Don't print stuff or it will go over the wire... */ 232 _exit(127); 233 IF_NC_EXTRA(bb_perror_msg_and_die("can't execute '%s'", execparam[0]);) 233 234 } 234 235 … … 239 240 FD_SET(STDIN_FILENO, &readfds); 240 241 242 #define iobuf bb_common_bufsiz1 243 setup_common_bufsiz(); 241 244 for (;;) { 242 245 int fd; … … 249 252 bb_perror_msg_and_die("select"); 250 253 251 #define iobuf bb_common_bufsiz1252 254 fd = STDIN_FILENO; 253 255 while (1) { 254 256 if (FD_ISSET(fd, &testfds)) { 255 nread = safe_read(fd, iobuf, sizeof(iobuf));257 nread = safe_read(fd, iobuf, COMMON_BUFSIZE); 256 258 if (fd == cfd) { 257 259 if (nread < 1) … … 262 264 /* Close outgoing half-connection so they get EOF, 263 265 * but leave incoming alone so we can see response */ 264 shutdown(cfd, 1);266 shutdown(cfd, SHUT_WR); 265 267 FD_CLR(STDIN_FILENO, &readfds); 266 268 } -
branches/3.3/mindi-busybox/networking/nc_bloaty.c
r3232 r3621 49 49 * on the command line, but accept() says that it came from different addr) 50 50 * are closed, but we don't exit - we continue to listen/accept. 51 * Since bbox 1.22: 52 * - nc exits when _both_ stdin and network are closed. 53 * This makes these two commands: 54 * echo "Yes" | nc 127.0.0.1 1234 55 * echo "no" | nc -lp 1234 56 * exchange their data _and exit_ instead of being stuck. 51 57 */ 52 58 … … 64 70 //usage: IF_NC_SERVER( 65 71 //usage: "\n -l Listen mode, for inbound connects" 72 //usage: "\n -lk With -e, provides persistent server" 73 /* -ll does the same as -lk, but its our extension, while -k is BSD'd, 74 * presumably more widely known. Therefore we advertise it, not -ll. 75 * I would like to drop -ll support, but our "small" nc supports it, 76 * and Rob uses it. 77 */ 66 78 //usage: ) 67 79 //usage: "\n -p PORT Local port" … … 129 141 jmp_buf jbuf; /* timer crud */ 130 142 131 fd_set ding1; /* for select loop */132 fd_set ding2;133 143 char bigbuf_in[BIGSIZ]; /* data buffers */ 134 144 char bigbuf_net[BIGSIZ]; … … 142 152 #define remend (G.remend ) 143 153 #define jbuf (G.jbuf ) 144 #define ding1 (G.ding1 )145 #define ding2 (G.ding2 )146 154 #define bigbuf_in (G.bigbuf_in ) 147 155 #define bigbuf_net (G.bigbuf_net) … … 167 175 OPT_w = (1 << 5), 168 176 OPT_l = (1 << 6) * ENABLE_NC_SERVER, 169 OPT_i = (1 << (6+ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 170 OPT_o = (1 << (7+ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 171 OPT_z = (1 << (8+ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 177 OPT_k = (1 << 7) * ENABLE_NC_SERVER, 178 OPT_i = (1 << (6+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 179 OPT_o = (1 << (7+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 180 OPT_z = (1 << (8+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 172 181 }; 173 182 174 183 #define o_nflag (option_mask32 & OPT_n) 175 184 #define o_udpmode (option_mask32 & OPT_u) 176 #if ENABLE_NC_SERVER177 #define o_listen (option_mask32 & OPT_l)178 #else179 #define o_listen 0180 #endif181 185 #if ENABLE_NC_EXTRA 182 186 #define o_ofile (option_mask32 & OPT_o) … … 299 303 given host/port args, any connections from elsewhere are rejected. This 300 304 in conjunction with local-address binding should limit things nicely... */ 301 static void dolisten( void)305 static void dolisten(int is_persistent, char **proggie) 302 306 { 303 307 int rr; … … 372 376 } else { 373 377 /* TCP */ 378 another: 374 379 arm(o_wait); /* wrap this in a timer, too; 0 = forever */ 375 380 if (setjmp(jbuf) == 0) { … … 406 411 } else 407 412 bb_error_msg_and_die("timeout"); 413 414 if (is_persistent && proggie) { 415 /* -l -k -e PROG */ 416 signal(SIGCHLD, SIG_IGN); /* no zombies please */ 417 if (xvfork() != 0) { 418 /* parent: go back and accept more connections */ 419 close(rr); 420 goto another; 421 } 422 /* child */ 423 signal(SIGCHLD, SIG_DFL); 424 } 425 408 426 xmove_fd(rr, netfd); /* dump the old socket, here's our new one */ 409 427 /* find out what address the connection was *to* on our end, in case we're … … 455 473 free(remhostname); 456 474 } 475 476 if (proggie) 477 doexec(proggie); 457 478 } 458 479 … … 572 593 unsigned rnleft; 573 594 unsigned netretry; /* net-read retry counter */ 574 unsigned wretry; /* net-write sanity counter */ 575 unsigned wfirst; /* one-shot flag to skip first net read */ 595 unsigned fds_open; 576 596 577 597 /* if you don't have all this FD_* macro hair in sys/types.h, you'll have to 578 598 either find it or do your own bit-bashing: *ding1 |= (1 << fd), etc... */ 579 FD_SET(netfd, &ding1); /* global: the net is open */ 599 fd_set ding1; /* for select loop */ 600 fd_set ding2; 601 FD_ZERO(&ding1); 602 FD_SET(netfd, &ding1); 603 FD_SET(STDIN_FILENO, &ding1); 604 fds_open = 2; 605 580 606 netretry = 2; 581 wfirst = 0;582 607 rzleft = rnleft = 0; 583 608 if (o_interval) 584 609 sleep(o_interval); /* pause *before* sending stuff, too */ 585 610 586 errno = 0; /* clear from sleep, close, whatever */587 611 /* and now the big ol' select shoveling loop ... */ 588 while (FD_ISSET(netfd, &ding1)) { /* i.e. till the *net* closes! */ 589 wretry = 8200; /* more than we'll ever hafta write */ 590 if (wfirst) { /* any saved stdin buffer? */ 591 wfirst = 0; /* clear flag for the duration */ 592 goto shovel; /* and go handle it first */ 593 } 612 /* nc 1.10 has "while (FD_ISSET(netfd)" here */ 613 while (fds_open) { 614 unsigned wretry = 8200; /* net-write sanity counter */ 615 594 616 ding2 = ding1; /* FD_COPY ain't portable... */ 595 617 /* some systems, notably linux, crap into their select timers on return, so … … 611 633 from the net during that time, assume it's dead and close it too. */ 612 634 if (rr == 0) { 613 if (!FD_ISSET(STDIN_FILENO, &ding1)) 635 if (!FD_ISSET(STDIN_FILENO, &ding1)) { 614 636 netretry--; /* we actually try a coupla times. */ 615 if (!netretry) { 616 if (o_verbose > 1) /* normally we don't care */ 617 fprintf(stderr, "net timeout\n"); 618 close(netfd); 619 return 0; /* not an error! */ 637 if (!netretry) { 638 if (o_verbose > 1) /* normally we don't care */ 639 fprintf(stderr, "net timeout\n"); 640 /*close(netfd); - redundant, exit will do it */ 641 return 0; /* not an error! */ 642 } 620 643 } 621 644 } /* select timeout */ … … 631 654 bb_perror_msg("net read"); 632 655 } 633 FD_CLR(netfd, &ding1); /* net closed, we'll finish up... */ 656 FD_CLR(netfd, &ding1); /* net closed */ 657 fds_open--; 634 658 rzleft = 0; /* can't write anymore: broken pipe */ 635 659 } else { … … 651 675 mobygrams are kinda fun and exercise the reassembler. */ 652 676 if (rr <= 0) { /* at end, or fukt, or ... */ 653 FD_CLR(STDIN_FILENO, &ding1); /* disable and close stdin */ 654 close(STDIN_FILENO); 655 // Does it make sense to shutdown(net_fd, SHUT_WR) 656 // to let other side know that we won't write anything anymore? 657 // (and what about keeping compat if we do that?) 677 FD_CLR(STDIN_FILENO, &ding1); /* disable stdin */ 678 /*close(STDIN_FILENO); - not really necessary */ 679 /* Let peer know we have no more data */ 680 /* nc 1.10 doesn't do this: */ 681 shutdown(netfd, SHUT_WR); 682 fds_open--; 658 683 } else { 659 684 rzleft = rr; … … 666 691 not sure if the order of this matters, but write net -> stdout first. */ 667 692 668 /* sanity check. Works because they're both unsigned... */669 if ((rzleft > 8200) || (rnleft > 8200)) {670 holler_error("bogus buffers: %u, %u", rzleft, rnleft);671 rzleft = rnleft = 0;672 }673 /* net write retries sometimes happen on UDP connections */674 if (!wretry) { /* is something hung? */675 holler_error("too many output retries");676 return 1;677 }678 693 if (rnleft) { 679 694 rr = write(STDOUT_FILENO, np, rnleft); … … 681 696 if (o_ofile) /* log the stdout */ 682 697 oprint('<', (unsigned char *)np, rr); 683 np += rr; /* fix up ptrs and whatnot */684 rnleft -= rr; /* will get sanity-checked above */685 wrote_out += rr; 698 np += rr; 699 rnleft -= rr; 700 wrote_out += rr; /* global count */ 686 701 } 687 702 Debug("wrote %d to stdout, errno %d", rr, errno); … … 698 713 zp += rr; 699 714 rzleft -= rr; 700 wrote_net += rr; 715 wrote_net += rr; /* global count */ 701 716 } 702 717 Debug("wrote %d to net, errno %d", rr, errno); … … 704 719 if (o_interval) { /* cycle between slow lines, or ... */ 705 720 sleep(o_interval); 706 errno = 0; /* clear from sleep */707 721 continue; /* ...with hairy select loop... */ 708 722 } 709 if ( (rzleft) || (rnleft)) {/* shovel that shit till they ain't */723 if (rzleft || rnleft) { /* shovel that shit till they ain't */ 710 724 wretry--; /* none left, and get another load */ 725 /* net write retries sometimes happen on UDP connections */ 726 if (!wretry) { /* is something hung? */ 727 holler_error("too many output retries"); 728 return 1; 729 } 711 730 goto shovel; 712 731 } 713 } /* while ding1:netfd is open*/732 } /* while (fds_open) */ 714 733 715 734 /* XXX: maybe want a more graceful shutdown() here, or screw around with … … 731 750 char **proggie; 732 751 int x; 752 unsigned cnt_l = 0; 733 753 unsigned o_lport = 0; 734 754 … … 761 781 char *optpos = *proggie + 1; 762 782 /* Skip all valid opts w/o params */ 763 optpos = optpos + strspn(optpos, "nuv"IF_NC_SERVER("l ")IF_NC_EXTRA("z"));783 optpos = optpos + strspn(optpos, "nuv"IF_NC_SERVER("lk")IF_NC_EXTRA("z")); 764 784 if (*optpos == 'e' && !optpos[1]) { 765 785 *optpos = '\0'; … … 775 795 776 796 // -g -G -t -r deleted, unimplemented -a deleted too 777 opt_complementary = "?2:vv: w+"; /* max 2 params; -v is a counter; -w N */778 getopt32(argv, "np:s:uvw:" IF_NC_SERVER("l ")797 opt_complementary = "?2:vv:ll:w+"; /* max 2 params; -v and -l are counters; -w N */ 798 getopt32(argv, "np:s:uvw:" IF_NC_SERVER("lk") 779 799 IF_NC_EXTRA("i:o:z"), 780 800 &str_p, &str_s, &o_wait 781 IF_NC_EXTRA(, &str_i, &str_o), &o_verbose );801 IF_NC_EXTRA(, &str_i, &str_o), &o_verbose IF_NC_SERVER(, &cnt_l)); 782 802 argv += optind; 783 803 #if ENABLE_NC_EXTRA … … 785 805 o_interval = xatou_range(str_i, 1, 0xffff); 786 806 #endif 807 #if ENABLE_NC_SERVER 787 808 //if (option_mask32 & OPT_l) /* listen mode */ 809 if (option_mask32 & OPT_k) /* persistent server mode */ 810 cnt_l = 2; 811 #endif 788 812 //if (option_mask32 & OPT_n) /* numeric-only, no DNS lookups */ 789 813 //if (option_mask32 & OPT_o) /* hexdump log */ … … 834 858 socket_want_pktinfo(netfd); 835 859 if (!ENABLE_FEATURE_UNIX_LOCAL 836 || o_listen860 || cnt_l != 0 /* listen */ 837 861 || ouraddr->u.sa.sa_family != AF_UNIX 838 862 ) { … … 840 864 } 841 865 #if 0 842 setsockopt (netfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeofo_rcvbuf);843 setsockopt (netfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeofo_sndbuf);866 setsockopt_SOL_SOCKET_int(netfd, SO_RCVBUF, o_rcvbuf); 867 setsockopt_SOL_SOCKET_int(netfd, SO_SNDBUF, o_sndbuf); 844 868 #endif 845 869 … … 853 877 #endif 854 878 855 FD_SET(STDIN_FILENO, &ding1); /* stdin *is* initially open */856 879 if (proggie) { 857 close( 0); /* won't need stdin */880 close(STDIN_FILENO); /* won't need stdin */ 858 881 option_mask32 &= ~OPT_o; /* -o with -e is meaningless! */ 859 882 } … … 863 886 #endif 864 887 865 if ( o_listen) {866 dolisten( );888 if (cnt_l != 0) { 889 dolisten((cnt_l - 1), proggie); 867 890 /* dolisten does its own connect reporting */ 868 if (proggie) /* -e given? */869 doexec(proggie);870 891 x = readwrite(); /* it even works with UDP! */ 871 892 } else { -
branches/3.3/mindi-busybox/networking/netstat.c
r3232 r3621 120 120 /* When there are IPv6 connections the IPv6 addresses will be 121 121 * truncated to none-recognition. The '-W' option makes the 122 * address columns wide enough to accom odate for longest possible122 * address columns wide enough to accommodate for longest possible 123 123 * IPv6 addresses, i.e. addresses of the form 124 124 * xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd … … 126 126 #define ADDR_WIDE 51 /* INET6_ADDRSTRLEN + 5 for the port number */ 127 127 #if ENABLE_FEATURE_NETSTAT_WIDE 128 # define FMT_NET_CONN_DATA "%s %6l d %6ld%-*s %-*s %-12s"128 # define FMT_NET_CONN_DATA "%s %6lu %6lu %-*s %-*s %-12s" 129 129 # define FMT_NET_CONN_HEADER "\nProto Recv-Q Send-Q %-*s %-*s State %s\n" 130 130 #else 131 # define FMT_NET_CONN_DATA "%s %6l d %6ld%-23s %-23s %-12s"131 # define FMT_NET_CONN_DATA "%s %6lu %6lu %-23s %-23s %-12s" 132 132 # define FMT_NET_CONN_HEADER "\nProto Recv-Q Send-Q %-23s %-23s State %s\n" 133 133 #endif … … 229 229 long inode = -1; 230 230 231 if ( strncmp(lname, "socket:[", sizeof("socket:[")-1) == 0) {231 if (is_prefixed_with(lname, "socket:[")) { 232 232 /* "socket:[12345]", extract the "12345" as inode */ 233 233 inode = bb_strtoul(lname + sizeof("socket:[")-1, (char**)&lname, 0); 234 234 if (*lname != ']') 235 235 inode = -1; 236 } else if ( strncmp(lname, "[0000]:", sizeof("[0000]:")-1) == 0) {236 } else if (is_prefixed_with(lname, "[0000]:")) { 237 237 /* "[0000]:12345", extract the "12345" as inode */ 238 238 inode = bb_strtoul(lname + sizeof("[0000]:")-1, NULL, 0); … … 404 404 "%32[0-9A-Fa-f]:%X %X " 405 405 "%lX:%lX %*X:%*X " 406 "%*X %d %*d %l d",406 "%*X %d %*d %lu ", 407 407 local_addr, ¶m->local_port, 408 408 rem_addr, ¶m->rem_port, ¶m->state, … … 612 612 strcat(ss_flags, "]"); 613 613 614 printf("%-5s %-6l d%-11s %-10s %-13s %6lu ",614 printf("%-5s %-6lu %-11s %-10s %-13s %6lu ", 615 615 ss_proto, refcnt, ss_flags, ss_type, ss_state, inode 616 616 ); … … 623 623 /* TODO: currently we stop at first NUL byte. Is it a problem? */ 624 624 line += path_ofs; 625 *strchrnul(line, '\n') = '\0';625 chomp(line); 626 626 while (*line) 627 627 fputc_printable(*line++, stdout); -
branches/3.3/mindi-busybox/networking/nslookup.c
r3232 r3621 139 139 len_and_sockaddr *lsa; 140 140 141 if (!server) 142 return; 143 141 144 /* NB: this works even with, say, "[::1]:5353"! :) */ 142 145 lsa = xhost2sockaddr(server, 53); … … 182 185 /*_res.options |= RES_USE_INET6;*/ 183 186 184 if (argv[2]) 185 set_default_dns(argv[2]); 187 set_default_dns(argv[2]); 186 188 187 189 server_print(); 190 191 /* getaddrinfo and friends are free to request a resolver 192 * reinitialization. Just in case, set_default_dns() again 193 * after getaddrinfo (in server_print). This reportedly helps 194 * with bug 675 "nslookup does not properly use second argument" 195 * at least on Debian Wheezy and Openwrt AA (eglibc based). 196 */ 197 set_default_dns(argv[2]); 198 188 199 return print_host(argv[1], "Name:"); 189 200 } -
branches/3.3/mindi-busybox/networking/ntpd.c
r3232 r3621 2 2 * NTP client/server, based on OpenNTPD 3.9p1 3 3 * 4 * Author: Adam Tkac<vonsch@gmail.com>4 * Busybox port author: Adam Tkac (C) 2009 <vonsch@gmail.com> 5 5 * 6 * Licensed under GPLv2, see file LICENSE in this source tree. 6 * OpenNTPd 3.9p1 copyright holders: 7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 8 * Copyright (c) 2004 Alexander Guy <alexander.guy@andern.org> 9 * 10 * OpenNTPd code is licensed under ISC-style licence: 11 * 12 * Permission to use, copy, modify, and distribute this software for any 13 * purpose with or without fee is hereby granted, provided that the above 14 * copyright notice and this permission notice appear in all copies. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 17 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 20 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 21 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 22 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 23 *********************************************************************** 7 24 * 8 25 * Parts of OpenNTPD clock syncronization code is replaced by 9 * code which is based on ntp-4.2.6, wh uch carries the following26 * code which is based on ntp-4.2.6, which carries the following 10 27 * copyright notice: 11 28 * 12 *********************************************************************** 13 * * 14 * Copyright (c) University of Delaware 1992-2009 * 15 * * 16 * Permission to use, copy, modify, and distribute this software and * 17 * its documentation for any purpose with or without fee is hereby * 18 * granted, provided that the above copyright notice appears in all * 19 * copies and that both the copyright notice and this permission * 20 * notice appear in supporting documentation, and that the name * 21 * University of Delaware not be used in advertising or publicity * 22 * pertaining to distribution of the software without specific, * 23 * written prior permission. The University of Delaware makes no * 24 * representations about the suitability this software for any * 25 * purpose. It is provided "as is" without express or implied * 26 * warranty. * 27 * * 29 * Copyright (c) University of Delaware 1992-2009 30 * 31 * Permission to use, copy, modify, and distribute this software and 32 * its documentation for any purpose with or without fee is hereby 33 * granted, provided that the above copyright notice appears in all 34 * copies and that both the copyright notice and this permission 35 * notice appear in supporting documentation, and that the name 36 * University of Delaware not be used in advertising or publicity 37 * pertaining to distribution of the software without specific, 38 * written prior permission. The University of Delaware makes no 39 * representations about the suitability this software for any 40 * purpose. It is provided "as is" without express or implied warranty. 28 41 *********************************************************************** 29 42 */ 30 43 31 44 //usage:#define ntpd_trivial_usage 32 //usage: "[-dnqNw"IF_FEATURE_NTPD_SERVER("l ")"] [-S PROG] [-p PEER]..."45 //usage: "[-dnqNw"IF_FEATURE_NTPD_SERVER("l -I IFACE")"] [-S PROG] [-p PEER]..." 33 46 //usage:#define ntpd_full_usage "\n\n" 34 47 //usage: "NTP client/server\n" … … 38 51 //usage: "\n -N Run at high priority" 39 52 //usage: "\n -w Do not set time (only query peers), implies -n" 40 //usage: IF_FEATURE_NTPD_SERVER(41 //usage: "\n -l Run as server on port 123"42 //usage: )43 53 //usage: "\n -S PROG Run PROG after stepping time, stratum change, and every 11 mins" 44 54 //usage: "\n -p PEER Obtain time from PEER (may be repeated)" 55 //usage: IF_FEATURE_NTPD_CONF( 56 //usage: "\n If -p is not given, 'server HOST' lines" 57 //usage: "\n from /etc/ntp.conf are used" 58 //usage: ) 59 //usage: IF_FEATURE_NTPD_SERVER( 60 //usage: "\n -l Also run as server on port 123" 61 //usage: "\n -I IFACE Bind server to IFACE, implies -l" 62 //usage: ) 63 64 // -l and -p options are not compatible with "standard" ntpd: 65 // it has them as "-l logfile" and "-p pidfile". 66 // -S and -w are not compat either, "standard" ntpd has no such opts. 45 67 46 68 #include "libbb.h" … … 52 74 # define IPTOS_LOWDELAY 0x10 53 75 #endif 54 #ifndef IP_PKTINFO55 # error "Sorry, your kernel has to support IP_PKTINFO"56 #endif57 76 58 77 59 78 /* Verbosity control (max level of -dddd options accepted). 60 * max 5 is very talkative (and bloated). 2is non-bloated,79 * max 6 is very talkative (and bloated). 3 is non-bloated, 61 80 * production level setting. 62 81 */ 63 #define MAX_VERBOSE 282 #define MAX_VERBOSE 3 64 83 65 84 … … 91 110 * then the time is stepped, all datapoints are discarded, 92 111 * and we go back to steady state. 112 * 113 * Made some changes to speed up re-syncing after our clock goes bad 114 * (tested with suspending my laptop): 115 * - if largish offset (>= STEP_THRESHOLD == 1 sec) is seen 116 * from a peer, schedule next query for this peer soon 117 * without drastically lowering poll interval for everybody. 118 * This makes us collect enough data for step much faster: 119 * e.g. at poll = 10 (1024 secs), step was done within 5 minutes 120 * after first reply which indicated that our clock is 14 seconds off. 121 * - on step, do not discard d_dispersion data of the existing datapoints, 122 * do not clear reachable_bits. This prevents discarding first ~8 123 * datapoints after the step. 93 124 */ 94 125 95 #define RETRY_INTERVAL 5 /* on error, retry in N secs */ 96 #define RESPONSE_INTERVAL 15 /* wait for reply up to N secs */ 97 #define INITIAL_SAMPLES 4 /* how many samples do we want for init */ 98 99 /* Clock discipline parameters and constants */ 126 #define INITIAL_SAMPLES 4 /* how many samples do we want for init */ 127 #define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this */ 128 129 #define RETRY_INTERVAL 32 /* on send/recv error, retry in N secs (need to be power of 2) */ 130 #define NOREPLY_INTERVAL 512 /* sent, but got no reply: cap next query by this many seconds */ 131 #define RESPONSE_INTERVAL 16 /* wait for reply up to N secs */ 100 132 101 133 /* Step threshold (sec). std ntpd uses 0.128. 102 * Using exact power of 2 (1/8) results in smaller code */ 103 #define STEP_THRESHOLD 0.125 104 #define WATCH_THRESHOLD 128 /* stepout threshold (sec). std ntpd uses 900 (11 mins (!)) */ 134 */ 135 #define STEP_THRESHOLD 1 136 /* Slew threshold (sec): adjtimex() won't accept offsets larger than this. 137 * Using exact power of 2 (1/8) results in smaller code 138 */ 139 #define SLEW_THRESHOLD 0.125 140 /* Stepout threshold (sec). std ntpd uses 900 (11 mins (!)) */ 141 #define WATCH_THRESHOLD 128 105 142 /* NB: set WATCH_THRESHOLD to ~60 when debugging to save time) */ 106 143 //UNUSED: #define PANIC_THRESHOLD 1000 /* panic threshold (sec) */ 144 145 /* 146 * If we got |offset| > BIGOFF from a peer, cap next query interval 147 * for this peer by this many seconds: 148 */ 149 #define BIGOFF STEP_THRESHOLD 150 #define BIGOFF_INTERVAL (1 << 7) /* 128 s */ 107 151 108 152 #define FREQ_TOLERANCE 0.000015 /* frequency tolerance (15 PPM) */ 109 153 #define BURSTPOLL 0 /* initial poll */ 110 154 #define MINPOLL 5 /* minimum poll interval. std ntpd uses 6 (6: 64 sec) */ 111 /* If offset > discipline_jitter * POLLADJ_GATE, and poll interval is >= 2^BIGPOLL, 112 * then it is decreased _at once_. (If < 2^BIGPOLL, it will be decreased _eventually_). 155 /* 156 * If offset > discipline_jitter * POLLADJ_GATE, and poll interval is > 2^BIGPOLL, 157 * then it is decreased _at once_. (If <= 2^BIGPOLL, it will be decreased _eventually_). 113 158 */ 114 #define BIGPOLL 10 /* 2^10 sec ~= 17min */159 #define BIGPOLL 9 /* 2^9 sec ~= 8.5 min */ 115 160 #define MAXPOLL 12 /* maximum poll interval (12: 1.1h, 17: 36.4h). std ntpd uses 17 */ 116 /* Actively lower poll when we see such big offsets. 117 * With STEP_THRESHOLD = 0.125, it means we try to sync more aggressively 118 * if offset increases over ~0.04 sec */ 119 #define POLLDOWN_OFFSET (STEP_THRESHOLD / 3) 161 /* 162 * Actively lower poll when we see such big offsets. 163 * With SLEW_THRESHOLD = 0.125, it means we try to sync more aggressively 164 * if offset increases over ~0.04 sec 165 */ 166 //#define POLLDOWN_OFFSET (SLEW_THRESHOLD / 3) 120 167 #define MINDISP 0.01 /* minimum dispersion (sec) */ 121 168 #define MAXDISP 16 /* maximum dispersion (sec) */ … … 228 275 uint8_t lastpkt_stratum; 229 276 uint8_t reachable_bits; 230 231 277 /* when to send new query (if p_fd == -1) 278 * or when receive times out (if p_fd >= 0): */ 232 279 double next_action_time; 233 280 double p_xmttime; 281 double p_raw_delay; 282 /* p_raw_delay is set even by "high delay" packets */ 283 /* lastpkt_delay isn't */ 234 284 double lastpkt_recv_time; 235 285 double lastpkt_delay; … … 243 293 /* last sent packet: */ 244 294 msg_t p_xmt_msg; 295 char p_hostname[1]; 245 296 } peer_t; 246 297 … … 260 311 OPT_S = (1 << 6), 261 312 OPT_l = (1 << 7) * ENABLE_FEATURE_NTPD_SERVER, 313 OPT_I = (1 << 8) * ENABLE_FEATURE_NTPD_SERVER, 262 314 /* We hijack some bits for other purposes */ 263 315 OPT_qq = (1 << 31), … … 278 330 #if ENABLE_FEATURE_NTPD_SERVER 279 331 int listen_fd; 332 char *if_name; 280 333 # define G_listen_fd (G.listen_fd) 281 334 #else … … 329 382 #define G_precision_sec 0.002 330 383 uint8_t stratum; 331 /* Bool. After set to 1, never goes back to 0: */332 smallint initial_poll_complete;333 384 334 385 #define STATE_NSET 0 /* initial state, "nothing is set" */ 335 386 //#define STATE_FSET 1 /* frequency set from file */ 336 #define STATE_SPIK2 /* spike detected */387 //#define STATE_SPIK 2 /* spike detected */ 337 388 //#define STATE_FREQ 3 /* initial frequency */ 338 389 #define STATE_SYNC 4 /* clock synchronized (normal operation) */ … … 359 410 #define G (*ptr_to_globals) 360 411 361 static const int const_IPTOS_LOWDELAY = IPTOS_LOWDELAY;362 363 412 364 413 #define VERB1 if (MAX_VERBOSE && G.verbose) … … 367 416 #define VERB4 if (MAX_VERBOSE >= 4 && G.verbose >= 4) 368 417 #define VERB5 if (MAX_VERBOSE >= 5 && G.verbose >= 5) 418 #define VERB6 if (MAX_VERBOSE >= 6 && G.verbose >= 6) 369 419 370 420 … … 568 618 sum = 0; 569 619 for (i = 0; i < NUM_DATAPOINTS; i++) { 570 VERB 4{620 VERB5 { 571 621 bb_error_msg("datapoint[%d]: off:%f disp:%f(%f) age:%f%s", 572 622 i, … … 665 715 p->filter_jitter = sum > G_precision_sec ? sum : G_precision_sec; 666 716 667 VERB 3bb_error_msg("filter offset:%+f disp:%f jitter:%f",717 VERB4 bb_error_msg("filter offset:%+f disp:%f jitter:%f", 668 718 p->filter_offset, 669 719 p->filter_dispersion, … … 675 725 { 676 726 int i; 677 bool small_ofs = fabs(offset) < 16 * STEP_THRESHOLD; 727 bool small_ofs = fabs(offset) < STEP_THRESHOLD; 728 729 /* Used to set p->filter_datapoint[i].d_dispersion = MAXDISP 730 * and clear reachable bits, but this proved to be too agressive: 731 * after step (tested with suspending laptop for ~30 secs), 732 * this caused all previous data to be considered invalid, 733 * making us needing to collect full ~8 datapoins per peer 734 * after step in order to start trusting them. 735 * In turn, this was making poll interval decrease even after 736 * step was done. (Poll interval decreases already before step 737 * in this scenario, because we see large offsets and end up with 738 * no good peer to select). 739 */ 678 740 679 741 for (i = 0; i < NUM_DATAPOINTS; i++) { … … 690 752 p->filter_datapoint[i].d_recv_time = G.cur_time; 691 753 p->filter_datapoint[i].d_offset = 0; 692 p->filter_datapoint[i].d_dispersion = MAXDISP;754 /*p->filter_datapoint[i].d_dispersion = MAXDISP;*/ 693 755 } 694 756 } … … 696 758 p->lastpkt_recv_time += offset; 697 759 } else { 698 p->reachable_bits = 0;760 /*p->reachable_bits = 0;*/ 699 761 p->lastpkt_recv_time = G.cur_time; 700 762 } 701 763 filter_datapoints(p); /* recalc p->filter_xxx */ 702 VERB 5bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time);764 VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); 703 765 } 704 766 705 767 static void 706 add_peers(char *s) 707 { 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 792 add_peers(const char *s) 793 { 794 llist_t *item; 708 795 peer_t *p; 709 796 710 p = xzalloc(sizeof(*p)); 711 p->p_lsa = xhost2sockaddr(s, 123); 712 p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa); 797 p = xzalloc(sizeof(*p) + strlen(s)); 798 strcpy(p->p_hostname, s); 799 resolve_peer_hostname(p, /*loop_on_fail=*/ 1); 800 801 /* Names like N.<country2chars>.pool.ntp.org are randomly resolved 802 * to a pool of machines. Sometimes different N's resolve to the same IP. 803 * It is not useful to have two peers with same IP. We skip duplicates. 804 */ 805 for (item = G.ntp_peers; item != NULL; item = item->link) { 806 peer_t *pp = (peer_t *) item->data; 807 if (strcmp(p->p_dotted, pp->p_dotted) == 0) { 808 bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted); 809 free(p->p_lsa); 810 free(p->p_dotted); 811 free(p); 812 return; 813 } 814 } 815 713 816 p->p_fd = -1; 714 817 p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); 715 818 p->next_action_time = G.cur_time; /* = set_next(p, 0); */ 716 reset_peer_stats(p, 16 *STEP_THRESHOLD);819 reset_peer_stats(p, STEP_THRESHOLD); 717 820 718 821 llist_add_to(&G.ntp_peers, p); … … 778 881 if (family == AF_INET) 779 882 #endif 780 setsockopt (fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY));883 setsockopt_int(fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); 781 884 free(local_lsa); 782 885 } … … 801 904 * Save the real transmit timestamp locally. 802 905 */ 803 p->p_xmt_msg.m_xmttime.int_partl = rand om();804 p->p_xmt_msg.m_xmttime.fractionl = rand om();906 p->p_xmt_msg.m_xmttime.int_partl = rand(); 907 p->p_xmt_msg.m_xmttime.fractionl = rand(); 805 908 p->p_xmttime = gettime1900d(); 909 910 /* Were doing it only if sendto worked, but 911 * loss of sync detection needs reachable_bits updated 912 * even if sending fails *locally*: 913 * "network is unreachable" because cable was pulled? 914 * We still need to declare "unsync" if this condition persists. 915 */ 916 p->reachable_bits <<= 1; 806 917 807 918 if (do_sendto(p->p_fd, /*from:*/ NULL, /*to:*/ &p->p_lsa->u.sa, /*addrlen:*/ p->p_lsa->len, … … 810 921 close(p->p_fd); 811 922 p->p_fd = -1; 923 /* 924 * We know that we sent nothing. 925 * We can retry *soon* without fearing 926 * that we are flooding the peer. 927 */ 812 928 set_next(p, RETRY_INTERVAL); 813 929 return; 814 930 } 815 931 816 p->reachable_bits <<= 1;817 932 set_next(p, RESPONSE_INTERVAL); 818 933 } … … 820 935 821 936 /* Note that there is no provision to prevent several run_scripts 822 * to be donein quick succession. In fact, it happens rather often937 * to be started in quick succession. In fact, it happens rather often 823 938 * if initial syncronization results in a step. 824 939 * You will see "step" and then "stratum" script runs, sometimes … … 830 945 char *argv[3]; 831 946 char *env1, *env2, *env3, *env4; 947 948 G.last_script_run = G.cur_time; 832 949 833 950 if (!G.script_name) … … 867 984 free(env3); 868 985 free(env4); 869 870 G.last_script_run = G.cur_time;871 986 } 872 987 … … 888 1003 VERB2 { 889 1004 tval = tvc.tv_sec; 890 strftime (buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&tval));1005 strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval); 891 1006 bb_error_msg("current time is %s.%06u", buf, (unsigned)tvc.tv_usec); 892 1007 } 893 1008 tval = tvn.tv_sec; 894 strftime (buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&tval));1009 strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval); 895 1010 bb_error_msg("setting time to %s.%06u (offset %+fs)", buf, (unsigned)tvn.tv_usec, offset); 896 1011 … … 921 1036 } 922 1037 1038 static void clamp_pollexp_and_set_MAXSTRAT(void) 1039 { 1040 if (G.poll_exp < MINPOLL) 1041 G.poll_exp = MINPOLL; 1042 if (G.poll_exp > BIGPOLL) 1043 G.poll_exp = BIGPOLL; 1044 G.polladj_count = 0; 1045 G.stratum = MAXSTRAT; 1046 } 1047 923 1048 924 1049 /* … … 960 1085 if ((p->reachable_bits & (p->reachable_bits-1)) == 0) { 961 1086 /* One or zero bits in reachable_bits */ 962 VERB 3bb_error_msg("peer %s unfit for selection: unreachable", p->p_dotted);1087 VERB4 bb_error_msg("peer %s unfit for selection: unreachable", p->p_dotted); 963 1088 return 0; 964 1089 } … … 967 1092 || p->lastpkt_stratum >= MAXSTRAT 968 1093 ) { 969 VERB 3bb_error_msg("peer %s unfit for selection: bad status/stratum", p->p_dotted);1094 VERB4 bb_error_msg("peer %s unfit for selection: bad status/stratum", p->p_dotted); 970 1095 return 0; 971 1096 } … … 973 1098 /* rd is root_distance(p) */ 974 1099 if (rd > MAXDIST + FREQ_TOLERANCE * (1 << G.poll_exp)) { 975 VERB 3bb_error_msg("peer %s unfit for selection: root distance too high", p->p_dotted);1100 VERB4 bb_error_msg("peer %s unfit for selection: root distance too high", p->p_dotted); 976 1101 return 0; 977 1102 } … … 1002 1127 num_points = 0; 1003 1128 item = G.ntp_peers; 1004 if (G.initial_poll_complete)while (item != NULL) {1129 while (item != NULL) { 1005 1130 double rd, offset; 1006 1131 … … 1013 1138 } 1014 1139 1015 VERB 4bb_error_msg("interval: [%f %f %f] %s",1140 VERB5 bb_error_msg("interval: [%f %f %f] %s", 1016 1141 offset - rd, 1017 1142 offset, … … 1038 1163 num_candidates = num_points / 3; 1039 1164 if (num_candidates == 0) { 1040 VERB3 bb_error_msg("no valid datapoints , no peer selected");1165 VERB3 bb_error_msg("no valid datapoints%s", ", no peer selected"); 1041 1166 return NULL; 1042 1167 } … … 1096 1221 num_falsetickers++; 1097 1222 if (num_falsetickers * 2 >= num_candidates) { 1098 VERB3 bb_error_msg("too many falsetickers:%d (candidates:%d), no peer selected", 1099 num_falsetickers, num_candidates); 1223 VERB3 bb_error_msg("falsetickers:%d, candidates:%d%s", 1224 num_falsetickers, num_candidates, 1225 ", no peer selected"); 1100 1226 return NULL; 1101 1227 } 1102 1228 } 1103 VERB 3bb_error_msg("selected interval: [%f, %f]; candidates:%d falsetickers:%d",1229 VERB4 bb_error_msg("selected interval: [%f, %f]; candidates:%d falsetickers:%d", 1104 1230 low, high, num_candidates, num_falsetickers); 1105 1231 … … 1119 1245 /* x.opt_rd == root_distance(p); */ 1120 1246 survivor[num_survivors].metric = MAXDIST * p->lastpkt_stratum + point[i].opt_rd; 1121 VERB 4bb_error_msg("survivor[%d] metric:%f peer:%s",1247 VERB5 bb_error_msg("survivor[%d] metric:%f peer:%s", 1122 1248 num_survivors, survivor[num_survivors].metric, p->p_dotted); 1123 1249 num_survivors++; … … 1129 1255 */ 1130 1256 if (num_survivors < MIN_SELECTED) { 1131 VERB3 bb_error_msg("num_survivors %d < %d, no peer selected", 1132 num_survivors, MIN_SELECTED); 1257 VERB3 bb_error_msg("survivors:%d%s", 1258 num_survivors, 1259 ", no peer selected"); 1133 1260 return NULL; 1134 1261 } … … 1150 1277 1151 1278 if (num_survivors <= MIN_CLUSTERED) { 1152 VERB 3bb_error_msg("num_survivors %d <= %d, not discarding more",1279 VERB4 bb_error_msg("num_survivors %d <= %d, not discarding more", 1153 1280 num_survivors, MIN_CLUSTERED); 1154 1281 break; … … 1176 1303 max_idx = i; 1177 1304 } 1178 VERB 5bb_error_msg("survivor %d selection_jitter^2:%f",1305 VERB6 bb_error_msg("survivor %d selection_jitter^2:%f", 1179 1306 i, selection_jitter_sq); 1180 1307 } 1181 1308 max_selection_jitter = SQRT(max_selection_jitter / num_survivors); 1182 VERB 4bb_error_msg("max_selection_jitter (at %d):%f min_jitter:%f",1309 VERB5 bb_error_msg("max_selection_jitter (at %d):%f min_jitter:%f", 1183 1310 max_idx, max_selection_jitter, min_jitter); 1184 1311 … … 1189 1316 */ 1190 1317 if (max_selection_jitter < min_jitter) { 1191 VERB 3bb_error_msg("max_selection_jitter:%f < min_jitter:%f, num_survivors:%d, not discarding more",1318 VERB4 bb_error_msg("max_selection_jitter:%f < min_jitter:%f, num_survivors:%d, not discarding more", 1192 1319 max_selection_jitter, min_jitter, num_survivors); 1193 1320 break; … … 1197 1324 * and go around again. 1198 1325 */ 1199 VERB 5bb_error_msg("dropping survivor %d", max_idx);1326 VERB6 bb_error_msg("dropping survivor %d", max_idx); 1200 1327 num_survivors--; 1201 1328 while (max_idx < num_survivors) { … … 1239 1366 for (i = 1; i < num_survivors; i++) { 1240 1367 if (G.last_update_peer == survivor[i].p) { 1241 VERB 4bb_error_msg("keeping old synced peer");1368 VERB5 bb_error_msg("keeping old synced peer"); 1242 1369 p = G.last_update_peer; 1243 1370 goto keep_old; … … 1247 1374 G.last_update_peer = p; 1248 1375 keep_old: 1249 VERB 3bb_error_msg("selected peer %s filter_offset:%+f age:%f",1376 VERB4 bb_error_msg("selected peer %s filter_offset:%+f age:%f", 1250 1377 p->p_dotted, 1251 1378 p->filter_offset, … … 1266 1393 * the current time. 1267 1394 */ 1268 VERB 3bb_error_msg("disc_state=%d last update offset=%f recv_time=%f",1395 VERB4 bb_error_msg("disc_state=%d last update offset=%f recv_time=%f", 1269 1396 disc_state, offset, recv_time); 1270 1397 G.discipline_state = disc_state; … … 1285 1412 double freq_drift; 1286 1413 #endif 1414 #if !USING_KERNEL_PLL_LOOP || USING_INITIAL_FREQ_ESTIMATION 1287 1415 double since_last_update; 1416 #endif 1288 1417 double etemp, dtemp; 1289 1418 … … 1304 1433 */ 1305 1434 if (recv_time <= G.last_update_recv_time) { 1306 VERB3 bb_error_msg(" same or older datapoint: %f >= %f, not using it",1307 G.last_update_recv_time, recv_time);1435 VERB3 bb_error_msg("update from %s: same or older datapoint, not using it", 1436 p->p_dotted); 1308 1437 return 0; /* "leave poll interval as is" */ 1309 1438 } … … 1313 1442 * and frequency errors. 1314 1443 */ 1444 #if !USING_KERNEL_PLL_LOOP || USING_INITIAL_FREQ_ESTIMATION 1315 1445 since_last_update = recv_time - G.reftime; 1446 #endif 1316 1447 #if !USING_KERNEL_PLL_LOOP 1317 1448 freq_drift = 0; … … 1321 1452 /* Ignore updates until the stepout threshold */ 1322 1453 if (since_last_update < WATCH_THRESHOLD) { 1323 VERB 3bb_error_msg("measuring drift, datapoint ignored, %f sec remains",1454 VERB4 bb_error_msg("measuring drift, datapoint ignored, %f sec remains", 1324 1455 WATCH_THRESHOLD - since_last_update); 1325 1456 return 0; /* "leave poll interval as is" */ … … 1335 1466 */ 1336 1467 if (abs_offset > STEP_THRESHOLD) { 1468 #if 0 1469 double remains; 1470 1471 // This "spike state" seems to be useless, peer selection already drops 1472 // occassional "bad" datapoints. If we are here, there were _many_ 1473 // large offsets. When a few first large offsets are seen, 1474 // we end up in "no valid datapoints, no peer selected" state. 1475 // Only when enough of them are seen (which means it's not a fluke), 1476 // we end up here. Looks like _our_ clock is off. 1337 1477 switch (G.discipline_state) { 1338 1478 case STATE_SYNC: 1339 1479 /* The first outlyer: ignore it, switch to SPIK state */ 1340 VERB3 bb_error_msg("offset:%+f - spike detected", offset); 1480 VERB3 bb_error_msg("update from %s: offset:%+f, spike%s", 1481 p->p_dotted, offset, 1482 ""); 1341 1483 G.discipline_state = STATE_SPIK; 1342 1484 return -1; /* "decrease poll interval" */ … … 1346 1488 * is found or the stepout threshold is exceeded. 1347 1489 */ 1348 if (since_last_update < WATCH_THRESHOLD) { 1349 VERB3 bb_error_msg("spike detected, datapoint ignored, %f sec remains", 1350 WATCH_THRESHOLD - since_last_update); 1490 remains = WATCH_THRESHOLD - since_last_update; 1491 if (remains > 0) { 1492 VERB3 bb_error_msg("update from %s: offset:%+f, spike%s", 1493 p->p_dotted, offset, 1494 ", datapoint ignored"); 1351 1495 return -1; /* "decrease poll interval" */ 1352 1496 } 1353 1497 /* fall through: we need to step */ 1354 1498 } /* switch */ 1499 #endif 1355 1500 1356 1501 /* Step the time and clamp down the poll interval. … … 1375 1520 * intervals. 1376 1521 */ 1377 VERB 3bb_error_msg("stepping time by %+f; poll_exp=MINPOLL", offset);1522 VERB4 bb_error_msg("stepping time by %+f; poll_exp=MINPOLL", offset); 1378 1523 step_time(offset); 1379 1524 if (option_mask32 & OPT_q) { … … 1382 1527 } 1383 1528 1384 G.polladj_count = 0; 1385 G.poll_exp = MINPOLL; 1386 G.stratum = MAXSTRAT; 1529 clamp_pollexp_and_set_MAXSTRAT(); 1387 1530 1388 1531 run_script("step", offset); 1532 1533 recv_time += offset; 1389 1534 1390 1535 #if USING_INITIAL_FREQ_ESTIMATION … … 1396 1541 abs_offset = offset = 0; 1397 1542 set_new_values(STATE_SYNC, offset, recv_time); 1398 1399 1543 } else { /* abs_offset <= STEP_THRESHOLD */ 1400 1544 1401 if (G.poll_exp < MINPOLL && G.initial_poll_complete) { 1402 VERB3 bb_error_msg("small offset:%+f, disabling burst mode", offset); 1403 G.polladj_count = 0; 1404 G.poll_exp = MINPOLL; 1405 } 1545 /* The ratio is calculated before jitter is updated to make 1546 * poll adjust code more sensitive to large offsets. 1547 */ 1548 G.offset_to_jitter_ratio = abs_offset / G.discipline_jitter; 1406 1549 1407 1550 /* Compute the clock jitter as the RMS of exponentially … … 1411 1554 dtemp = SQUARE(offset - G.last_update_offset); 1412 1555 G.discipline_jitter = SQRT(etemp + (dtemp - etemp) / AVG); 1556 if (G.discipline_jitter < G_precision_sec) 1557 G.discipline_jitter = G_precision_sec; 1413 1558 1414 1559 switch (G.discipline_state) { … … 1429 1574 set_new_values(STATE_SYNC, offset, recv_time); 1430 1575 #endif 1431 VERB 3bb_error_msg("transitioning to FREQ, datapoint ignored");1576 VERB4 bb_error_msg("transitioning to FREQ, datapoint ignored"); 1432 1577 return 0; /* "leave poll interval as is" */ 1433 1578 … … 1487 1632 } 1488 1633 1489 if (G.discipline_jitter < G_precision_sec)1490 G.discipline_jitter = G_precision_sec;1491 G.offset_to_jitter_ratio = abs_offset / G.discipline_jitter;1492 1493 1634 G.reftime = G.cur_time; 1494 1635 G.ntp_status = p->lastpkt_status; … … 1498 1639 dtemp += MAXD(p->filter_dispersion + FREQ_TOLERANCE * (G.cur_time - p->lastpkt_recv_time) + abs_offset, MINDISP); 1499 1640 G.rootdisp = p->lastpkt_rootdisp + dtemp; 1500 VERB 3bb_error_msg("updating leap/refid/reftime/rootdisp from peer %s", p->p_dotted);1641 VERB4 bb_error_msg("updating leap/refid/reftime/rootdisp from peer %s", p->p_dotted); 1501 1642 1502 1643 /* We are in STATE_SYNC now, but did not do adjtimex yet. … … 1518 1659 G.discipline_wander = SQRT(etemp + (dtemp - etemp) / AVG); 1519 1660 1520 VERB 3bb_error_msg("discipline freq_drift=%.9f(int:%ld corr:%e) wander=%f",1661 VERB4 bb_error_msg("discipline freq_drift=%.9f(int:%ld corr:%e) wander=%f", 1521 1662 G.discipline_freq_drift, 1522 1663 (long)(G.discipline_freq_drift * 65536e6), … … 1524 1665 G.discipline_wander); 1525 1666 #endif 1526 VERB 3{1667 VERB4 { 1527 1668 memset(&tmx, 0, sizeof(tmx)); 1528 1669 if (adjtimex(&tmx) < 0) … … 1543 1684 #endif 1544 1685 tmx.modes = ADJ_OFFSET | ADJ_STATUS | ADJ_TIMECONST;// | ADJ_MAXERROR | ADJ_ESTERROR; 1545 tmx.offset = (offset * 1000000); /* usec */ 1546 tmx.status = STA_PLL; 1547 if (G.ntp_status & LI_PLUSSEC) 1548 tmx.status |= STA_INS; 1549 if (G.ntp_status & LI_MINUSSEC) 1550 tmx.status |= STA_DEL; 1551 1552 tmx.constant = G.poll_exp - 4; 1686 tmx.constant = (int)G.poll_exp - 4; 1553 1687 /* EXPERIMENTAL. 1554 1688 * The below if statement should be unnecessary, but... … … 1561 1695 * larger than jitter. 1562 1696 */ 1563 if ( tmx.constant > 0 &&G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE)1697 if (G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE) 1564 1698 tmx.constant--; 1699 tmx.offset = (long)(offset * 1000000); /* usec */ 1700 if (SLEW_THRESHOLD < STEP_THRESHOLD) { 1701 if (tmx.offset > (long)(SLEW_THRESHOLD * 1000000)) { 1702 tmx.offset = (long)(SLEW_THRESHOLD * 1000000); 1703 tmx.constant--; 1704 } 1705 if (tmx.offset < -(long)(SLEW_THRESHOLD * 1000000)) { 1706 tmx.offset = -(long)(SLEW_THRESHOLD * 1000000); 1707 tmx.constant--; 1708 } 1709 } 1710 if (tmx.constant < 0) 1711 tmx.constant = 0; 1712 1713 tmx.status = STA_PLL; 1714 if (G.ntp_status & LI_PLUSSEC) 1715 tmx.status |= STA_INS; 1716 if (G.ntp_status & LI_MINUSSEC) 1717 tmx.status |= STA_DEL; 1565 1718 1566 1719 //tmx.esterror = (uint32_t)(clock_jitter * 1e6); … … 1572 1725 * Not sure why. Perhaps it is normal. 1573 1726 */ 1574 VERB 3bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x",1727 VERB4 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x", 1575 1728 rc, tmx.freq, tmx.offset, tmx.status); 1576 1729 G.kernel_freq_drift = tmx.freq / 65536; 1577 VERB2 bb_error_msg("update from:%s offset:%+f jitter:%f clock drift:%+.3fppm tc:%d", 1578 p->p_dotted, offset, G.discipline_jitter, (double)tmx.freq / 65536, (int)tmx.constant); 1730 VERB2 bb_error_msg("update from:%s offset:%+f delay:%f jitter:%f clock drift:%+.3fppm tc:%d", 1731 p->p_dotted, 1732 offset, 1733 p->lastpkt_delay, 1734 G.discipline_jitter, 1735 (double)tmx.freq / 65536, 1736 (int)tmx.constant 1737 ); 1579 1738 1580 1739 return 1; /* "ok to increase poll interval" */ … … 1587 1746 */ 1588 1747 static unsigned 1589 retry_interval(void) 1590 { 1591 /* Local problem, want to retry soon */ 1592 unsigned interval, r; 1593 interval = RETRY_INTERVAL; 1594 r = random(); 1595 interval += r % (unsigned)(RETRY_INTERVAL / 4); 1596 VERB3 bb_error_msg("chose retry interval:%u", interval); 1748 poll_interval(int upper_bound) 1749 { 1750 unsigned interval, r, mask; 1751 interval = 1 << G.poll_exp; 1752 if (interval > upper_bound) 1753 interval = upper_bound; 1754 mask = ((interval-1) >> 4) | 1; 1755 r = rand(); 1756 interval += r & mask; /* ~ random(0..1) * interval/16 */ 1757 VERB4 bb_error_msg("chose poll interval:%u (poll_exp:%d)", interval, G.poll_exp); 1597 1758 return interval; 1598 1759 } 1599 static unsigned 1600 poll_interval(int exponent) 1601 { 1602 unsigned interval, r; 1603 exponent = G.poll_exp + exponent; 1604 if (exponent < 0) 1605 exponent = 0; 1606 interval = 1 << exponent; 1607 r = random(); 1608 interval += ((r & (interval-1)) >> 4) + ((r >> 8) & 1); /* + 1/16 of interval, max */ 1609 VERB3 bb_error_msg("chose poll interval:%u (poll_exp:%d exp:%d)", interval, G.poll_exp, exponent); 1610 return interval; 1760 static void 1761 adjust_poll(int count) 1762 { 1763 G.polladj_count += count; 1764 if (G.polladj_count > POLLADJ_LIMIT) { 1765 G.polladj_count = 0; 1766 if (G.poll_exp < MAXPOLL) { 1767 G.poll_exp++; 1768 VERB4 bb_error_msg("polladj: discipline_jitter:%f ++poll_exp=%d", 1769 G.discipline_jitter, G.poll_exp); 1770 } 1771 } else if (G.polladj_count < -POLLADJ_LIMIT || (count < 0 && G.poll_exp > BIGPOLL)) { 1772 G.polladj_count = 0; 1773 if (G.poll_exp > MINPOLL) { 1774 llist_t *item; 1775 1776 G.poll_exp--; 1777 /* Correct p->next_action_time in each peer 1778 * which waits for sending, so that they send earlier. 1779 * Old pp->next_action_time are on the order 1780 * of t + (1 << old_poll_exp) + small_random, 1781 * we simply need to subtract ~half of that. 1782 */ 1783 for (item = G.ntp_peers; item != NULL; item = item->link) { 1784 peer_t *pp = (peer_t *) item->data; 1785 if (pp->p_fd < 0) 1786 pp->next_action_time -= (1 << G.poll_exp); 1787 } 1788 VERB4 bb_error_msg("polladj: discipline_jitter:%f --poll_exp=%d", 1789 G.discipline_jitter, G.poll_exp); 1790 } 1791 } else { 1792 VERB4 bb_error_msg("polladj: count:%d", G.polladj_count); 1793 } 1611 1794 } 1612 1795 static NOINLINE void … … 1617 1800 msg_t msg; 1618 1801 double T1, T2, T3, T4; 1802 double offset; 1803 double prev_delay, delay; 1619 1804 unsigned interval; 1620 1805 datapoint_t *datapoint; 1621 1806 peer_t *q; 1622 1807 1808 offset = 0; 1809 1623 1810 /* We can recvfrom here and check from.IP, but some multihomed 1624 1811 * ntp servers reply from their *other IP*. 1625 1812 * TODO: maybe we should check at least what we can: from.port == 123? 1626 1813 */ 1814 recv_again: 1627 1815 size = recv(p->p_fd, &msg, sizeof(msg), MSG_DONTWAIT); 1628 if (size == -1) { 1629 bb_perror_msg("recv(%s) error", p->p_dotted); 1630 if (errno == EHOSTUNREACH || errno == EHOSTDOWN 1631 || errno == ENETUNREACH || errno == ENETDOWN 1632 || errno == ECONNREFUSED || errno == EADDRNOTAVAIL 1633 || errno == EAGAIN 1634 ) { 1635 //TODO: always do this? 1636 interval = retry_interval(); 1637 goto set_next_and_ret; 1638 } 1639 xfunc_die(); 1816 if (size < 0) { 1817 if (errno == EINTR) 1818 /* Signal caught */ 1819 goto recv_again; 1820 if (errno == EAGAIN) 1821 /* There was no packet after all 1822 * (poll() returning POLLIN for a fd 1823 * is not a ironclad guarantee that data is there) 1824 */ 1825 return; 1826 /* 1827 * If you need a different handling for a specific 1828 * errno, always explain it in comment. 1829 */ 1830 bb_perror_msg_and_die("recv(%s) error", p->p_dotted); 1640 1831 } 1641 1832 … … 1663 1854 || msg.m_stratum > NTP_MAXSTRATUM 1664 1855 ) { 1665 // TODO: stratum 0 responses may have commands in 32-bit m_refid field: 1666 // "DENY", "RSTR" - peer does not like us at all 1667 // "RATE" - peer is overloaded, reduce polling freq 1668 interval = poll_interval(0); 1669 bb_error_msg("reply from %s: peer is unsynced, next query in %us", p->p_dotted, interval); 1670 goto set_next_and_ret; 1856 bb_error_msg("reply from %s: peer is unsynced", p->p_dotted); 1857 /* 1858 * Stratum 0 responses may have commands in 32-bit m_refid field: 1859 * "DENY", "RSTR" - peer does not like us at all, 1860 * "RATE" - peer is overloaded, reduce polling freq. 1861 * If poll interval is small, increase it. 1862 */ 1863 if (G.poll_exp < BIGPOLL) 1864 goto increase_interval; 1865 goto pick_normal_interval; 1671 1866 } 1672 1867 … … 1674 1869 // if (msg.m_rootdelay / 2 + msg.m_rootdisp >= MAXDISP || p->lastpkt_reftime > msg.m_xmt) 1675 1870 // return; /* invalid header values */ 1676 1677 p->lastpkt_status = msg.m_status;1678 p->lastpkt_stratum = msg.m_stratum;1679 p->lastpkt_rootdelay = sfp_to_d(msg.m_rootdelay);1680 p->lastpkt_rootdisp = sfp_to_d(msg.m_rootdisp);1681 p->lastpkt_refid = msg.m_refid;1682 1871 1683 1872 /* … … 1700 1889 T4 = G.cur_time; 1701 1890 1702 p->lastpkt_recv_time = T4;1703 1704 VERB5 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time);1705 p->datapoint_idx = p->reachable_bits ? (p->datapoint_idx + 1) % NUM_DATAPOINTS : 0;1706 datapoint = &p->filter_datapoint[p->datapoint_idx];1707 datapoint->d_recv_time = T4;1708 datapoint->d_offset = ((T2 - T1) + (T3 - T4)) / 2;1709 1891 /* The delay calculation is a special case. In cases where the 1710 1892 * server and client clocks are running at different rates and … … 1713 1895 * the delay is clamped not less than the system precision. 1714 1896 */ 1715 p->lastpkt_delay = (T4 - T1) - (T3 - T2); 1716 if (p->lastpkt_delay < G_precision_sec) 1717 p->lastpkt_delay = G_precision_sec; 1897 delay = (T4 - T1) - (T3 - T2); 1898 if (delay < G_precision_sec) 1899 delay = G_precision_sec; 1900 /* 1901 * If this packet's delay is much bigger than the last one, 1902 * it's better to just ignore it than use its much less precise value. 1903 */ 1904 prev_delay = p->p_raw_delay; 1905 p->p_raw_delay = delay; 1906 if (p->reachable_bits && delay > prev_delay * BAD_DELAY_GROWTH) { 1907 bb_error_msg("reply from %s: delay %f is too high, ignoring", p->p_dotted, delay); 1908 goto pick_normal_interval; 1909 } 1910 1911 p->lastpkt_delay = delay; 1912 p->lastpkt_recv_time = T4; 1913 VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); 1914 p->lastpkt_status = msg.m_status; 1915 p->lastpkt_stratum = msg.m_stratum; 1916 p->lastpkt_rootdelay = sfp_to_d(msg.m_rootdelay); 1917 p->lastpkt_rootdisp = sfp_to_d(msg.m_rootdisp); 1918 p->lastpkt_refid = msg.m_refid; 1919 1920 p->datapoint_idx = p->reachable_bits ? (p->datapoint_idx + 1) % NUM_DATAPOINTS : 0; 1921 datapoint = &p->filter_datapoint[p->datapoint_idx]; 1922 datapoint->d_recv_time = T4; 1923 datapoint->d_offset = offset = ((T2 - T1) + (T3 - T4)) / 2; 1718 1924 datapoint->d_dispersion = LOG2D(msg.m_precision_exp) + G_precision_sec; 1719 1925 if (!p->reachable_bits) { … … 1721 1927 int i; 1722 1928 for (i = 0; i < NUM_DATAPOINTS; i++) { 1723 p->filter_datapoint[i].d_offset = datapoint->d_offset;1929 p->filter_datapoint[i].d_offset = offset; 1724 1930 } 1725 1931 } … … 1729 1935 bb_error_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x", 1730 1936 p->p_dotted, 1731 datapoint->d_offset,1937 offset, 1732 1938 p->lastpkt_delay, 1733 1939 p->lastpkt_status, … … 1745 1951 filter_datapoints(p); 1746 1952 q = select_and_cluster(); 1747 rc = -1;1953 rc = 0; 1748 1954 if (q) { 1749 rc = 0;1750 1955 if (!(option_mask32 & OPT_w)) { 1751 1956 rc = update_local_clock(q); 1957 #if 0 1958 //Disabled this because there is a case where largish offsets 1959 //are unavoidable: if network round-trip delay is, say, ~0.6s, 1960 //error in offset estimation would be ~delay/2 ~= 0.3s. 1961 //Thus, offsets will be usually in -0.3...0.3s range. 1962 //In this case, this code would keep poll interval small, 1963 //but it won't be helping. 1964 //BIGOFF check below deals with a case of seeing multi-second offsets. 1965 1752 1966 /* If drift is dangerously large, immediately 1753 1967 * drop poll interval one step down. 1754 1968 */ 1755 1969 if (fabs(q->filter_offset) >= POLLDOWN_OFFSET) { 1756 VERB3 bb_error_msg("offset:%+f > POLLDOWN_OFFSET", q->filter_offset); 1757 goto poll_down; 1970 VERB4 bb_error_msg("offset:%+f > POLLDOWN_OFFSET", q->filter_offset); 1971 adjust_poll(-POLLADJ_LIMIT * 3); 1972 rc = 0; 1758 1973 } 1759 } 1760 } 1761 /* else: no peer selected, rc = -1: we want to poll more often */ 1974 #endif 1975 } 1976 } else { 1977 /* No peer selected. 1978 * If poll interval is small, increase it. 1979 */ 1980 if (G.poll_exp < BIGPOLL) 1981 goto increase_interval; 1982 } 1762 1983 1763 1984 if (rc != 0) { … … 1771 1992 /* was += G.poll_exp but it is a bit 1772 1993 * too optimistic for my taste at high poll_exp's */ 1773 G.polladj_count += MINPOLL; 1774 if (G.polladj_count > POLLADJ_LIMIT) { 1775 G.polladj_count = 0; 1776 if (G.poll_exp < MAXPOLL) { 1777 G.poll_exp++; 1778 VERB3 bb_error_msg("polladj: discipline_jitter:%f ++poll_exp=%d", 1779 G.discipline_jitter, G.poll_exp); 1780 } 1781 } else { 1782 VERB3 bb_error_msg("polladj: incr:%d", G.polladj_count); 1783 } 1994 increase_interval: 1995 adjust_poll(MINPOLL); 1784 1996 } else { 1785 G.polladj_count -= G.poll_exp * 2; 1786 if (G.polladj_count < -POLLADJ_LIMIT || G.poll_exp >= BIGPOLL) { 1787 poll_down: 1788 G.polladj_count = 0; 1789 if (G.poll_exp > MINPOLL) { 1790 llist_t *item; 1791 1792 G.poll_exp--; 1793 /* Correct p->next_action_time in each peer 1794 * which waits for sending, so that they send earlier. 1795 * Old pp->next_action_time are on the order 1796 * of t + (1 << old_poll_exp) + small_random, 1797 * we simply need to subtract ~half of that. 1798 */ 1799 for (item = G.ntp_peers; item != NULL; item = item->link) { 1800 peer_t *pp = (peer_t *) item->data; 1801 if (pp->p_fd < 0) 1802 pp->next_action_time -= (1 << G.poll_exp); 1803 } 1804 VERB3 bb_error_msg("polladj: discipline_jitter:%f --poll_exp=%d", 1805 G.discipline_jitter, G.poll_exp); 1806 } 1807 } else { 1808 VERB3 bb_error_msg("polladj: decr:%d", G.polladj_count); 1809 } 1997 VERB3 if (rc > 0) 1998 bb_error_msg("want smaller interval: offset/jitter = %u", 1999 G.offset_to_jitter_ratio); 2000 adjust_poll(-G.poll_exp * 2); 1810 2001 } 1811 2002 } 1812 2003 1813 2004 /* Decide when to send new query for this peer */ 1814 interval = poll_interval(0); 1815 1816 set_next_and_ret: 2005 pick_normal_interval: 2006 interval = poll_interval(INT_MAX); 2007 if (fabs(offset) >= BIGOFF && interval > BIGOFF_INTERVAL) { 2008 /* If we are synced, offsets are less than SLEW_THRESHOLD, 2009 * or at the very least not much larger than it. 2010 * Now we see a largish one. 2011 * Either this peer is feeling bad, or packet got corrupted, 2012 * or _our_ clock is wrong now and _all_ peers will show similar 2013 * largish offsets too. 2014 * I observed this with laptop suspend stopping clock. 2015 * In any case, it makes sense to make next request soonish: 2016 * cases 1 and 2: get a better datapoint, 2017 * case 3: allows to resync faster. 2018 */ 2019 interval = BIGOFF_INTERVAL; 2020 } 2021 1817 2022 set_next(p, interval); 1818 2023 } … … 1844 2049 bb_error_msg("malformed packet received from %s: size %u", addr, (int)size); 1845 2050 free(addr); 2051 goto bail; 2052 } 2053 2054 /* Respond only to client and symmetric active packets */ 2055 if ((msg.m_status & MODE_MASK) != MODE_CLIENT 2056 && (msg.m_status & MODE_MASK) != MODE_SYM_ACT 2057 ) { 1846 2058 goto bail; 1847 2059 } … … 1979 2191 llist_t *peers; 1980 2192 1981 srand om(getpid());2193 srand(getpid()); 1982 2194 1983 2195 if (getuid()) … … 1985 2197 1986 2198 /* Set some globals */ 2199 G.discipline_jitter = G_precision_sec; 1987 2200 G.stratum = MAXSTRAT; 1988 2201 if (BURSTPOLL != 0) … … 1992 2205 /* Parse options */ 1993 2206 peers = NULL; 1994 opt_complementary = "dd:p::wn"; /* d: counter; p: list; -w implies -n */ 2207 opt_complementary = "dd:p::wn" /* -d: counter; -p: list; -w implies -n */ 2208 IF_FEATURE_NTPD_SERVER(":Il"); /* -I implies -l */ 1995 2209 opts = getopt32(argv, 1996 2210 "nqNx" /* compat */ 1997 2211 "wp:S:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */ 2212 IF_FEATURE_NTPD_SERVER("I:") /* compat */ 1998 2213 "d" /* compat */ 1999 2214 "46aAbgL", /* compat, ignored */ 2000 &peers, &G.script_name, &G.verbose); 2001 if (!(opts & (OPT_p|OPT_l))) 2002 bb_show_usage(); 2215 &peers,&G.script_name, 2216 #if ENABLE_FEATURE_NTPD_SERVER 2217 &G.if_name, 2218 #endif 2219 &G.verbose); 2220 2003 2221 // if (opts & OPT_x) /* disable stepping, only slew is allowed */ 2004 2222 // G.time_was_stepped = 1; … … 2006 2224 while (peers) 2007 2225 add_peers(llist_pop(&peers)); 2008 } else { 2226 } 2227 #if ENABLE_FEATURE_NTPD_CONF 2228 else { 2229 parser_t *parser; 2230 char *token[3]; 2231 2232 parser = config_open("/etc/ntp.conf"); 2233 while (config_read(parser, token, 3, 1, "# \t", PARSE_NORMAL)) { 2234 if (strcmp(token[0], "server") == 0 && token[1]) { 2235 add_peers(token[1]); 2236 continue; 2237 } 2238 bb_error_msg("skipping %s:%u: unimplemented command '%s'", 2239 "/etc/ntp.conf", parser->lineno, token[0] 2240 ); 2241 } 2242 config_close(parser); 2243 } 2244 #endif 2245 if (G.peer_cnt == 0) { 2246 if (!(opts & OPT_l)) 2247 bb_show_usage(); 2009 2248 /* -l but no peers: "stratum 1 server" mode */ 2010 2249 G.stratum = 1; 2011 }2012 if (!(opts & OPT_n)) {2013 bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv);2014 logmode = LOGMODE_NONE;2015 2250 } 2016 2251 #if ENABLE_FEATURE_NTPD_SERVER … … 2018 2253 if (opts & OPT_l) { 2019 2254 G_listen_fd = create_and_bind_dgram_or_die(NULL, 123); 2255 if (opts & OPT_I) { 2256 if (setsockopt_bindtodevice(G_listen_fd, G.if_name)) 2257 xfunc_die(); 2258 } 2020 2259 socket_want_pktinfo(G_listen_fd); 2021 setsockopt(G_listen_fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY)); 2022 } 2023 #endif 2260 setsockopt_int(G_listen_fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); 2261 } 2262 #endif 2263 if (!(opts & OPT_n)) { 2264 bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv); 2265 logmode = LOGMODE_NONE; 2266 } 2024 2267 /* I hesitate to set -20 prio. -15 should be high enough for timekeeping */ 2025 2268 if (opts & OPT_N) … … 2109 2352 /* Time to send new req */ 2110 2353 if (--cnt == 0) { 2111 G.initial_poll_complete = 1; 2354 VERB4 bb_error_msg("disabling burst mode"); 2355 G.polladj_count = 0; 2356 G.poll_exp = MINPOLL; 2112 2357 } 2113 2358 send_query_to_peer(p); … … 2116 2361 close(p->p_fd); 2117 2362 p->p_fd = -1; 2118 timeout = poll_interval(-2); /* -2: try a bit sooner */ 2363 /* If poll interval is small, increase it */ 2364 if (G.poll_exp < BIGPOLL) 2365 adjust_poll(MINPOLL); 2366 timeout = poll_interval(NOREPLY_INTERVAL); 2119 2367 bb_error_msg("timed out waiting for %s, reach 0x%02x, next query in %us", 2120 2368 p->p_dotted, p->reachable_bits, timeout); 2369 2370 /* What if don't see it because it changed its IP? */ 2371 if (p->reachable_bits == 0) 2372 resolve_peer_hostname(p, /*loop_on_fail=*/ 0); 2373 2121 2374 set_next(p, timeout); 2122 2375 } … … 2160 2413 gettime1900d(); /* sets G.cur_time */ 2161 2414 if (nfds <= 0) { 2162 if (G.script_name && G.cur_time - G.last_script_run > 11*60) { 2415 if (!bb_got_signal /* poll wasn't interrupted by a signal */ 2416 && G.cur_time - G.last_script_run > 11*60 2417 ) { 2163 2418 /* Useful for updating battery-backed RTC and such */ 2164 2419 run_script("periodic", G.last_update_offset); 2165 2420 gettime1900d(); /* sets G.cur_time */ 2166 2421 } 2167 continue;2422 goto check_unsync; 2168 2423 } 2169 2424 … … 2195 2450 gettime1900d(); /* sets G.cur_time */ 2196 2451 } 2452 } 2453 2454 check_unsync: 2455 if (G.ntp_peers && G.stratum != MAXSTRAT) { 2456 for (item = G.ntp_peers; item != NULL; item = item->link) { 2457 peer_t *p = (peer_t *) item->data; 2458 if (p->reachable_bits) 2459 goto have_reachable_peer; 2460 } 2461 /* No peer responded for last 8 packets, panic */ 2462 clamp_pollexp_and_set_MAXSTRAT(); 2463 run_script("unsync", 0.0); 2464 have_reachable_peer: ; 2197 2465 } 2198 2466 } /* while (!bb_got_signal) */ -
branches/3.3/mindi-busybox/networking/ping.c
r3232 r3621 29 29 #include <netinet/ip_icmp.h> 30 30 #include "libbb.h" 31 #include "common_bufsiz.h" 31 32 32 33 #ifdef __BIONIC__ … … 90 91 //usage:# define ping_full_usage "\n\n" 91 92 //usage: "Send ICMP ECHO_REQUEST packets to network hosts\n" 93 //usage: IF_PING6( 92 94 //usage: "\n -4,-6 Force IP or IPv6 name resolution" 95 //usage: ) 93 96 //usage: "\n -c CNT Send only CNT pings" 94 97 //usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)" … … 99 102 //usage: "\n -w SEC Seconds until ping exits (default:infinite)" 100 103 //usage: "\n (can exit earlier with -c CNT)" 101 //usage: "\n -q Quiet, only display soutput at start"104 //usage: "\n -q Quiet, only display output at start" 102 105 //usage: "\n and when finished" 106 //usage: "\n -p Pattern to use for payload" 103 107 //usage: 104 108 //usage:# define ping6_trivial_usage … … 109 113 //usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)" 110 114 //usage: "\n -I IFACE/IP Use interface or IP address as source" 111 //usage: "\n -q Quiet, only display soutput at start"115 //usage: "\n -q Quiet, only display output at start" 112 116 //usage: "\n and when finished" 117 //usage: "\n -p Pattern to use for payload" 113 118 //usage: 114 119 //usage:#endif … … 148 153 MAXWAIT = 10, 149 154 PINGINTERVAL = 1, /* 1 second */ 155 pingsock = 0, 150 156 }; 157 158 static void 159 #if ENABLE_PING6 160 create_icmp_socket(len_and_sockaddr *lsa) 161 #else 162 create_icmp_socket(void) 163 #define create_icmp_socket(lsa) create_icmp_socket() 164 #endif 165 { 166 int sock; 167 #if ENABLE_PING6 168 if (lsa->u.sa.sa_family == AF_INET6) 169 sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); 170 else 171 #endif 172 sock = socket(AF_INET, SOCK_RAW, 1); /* 1 == ICMP */ 173 if (sock < 0) { 174 if (errno == EPERM) 175 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 176 bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket); 177 } 178 179 xmove_fd(sock, pingsock); 180 } 151 181 152 182 #if !ENABLE_FEATURE_FANCY_PING … … 158 188 char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; 159 189 } FIX_ALIASING; 160 #define G (*(struct globals*) &bb_common_bufsiz1)161 #define INIT_G() do { } while (0)190 #define G (*(struct globals*)bb_common_bufsiz1) 191 #define INIT_G() do { setup_common_bufsiz(); } while (0) 162 192 163 193 static void noresp(int ign UNUSED_PARAM) … … 170 200 { 171 201 struct icmp *pkt; 172 int pingsock, c; 173 174 pingsock = create_icmp_socket(); 202 int c; 175 203 176 204 pkt = (struct icmp *) G.packet; 177 memset(pkt, 0, sizeof(G.packet));205 /*memset(pkt, 0, sizeof(G.packet)); already is */ 178 206 pkt->icmp_type = ICMP_ECHO; 179 207 pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, sizeof(G.packet)); … … 183 211 /* listen for replies */ 184 212 while (1) { 213 #if 0 185 214 struct sockaddr_in from; 186 215 socklen_t fromlen = sizeof(from); … … 188 217 c = recvfrom(pingsock, G.packet, sizeof(G.packet), 0, 189 218 (struct sockaddr *) &from, &fromlen); 219 #else 220 c = recv(pingsock, G.packet, sizeof(G.packet), 0); 221 #endif 190 222 if (c < 0) { 191 223 if (errno != EINTR) … … 209 241 { 210 242 struct icmp6_hdr *pkt; 211 int pingsock,c;243 int c; 212 244 int sockopt; 213 245 214 pingsock = create_icmp6_socket();215 216 246 pkt = (struct icmp6_hdr *) G.packet; 217 memset(pkt, 0, sizeof(G.packet));247 /*memset(pkt, 0, sizeof(G.packet)); already is */ 218 248 pkt->icmp6_type = ICMP6_ECHO_REQUEST; 219 249 220 250 sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); 221 setsockopt (pingsock, SOL_RAW, IPV6_CHECKSUM, &sockopt, sizeof(sockopt));251 setsockopt_int(pingsock, SOL_RAW, IPV6_CHECKSUM, sockopt); 222 252 223 253 xsendto(pingsock, G.packet, DEFDATALEN + sizeof(struct icmp6_hdr), &lsa->u.sa, lsa->len); … … 225 255 /* listen for replies */ 226 256 while (1) { 257 #if 0 227 258 struct sockaddr_in6 from; 228 259 socklen_t fromlen = sizeof(from); … … 230 261 c = recvfrom(pingsock, G.packet, sizeof(G.packet), 0, 231 262 (struct sockaddr *) &from, &fromlen); 263 #else 264 c = recv(pingsock, G.packet, sizeof(G.packet), 0); 265 #endif 232 266 if (c < 0) { 233 267 if (errno != EINTR) … … 235 269 continue; 236 270 } 237 if (c >= ICMP_MINLEN) { /* icmp6_hdr */ 238 pkt = (struct icmp6_hdr *) G.packet; 271 if (c >= ICMP_MINLEN) { /* icmp6_hdr */ 239 272 if (pkt->icmp6_type == ICMP6_ECHO_REPLY) 240 273 break; … … 284 317 alarm(5); /* give the host 5000ms to respond */ 285 318 319 create_icmp_socket(lsa); 286 320 #if ENABLE_PING6 287 321 if (lsa->u.sa.sa_family == AF_INET6) … … 300 334 /* Full(er) version */ 301 335 302 #define OPT_STRING ("qvc:s:t:w:W:I: 4" IF_PING6("6"))336 #define OPT_STRING ("qvc:s:t:w:W:I:np:4" IF_PING6("6")) 303 337 enum { 304 338 OPT_QUIET = 1 << 0, … … 310 344 OPT_W = 1 << 6, 311 345 OPT_I = 1 << 7, 312 OPT_IPV4 = 1 << 8, 313 OPT_IPV6 = (1 << 9) * ENABLE_PING6, 346 /*OPT_n = 1 << 8, - ignored */ 347 OPT_p = 1 << 9, 348 OPT_IPV4 = 1 << 10, 349 OPT_IPV6 = (1 << 11) * ENABLE_PING6, 314 350 }; 315 351 316 352 317 353 struct globals { 318 int pingsock;319 354 int if_index; 320 355 char *str_I; … … 325 360 unsigned long ntransmitted, nreceived, nrepeats; 326 361 uint16_t myid; 362 uint8_t pattern; 327 363 unsigned tmin, tmax; /* in us */ 328 364 unsigned long long tsum; /* in us, sum of all times */ … … 342 378 #endif 343 379 } pingaddr; 344 char rcvd_tbl[MAX_DUP_CHK / 8];380 unsigned char rcvd_tbl[MAX_DUP_CHK / 8]; 345 381 } FIX_ALIASING; 346 #define G (*(struct globals*)&bb_common_bufsiz1) 347 #define pingsock (G.pingsock ) 382 #define G (*(struct globals*)bb_common_bufsiz1) 348 383 #define if_index (G.if_index ) 349 384 #define source_lsa (G.source_lsa ) 350 385 #define str_I (G.str_I ) 351 386 #define datalen (G.datalen ) 352 #define ntransmitted (G.ntransmitted)353 #define nreceived (G.nreceived )354 #define nrepeats (G.nrepeats )355 387 #define pingcount (G.pingcount ) 356 388 #define opt_ttl (G.opt_ttl ) … … 366 398 #define pingaddr (G.pingaddr ) 367 399 #define rcvd_tbl (G.rcvd_tbl ) 368 void BUG_ping_globals_too_big(void);369 400 #define INIT_G() do { \ 370 if (sizeof(G) > COMMON_BUFSIZE) \ 371 BUG_ping_globals_too_big(); \ 372 pingsock = -1; \ 401 setup_common_bufsiz(); \ 402 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ 373 403 datalen = DEFDATALEN; \ 374 404 timeout = MAXWAIT; \ … … 377 407 378 408 379 #define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */ 380 #define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */ 381 #define SET(bit) (A(bit) |= B(bit)) 382 #define CLR(bit) (A(bit) &= (~B(bit))) 383 #define TST(bit) (A(bit) & B(bit)) 384 385 /**************************************************************************/ 409 #define BYTE(bit) rcvd_tbl[(bit)>>3] 410 #define MASK(bit) (1 << ((bit) & 7)) 411 #define SET(bit) (BYTE(bit) |= MASK(bit)) 412 #define CLR(bit) (BYTE(bit) &= (~MASK(bit))) 413 #define TST(bit) (BYTE(bit) & MASK(bit)) 386 414 387 415 static void print_stats_and_exit(int junk) NORETURN; 388 416 static void print_stats_and_exit(int junk UNUSED_PARAM) 389 417 { 418 unsigned long ul; 419 unsigned long nrecv; 420 390 421 signal(SIGINT, SIG_IGN); 391 422 392 printf("\n--- %s ping statistics ---\n", hostname); 393 printf("%lu packets transmitted, ", ntransmitted); 394 printf("%lu packets received, ", nreceived); 395 if (nrepeats) 396 printf("%lu duplicates, ", nrepeats); 397 if (ntransmitted) 398 ntransmitted = (ntransmitted - nreceived) * 100 / ntransmitted; 399 printf("%lu%% packet loss\n", ntransmitted); 423 nrecv = G.nreceived; 424 printf("\n--- %s ping statistics ---\n" 425 "%lu packets transmitted, " 426 "%lu packets received, ", 427 hostname, G.ntransmitted, nrecv 428 ); 429 if (G.nrepeats) 430 printf("%lu duplicates, ", G.nrepeats); 431 ul = G.ntransmitted; 432 if (ul != 0) 433 ul = (ul - nrecv) * 100 / ul; 434 printf("%lu%% packet loss\n", ul); 400 435 if (tmin != UINT_MAX) { 401 unsigned tavg = tsum / (nrec eived +nrepeats);436 unsigned tavg = tsum / (nrecv + G.nrepeats); 402 437 printf("round-trip min/avg/max = %u.%03u/%u.%03u/%u.%03u ms\n", 403 438 tmin / 1000, tmin % 1000, … … 406 441 } 407 442 /* if condition is true, exit with 1 -- 'failure' */ 408 exit(nrec eived == 0 || (deadline && nreceived< pingcount));443 exit(nrecv == 0 || (deadline && nrecv < pingcount)); 409 444 } 410 445 … … 413 448 int sz; 414 449 415 CLR((uint16_t) ntransmitted % MAX_DUP_CHK);416 ntransmitted++;450 CLR((uint16_t)G.ntransmitted % MAX_DUP_CHK); 451 G.ntransmitted++; 417 452 418 453 size_pkt += datalen; … … 424 459 bb_error_msg_and_die(bb_msg_write_error); 425 460 426 if (pingcount == 0 || deadline || ntransmitted < pingcount) {461 if (pingcount == 0 || deadline || G.ntransmitted < pingcount) { 427 462 /* Didn't send all pings yet - schedule next in 1s */ 428 463 signal(SIGALRM, sp); … … 440 475 unsigned expire = timeout; 441 476 442 if ( nreceived) {477 if (G.nreceived) { 443 478 /* approx. 2*tmax, in seconds (2 RTT) */ 444 479 expire = tmax / (512*1024); … … 455 490 struct icmp *pkt = G.snd_packet; 456 491 457 //memset(pkt, 0, datalen + ICMP_MINLEN + 4); - G.snd_packet was xzalloced492 memset(pkt, G.pattern, datalen + ICMP_MINLEN + 4); 458 493 pkt->icmp_type = ICMP_ECHO; 459 494 /*pkt->icmp_code = 0;*/ 460 495 pkt->icmp_cksum = 0; /* cksum is calculated with this field set to 0 */ 461 pkt->icmp_seq = htons( ntransmitted); /* don't ++ here, it can be a macro */496 pkt->icmp_seq = htons(G.ntransmitted); /* don't ++ here, it can be a macro */ 462 497 pkt->icmp_id = myid; 463 498 … … 478 513 struct icmp6_hdr *pkt = G.snd_packet; 479 514 480 //memset(pkt, 0, datalen + sizeof(struct icmp6_hdr) + 4);515 memset(pkt, G.pattern, datalen + sizeof(struct icmp6_hdr) + 4); 481 516 pkt->icmp6_type = ICMP6_ECHO_REQUEST; 482 517 /*pkt->icmp6_code = 0;*/ 483 518 /*pkt->icmp6_cksum = 0;*/ 484 pkt->icmp6_seq = htons( ntransmitted); /* don't ++ here, it can be a macro */519 pkt->icmp6_seq = htons(G.ntransmitted); /* don't ++ here, it can be a macro */ 485 520 pkt->icmp6_id = myid; 486 521 487 522 /*if (datalen >= 4)*/ 488 *( uint32_t*)(&pkt->icmp6_data8[4]) = monotonic_us();523 *(bb__aliased_uint32_t*)(&pkt->icmp6_data8[4]) = monotonic_us(); 489 524 490 525 //TODO? pkt->icmp_cksum = inet_cksum(...); … … 546 581 uint16_t recv_seq, int ttl) 547 582 { 583 unsigned char *b, m; 548 584 const char *dupmsg = " (DUP!)"; 549 585 unsigned triptime = triptime; /* for gcc */ 550 551 ++nreceived;552 586 553 587 if (tp) { … … 562 596 } 563 597 564 if (TST(recv_seq % MAX_DUP_CHK)) { 565 ++nrepeats; 566 --nreceived; 598 b = &BYTE(recv_seq % MAX_DUP_CHK); 599 m = MASK(recv_seq % MAX_DUP_CHK); 600 /*if TST(recv_seq % MAX_DUP_CHK):*/ 601 if (*b & m) { 602 ++G.nrepeats; 567 603 } else { 568 SET(recv_seq % MAX_DUP_CHK); 604 /*SET(recv_seq % MAX_DUP_CHK):*/ 605 *b |= m; 606 ++G.nreceived; 569 607 dupmsg += 7; 570 608 } … … 649 687 int sockopt; 650 688 651 pingsock = create_icmp_socket();652 689 pingaddr.sin = lsa->u.sin; 653 690 if (source_lsa) { … … 657 694 xbind(pingsock, &source_lsa->u.sa, source_lsa->len); 658 695 } 659 if (str_I)660 setsockopt_bindtodevice(pingsock, str_I);661 696 662 697 /* enable broadcast pings */ … … 666 701 * broadcast ping etc) */ 667 702 sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */ 668 setsockopt (pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt));703 setsockopt_SOL_SOCKET_int(pingsock, SO_RCVBUF, sockopt); 669 704 670 705 if (opt_ttl != 0) { 671 setsockopt (pingsock, IPPROTO_IP, IP_TTL, &opt_ttl, sizeof(opt_ttl));706 setsockopt_int(pingsock, IPPROTO_IP, IP_TTL, opt_ttl); 672 707 /* above doesnt affect packets sent to bcast IP, so... */ 673 setsockopt (pingsock, IPPROTO_IP, IP_MULTICAST_TTL, &opt_ttl, sizeof(opt_ttl));708 setsockopt_int(pingsock, IPPROTO_IP, IP_MULTICAST_TTL, opt_ttl); 674 709 } 675 710 … … 693 728 } 694 729 unpack4(G.rcv_packet, c, &from); 695 if (pingcount && nreceived >= pingcount)730 if (pingcount && G.nreceived >= pingcount) 696 731 break; 697 732 } 698 733 } 699 734 #if ENABLE_PING6 700 extern int BUG_bad_offsetof_icmp6_cksum(void);701 735 static void ping6(len_and_sockaddr *lsa) 702 736 { … … 707 741 char control_buf[CMSG_SPACE(36)]; 708 742 709 pingsock = create_icmp6_socket();710 743 pingaddr.sin6 = lsa->u.sin6; 711 /* untested whether "-I addr" really works for IPv6: */712 744 if (source_lsa) 713 745 xbind(pingsock, &source_lsa->u.sa, source_lsa->len); 714 if (str_I)715 setsockopt_bindtodevice(pingsock, str_I);716 746 717 747 #ifdef ICMP6_FILTER … … 726 756 if (setsockopt(pingsock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, 727 757 sizeof(filt)) < 0) 728 bb_error_msg_and_die("setsockopt( ICMP6_FILTER)");758 bb_error_msg_and_die("setsockopt(%s)", "ICMP6_FILTER"); 729 759 } 730 760 #endif /*ICMP6_FILTER*/ … … 736 766 * broadcast ping etc) */ 737 767 sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */ 738 setsockopt (pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt));768 setsockopt_SOL_SOCKET_int(pingsock, SO_RCVBUF, sockopt); 739 769 740 770 sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); 741 if (offsetof(struct icmp6_hdr, icmp6_cksum) != 2) 742 BUG_bad_offsetof_icmp6_cksum(); 743 setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, &sockopt, sizeof(sockopt)); 771 BUILD_BUG_ON(offsetof(struct icmp6_hdr, icmp6_cksum) != 2); 772 setsockopt_int(pingsock, SOL_RAW, IPV6_CHECKSUM, sockopt); 744 773 745 774 /* request ttl info to be returned in ancillary data */ 746 setsockopt (pingsock, SOL_IPV6, IPV6_HOPLIMIT, &const_int_1, sizeof(const_int_1));775 setsockopt_1(pingsock, SOL_IPV6, IPV6_HOPLIMIT); 747 776 748 777 if (if_index) … … 785 814 } 786 815 unpack6(G.rcv_packet, c, &from, hoplimit); 787 if (pingcount && nreceived >= pingcount)816 if (pingcount && G.nreceived >= pingcount) 788 817 break; 789 818 } … … 799 828 } 800 829 printf(": %d data bytes\n", datalen); 830 831 create_icmp_socket(lsa); 832 /* untested whether "-I addr" really works for IPv6: */ 833 if (str_I) 834 setsockopt_bindtodevice(pingsock, str_I); 801 835 802 836 G.sizeof_rcv_packet = datalen + MAXIPLEN + MAXICMPLEN; … … 819 853 { 820 854 len_and_sockaddr *lsa; 821 char *str_s ;855 char *str_s, *str_p; 822 856 823 857 INIT_G(); … … 825 859 /* exactly one argument needed; -v and -q don't mix; -c NUM, -t NUM, -w NUM, -W NUM */ 826 860 opt_complementary = "=1:q--v:v--q:c+:t+:w+:W+"; 827 opt |= getopt32(argv, OPT_STRING, &pingcount, &str_s, &opt_ttl, &deadline, &timeout, &str_I );861 opt |= getopt32(argv, OPT_STRING, &pingcount, &str_s, &opt_ttl, &deadline, &timeout, &str_I, &str_p); 828 862 if (opt & OPT_s) 829 863 datalen = xatou16(str_s); // -s … … 836 870 } 837 871 } 872 if (opt & OPT_p) 873 G.pattern = xstrtou_range(str_p, 16, 0, 255); 874 838 875 myid = (uint16_t) getpid(); 839 876 hostname = argv[optind]; -
branches/3.3/mindi-busybox/networking/pscan.c
r3232 r3621 158 158 if (ENABLE_FEATURE_CLEAN_UP) free(lsap); 159 159 160 printf("% d closed, %d open, %dtimed out (or blocked) ports\n",160 printf("%u closed, %u open, %u timed out (or blocked) ports\n", 161 161 closed_ports, 162 162 open_ports, -
branches/3.3/mindi-busybox/networking/route.c
r3232 r3621 56 56 #define RTF_IRTT 0x0100 /* Initial round trip time */ 57 57 #define RTF_REJECT 0x0200 /* Reject route */ 58 #define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */ 58 59 #endif 59 60 … … 129 130 ; 130 131 131 static const int flags_ipvx[] = { /* MUST match tbl_ipvx[] values above. */132 static const uint16_t flags_ipvx[] = { /* MUST match tbl_ipvx[] values above. */ 132 133 #ifdef RTF_REJECT 133 134 RTF_REJECT, … … 284 285 rt->rt_flags |= RTF_IRTT; 285 286 rt->rt_irtt = xatoul(args_m1); 286 rt->rt_irtt *= ( sysconf(_SC_CLK_TCK) / 100); /* FIXME */287 rt->rt_irtt *= (bb_clk_tck() / 100); /* FIXME */ 287 288 #if 0 /* FIXME: do we need to check anything of this? */ 288 289 if (rt->rt_irtt < 1 || rt->rt_irtt > (120 * HZ)) { … … 450 451 #endif 451 452 452 static const unsigned flagvals[] = { /* Must agree with flagchars[]. */ 453 static const 454 IF_NOT_FEATURE_IPV6(uint16_t) 455 IF_FEATURE_IPV6(unsigned) 456 flagvals[] = { /* Must agree with flagchars[]. */ 457 RTF_UP, 453 458 RTF_GATEWAY, 454 459 RTF_HOST, … … 459 464 RTF_DEFAULT, 460 465 RTF_ADDRCONF, 461 RTF_CACHE 466 RTF_CACHE, 467 RTF_REJECT, 468 RTF_NONEXTHOP, /* this one doesn't fit into 16 bits */ 462 469 #endif 463 470 }; 464 465 #define IPV4_MASK (RTF_GATEWAY|RTF_HOST|RTF_REINSTATE|RTF_DYNAMIC|RTF_MODIFIED)466 #define IPV6_MASK (RTF_GATEWAY|RTF_HOST|RTF_DEFAULT|RTF_ADDRCONF|RTF_CACHE)467 468 471 /* Must agree with flagvals[]. */ 469 472 static const char flagchars[] ALIGN1 = 470 " GHRDM"473 "UGHRDM" 471 474 #if ENABLE_FEATURE_IPV6 472 "DAC "475 "DAC!n" 473 476 #endif 474 477 ; 478 #define IPV4_MASK (RTF_UP|RTF_GATEWAY|RTF_HOST|RTF_REINSTATE|RTF_DYNAMIC|RTF_MODIFIED) 479 #define IPV6_MASK (RTF_UP|RTF_GATEWAY|RTF_HOST|RTF_DEFAULT|RTF_ADDRCONF|RTF_CACHE|RTF_REJECT|RTF_NONEXTHOP) 475 480 476 481 static void set_flags(char *flagstr, int flags) 477 482 { 478 483 int i; 479 480 *flagstr++ = 'U';481 484 482 485 for (i = 0; (*flagstr = flagchars[i]) != 0; i++) { … … 492 495 char devname[64], flags[16], *sdest, *sgw; 493 496 unsigned long d, g, m; 497 int r; 494 498 int flgs, ref, use, metric, mtu, win, ir; 495 499 struct sockaddr_in s_addr; … … 502 506 netstatfmt ? " MSS Window irtt" : "Metric Ref Use"); 503 507 504 if (fscanf(fp, "%*[^\n]\n") < 0) { /* Skip the first line. */ 505 goto ERROR; /* Empty or missing line, or read error. */ 508 /* Skip the first line. */ 509 r = fscanf(fp, "%*[^\n]\n"); 510 if (r < 0) { 511 /* Empty line, read error, or EOF. Yes, if routing table 512 * is completely empty, /proc/net/route has no header. 513 */ 514 goto ERROR; 506 515 } 507 516 while (1) { 508 int r;509 517 r = fscanf(fp, "%63s%lx%lx%X%d%d%d%lx%d%d%d\n", 510 518 devname, &d, &g, &flgs, &ref, &use, &metric, &m, 511 519 &mtu, &win, &ir); 512 520 if (r != 11) { 521 ERROR: 513 522 if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */ 514 523 break; 515 524 } 516 ERROR: 517 bb_error_msg_and_die("fscanf"); 525 bb_perror_msg_and_die(bb_msg_read_error); 518 526 } 519 527 … … 575 583 r = fscanf(fp, "%32s%x%*s%x%32s%x%x%x%x%s\n", 576 584 addr6x+14, &prefix_len, &slen, addr6x+40+7, 577 &metric, & use, &refcnt, &iflags, iface);585 &metric, &refcnt, &use, &iflags, iface); 578 586 if (r != 9) { 579 587 if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */ … … 581 589 } 582 590 ERROR: 583 bb_ error_msg_and_die("fscanf");591 bb_perror_msg_and_die(bb_msg_read_error); 584 592 } 585 593 … … 607 615 } 608 616 609 if (!(iflags & RTF_UP)) { /* Skip interfaces that are down. */610 continue;611 }612 613 617 set_flags(flags, (iflags & IPV6_MASK)); 614 618 -
branches/3.3/mindi-busybox/networking/slattach.c
r3232 r3621 28 28 29 29 #include "libbb.h" 30 #include "libiproute/utils.h" /* invarg() */ 30 #include "common_bufsiz.h" 31 #include "libiproute/utils.h" /* invarg_1_to_2() */ 31 32 32 33 struct globals { … … 35 36 struct termios saved_state; 36 37 } FIX_ALIASING; 37 #define G (*(struct globals*) &bb_common_bufsiz1)38 #define G (*(struct globals*)bb_common_bufsiz1) 38 39 #define handle (G.handle ) 39 40 #define saved_disc (G.saved_disc ) 40 41 #define saved_state (G.saved_state ) 41 #define INIT_G() do { } while (0)42 #define INIT_G() do { setup_common_bufsiz(); } while (0) 42 43 43 44 … … 176 177 177 178 if (encap < 0) 178 invarg (proto, "protocol");179 invarg_1_to_2(proto, "protocol"); 179 180 if (encap > 3) 180 181 encap = 8; … … 184 185 baud_code = tty_value_to_baud(xatoi(baud_str)); 185 186 if (baud_code < 0) 186 invarg (baud_str, "baud rate");187 invarg_1_to_2(baud_str, "baud rate"); 187 188 } 188 189 -
branches/3.3/mindi-busybox/networking/tc.c
r3232 r3621 30 30 31 31 #include "libbb.h" 32 #include "common_bufsiz.h" 32 33 33 34 #include "libiproute/utils.h" … … 64 65 uint32_t filter_proto; 65 66 } FIX_ALIASING; 66 #define G (*(struct globals*)&bb_common_bufsiz1) 67 struct BUG_G_too_big { 68 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; 69 }; 67 #define G (*(struct globals*)bb_common_bufsiz1) 70 68 #define filter_ifindex (G.filter_ifindex) 71 69 #define filter_qdisc (G.filter_qdisc) … … 73 71 #define filter_prio (G.filter_prio) 74 72 #define filter_proto (G.filter_proto) 75 #define INIT_G() do { } while (0) 73 #define INIT_G() do { \ 74 setup_common_bufsiz(); \ 75 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ 76 } while (0) 76 77 77 78 /* Allocates a buffer containing the name of a class id. … … 152 153 153 154 if (use_iec) { 154 if (tmp >= 1000 .0*1024.0*1024.0)155 snprintf(buf, len, "%.0fMibit", tmp/ 1024.0*1024.0);156 else if (tmp >= 1000 .0*1024)155 if (tmp >= 1000*1024*1024) 156 snprintf(buf, len, "%.0fMibit", tmp/(1024*1024)); 157 else if (tmp >= 1000*1024) 157 158 snprintf(buf, len, "%.0fKibit", tmp/1024); 158 159 else 159 160 snprintf(buf, len, "%.0fbit", tmp); 160 161 } else { 161 if (tmp >= 1000 .0*1000000.0)162 snprintf(buf, len, "%.0fMbit", tmp/1000000 .0);163 else if (tmp >= 1000 .0 * 1000.0)164 snprintf(buf, len, "%.0fKbit", tmp/1000 .0);162 if (tmp >= 1000*1000000) 163 snprintf(buf, len, "%.0fMbit", tmp/1000000); 164 else if (tmp >= 1000*1000) 165 snprintf(buf, len, "%.0fKbit", tmp/1000); 165 166 else 166 167 snprintf(buf, len, "%.0fbit", tmp); … … 419 420 struct nlmsghdr *hdr, void *arg UNUSED_PARAM) 420 421 { 421 struct tcmsg *msg = NLMSG_DATA(hdr);422 int len = hdr->nlmsg_len;423 struct rtattr * tb[TCA_MAX+1];424 422 return 0; 425 423 } … … 464 462 obj = index_in_substrings(objects, *argv++); 465 463 466 if (obj < OBJ_qdisc)464 if (obj < 0) 467 465 bb_show_usage(); 468 466 if (!*argv) … … 471 469 cmd = index_in_substrings(commands, *argv); 472 470 if (cmd < 0) 473 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);471 invarg_1_to_2(*argv, argv[-1]); 474 472 argv++; 475 473 } … … 494 492 /* We don't care about duparg2("qdisc handle",*argv) for now */ 495 493 if (get_qdisc_handle(&filter_qdisc, *argv)) 496 invarg (*argv, "qdisc");494 invarg_1_to_2(*argv, "qdisc"); 497 495 } else 498 496 if (obj != OBJ_qdisc … … 504 502 /* nothing */ 505 503 } else { 506 invarg (*argv, "command");504 invarg_1_to_2(*argv, "command"); 507 505 } 508 506 NEXT_ARG(); … … 518 516 duparg(*argv, "parent"); 519 517 if (get_tc_classid(&handle, *argv)) 520 invarg (*argv, "parent");518 invarg_1_to_2(*argv, "parent"); 521 519 msg.tcm_parent = handle; 522 520 if (obj == OBJ_filter) … … 543 541 duparg(*argv, "protocol"); 544 542 if (ll_proto_a2n(&tmp, *argv)) 545 invarg (*argv, "protocol");543 invarg_1_to_2(*argv, "protocol"); 546 544 filter_proto = tmp; 547 545 } -
branches/3.3/mindi-busybox/networking/tcpudp.c
r3232 r3621 68 68 69 69 #include "libbb.h" 70 #include "common_bufsiz.h" 70 71 71 72 /* Wants <limits.h> etc, thus included after libbb.h: */ … … 92 93 char *env_var[1]; /* actually bigger */ 93 94 } FIX_ALIASING; 94 #define G (*(struct globals*) &bb_common_bufsiz1)95 #define G (*(struct globals*)bb_common_bufsiz1) 95 96 #define verbose (G.verbose ) 96 97 #define max_per_host (G.max_per_host) … … 101 102 #define env_var (G.env_var ) 102 103 #define INIT_G() do { \ 104 setup_common_bufsiz(); \ 103 105 cmax = 30; \ 104 106 env_cur = &env_var[0]; \ -
branches/3.3/mindi-busybox/networking/telnet.c
r3232 r3621 40 40 #include <netinet/in.h> 41 41 #include "libbb.h" 42 #include "common_bufsiz.h" 42 43 43 44 #ifdef __BIONIC__ … … 109 110 struct termios termios_raw; 110 111 } FIX_ALIASING; 111 #define G (*(struct globals*) &bb_common_bufsiz1)112 #define G (*(struct globals*)bb_common_bufsiz1) 112 113 #define INIT_G() do { \ 113 struct G_sizecheck { \ 114 char G_sizecheck[sizeof(G) > COMMON_BUFSIZE ? -1 : 1]; \ 115 }; \ 114 setup_common_bufsiz(); \ 115 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ 116 116 } while (0) 117 117 … … 126 126 static void iac_flush(void) 127 127 { 128 write(netfd, G.iacbuf, G.iaclen);128 full_write(netfd, G.iacbuf, G.iaclen); 129 129 G.iaclen = 0; 130 130 } 131 132 #define write_str(fd, str) write(fd, str, sizeof(str) - 1)133 131 134 132 static void doexit(int ev) NORETURN; … … 146 144 rawmode(); 147 145 148 write_str(1,"\r\nConsole escape. Commands are:\r\n\n"146 full_write1_str("\r\nConsole escape. Commands are:\r\n\n" 149 147 " l go to line mode\r\n" 150 148 " c go to character mode\r\n" … … 177 175 } 178 176 179 write_str(1,"continuing...\r\n");177 full_write1_str("continuing...\r\n"); 180 178 181 179 if (bb_got_signal) … … 384 382 put_iac(c); 385 383 386 put_iac((x >> 8) & 0xff); 387 put_iac(x & 0xff); 388 put_iac((y >> 8) & 0xff); 389 put_iac(y & 0xff); 384 /* "... & 0xff" implicitly done below */ 385 put_iac(x >> 8); 386 put_iac(x); 387 put_iac(y >> 8); 388 put_iac(y); 390 389 391 390 put_iac(IAC); … … 625 624 xmove_fd(create_and_connect_stream_or_die(host, port), netfd); 626 625 627 setsockopt (netfd, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));626 setsockopt_keepalive(netfd); 628 627 629 628 signal(SIGINT, record_signo); -
branches/3.3/mindi-busybox/networking/telnetd.c
r3232 r3621 45 45 46 46 #include "libbb.h" 47 #include "common_bufsiz.h" 47 48 #include <syslog.h> 48 49 … … 83 84 int maxfd; 84 85 } FIX_ALIASING; 85 #define G (*(struct globals*) &bb_common_bufsiz1)86 #define G (*(struct globals*)bb_common_bufsiz1) 86 87 #define INIT_G() do { \ 88 setup_common_bufsiz(); \ 87 89 G.loginpath = "/bin/login"; \ 88 90 G.issuefile = "/etc/issue.net"; \ … … 266 268 267 269 /* SO_KEEPALIVE by popular demand */ 268 setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));270 setsockopt_keepalive(sock); 269 271 #if ENABLE_FEATURE_TELNETD_STANDALONE 270 272 ts->sockfd_read = sock; … … 463 465 if (ts->shell_pid == pid) { 464 466 ts->shell_pid = -1; 465 // man utmp: 466 // When init(8) finds that a process has exited, it locates its utmp entry 467 // by ut_pid, sets ut_type to DEAD_PROCESS, and clears ut_user, ut_host 468 // and ut_time with null bytes. 469 // [same applies to other processes which maintain utmp entries, like telnetd] 470 // 471 // We do not bother actually clearing fields: 472 // it might be interesting to know who was logged in and from where 473 update_utmp(pid, DEAD_PROCESS, /*tty_name:*/ NULL, /*username:*/ NULL, /*hostname:*/ NULL); 467 update_utmp_DEAD_PROCESS(pid); 474 468 break; 475 469 } … … 740 734 kill_session: 741 735 if (ts->shell_pid > 0) 742 update_utmp (ts->shell_pid, DEAD_PROCESS, /*tty_name:*/ NULL, /*username:*/ NULL, /*hostname:*/ NULL);736 update_utmp_DEAD_PROCESS(ts->shell_pid); 743 737 free_session(ts); 744 738 ts = next; -
branches/3.3/mindi-busybox/networking/telnetd.ctrlSQ.patch
r2725 r3621 95 95 +#ifdef TIOCPKT 96 96 + int control; 97 + static const char lflow_on[] =97 + static const char lflow_on[] ALIGN1 = 98 98 + {IAC, SB, TELOPT_LFLOW, LFLOW_ON, IAC, SE}; 99 + static const char lflow_off[] =99 + static const char lflow_off[] ALIGN1 = 100 100 + {IAC, SB, TELOPT_LFLOW, LFLOW_OFF, IAC, SE}; 101 101 +# define RESERVED sizeof(lflow_on) -
branches/3.3/mindi-busybox/networking/tftp.c
r3232 r3621 52 52 53 53 #include "libbb.h" 54 #include "common_bufsiz.h" 54 55 #include <syslog.h> 55 56 … … 118 119 uint8_t error_pkt[4 + 32]; 119 120 struct passwd *pw; 120 /* used in tftpd_main(), a bit big for stack: */ 121 char block_buf[TFTP_BLKSIZE_DEFAULT]; 121 /* Used in tftpd_main() for initial packet */ 122 /* Some HP PA-RISC firmware always sends fixed 516-byte requests */ 123 char block_buf[516]; 124 char block_buf_tail[1]; 122 125 #if ENABLE_FEATURE_TFTP_PROGRESS_BAR 123 126 off_t pos; … … 127 130 #endif 128 131 } FIX_ALIASING; 129 #define G (*(struct globals*) &bb_common_bufsiz1)130 struct BUG_G_too_big { 131 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];132 }; 133 #define INIT_G() do {} while (0)132 #define G (*(struct globals*)bb_common_bufsiz1) 133 #define INIT_G() do { \ 134 setup_common_bufsiz(); \ 135 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ 136 } while (0) 134 137 135 138 #define G_error_pkt_reason (G.error_pkt[3]) … … 347 350 block_nr = 0; 348 351 } 349 350 352 } else { /* tftp */ 351 353 /* Open file (must be after changing user) */ … … 758 760 len_and_sockaddr *our_lsa; 759 761 len_and_sockaddr *peer_lsa; 760 char *local_file, *mode, *user_opt; 762 char *mode, *user_opt; 763 char *local_file = local_file; 761 764 const char *error_msg; 762 765 int opt, result, opcode; … … 794 797 } 795 798 796 result = recv_from_to(STDIN_FILENO, G.block_buf, sizeof(G.block_buf), 799 result = recv_from_to(STDIN_FILENO, 800 G.block_buf, sizeof(G.block_buf) + 1, 801 /* ^^^ sizeof+1 to reliably detect oversized input */ 797 802 0 /* flags */, 798 803 &peer_lsa->u.sa, &our_lsa->u.sa, our_lsa->len); … … 800 805 error_msg = "malformed packet"; 801 806 opcode = ntohs(*(uint16_t*)G.block_buf); 802 if (result < 4 || result > =sizeof(G.block_buf)803 || G.block_buf[result-1] != '\0'807 if (result < 4 || result > sizeof(G.block_buf) 808 /*|| G.block_buf[result-1] != '\0' - bug compatibility, see below */ 804 809 || (IF_FEATURE_TFTP_PUT(opcode != TFTP_RRQ) /* not download */ 805 810 IF_GETPUT(&&) … … 809 814 goto err; 810 815 } 816 /* Some HP PA-RISC firmware always sends fixed 516-byte requests, 817 * with trailing garbage. 818 * Support that by not requiring NUL to be the last byte (see above). 819 * To make strXYZ() ops safe, force NUL termination: 820 */ 821 G.block_buf_tail[0] = '\0'; 822 811 823 local_file = G.block_buf + 2; 812 824 if (local_file[0] == '.' || strstr(local_file, "/.")) { -
branches/3.3/mindi-busybox/networking/traceroute.c
r3232 r3621 212 212 213 213 //usage:#define traceroute_trivial_usage 214 //usage: "[-"IF_TRACEROUTE6("46")"FIldnrv] [-f 1ST_TTL] [-m MAXTTL] [-p PORT] [-q PROBES]\n" 215 //usage: " [-s SRC_IP] [-t TOS] [-w WAIT_SEC] [-g GATEWAY] [-i IFACE]\n" 214 //usage: "[-"IF_TRACEROUTE6("46")"FIlnrv] [-f 1ST_TTL] [-m MAXTTL] [-q PROBES] [-p PORT]\n" 215 //usage: " [-t TOS] [-w WAIT_SEC]" 216 //usage: IF_FEATURE_TRACEROUTE_SOURCE_ROUTE(" [-g GATEWAY]")" [-s SRC_IP] [-i IFACE]\n" 216 217 //usage: " [-z PAUSE_MSEC] HOST [BYTES]" 217 218 //usage:#define traceroute_full_usage "\n\n" … … 220 221 //usage: "\n -4,-6 Force IP or IPv6 name resolution" 221 222 //usage: ) 222 //usage: "\n -F Set the don't fragment bit" 223 //usage: "\n -F Set don't fragment bit" 224 //usage: IF_FEATURE_TRACEROUTE_USE_ICMP( 223 225 //usage: "\n -I Use ICMP ECHO instead of UDP datagrams" 224 //usage: "\n -l Display the TTL value of the returned packet" 225 //usage: "\n -d Set SO_DEBUG options to socket" 226 //usage: ) 227 //usage: "\n -l Display TTL value of the returned packet" 228 //Currently disabled (TRACEROUTE_SO_DEBUG==0) 229 ////usage: "\n -d Set SO_DEBUG options to socket" 226 230 //usage: "\n -n Print numeric addresses" 227 231 //usage: "\n -r Bypass routing tables, send directly to HOST" 232 //usage: IF_FEATURE_TRACEROUTE_VERBOSE( 228 233 //usage: "\n -v Verbose" 229 //usage: "\n -m Max time-to-live (max number of hops)" 230 //usage: "\n -p Base UDP port number used in probes" 234 //usage: ) 235 //usage: "\n -f N First number of hops (default 1)" 236 //usage: "\n -m N Max number of hops" 237 //usage: "\n -q N Number of probes per hop (default 3)" 238 //usage: "\n -p N Base UDP port number used in probes" 231 239 //usage: "\n (default 33434)" 232 //usage: "\n - q Number of probes per TTL (default 3)"233 //usage: "\n - s IP address to use as the source address"234 //usage: "\n -t Type-of-service in probe packets (default 0)"235 //usage: "\n -w Time in secondsto wait for a response (default 3)"236 //usage: "\n -g Loose source route gateway (8 max)"240 //usage: "\n -s IP Source address" 241 //usage: "\n -i IFACE Source interface" 242 //usage: "\n -t N Type-of-service in probe packets (default 0)" 243 //usage: "\n -w SEC Time to wait for a response (default 3)" 244 //usage: "\n -g IP Loose source route gateway (8 max)" 237 245 //usage: 238 246 //usage:#define traceroute6_trivial_usage 239 //usage: "[- dnrv] [-m MAXTTL] [-p PORT] [-q PROBES]\n"240 //usage: " [- s SRC_IP] [-t TOS] [-w WAIT_SEC] [-i IFACE]\n"247 //usage: "[-nrv] [-m MAXTTL] [-q PROBES] [-p PORT]\n" 248 //usage: " [-t TOS] [-w WAIT_SEC] [-s SRC_IP] [-i IFACE]\n" 241 249 //usage: " HOST [BYTES]" 242 250 //usage:#define traceroute6_full_usage "\n\n" 243 251 //usage: "Trace the route to HOST\n" 244 //usage: "\n -d Set SO_DEBUG options to socket" 252 //Currently disabled (TRACEROUTE_SO_DEBUG==0) 253 ////usage: "\n -d Set SO_DEBUG options to socket" 245 254 //usage: "\n -n Print numeric addresses" 246 255 //usage: "\n -r Bypass routing tables, send directly to HOST" 256 //usage: IF_FEATURE_TRACEROUTE_VERBOSE( 247 257 //usage: "\n -v Verbose" 248 //usage: "\n -m Max time-to-live (max number of hops)" 249 //usage: "\n -p Base UDP port number used in probes" 250 //usage: "\n (default is 33434)" 251 //usage: "\n -q Number of probes per TTL (default 3)" 252 //usage: "\n -s IP address to use as the source address" 253 //usage: "\n -t Type-of-service in probe packets (default 0)" 254 //usage: "\n -w Time in seconds to wait for a response (default 3)" 258 //usage: ) 259 //usage: "\n -m N Max number of hops" 260 //usage: "\n -q N Number of probes per hop (default 3)" 261 //usage: "\n -p N Base UDP port number used in probes" 262 //usage: "\n (default 33434)" 263 //usage: "\n -s IP Source address" 264 //usage: "\n -i IFACE Source interface" 265 //usage: "\n -t N Type-of-service in probe packets (default 0)" 266 //usage: "\n -w SEC Time wait for a response (default 3)" 255 267 256 268 #define TRACEROUTE_SO_DEBUG 0 257 258 /* TODO: undefs were uncommented - ??! we have config system for that! */259 /* probably ok to remove altogether */260 //#undef CONFIG_FEATURE_TRACEROUTE_VERBOSE261 //#define CONFIG_FEATURE_TRACEROUTE_VERBOSE262 //#undef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE263 //#define CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE264 //#undef CONFIG_FEATURE_TRACEROUTE_USE_ICMP265 //#define CONFIG_FEATURE_TRACEROUTE_USE_ICMP266 267 269 268 270 #include <net/if.h> … … 388 390 389 391 390 /* libbb candidate? tftp uses this idiom too */391 static len_and_sockaddr* dup_sockaddr(const len_and_sockaddr *lsa)392 {393 len_and_sockaddr *new_lsa = xzalloc(LSA_LEN_SIZE + lsa->len);394 memcpy(new_lsa, lsa, LSA_LEN_SIZE + lsa->len);395 return new_lsa;396 }397 398 399 392 static int 400 393 wait_for_reply(len_and_sockaddr *from_lsa, struct sockaddr *to, unsigned *timestamp_us, int *left_ms) … … 481 474 #if ENABLE_TRACEROUTE6 482 475 if (dest_lsa->u.sa.sa_family == AF_INET6) { 483 res = setsockopt (sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));484 if (res <0)485 bb_perror_msg_and_die("setsockopt UNICAST_HOPS %d", ttl);476 res = setsockopt_int(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, ttl); 477 if (res != 0) 478 bb_perror_msg_and_die("setsockopt(%s) %d", "UNICAST_HOPS", ttl); 486 479 out = outip; 487 480 len = packlen; … … 490 483 { 491 484 #if defined IP_TTL 492 res = setsockopt (sndsock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));493 if (res <0)494 bb_perror_msg_and_die("setsockopt ttl %d", ttl);485 res = setsockopt_int(sndsock, IPPROTO_IP, IP_TTL, ttl); 486 if (res != 0) 487 bb_perror_msg_and_die("setsockopt(%s) %d", "TTL", ttl); 495 488 #endif 496 489 out = outicmp; … … 505 498 res = xsendto(sndsock, out, len, &dest_lsa->u.sa, dest_lsa->len); 506 499 if (res != len) 507 bb_ info_msg("sent %d octets, ret=%d", len, res);500 bb_error_msg("sent %d octets, ret=%d", len, res); 508 501 } 509 502 … … 792 785 { 793 786 int minpacket; 787 #ifdef IP_TOS 794 788 int tos = 0; 789 #endif 795 790 int max_ttl = 30; 796 791 int nprobes = 3; … … 806 801 char *pausemsecs_str; 807 802 char *first_ttl_str; 803 char *dest_str; 808 804 #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE 809 805 llist_t *source_route_list = NULL; … … 838 834 bb_error_msg("warning: ip checksums disabled"); 839 835 #endif 836 #ifdef IP_TOS 840 837 if (op & OPT_TOS) 841 838 tos = xatou_range(tos_str, 0, 255); 839 #endif 842 840 if (op & OPT_MAX_TTL) 843 841 max_ttl = xatou_range(max_ttl_str, 1, 255); … … 905 903 xmove_fd(xsocket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6), rcvsock); 906 904 # ifdef IPV6_RECVPKTINFO 907 setsockopt(rcvsock, SOL_IPV6, IPV6_RECVPKTINFO, 908 &const_int_1, sizeof(const_int_1)); 909 setsockopt(rcvsock, SOL_IPV6, IPV6_2292PKTINFO, 910 &const_int_1, sizeof(const_int_1)); 905 setsockopt_1(rcvsock, SOL_IPV6, IPV6_RECVPKTINFO); 906 setsockopt_1(rcvsock, SOL_IPV6, IPV6_2292PKTINFO); 911 907 # else 912 setsockopt(rcvsock, SOL_IPV6, IPV6_PKTINFO, 913 &const_int_1, sizeof(const_int_1)); 908 setsockopt_1(rcvsock, SOL_IPV6, IPV6_PKTINFO); 914 909 # endif 915 910 } else … … 921 916 #if TRACEROUTE_SO_DEBUG 922 917 if (op & OPT_DEBUG) 923 setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG, 924 &const_int_1, sizeof(const_int_1)); 918 setsockopt_SOL_SOCKET_1(rcvsock, SO_DEBUG); 925 919 #endif 926 920 if (op & OPT_BYPASS_ROUTE) 927 setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE, 928 &const_int_1, sizeof(const_int_1)); 921 setsockopt_SOL_SOCKET_1(rcvsock, SO_DONTROUTE); 929 922 930 923 #if ENABLE_TRACEROUTE6 931 924 if (af == AF_INET6) { 932 static const int two = 2; 933 if (setsockopt(rcvsock, SOL_RAW, IPV6_CHECKSUM, &two, sizeof(two)) < 0) 934 bb_perror_msg_and_die("setsockopt RAW_CHECKSUM"); 925 if (setsockopt_int(rcvsock, SOL_RAW, IPV6_CHECKSUM, 2) != 0) 926 bb_perror_msg_and_die("setsockopt(%s)", "IPV6_CHECKSUM"); 935 927 xmove_fd(xsocket(af, SOCK_DGRAM, 0), sndsock); 936 928 } else … … 969 961 970 962 #ifdef SO_SNDBUF 971 if (setsockopt (sndsock, SOL_SOCKET, SO_SNDBUF, &packlen, sizeof(packlen)) <0) {972 bb_perror_msg_and_die(" SO_SNDBUF");963 if (setsockopt_SOL_SOCKET_int(sndsock, SO_SNDBUF, packlen) != 0) { 964 bb_perror_msg_and_die("setsockopt(%s)", "SO_SNDBUF"); 973 965 } 974 966 #endif 975 967 #ifdef IP_TOS 976 if ((op & OPT_TOS) && setsockopt (sndsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) <0) {977 bb_perror_msg_and_die("setsockopt tos %d", tos);968 if ((op & OPT_TOS) && setsockopt_int(sndsock, IPPROTO_IP, IP_TOS, tos) != 0) { 969 bb_perror_msg_and_die("setsockopt(%s) %d", "TOS", tos); 978 970 } 979 971 #endif 980 972 #ifdef IP_DONTFRAG 981 973 if (op & OPT_DONT_FRAGMNT) 982 setsockopt(sndsock, IPPROTO_IP, IP_DONTFRAG, 983 &const_int_1, sizeof(const_int_1)); 974 setsockopt_1(sndsock, IPPROTO_IP, IP_DONTFRAG); 984 975 #endif 985 976 #if TRACEROUTE_SO_DEBUG 986 977 if (op & OPT_DEBUG) 987 setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, 988 &const_int_1, sizeof(const_int_1)); 978 setsockopt_SOL_SOCKET_1(sndsock, SO_DEBUG); 989 979 #endif 990 980 if (op & OPT_BYPASS_ROUTE) 991 setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, 992 &const_int_1, sizeof(const_int_1)); 981 setsockopt_SOL_SOCKET_1(sndsock, SO_DONTROUTE); 993 982 994 983 outip = xzalloc(packlen); … … 1060 1049 xsetuid(getuid()); 1061 1050 1062 printf("traceroute to %s (%s)", argv[0], 1063 xmalloc_sockaddr2dotted_noport(&dest_lsa->u.sa)); 1051 dest_str = xmalloc_sockaddr2dotted_noport(&dest_lsa->u.sa); 1052 printf("traceroute to %s (%s)", argv[0], dest_str); 1053 if (ENABLE_FEATURE_CLEAN_UP) { 1054 free(dest_str); 1055 } 1056 1064 1057 if (op & OPT_SOURCE) 1065 1058 printf(" from %s", source); 1066 1059 printf(", %d hops max, %d byte packets\n", max_ttl, packlen); 1067 1060 1068 from_lsa = dup_sockaddr(dest_lsa);1061 from_lsa = xmemdup(dest_lsa, LSA_LEN_SIZE + dest_lsa->len); 1069 1062 lastaddr = xzalloc(dest_lsa->len); 1070 1063 to = xzalloc(dest_lsa->len); … … 1217 1210 } 1218 1211 1212 if (ENABLE_FEATURE_CLEAN_UP) { 1213 free(to); 1214 free(lastaddr); 1215 free(from_lsa); 1216 } 1217 1219 1218 return 0; 1220 1219 } -
branches/3.3/mindi-busybox/networking/tunctl.c
r3232 r3621 83 83 if (opts & OPT_d) { 84 84 IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)0); 85 bb_info_msg("Set '%s' %spersistent", ifr.ifr_name, "non");85 printf("Set '%s' nonpersistent\n", ifr.ifr_name); 86 86 return EXIT_SUCCESS; 87 87 } -
branches/3.3/mindi-busybox/networking/udhcp/Config.src
r3232 r3621 85 85 and restart the discover process. 86 86 87 config FEATURE_UDHCPC_SANITIZEOPT 88 bool "Do not pass malformed host and domain names" 89 default y 90 depends on UDHCPC 91 help 92 If selected, udhcpc will check some options (such as option 12 - 93 hostname) and if they don't look like valid hostnames 94 (for example, if they start with dash or contain spaces), 95 they will be replaced with string "bad" when exporting 96 to the environment. 97 87 98 config FEATURE_UDHCP_PORT 88 99 bool "Enable '-P port' option for udhcpd and udhcpc" -
branches/3.3/mindi-busybox/networking/udhcp/arpping.c
r3232 r3621 40 40 uint32_t from_ip, 41 41 uint8_t *from_mac, 42 const char *interface) 42 const char *interface, 43 unsigned timeo) 43 44 { 44 45 int timeout_ms; … … 48 49 struct sockaddr addr; /* for interface name */ 49 50 struct arpMsg arp; 51 52 if (!timeo) 53 return 1; 50 54 51 55 s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)); … … 84 88 85 89 /* wait for arp reply, and check it */ 86 timeout_ms = 2000;90 timeout_ms = (int)timeo; 87 91 do { 88 92 typedef uint32_t aliased_uint32_t FIX_ALIASING; … … 125 129 * (people did see overflows here when system time jumps): 126 130 */ 127 } while ((unsigned)timeout_ms <= 2000);131 } while ((unsigned)timeout_ms <= timeo); 128 132 129 133 ret: 130 134 close(s); 131 log1("%srp reply received for this address", rv ? " No a" : "A");135 log1("%srp reply received for this address", rv ? "no a" : "A"); 132 136 return rv; 133 137 } -
branches/3.3/mindi-busybox/networking/udhcp/common.c
r3232 r3621 63 63 { OPTION_U8 , 0x85 }, /* DHCP_VLAN_PRIORITY */ 64 64 #endif 65 { OPTION_STRING , 0xd1 }, /* DHCP_PXE_CONF_FILE */ 66 { OPTION_STRING , 0xd2 }, /* DHCP_PXE_PATH_PREFIX */ 65 67 { OPTION_6RD , 0xd4 }, /* DHCP_6RD */ 66 68 { OPTION_STATIC_ROUTES | OPTION_LIST , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ … … 129 131 "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY */ 130 132 #endif 133 "pxeconffile" "\0" /* DHCP_PXE_CONF_FILE */ 134 "pxepathprefix" "\0" /* DHCP_PXE_PATH_PREFIX */ 131 135 "ip6rd" "\0" /* DHCP_6RD */ 132 136 "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ … … 139 143 * xmalloc_optname_optval: to estimate string length 140 144 * from binary option length: (option[LEN] / dhcp_option_lengths[opt_type]) 141 * is the number of elements, multiply i nby one element's string width145 * is the number of elements, multiply it by one element's string width 142 146 * (len_of_option_as_string[opt_type]) and you know how wide string you need. 143 147 */ … … 159 163 /* Just like OPTION_STRING, we use minimum length here */ 160 164 [OPTION_STATIC_ROUTES] = 5, 161 [OPTION_6RD] = 22, /* ignored by udhcp_str2optset */ 165 [OPTION_6RD] = 12, /* ignored by udhcp_str2optset */ 166 /* The above value was chosen as follows: 167 * len_of_option_as_string[] for this option is >60: it's a string of the form 168 * "32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 ". 169 * Each additional ipv4 address takes 4 bytes in binary option and appends 170 * another "255.255.255.255 " 16-byte string. We can set [OPTION_6RD] = 4 171 * but this severely overestimates string length: instead of 16 bytes, 172 * it adds >60 for every 4 bytes in binary option. 173 * We cheat and declare here that option is in units of 12 bytes. 174 * This adds more than 60 bytes for every three ipv4 addresses - more than enough. 175 * (Even 16 instead of 12 should work, but let's be paranoid). 176 */ 162 177 }; 163 178 … … 169 184 char buf[256 * 2 + 2]; 170 185 *bin2hex(buf, (void*) (opt + OPT_DATA), opt[OPT_LEN]) = '\0'; 171 bb_ info_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf);186 bb_error_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf); 172 187 } 173 188 } … … 243 258 244 259 if (optionptr[OPT_CODE] == code) { 245 log_option(" Option found", optionptr);260 log_option("option found", optionptr); 246 261 return optionptr + OPT_DATA; 247 262 } … … 255 270 256 271 /* log3 because udhcpc uses it a lot - very noisy */ 257 log3(" Option 0x%02x not found", code);272 log3("option 0x%02x not found", code); 258 273 return NULL; 259 274 } … … 289 304 return; 290 305 } 291 log_option(" Adding option", addopt);306 log_option("adding option", addopt); 292 307 memcpy(optionptr + end, addopt, len); 293 308 optionptr[end + len] = DHCP_END; … … 372 387 int length) 373 388 { 374 struct option_set *existing, *new, **curr; 375 char *allocated = NULL; 389 struct option_set *existing; 390 char *allocated; 391 392 allocated = allocate_tempopt_if_needed(optflag, buffer, &length); 393 #if ENABLE_FEATURE_UDHCP_RFC3397 394 if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_DNS_STRING) { 395 /* reuse buffer and length for RFC1035-formatted string */ 396 allocated = buffer = (char *)dname_enc(NULL, 0, buffer, &length); 397 } 398 #endif 376 399 377 400 existing = udhcp_find_option(*opt_list, optflag->code); 378 401 if (!existing) { 379 log2("Attaching option %02x to list", optflag->code); 380 allocated = allocate_tempopt_if_needed(optflag, buffer, &length); 381 #if ENABLE_FEATURE_UDHCP_RFC3397 382 if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_DNS_STRING) { 383 /* reuse buffer and length for RFC1035-formatted string */ 384 allocated = buffer = (char *)dname_enc(NULL, 0, buffer, &length); 385 } 386 #endif 402 struct option_set *new, **curr; 403 387 404 /* make a new option */ 405 log2("attaching option %02x to list", optflag->code); 388 406 new = xmalloc(sizeof(*new)); 389 407 new->data = xmalloc(length + OPT_DATA); … … 405 423 406 424 /* add it to an existing option */ 407 log2("Attaching option %02x to existing member of list", optflag->code); 408 allocated = allocate_tempopt_if_needed(optflag, buffer, &length); 425 log2("attaching option %02x to existing member of list", optflag->code); 409 426 old_len = existing->data[OPT_LEN]; 410 #if ENABLE_FEATURE_UDHCP_RFC3397411 if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_DNS_STRING) {412 /* reuse buffer and length for RFC1035-formatted string */413 allocated = buffer = (char *)dname_enc(existing->data + OPT_DATA, old_len, buffer, &length);414 }415 #endif416 427 if (old_len + length < 255) { 417 428 /* actually 255 is ok too, but adding a space can overlow it */ … … 425 436 old_len++; 426 437 } 427 memcpy(existing->data + OPT_DATA + old_len, buffer, length);438 memcpy(existing->data + OPT_DATA + old_len, (allocated ? allocated : buffer), length); 428 439 existing->data[OPT_LEN] = old_len + length; 429 440 } /* else, ignore the data, we could put this in a second option in the future */ -
branches/3.3/mindi-busybox/networking/udhcp/common.h
r3232 r3621 10 10 11 11 #include "libbb.h" 12 #include "common_bufsiz.h" 12 13 #include <netinet/udp.h> 13 14 #include <netinet/ip.h> … … 150 151 //#define DHCP_SIP_SERVERS 0x78 /* RFC 3361. flag byte, then: 0: domain names, 1: IP addrs */ 151 152 //#define DHCP_STATIC_ROUTES 0x79 /* RFC 3442. (mask,ip,router) tuples */ 152 #define DHCP_VLAN_ID 0x84 /* 802.1P VLAN ID */ 153 #define DHCP_VLAN_PRIORITY 0x85 /* 802.1Q VLAN priority */ 153 //#define DHCP_VLAN_ID 0x84 /* 802.1P VLAN ID */ 154 //#define DHCP_VLAN_PRIORITY 0x85 /* 802.1Q VLAN priority */ 155 //#define DHCP_PXE_CONF_FILE 0xd1 /* RFC 5071 Configuration File */ 156 //#define DHCP_PXE_PATH_PREFIX 0xd2 /* RFC 5071 Configuration File */ 154 157 //#define DHCP_MS_STATIC_ROUTES 0xf9 /* Microsoft's pre-RFC 3442 code for 0x79? */ 155 158 //#define DHCP_WPAD 0xfc /* MSIE's Web Proxy Autodiscovery Protocol */ … … 255 258 # define IF_UDHCP_VERBOSE(...) __VA_ARGS__ 256 259 extern unsigned dhcp_verbose; 257 # define log1(...) do { if (dhcp_verbose >= 1) bb_ info_msg(__VA_ARGS__); } while (0)260 # define log1(...) do { if (dhcp_verbose >= 1) bb_error_msg(__VA_ARGS__); } while (0) 258 261 # if CONFIG_UDHCP_DEBUG >= 2 259 262 void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC; 260 # define log2(...) do { if (dhcp_verbose >= 2) bb_ info_msg(__VA_ARGS__); } while (0)263 # define log2(...) do { if (dhcp_verbose >= 2) bb_error_msg(__VA_ARGS__); } while (0) 261 264 # else 262 265 # define udhcp_dump_packet(...) ((void)0) … … 264 267 # endif 265 268 # if CONFIG_UDHCP_DEBUG >= 3 266 # define log3(...) do { if (dhcp_verbose >= 3) bb_ info_msg(__VA_ARGS__); } while (0)269 # define log3(...) do { if (dhcp_verbose >= 3) bb_error_msg(__VA_ARGS__); } while (0) 267 270 # else 268 271 # define log3(...) ((void)0) … … 310 313 uint32_t from_ip, 311 314 uint8_t *from_mac, 312 const char *interface) FAST_FUNC; 315 const char *interface, 316 unsigned timeo) FAST_FUNC; 313 317 314 318 /* note: ip is a pointer to an IPv6 in network order, possibly misaliged */ -
branches/3.3/mindi-busybox/networking/udhcp/dhcpc.c
r3306 r3621 26 26 #include "dhcpc.h" 27 27 28 #include <asm/types.h> 29 #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined(_NEWLIB_VERSION) 30 # include <netpacket/packet.h> 31 # include <net/ethernet.h> 32 #else 33 # include <linux/if_packet.h> 34 # include <linux/if_ether.h> 28 #include <netinet/if_ether.h> 29 #include <linux/filter.h> 30 #include <linux/if_packet.h> 31 32 #ifndef PACKET_AUXDATA 33 # define PACKET_AUXDATA 8 34 struct tpacket_auxdata { 35 uint32_t tp_status; 36 uint32_t tp_len; 37 uint32_t tp_snaplen; 38 uint16_t tp_mac; 39 uint16_t tp_net; 40 uint16_t tp_vlan_tci; 41 uint16_t tp_padding; 42 }; 35 43 #endif 36 #include <linux/filter.h> 44 37 45 38 46 /* "struct client_config_t client_config" is in bb_common_bufsiz1 */ … … 61 69 "background\0" No_argument "b" 62 70 "broadcast\0" No_argument "B" 63 IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument"a")71 IF_FEATURE_UDHCPC_ARPING("arping\0" Optional_argument "a") 64 72 IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P") 65 73 ; … … 102 110 103 111 /* get a rough idea of how long an option will be (rounding up...) */ 104 static const uint8_t len_of_option_as_string[] = {112 static const uint8_t len_of_option_as_string[] ALIGN1 = { 105 113 [OPTION_IP ] = sizeof("255.255.255.255 "), 106 114 [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2, 107 115 [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "), 108 [OPTION_6RD ] = sizeof(" 32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "),116 [OPTION_6RD ] = sizeof("132 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "), 109 117 [OPTION_STRING ] = 1, 110 118 [OPTION_STRING_HOST ] = 1, … … 143 151 } 144 152 153 #if ENABLE_FEATURE_UDHCPC_SANITIZEOPT 145 154 /* Check if a given label represents a valid DNS label 146 155 * Return pointer to the first character after the label upon success, … … 162 171 ch = *label; 163 172 if ((ch|0x20) < 'a' || (ch|0x20) > 'z') { 164 if (pos == 0) {165 /* label must begin with letter */166 return NULL;167 }168 173 if (ch < '0' || ch > '9') { 169 174 if (ch == '\0' || ch == '.') … … 197 202 //return ((name - start) < 1025); /* NS_MAXDNAME */ 198 203 name++; 199 } 200 } 204 if (*name == '\0') 205 return 1; // We allow trailing dot too 206 } 207 } 208 #else 209 # define good_hostname(name) 1 210 #endif 201 211 202 212 /* Create "opt_name=opt_value" string */ … … 213 223 optlen = dhcp_option_lengths[type]; 214 224 upper_length = len_of_option_as_string[type] 215 * ((unsigned)(len + optlen - 1) / (unsigned)optlen);225 * ((unsigned)(len + optlen) / (unsigned)optlen); 216 226 217 227 dest = ret = xmalloc(upper_length + strlen(opt_name) + 2); … … 552 562 553 563 /* call script */ 554 log1(" Executing %s %s", client_config.script, name);564 log1("executing %s %s", client_config.script, name); 555 565 argv[0] = (char*) client_config.script; 556 566 argv[1] = (char*) name; … … 666 676 */ 667 677 668 static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet )678 static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet, uint32_t src_nip) 669 679 { 670 680 return udhcp_send_raw_packet(packet, 671 /*src*/ INADDR_ANY, CLIENT_PORT,681 /*src*/ src_nip, CLIENT_PORT, 672 682 /*dst*/ INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR, 673 683 client_config.ifindex); 684 } 685 686 static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server) 687 { 688 if (server) 689 return udhcp_send_kernel_packet(packet, 690 ciaddr, CLIENT_PORT, 691 server, SERVER_PORT); 692 return raw_bcast_from_client_config_ifindex(packet, ciaddr); 674 693 } 675 694 … … 696 715 add_client_options(&packet); 697 716 698 bb_ info_msg("Sending discover...");699 return raw_bcast_from_client_config_ifindex(&packet );717 bb_error_msg("sending %s", "discover"); 718 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); 700 719 } 701 720 … … 740 759 741 760 addr.s_addr = requested; 742 bb_ info_msg("Sending select for %s...", inet_ntoa(addr));743 return raw_bcast_from_client_config_ifindex(&packet );761 bb_error_msg("sending select for %s", inet_ntoa(addr)); 762 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); 744 763 } 745 764 … … 779 798 add_client_options(&packet); 780 799 781 bb_info_msg("Sending renew..."); 782 if (server) 783 return udhcp_send_kernel_packet(&packet, 784 ciaddr, CLIENT_PORT, 785 server, SERVER_PORT); 786 return raw_bcast_from_client_config_ifindex(&packet); 800 bb_error_msg("sending %s", "renew"); 801 return bcast_or_ucast(&packet, ciaddr, server); 787 802 } 788 803 … … 812 827 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); 813 828 814 bb_ info_msg("Sending decline...");815 return raw_bcast_from_client_config_ifindex(&packet );829 bb_error_msg("sending %s", "decline"); 830 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); 816 831 } 817 832 #endif … … 832 847 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); 833 848 834 bb_info_msg("Sending release..."); 835 return udhcp_send_kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT); 849 bb_error_msg("sending %s", "release"); 850 /* Note: normally we unicast here since "server" is not zero. 851 * However, there _are_ people who run "address-less" DHCP servers, 852 * and reportedly ISC dhcp client and Windows allow that. 853 */ 854 return bcast_or_ucast(&packet, ciaddr, server); 836 855 } 837 856 … … 843 862 struct ip_udp_dhcp_packet packet; 844 863 uint16_t check; 845 #ifdef PACKET_AUXDATA846 864 unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))]; 847 struct cmsghdr *cmsg;848 #endif849 865 struct iovec iov; 850 866 struct msghdr msg; 851 852 #ifdef PACKET_AUXDATA 867 struct cmsghdr *cmsg; 868 853 869 /* used to use just safe_read(fd, &packet, sizeof(packet)) 854 870 * but we need to check for TP_STATUS_CSUMNOTREADY :( … … 866 882 if (errno == EINTR) 867 883 continue; 868 log1(" Packet read error, ignoring");884 log1("packet read error, ignoring"); 869 885 /* NB: possible down interface, etc. Caller should pause. */ 870 886 return bytes; /* returns -1 */ … … 872 888 break; 873 889 } 874 #else875 memset(&packet, 0, sizeof(packet));876 bytes = safe_read(fd, &packet, sizeof(packet));877 if (bytes < 0) {878 log1("Packet read error, ignoring");879 /* NB: possible down interface, etc. Caller should pause. */880 return bytes; /* returns -1 */881 }882 #endif883 890 884 891 if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) { 885 log1(" Packet is too short, ignoring");892 log1("packet is too short, ignoring"); 886 893 return -2; 887 894 } … … 889 896 if (bytes < ntohs(packet.ip.tot_len)) { 890 897 /* packet is bigger than sizeof(packet), we did partial read */ 891 log1(" Oversized packet, ignoring");898 log1("oversized packet, ignoring"); 892 899 return -2; 893 900 } … … 904 911 || ntohs(packet.udp.len) != (uint16_t)(bytes - sizeof(packet.ip)) 905 912 ) { 906 log1(" Unrelated/bogus packet, ignoring");913 log1("unrelated/bogus packet, ignoring"); 907 914 return -2; 908 915 } … … 912 919 packet.ip.check = 0; 913 920 if (check != inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip))) { 914 log1(" Bad IP header checksum, ignoring");921 log1("bad IP header checksum, ignoring"); 915 922 return -2; 916 923 } 917 924 918 #ifdef PACKET_AUXDATA919 925 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { 920 926 if (cmsg->cmsg_level == SOL_PACKET … … 930 936 } 931 937 } 932 #endif933 938 934 939 /* verify UDP checksum. IP header has to be modified for this */ … … 939 944 packet.udp.check = 0; 940 945 if (check && check != inet_cksum((uint16_t *)&packet, bytes)) { 941 log1(" Packet with bad UDP checksum received, ignoring");946 log1("packet with bad UDP checksum received, ignoring"); 942 947 return -2; 943 948 } 944 #ifdef PACKET_AUXDATA945 949 skip_udp_sum_check: 946 #endif947 950 948 951 if (packet.data.cookie != htonl(DHCP_MAGIC)) { 949 bb_ info_msg("Packet with bad magic, ignoring");952 bb_error_msg("packet with bad magic, ignoring"); 950 953 return -2; 951 954 } 952 955 953 log1(" Receiveda packet");956 log1("received %s", "a packet"); 954 957 udhcp_dump_packet(&packet.data); 955 958 … … 990 993 struct sockaddr_ll sock; 991 994 992 /* 993 * Comment: 994 * 995 * I've selected not to see LL header, so BPF doesn't see it, too. 996 * The filter may also pass non-IP and non-ARP packets, but we do 997 * a more complete check when receiving the message in userspace. 998 * 999 * and filter shamelessly stolen from: 1000 * 1001 * http://www.flamewarmaster.de/software/dhcpclient/ 1002 * 1003 * There are a few other interesting ideas on that page (look under 1004 * "Motivation"). Use of netlink events is most interesting. Think 1005 * of various network servers listening for events and reconfiguring. 1006 * That would obsolete sending HUP signals and/or make use of restarts. 1007 * 1008 * Copyright: 2006, 2007 Stefan Rompf <sux@loplof.de>. 1009 * License: GPL v2. 1010 * 1011 * TODO: make conditional? 995 log1("opening raw socket on ifindex %d", ifindex); //log2? 996 997 fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); 998 /* ^^^^^ 999 * SOCK_DGRAM: remove link-layer headers on input (SOCK_RAW keeps them) 1000 * ETH_P_IP: want to receive only packets with IPv4 eth type 1012 1001 */ 1013 static const struct sock_filter filter_instr[] = { 1014 /* load 9th byte (protocol) */ 1015 BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9), 1016 /* jump to L1 if it is IPPROTO_UDP, else to L4 */ 1017 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6), 1018 /* L1: load halfword from offset 6 (flags and frag offset) */ 1019 BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6), 1020 /* jump to L4 if any bits in frag offset field are set, else to L2 */ 1021 BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0), 1022 /* L2: skip IP header (load index reg with header len) */ 1023 BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0), 1024 /* load udp destination port from halfword[header_len + 2] */ 1025 BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2), 1026 /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */ 1027 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1), 1028 /* L3: accept packet */ 1029 BPF_STMT(BPF_RET|BPF_K, 0xffffffff), 1030 /* L4: discard packet */ 1031 BPF_STMT(BPF_RET|BPF_K, 0), 1032 }; 1033 static const struct sock_fprog filter_prog = { 1034 .len = sizeof(filter_instr) / sizeof(filter_instr[0]), 1035 /* casting const away: */ 1036 .filter = (struct sock_filter *) filter_instr, 1037 }; 1038 1039 log1("Opening raw socket on ifindex %d", ifindex); //log2? 1040 1041 fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); 1042 log1("Got raw socket fd"); //log2? 1002 log1("got raw socket fd"); //log2? 1043 1003 1044 1004 sock.sll_family = AF_PACKET; … … 1047 1007 xbind(fd, (struct sockaddr *) &sock, sizeof(sock)); 1048 1008 1009 #if 0 /* Several users reported breakage when BPF filter is used */ 1049 1010 if (CLIENT_PORT == 68) { 1050 1011 /* Use only if standard port is in use */ 1012 /* 1013 * I've selected not to see LL header, so BPF doesn't see it, too. 1014 * The filter may also pass non-IP and non-ARP packets, but we do 1015 * a more complete check when receiving the message in userspace. 1016 * 1017 * and filter shamelessly stolen from: 1018 * 1019 * http://www.flamewarmaster.de/software/dhcpclient/ 1020 * 1021 * There are a few other interesting ideas on that page (look under 1022 * "Motivation"). Use of netlink events is most interesting. Think 1023 * of various network servers listening for events and reconfiguring. 1024 * That would obsolete sending HUP signals and/or make use of restarts. 1025 * 1026 * Copyright: 2006, 2007 Stefan Rompf <sux@loplof.de>. 1027 * License: GPL v2. 1028 */ 1029 static const struct sock_filter filter_instr[] = { 1030 /* load 9th byte (protocol) */ 1031 BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9), 1032 /* jump to L1 if it is IPPROTO_UDP, else to L4 */ 1033 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6), 1034 /* L1: load halfword from offset 6 (flags and frag offset) */ 1035 BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6), 1036 /* jump to L4 if any bits in frag offset field are set, else to L2 */ 1037 BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0), 1038 /* L2: skip IP header (load index reg with header len) */ 1039 BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0), 1040 /* load udp destination port from halfword[header_len + 2] */ 1041 BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2), 1042 /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */ 1043 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1), 1044 /* L3: accept packet ("accept 0x7fffffff bytes") */ 1045 /* Accepting 0xffffffff works too but kernel 2.6.19 is buggy */ 1046 BPF_STMT(BPF_RET|BPF_K, 0x7fffffff), 1047 /* L4: discard packet ("accept zero bytes") */ 1048 BPF_STMT(BPF_RET|BPF_K, 0), 1049 }; 1050 static const struct sock_fprog filter_prog = { 1051 .len = sizeof(filter_instr) / sizeof(filter_instr[0]), 1052 /* casting const away: */ 1053 .filter = (struct sock_filter *) filter_instr, 1054 }; 1051 1055 /* Ignoring error (kernel may lack support for this) */ 1052 1056 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, 1053 1057 sizeof(filter_prog)) >= 0) 1054 log1("Attached filter to raw socket fd"); // log? 1055 } 1056 1057 #ifdef PACKET_AUXDATA 1058 if (setsockopt(fd, SOL_PACKET, PACKET_AUXDATA, 1059 &const_int_1, sizeof(int)) < 0 1060 ) { 1058 log1("attached filter to raw socket fd"); // log? 1059 } 1060 #endif 1061 1062 if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) { 1061 1063 if (errno != ENOPROTOOPT) 1062 log1("Can't set PACKET_AUXDATA on raw socket"); 1063 } 1064 #else 1065 sock.sll_family = AF_PACKET; 1066 sock.sll_protocol = htons(ETH_P_IP); 1067 sock.sll_ifindex = ifindex; 1068 xbind(fd, (struct sockaddr *) &sock, sizeof(sock)); 1069 #endif 1070 1071 log1("Created raw socket"); 1064 log1("can't set PACKET_AUXDATA on raw socket"); 1065 } 1066 1067 log1("created raw socket"); 1072 1068 1073 1069 return fd; … … 1076 1072 static void change_listen_mode(int new_mode) 1077 1073 { 1078 log1(" Entering listen mode: %s",1074 log1("entering listen mode: %s", 1079 1075 new_mode != LISTEN_NONE 1080 1076 ? (new_mode == LISTEN_KERNEL ? "kernel" : "raw") … … 1097 1093 static void perform_renew(void) 1098 1094 { 1099 bb_ info_msg("Performing aDHCP renew");1095 bb_error_msg("performing DHCP renew"); 1100 1096 switch (state) { 1101 1097 case BOUND: … … 1127 1123 strcpy(buffer, inet_ntoa(temp_addr)); 1128 1124 temp_addr.s_addr = requested_ip; 1129 bb_ info_msg("Unicasting a release of %s to %s",1125 bb_error_msg("unicasting a release of %s to %s", 1130 1126 inet_ntoa(temp_addr), buffer); 1131 1127 send_release(server_addr, requested_ip); /* unicast */ 1132 1128 udhcp_run_script(NULL, "deconfig"); 1133 1129 } 1134 bb_ info_msg("Entering released state");1130 bb_error_msg("entering released state"); 1135 1131 1136 1132 change_listen_mode(LISTEN_NONE); … … 1165 1161 //usage:#endif 1166 1162 //usage:#define udhcpc_trivial_usage 1167 //usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"oCRB] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n" 1168 //usage: " [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]") 1163 //usage: "[-fbq"IF_UDHCP_VERBOSE("v")"RB]"IF_FEATURE_UDHCPC_ARPING(" [-a[MSEC]]")" [-t N] [-T SEC] [-A SEC/-n]\n" 1164 //usage: " [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-s PROG] [-p PIDFILE]\n" 1165 //usage: " [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]..." 1169 1166 //usage:#define udhcpc_full_usage "\n" 1170 1167 //usage: IF_LONG_OPTS( 1171 1168 //usage: "\n -i,--interface IFACE Interface to use (default eth0)" 1169 //usage: IF_FEATURE_UDHCP_PORT( 1170 //usage: "\n -P,--client-port PORT Use PORT (default 68)" 1171 //usage: ) 1172 //usage: "\n -s,--script PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" 1172 1173 //usage: "\n -p,--pidfile FILE Create pidfile" 1173 //usage: "\n -s,--script PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"1174 1174 //usage: "\n -B,--broadcast Request broadcast replies" 1175 //usage: "\n -t,--retries N Send up to N discover packets" 1176 //usage: "\n -T,--timeout N Pause between packets (default 3 seconds)" 1177 //usage: "\n -A,--tryagain N Wait N seconds after failure (default 20)" 1175 //usage: "\n -t,--retries N Send up to N discover packets (default 3)" 1176 //usage: "\n -T,--timeout SEC Pause between packets (default 3)" 1177 //usage: "\n -A,--tryagain SEC Wait if lease is not obtained (default 20)" 1178 //usage: "\n -n,--now Exit if lease is not obtained" 1179 //usage: "\n -q,--quit Exit after obtaining lease" 1180 //usage: "\n -R,--release Release IP on exit" 1178 1181 //usage: "\n -f,--foreground Run in foreground" 1179 1182 //usage: USE_FOR_MMU( 1180 1183 //usage: "\n -b,--background Background if lease is not obtained" 1181 1184 //usage: ) 1182 //usage: "\n -n,--now Exit if lease is not obtained"1183 //usage: "\n -q,--quit Exit after obtaining lease"1184 //usage: "\n -R,--release Release IP on exit"1185 1185 //usage: "\n -S,--syslog Log to syslog too" 1186 //usage: IF_FEATURE_UDHCP _PORT(1187 //usage: "\n - P,--client-port N Use port N (default 68)"1186 //usage: IF_FEATURE_UDHCPC_ARPING( 1187 //usage: "\n -a[MSEC],--arping[=MSEC] Validate offered address with ARP ping" 1188 1188 //usage: ) 1189 //usage: IF_FEATURE_UDHCPC_ARPING( 1190 //usage: "\n -a,--arping Use arping to validate offered address" 1191 //usage: ) 1189 //usage: "\n -r,--request IP Request this IP address" 1190 //usage: "\n -o,--no-default-options Don't request any options (unless -O is given)" 1192 1191 //usage: "\n -O,--request-option OPT Request option OPT from server (cumulative)" 1193 //usage: "\n -o,--no-default-options Don't request any options (unless -O is given)"1194 //usage: "\n -r,--request IP Request this IP address"1195 1192 //usage: "\n -x OPT:VAL Include option OPT in sent packets (cumulative)" 1196 1193 //usage: "\n Examples of string, numeric, and hex byte opts:" … … 1207 1204 //usage: IF_NOT_LONG_OPTS( 1208 1205 //usage: "\n -i IFACE Interface to use (default eth0)" 1206 //usage: IF_FEATURE_UDHCP_PORT( 1207 //usage: "\n -P PORT Use PORT (default 68)" 1208 //usage: ) 1209 //usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" 1209 1210 //usage: "\n -p FILE Create pidfile" 1210 //usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"1211 1211 //usage: "\n -B Request broadcast replies" 1212 //usage: "\n -t N Send up to N discover packets" 1213 //usage: "\n -T N Pause between packets (default 3 seconds)" 1214 //usage: "\n -A N Wait N seconds (default 20) after failure" 1212 //usage: "\n -t N Send up to N discover packets (default 3)" 1213 //usage: "\n -T SEC Pause between packets (default 3)" 1214 //usage: "\n -A SEC Wait if lease is not obtained (default 20)" 1215 //usage: "\n -n Exit if lease is not obtained" 1216 //usage: "\n -q Exit after obtaining lease" 1217 //usage: "\n -R Release IP on exit" 1215 1218 //usage: "\n -f Run in foreground" 1216 1219 //usage: USE_FOR_MMU( 1217 1220 //usage: "\n -b Background if lease is not obtained" 1218 1221 //usage: ) 1219 //usage: "\n -n Exit if lease is not obtained"1220 //usage: "\n -q Exit after obtaining lease"1221 //usage: "\n -R Release IP on exit"1222 1222 //usage: "\n -S Log to syslog too" 1223 //usage: IF_FEATURE_UDHCP _PORT(1224 //usage: "\n - P N Use port N (default 68)"1223 //usage: IF_FEATURE_UDHCPC_ARPING( 1224 //usage: "\n -a[MSEC] Validate offered address with ARP ping" 1225 1225 //usage: ) 1226 //usage: IF_FEATURE_UDHCPC_ARPING( 1227 //usage: "\n -a Use arping to validate offered address" 1228 //usage: ) 1226 //usage: "\n -r IP Request this IP address" 1227 //usage: "\n -o Don't request any options (unless -O is given)" 1229 1228 //usage: "\n -O OPT Request option OPT from server (cumulative)" 1230 //usage: "\n -o Don't request any options (unless -O is given)"1231 //usage: "\n -r IP Request this IP address"1232 1229 //usage: "\n -x OPT:VAL Include option OPT in sent packets (cumulative)" 1233 1230 //usage: "\n Examples of string, numeric, and hex byte opts:" … … 1250 1247 int udhcpc_main(int argc UNUSED_PARAM, char **argv) 1251 1248 { 1252 uint8_t * temp, *message;1249 uint8_t *message; 1253 1250 const char *str_V, *str_h, *str_F, *str_r; 1251 IF_FEATURE_UDHCPC_ARPING(const char *str_a = "2000";) 1254 1252 IF_FEATURE_UDHCP_PORT(char *str_P;) 1255 1253 void *clientid_mac_ptr; … … 1266 1264 unsigned already_waited_sec; 1267 1265 unsigned opt; 1266 IF_FEATURE_UDHCPC_ARPING(unsigned arpping_ms;) 1268 1267 int max_fd; 1269 1268 int retval; 1270 1269 fd_set rfds; 1270 1271 setup_common_bufsiz(); 1271 1272 1272 1273 /* Default options */ … … 1283 1284 opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB" 1284 1285 USE_FOR_MMU("b") 1285 IF_FEATURE_UDHCPC_ARPING("a ")1286 IF_FEATURE_UDHCPC_ARPING("a::") 1286 1287 IF_FEATURE_UDHCP_PORT("P:") 1287 1288 "v" … … 1292 1293 , &list_O 1293 1294 , &list_x 1295 IF_FEATURE_UDHCPC_ARPING(, &str_a) 1294 1296 IF_FEATURE_UDHCP_PORT(, &str_P) 1295 1297 IF_UDHCP_VERBOSE(, &dhcp_verbose) … … 1323 1325 } 1324 1326 #endif 1327 IF_FEATURE_UDHCPC_ARPING(arpping_ms = xatou(str_a);) 1325 1328 while (list_O) { 1326 1329 char *optstr = llist_pop(&list_O); … … 1395 1398 write_pidfile(client_config.pidfile); 1396 1399 /* Goes to stdout (unless NOMMU) and possibly syslog */ 1397 bb_ info_msg("%s (v"BB_VER") started", applet_name);1400 bb_error_msg("started, v"BB_VER); 1398 1401 /* Set up the signal pipe */ 1399 1402 udhcp_sp_setup(); … … 1434 1437 /* If we already timed out, fall through with retval = 0, else... */ 1435 1438 if ((int)tv.tv_sec > 0) { 1436 log1(" Waiting on select %u seconds", (int)tv.tv_sec);1439 log1("waiting on select %u seconds", (int)tv.tv_sec); 1437 1440 timestamp_before_wait = (unsigned)monotonic_sec(); 1438 1441 retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); … … 1485 1488 #if BB_MMU /* -b is not supported on NOMMU */ 1486 1489 if (opt & OPT_b) { /* background if no lease */ 1487 bb_ info_msg("No lease, forking to background");1490 bb_error_msg("no lease, forking to background"); 1488 1491 client_background(); 1489 1492 /* do not background again! */ … … 1492 1495 #endif 1493 1496 if (opt & OPT_n) { /* abort if no lease */ 1494 bb_ info_msg("No lease, failing");1497 bb_error_msg("no lease, failing"); 1495 1498 retval = 1; 1496 1499 goto ret; … … 1501 1504 continue; 1502 1505 case REQUESTING: 1503 if ( !discover_retries || packet_num < discover_retries) {1506 if (packet_num < 3) { 1504 1507 /* send broadcast select packet */ 1505 1508 send_select(xid, server_addr, requested_ip); … … 1520 1523 client_config.first_secs = 0; /* make secs field count from 0 */ 1521 1524 change_listen_mode(LISTEN_KERNEL); 1522 log1(" Entering renew state");1525 log1("entering renew state"); 1523 1526 /* fall right through */ 1524 1527 case RENEW_REQUESTED: /* manual (SIGUSR1) renew */ … … 1540 1543 } 1541 1544 /* Timed out, enter rebinding state */ 1542 log1(" Entering rebinding state");1545 log1("entering rebinding state"); 1543 1546 state = REBINDING; 1544 1547 /* fall right through */ … … 1555 1558 } 1556 1559 /* Timed out, enter init state */ 1557 bb_ info_msg("Lease lost, entering init state");1560 bb_error_msg("lease lost, entering init state"); 1558 1561 udhcp_run_script(NULL, "deconfig"); 1559 1562 state = INIT_SELECTING; … … 1603 1606 continue; 1604 1607 case SIGTERM: 1605 bb_ info_msg("ReceivedSIGTERM");1608 bb_error_msg("received %s", "SIGTERM"); 1606 1609 goto ret0; 1607 1610 } … … 1621 1624 if (len == -1) { 1622 1625 /* Error is severe, reopen socket */ 1623 bb_ info_msg("Read error: %s, reopening socket", strerror(errno));1626 bb_error_msg("read error: %s, reopening socket", strerror(errno)); 1624 1627 sleep(discover_timeout); /* 3 seconds by default */ 1625 1628 change_listen_mode(listen_mode); /* just close and reopen */ … … 1658 1661 /* Must be a DHCPOFFER */ 1659 1662 if (*message == DHCPOFFER) { 1663 uint8_t *temp; 1664 1660 1665 /* What exactly is server's IP? There are several values. 1661 1666 * Example DHCP offer captured with tchdump: … … 1677 1682 * "Next server" and router are definitely wrong ones to use, though... 1678 1683 */ 1684 /* We used to ignore pcakets without DHCP_SERVER_ID. 1685 * I've got user reports from people who run "address-less" servers. 1686 * They either supply DHCP_SERVER_ID of 0.0.0.0 or don't supply it at all. 1687 * They say ISC DHCP client supports this case. 1688 */ 1689 server_addr = 0; 1679 1690 temp = udhcp_get_option(&packet, DHCP_SERVER_ID); 1680 1691 if (!temp) { 1681 bb_error_msg("no server ID, ignoring packet"); 1682 continue; 1683 /* still selecting - this server looks bad */ 1692 bb_error_msg("no server ID, using 0.0.0.0"); 1693 } else { 1694 /* it IS unaligned sometimes, don't "optimize" */ 1695 move_from_unaligned32(server_addr, temp); 1684 1696 } 1685 /* it IS unaligned sometimes, don't "optimize" */1686 move_from_unaligned32(server_addr, temp);1687 1697 /*xid = packet.xid; - already is */ 1688 1698 requested_ip = packet.yiaddr; … … 1700 1710 case REBINDING: 1701 1711 if (*message == DHCPACK) { 1712 unsigned start; 1702 1713 uint32_t lease_seconds; 1703 1714 struct in_addr temp_addr; 1715 uint8_t *temp; 1704 1716 1705 1717 temp = udhcp_get_option(&packet, DHCP_LEASE_TIME); … … 1732 1744 (uint32_t) 0, 1733 1745 client_config.client_mac, 1734 client_config.interface) 1746 client_config.interface, 1747 arpping_ms) 1735 1748 ) { 1736 bb_ info_msg("Offered address is in use "1749 bb_error_msg("offered address is in use " 1737 1750 "(got ARP reply), declining"); 1738 1751 send_decline(/*xid,*/ server_addr, packet.yiaddr); … … 1752 1765 #endif 1753 1766 /* enter bound state */ 1754 timeout = lease_seconds / 2;1755 1767 temp_addr.s_addr = packet.yiaddr; 1756 bb_ info_msg("Lease of %s obtained, lease time %u",1768 bb_error_msg("lease of %s obtained, lease time %u", 1757 1769 inet_ntoa(temp_addr), (unsigned)lease_seconds); 1758 1770 requested_ip = packet.yiaddr; 1771 1772 start = monotonic_sec(); 1759 1773 udhcp_run_script(&packet, state == REQUESTING ? "bound" : "renew"); 1774 already_waited_sec = (unsigned)monotonic_sec() - start; 1775 timeout = lease_seconds / 2; 1776 if ((unsigned)timeout < already_waited_sec) { 1777 /* Something went wrong. Back to discover state */ 1778 timeout = already_waited_sec = 0; 1779 } 1760 1780 1761 1781 state = BOUND; … … 1775 1795 /* make future renew packets use different xid */ 1776 1796 /* xid = random_xid(); ...but why bother? */ 1777 already_waited_sec = 0; 1797 1778 1798 continue; /* back to main loop */ 1779 1799 } 1780 1800 if (*message == DHCPNAK) { 1801 /* If network has more than one DHCP server, 1802 * "wrong" server can reply first, with a NAK. 1803 * Do not interpret it as a NAK from "our" server. 1804 */ 1805 if (server_addr != 0) { 1806 uint32_t svid; 1807 uint8_t *temp; 1808 1809 temp = udhcp_get_option(&packet, DHCP_SERVER_ID); 1810 if (!temp) { 1811 non_matching_svid: 1812 log1("%s with wrong server ID, ignoring packet", 1813 "Received DHCP NAK" 1814 ); 1815 continue; 1816 } 1817 move_from_unaligned32(svid, temp); 1818 if (svid != server_addr) 1819 goto non_matching_svid; 1820 } 1781 1821 /* return to init state */ 1782 bb_ info_msg("ReceivedDHCP NAK");1822 bb_error_msg("received %s", "DHCP NAK"); 1783 1823 udhcp_run_script(&packet, "nak"); 1784 1824 if (state != REQUESTING) -
branches/3.3/mindi-busybox/networking/udhcp/dhcpc.h
r3232 r3621 30 30 31 31 #if ENABLE_FEATURE_UDHCP_PORT 32 #define CLIENT_PORT (client_config.port) 32 #define CLIENT_PORT (client_config.port) 33 #define CLIENT_PORT6 (client_config.port) 33 34 #else 34 #define CLIENT_PORT 68 35 #define CLIENT_PORT 68 36 #define CLIENT_PORT6 546 35 37 #endif 36 38 -
branches/3.3/mindi-busybox/networking/udhcp/dhcpd.c
r3232 r3621 23 23 24 24 //usage:#define udhcpd_trivial_usage 25 //usage: "[-fS] " IF_FEATURE_UDHCP_PORT(" [-P N]") " [CONFFILE]"25 //usage: "[-fS] [-I ADDR]" IF_FEATURE_UDHCP_PORT(" [-P N]") " [CONFFILE]" 26 26 //usage:#define udhcpd_full_usage "\n\n" 27 27 //usage: "DHCP server\n" 28 28 //usage: "\n -f Run in foreground" 29 29 //usage: "\n -S Log to syslog too" 30 //usage: "\n -I ADDR Local address" 31 //usage: "\n -a MSEC Timeout for ARP ping (default 2000)" 30 32 //usage: IF_FEATURE_UDHCP_PORT( 31 33 //usage: "\n -P N Use port N (default 67)" … … 60 62 || dhcp_pkt->ciaddr == 0 61 63 ) { 62 log1(" Broadcasting packet to client");64 log1("broadcasting packet to client"); 63 65 ciaddr = INADDR_BROADCAST; 64 66 chaddr = MAC_BCAST_ADDR; 65 67 } else { 66 log1(" Unicasting packet to client ciaddr");68 log1("unicasting packet to client ciaddr"); 67 69 ciaddr = dhcp_pkt->ciaddr; 68 70 chaddr = dhcp_pkt->chaddr; … … 78 80 static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt) 79 81 { 80 log1(" Forwarding packet to relay");82 log1("forwarding packet to relay"); 81 83 82 84 udhcp_send_kernel_packet(dhcp_pkt, … … 148 150 uint32_t static_lease_nip, 149 151 struct dyn_lease *lease, 150 uint8_t *requested_ip_opt) 152 uint8_t *requested_ip_opt, 153 unsigned arpping_ms) 151 154 { 152 155 struct dhcp_packet packet; … … 187 190 else { 188 191 /* Otherwise, find a free IP */ 189 packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr );192 packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr, arpping_ms); 190 193 } 191 194 … … 212 215 213 216 addr.s_addr = packet.yiaddr; 214 bb_ info_msg("Sending OFFER of %s", inet_ntoa(addr));217 bb_error_msg("sending OFFER of %s", inet_ntoa(addr)); 215 218 /* send_packet emits error message itself if it detects failure */ 216 219 send_packet(&packet, /*force_bcast:*/ 0); … … 224 227 init_packet(&packet, oldpacket, DHCPNAK); 225 228 226 log1(" SendingNAK");229 log1("sending %s", "NAK"); 227 230 send_packet(&packet, /*force_bcast:*/ 1); 228 231 } … … 245 248 246 249 addr.s_addr = yiaddr; 247 bb_ info_msg("Sending ACK to %s", inet_ntoa(addr));250 bb_error_msg("sending ACK to %s", inet_ntoa(addr)); 248 251 send_packet(&packet, /*force_bcast:*/ 0); 249 252 … … 303 306 unsigned opt; 304 307 struct option_set *option; 308 char *str_I = str_I; 309 const char *str_a = "2000"; 310 unsigned arpping_ms; 305 311 IF_FEATURE_UDHCP_PORT(char *str_P;) 306 312 307 #if ENABLE_FEATURE_UDHCP_PORT 308 SERVER_PORT = 67; 309 CLIENT_PORT = 68;310 #endif 313 setup_common_bufsiz(); 314 315 IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) 316 IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) 311 317 312 318 #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 313 319 opt_complementary = "vv"; 314 320 #endif 315 opt = getopt32(argv, "fSv" 316 IF_FEATURE_UDHCP_PORT("P:", &str_P) 321 opt = getopt32(argv, "fSI:va:" 322 IF_FEATURE_UDHCP_PORT("P:") 323 , &str_I 324 , &str_a 325 IF_FEATURE_UDHCP_PORT(, &str_P) 317 326 IF_UDHCP_VERBOSE(, &dhcp_verbose) 318 327 ); … … 327 336 logmode |= LOGMODE_SYSLOG; 328 337 } 338 if (opt & 4) { /* -I */ 339 len_and_sockaddr *lsa = xhost_and_af2sockaddr(str_I, 0, AF_INET); 340 server_config.server_nip = lsa->u.sin.sin_addr.s_addr; 341 free(lsa); 342 } 329 343 #if ENABLE_FEATURE_UDHCP_PORT 330 if (opt & 8) { /* -P */344 if (opt & 32) { /* -P */ 331 345 SERVER_PORT = xatou16(str_P); 332 346 CLIENT_PORT = SERVER_PORT + 1; 333 347 } 334 348 #endif 349 arpping_ms = xatou(str_a); 350 335 351 /* Would rather not do read_config before daemonization - 336 352 * otherwise NOMMU machines will parse config twice */ … … 346 362 /* if (!..) bb_perror_msg("can't create pidfile %s", pidfile); */ 347 363 348 bb_ info_msg("%s (v"BB_VER") started", applet_name);364 bb_error_msg("started, v"BB_VER); 349 365 350 366 option = udhcp_find_option(server_config.options, DHCP_LEASE_TIME); … … 368 384 if (udhcp_read_interface(server_config.interface, 369 385 &server_config.ifindex, 370 &server_config.server_nip,386 (server_config.server_nip == 0 ? &server_config.server_nip : NULL), 371 387 server_config.server_mac) 372 388 ) { … … 398 414 max_sock = udhcp_sp_fd_set(&rfds, server_socket); 399 415 if (server_config.auto_time) { 400 tv.tv_sec = timeout_end - monotonic_sec(); 416 /* cast to signed is essential if tv_sec is wider than int */ 417 tv.tv_sec = (int)(timeout_end - monotonic_sec()); 401 418 tv.tv_usec = 0; 402 419 } … … 411 428 } 412 429 if (retval < 0 && errno != EINTR) { 413 log1(" Error on select");430 log1("error on select"); 414 431 continue; 415 432 } … … 417 434 switch (udhcp_sp_read(&rfds)) { 418 435 case SIGUSR1: 419 bb_ info_msg("ReceivedSIGUSR1");436 bb_error_msg("received %s", "SIGUSR1"); 420 437 write_leases(); 421 438 /* why not just reset the timeout, eh */ 422 439 goto continue_with_autotime; 423 440 case SIGTERM: 424 bb_ info_msg("ReceivedSIGTERM");441 bb_error_msg("received %s", "SIGTERM"); 425 442 write_leases(); 426 443 goto ret0; … … 435 452 /* bytes can also be -2 ("bad packet data") */ 436 453 if (bytes == -1 && errno != EINTR) { 437 log1(" Read error: %s, reopening socket", strerror(errno));454 log1("read error: %s, reopening socket", strerror(errno)); 438 455 close(server_socket); 439 456 server_socket = -1; … … 470 487 static_lease_nip = get_static_nip_by_mac(server_config.static_leases, &packet.chaddr); 471 488 if (static_lease_nip) { 472 bb_ info_msg("Found static lease: %x", static_lease_nip);489 bb_error_msg("found static lease: %x", static_lease_nip); 473 490 memcpy(&fake_lease.lease_mac, &packet.chaddr, 6); 474 491 fake_lease.lease_nip = static_lease_nip; … … 488 505 489 506 case DHCPDISCOVER: 490 log1(" ReceivedDISCOVER");491 492 send_offer(&packet, static_lease_nip, lease, requested_ip_opt );507 log1("received %s", "DISCOVER"); 508 509 send_offer(&packet, static_lease_nip, lease, requested_ip_opt, arpping_ms); 493 510 break; 494 511 495 512 case DHCPREQUEST: 496 log1(" ReceivedREQUEST");513 log1("received %s", "REQUEST"); 497 514 /* RFC 2131: 498 515 … … 619 636 * ciaddr must be 0 (we do not check this) 620 637 */ 621 log1(" ReceivedDECLINE");638 log1("received %s", "DECLINE"); 622 639 if (server_id_opt 623 640 && requested_ip_opt … … 639 656 * ciaddr must be filled in 640 657 */ 641 log1(" ReceivedRELEASE");658 log1("received %s", "RELEASE"); 642 659 if (server_id_opt 643 660 && lease /* chaddr matches this lease */ … … 649 666 650 667 case DHCPINFORM: 651 log1(" ReceivedINFORM");668 log1("received %s", "INFORM"); 652 669 send_inform(&packet); 653 670 break; -
branches/3.3/mindi-busybox/networking/udhcp/dhcpd.h
r2725 r3621 58 58 } FIX_ALIASING; 59 59 60 #define server_config (*(struct server_config_t*) &bb_common_bufsiz1)60 #define server_config (*(struct server_config_t*)bb_common_bufsiz1) 61 61 /* client_config sits in 2nd half of bb_common_bufsiz1 */ 62 62 63 63 #if ENABLE_FEATURE_UDHCP_PORT 64 #define SERVER_PORT (server_config.port) 64 #define SERVER_PORT (server_config.port) 65 #define SERVER_PORT6 (server_config.port) 65 66 #else 66 #define SERVER_PORT 67 67 #define SERVER_PORT 67 68 #define SERVER_PORT6 547 67 69 #endif 68 70 … … 99 101 struct dyn_lease *find_lease_by_mac(const uint8_t *mac) FAST_FUNC; 100 102 struct dyn_lease *find_lease_by_nip(uint32_t nip) FAST_FUNC; 101 uint32_t find_free_or_expired_nip(const uint8_t *safe_mac ) FAST_FUNC;103 uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arpping_ms) FAST_FUNC; 102 104 103 105 -
branches/3.3/mindi-busybox/networking/udhcp/dhcprelay.c
r3232 r3621 34 34 } FIX_ALIASING; 35 35 36 #define dhcprelay_xid_list (*(struct xid_item*)&bb_common_bufsiz1) 36 #define dhcprelay_xid_list (*(struct xid_item*)bb_common_bufsiz1) 37 #define INIT_G() do { setup_common_bufsiz(); } while (0) 37 38 38 39 static struct xid_item *xid_add(uint32_t xid, struct sockaddr_in *ip, int client) … … 257 258 int num_sockets, max_socket; 258 259 uint32_t our_nip; 260 261 INIT_G(); 259 262 260 263 server_addr.sin_family = AF_INET; -
branches/3.3/mindi-busybox/networking/udhcp/domain_codec.c
r2725 r3621 8 8 */ 9 9 #ifdef DNS_COMPR_TESTING 10 # define _GNU_SOURCE 10 11 # define FAST_FUNC /* nothing */ 11 12 # define xmalloc malloc … … 43 44 while (1) { 44 45 /* note: "return NULL" below are leak-safe since 45 * dst isn't yet allocated*/46 * dst isn't allocated yet */ 46 47 const uint8_t *c; 47 48 unsigned crtpos, retpos, depth, len; … … 64 65 return NULL; 65 66 if (dst) 66 memcpy(dst + len, c + 1, *c); 67 /* \3com ---> "com." */ 68 ((char*)mempcpy(dst + len, c + 1, *c))[0] = '.'; 67 69 len += *c + 1; 68 70 crtpos += *c + 1; 69 if (dst)70 dst[len - 1] = '.';71 71 } else { 72 72 /* NUL: end of current domain name */ … … 79 79 retpos = depth = 0; 80 80 } 81 if (dst) 81 if (dst && len != 0) 82 /* \4host\3com\0\4host and we are at \0: 83 * \3com was converted to "com.", change dot to space. 84 */ 82 85 dst[len - 1] = ' '; 83 86 } … … 96 99 /* allocate dst buffer and copy pre */ 97 100 unsigned plen = strlen(pre); 98 ret = dst = xmalloc(plen + len); 99 memcpy(dst, pre, plen); 100 dst += plen; 101 ret = xmalloc(plen + len); 102 dst = stpcpy(ret, pre); 101 103 } else { 102 104 dst[len - 1] = '\0'; … … 229 231 uint8_t *encoded; 230 232 233 uint8_t str[6] = { 0x00, 0x00, 0x02, 0x65, 0x65, 0x00 }; 234 printf("NUL:'%s'\n", dname_dec(str, 6, "")); 235 231 236 #define DNAME_DEC(encoded,pre) dname_dec((uint8_t*)(encoded), sizeof(encoded), (pre)) 232 237 printf("'%s'\n", DNAME_DEC("\4host\3com\0", "test1:")); -
branches/3.3/mindi-busybox/networking/udhcp/dumpleases.c
r3232 r3621 5 5 6 6 //usage:#define dumpleases_trivial_usage 7 //usage: "[-r|-a] [- f LEASEFILE]"7 //usage: "[-r|-a] [-d] [-f LEASEFILE]" 8 8 //usage:#define dumpleases_full_usage "\n\n" 9 9 //usage: "Display DHCP leases granted by udhcpd\n" … … 12 12 //usage: "\n -r,--remaining Show remaining time" 13 13 //usage: "\n -a,--absolute Show expiration time" 14 //usage: "\n -d,--decimal Show time in seconds" 14 15 //usage: ) 15 16 //usage: IF_NOT_LONG_OPTS( … … 17 18 //usage: "\n -r Show remaining time" 18 19 //usage: "\n -a Show expiration time" 20 //usage: "\n -d Show time in seconds" 19 21 //usage: ) 20 22 … … 29 31 int i; 30 32 unsigned opt; 31 int64_t written_at, curr , expires_abs;33 int64_t written_at, curr; 32 34 const char *file = LEASES_FILE; 33 35 struct dyn_lease lease; 34 struct in_addr addr;35 36 36 37 enum { … … 38 39 OPT_r = 0x2, // -r 39 40 OPT_f = 0x4, // -f 41 OPT_d = 0x8, // -d 40 42 }; 41 43 #if ENABLE_LONG_OPTS … … 44 46 "remaining\0" No_argument "r" 45 47 "file\0" Required_argument "f" 48 "decimal\0" No_argument "d" 46 49 ; 47 50 … … 51 54 52 55 opt_complementary = "=0:a--r:r--a"; 53 opt = getopt32(argv, "arf: ", &file);56 opt = getopt32(argv, "arf:d", &file); 54 57 55 58 fd = xopen(file, O_RDONLY); 56 59 57 printf("Mac Address IP Address Host Name Expires %s\n", (opt & OPT_a) ? "at" : "in");60 /* "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 */ 58 61 /* "00:00:00:00:00:00 255.255.255.255 ABCDEFGHIJKLMNOPQRS Wed Jun 30 21:49:08 1993" */ 59 /* "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 */ 62 printf("Mac %-14s" "IP %-13s" "Host %-15s" "Expires %s\n", 63 "Address", "Address", "Name", 64 (opt & OPT_a) ? "at" : "in" 65 ); 60 66 61 67 xread(fd, &written_at, sizeof(written_at)); … … 66 72 67 73 while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { 74 struct in_addr addr; 75 int64_t expires_abs; 76 68 77 const char *fmt = ":%02x" + 1; 69 78 for (i = 0; i < 6; i++) { … … 88 97 continue; 89 98 } 99 if (opt & OPT_d) { 100 /* -d: decimal time */ 101 if (!(opt & OPT_a)) 102 expires_abs -= curr; 103 printf("%llu\n", (unsigned long long) expires_abs); 104 continue; 105 } 90 106 if (!(opt & OPT_a)) { /* no -a */ 91 107 unsigned d, h, m; -
branches/3.3/mindi-busybox/networking/udhcp/files.c
r3232 r3621 58 58 const char *keyword; 59 59 int (*handler)(const char *line, void *var) FAST_FUNC; 60 void *var;60 unsigned ofs; 61 61 const char *def; 62 62 }; 63 63 64 #define OFS(field) offsetof(struct server_config_t, field) 65 64 66 static const struct config_keyword keywords[] = { 65 67 /* keyword handler variable address default */ 66 {"start" , udhcp_str2nip , &server_config.start_ip, "192.168.0.20"},67 {"end" , udhcp_str2nip , &server_config.end_ip, "192.168.0.254"},68 {"interface" , read_str , &server_config.interface, "eth0"},68 {"start" , udhcp_str2nip , OFS(start_ip ), "192.168.0.20"}, 69 {"end" , udhcp_str2nip , OFS(end_ip ), "192.168.0.254"}, 70 {"interface" , read_str , OFS(interface ), "eth0"}, 69 71 /* Avoid "max_leases value not sane" warning by setting default 70 72 * to default_end_ip - default_start_ip + 1: */ 71 {"max_leases" , read_u32 , &server_config.max_leases, "235"},72 {"auto_time" , read_u32 , &server_config.auto_time, "7200"},73 {"decline_time" , read_u32 , &server_config.decline_time, "3600"},74 {"conflict_time", read_u32 , &server_config.conflict_time, "3600"},75 {"offer_time" , read_u32 , &server_config.offer_time, "60"},76 {"min_lease" , read_u32 , &server_config.min_lease_sec, "60"},77 {"lease_file" , read_str , &server_config.lease_file, LEASES_FILE},78 {"pidfile" , read_str , &server_config.pidfile, "/var/run/udhcpd.pid"},79 {"siaddr" , udhcp_str2nip , &server_config.siaddr_nip, "0.0.0.0"},73 {"max_leases" , read_u32 , OFS(max_leases ), "235"}, 74 {"auto_time" , read_u32 , OFS(auto_time ), "7200"}, 75 {"decline_time" , read_u32 , OFS(decline_time ), "3600"}, 76 {"conflict_time", read_u32 , OFS(conflict_time), "3600"}, 77 {"offer_time" , read_u32 , OFS(offer_time ), "60"}, 78 {"min_lease" , read_u32 , OFS(min_lease_sec), "60"}, 79 {"lease_file" , read_str , OFS(lease_file ), LEASES_FILE}, 80 {"pidfile" , read_str , OFS(pidfile ), "/var/run/udhcpd.pid"}, 81 {"siaddr" , udhcp_str2nip , OFS(siaddr_nip ), "0.0.0.0"}, 80 82 /* keywords with no defaults must be last! */ 81 {"option" , udhcp_str2optset, &server_config.options, ""},82 {"opt" , udhcp_str2optset, &server_config.options, ""},83 {"notify_file" , read_str , &server_config.notify_file, NULL},84 {"sname" , read_str , &server_config.sname, NULL},85 {"boot_file" , read_str , &server_config.boot_file, NULL},86 {"static_lease" , read_staticlease, &server_config.static_leases, ""},83 {"option" , udhcp_str2optset, OFS(options ), ""}, 84 {"opt" , udhcp_str2optset, OFS(options ), ""}, 85 {"notify_file" , read_str , OFS(notify_file ), NULL}, 86 {"sname" , read_str , OFS(sname ), NULL}, 87 {"boot_file" , read_str , OFS(boot_file ), NULL}, 88 {"static_lease" , read_staticlease, OFS(static_leases), ""}, 87 89 }; 88 90 enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 }; … … 96 98 97 99 for (i = 0; i < KWS_WITH_DEFAULTS; i++) 98 keywords[i].handler(keywords[i].def, keywords[i].var);100 keywords[i].handler(keywords[i].def, (char*)&server_config + keywords[i].ofs); 99 101 100 102 parser = config_open(file); … … 102 104 for (k = keywords, i = 0; i < ARRAY_SIZE(keywords); k++, i++) { 103 105 if (strcasecmp(token[0], k->keyword) == 0) { 104 if (!k->handler(token[1], k->var)) {106 if (!k->handler(token[1], (char*)&server_config + k->ofs)) { 105 107 bb_error_msg("can't parse line %u in %s", 106 108 parser->lineno, file); 107 109 /* reset back to the default value */ 108 k->handler(k->def, k->var);110 k->handler(k->def, (char*)&server_config + k->ofs); 109 111 } 110 112 break; … … 190 192 191 193 while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { 192 //FIXME: what if it matches some static lease?193 194 uint32_t y = ntohl(lease.lease_nip); 194 195 if (y >= server_config.start_ip && y <= server_config.end_ip) { 195 196 signed_leasetime_t expires = ntohl(lease.expires) - (signed_leasetime_t)time_passed; 197 uint32_t static_nip; 198 196 199 if (expires <= 0) 200 /* We keep expired leases: add_lease() will add 201 * a lease with 0 seconds remaining. 202 * Fewer IP address changes this way for mass reboot scenario. 203 */ 204 expires = 0; 205 206 /* Check if there is a different static lease for this IP or MAC */ 207 static_nip = get_static_nip_by_mac(server_config.static_leases, lease.lease_mac); 208 if (static_nip) { 209 /* NB: we do not add lease even if static_nip == lease.lease_nip. 210 */ 197 211 continue; 212 } 213 if (is_nip_reserved(server_config.static_leases, lease.lease_nip)) 214 continue; 215 198 216 /* NB: add_lease takes "relative time", IOW, 199 217 * lease duration, not lease deadline. */ … … 211 229 } 212 230 } 213 log1(" Read %d leases", i);231 log1("read %d leases", i); 214 232 ret: 215 233 close(fd); -
branches/3.3/mindi-busybox/networking/udhcp/leases.c
r3232 r3621 18 18 * and therefore can't ever match */ 19 19 for (i = 0; i < server_config.max_leases; i++) { 20 if (g_leases[i].expires < oldest_time) { 20 if (g_leases[i].expires == 0 /* empty entry */ 21 || g_leases[i].expires < oldest_time 22 ) { 21 23 oldest_time = g_leases[i].expires; 22 24 oldest_lease = &g_leases[i]; … … 66 68 hostname_len = sizeof(oldest->hostname); 67 69 p = safe_strncpy(oldest->hostname, hostname, hostname_len); 68 /* sanitization (s/non-ASCII/^/g) */ 70 /* 71 * Sanitization (s/bad_char/./g). 72 * The intent is not to allow only "DNS-valid" hostnames, 73 * but merely make dumpleases output safe for shells to use. 74 * We accept "0-9A-Za-z._-", all other chars turn to dots. 75 */ 69 76 while (*p) { 70 if ( *p < ' ' || *p > 126)71 *p = ' ^';77 if (!isalnum(*p) && *p != '-' && *p != '_') 78 *p = '.'; 72 79 p++; 73 80 } … … 113 120 114 121 /* Check if the IP is taken; if it is, add it to the lease table */ 115 static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac )122 static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac, unsigned arpping_ms) 116 123 { 117 124 struct in_addr temp; … … 121 128 server_config.server_nip, 122 129 server_config.server_mac, 123 server_config.interface); 130 server_config.interface, 131 arpping_ms); 124 132 if (r) 125 133 return r; 126 134 127 135 temp.s_addr = nip; 128 bb_ info_msg("%s belongs to someone, reserving it for %u seconds",136 bb_error_msg("%s belongs to someone, reserving it for %u seconds", 129 137 inet_ntoa(temp), (unsigned)server_config.conflict_time); 130 138 add_lease(NULL, nip, server_config.conflict_time, NULL, 0); … … 133 141 134 142 /* Find a new usable (we think) address */ 135 uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac )143 uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arpping_ms) 136 144 { 137 145 uint32_t addr; … … 178 186 if (!lease) { 179 187 //TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping! 180 if (nobody_responds_to_arp(nip, safe_mac ))188 if (nobody_responds_to_arp(nip, safe_mac, arpping_ms)) 181 189 return nip; 182 190 } else { … … 195 203 if (oldest_lease 196 204 && is_expired_lease(oldest_lease) 197 && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac )205 && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac, arpping_ms) 198 206 ) { 199 207 return oldest_lease->lease_nip; -
branches/3.3/mindi-busybox/networking/udhcp/packet.c
r3232 r3621 39 39 return; 40 40 41 bb_ info_msg(42 //" 41 bb_error_msg( 42 //"op %x" 43 43 //" htype %x" 44 44 " hlen %x" … … 74 74 ); 75 75 *bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0'; 76 bb_ info_msg("chaddr %s", buf);76 bb_error_msg("chaddr %s", buf); 77 77 } 78 78 #endif … … 86 86 bytes = safe_read(fd, packet, sizeof(*packet)); 87 87 if (bytes < 0) { 88 log1(" Packet read error, ignoring");88 log1("packet read error, ignoring"); 89 89 return bytes; /* returns -1 */ 90 90 } … … 93 93 || packet->cookie != htonl(DHCP_MAGIC) 94 94 ) { 95 bb_ info_msg("Packet with bad magic, ignoring");95 bb_error_msg("packet with bad magic, ignoring"); 96 96 return -2; 97 97 } 98 log1(" Receiveda packet");98 log1("received %s", "a packet"); 99 99 udhcp_dump_packet(packet); 100 100 … … 144 144 * In order to work with those buggy servers, 145 145 * we truncate packets after end option byte. 146 * 147 * However, RFC 1542 says "The IP Total Length and UDP Length 148 * must be large enough to contain the minimal BOOTP header of 300 octets". 149 * Thus, we retain enough padding to not go below 300 BOOTP bytes. 150 * Some devices have filters which drop DHCP packets shorter than that. 146 151 */ 147 152 padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(packet.data.options); 153 if (padding > DHCP_SIZE - 300) 154 padding = DHCP_SIZE - 300; 148 155 149 156 packet.ip.protocol = IPPROTO_UDP; … … 216 223 udhcp_dump_packet(dhcp_pkt); 217 224 padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(dhcp_pkt->options); 225 if (padding > DHCP_SIZE - 300) 226 padding = DHCP_SIZE - 300; 218 227 result = safe_write(fd, dhcp_pkt, DHCP_SIZE - padding); 219 228 msg = "write"; -
branches/3.3/mindi-busybox/networking/udhcp/socket.c
r3232 r3621 57 57 return -1; 58 58 } 59 log1(" Adapter index %d", ifr->ifr_ifindex);59 log1("adapter index %d", ifr->ifr_ifindex); 60 60 *ifindex = ifr->ifr_ifindex; 61 61 } … … 83 83 char *colon; 84 84 85 log1(" Opening listen socket on *:%d %s", port, inf);85 log1("opening listen socket on *:%d %s", port, inf); 86 86 fd = xsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 87 87 -
branches/3.3/mindi-busybox/networking/udhcp/static_leases.c
r2725 r3621 67 67 cur = *st_lease_pp; 68 68 while (cur) { 69 bb_ info_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x",69 bb_error_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x", 70 70 cur->mac[0], cur->mac[1], cur->mac[2], 71 71 cur->mac[3], cur->mac[4], cur->mac[5], -
branches/3.3/mindi-busybox/networking/wget.c
r3232 r3621 10 10 */ 11 11 12 //config:config WGET 13 //config: bool "wget" 14 //config: default y 15 //config: help 16 //config: wget is a utility for non-interactive download of files from HTTP 17 //config: and FTP servers. 18 //config: 19 //config:config FEATURE_WGET_STATUSBAR 20 //config: bool "Enable a nifty process meter (+2k)" 21 //config: default y 22 //config: depends on WGET 23 //config: help 24 //config: Enable the transfer progress bar for wget transfers. 25 //config: 26 //config:config FEATURE_WGET_AUTHENTICATION 27 //config: bool "Enable HTTP authentication" 28 //config: default y 29 //config: depends on WGET 30 //config: help 31 //config: Support authenticated HTTP transfers. 32 //config: 33 //config:config FEATURE_WGET_LONG_OPTIONS 34 //config: bool "Enable long options" 35 //config: default y 36 //config: depends on WGET && LONG_OPTS 37 //config: help 38 //config: Support long options for the wget applet. 39 //config: 40 //config:config FEATURE_WGET_TIMEOUT 41 //config: bool "Enable timeout option -T SEC" 42 //config: default y 43 //config: depends on WGET 44 //config: help 45 //config: Supports network read and connect timeouts for wget, 46 //config: so that wget will give up and timeout, through the -T 47 //config: command line option. 48 //config: 49 //config: Currently only connect and network data read timeout are 50 //config: supported (i.e., timeout is not applied to the DNS query). When 51 //config: FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option 52 //config: will work in addition to -T. 53 //config: 54 //config:config FEATURE_WGET_OPENSSL 55 //config: bool "Try to connect to HTTPS using openssl" 56 //config: default y 57 //config: depends on WGET 58 //config: help 59 //config: Choose how wget establishes SSL connection for https:// URLs. 60 //config: 61 //config: Busybox itself contains no SSL code. wget will spawn 62 //config: a helper program to talk over HTTPS. 63 //config: 64 //config: OpenSSL has a simple SSL client for debug purposes. 65 //config: If you select "openssl" helper, wget will effectively call 66 //config: "openssl s_client -quiet -connect IP:443 2>/dev/null" 67 //config: and pipe its data through it. 68 //config: Note inconvenient API: host resolution is done twice, 69 //config: and there is no guarantee openssl's idea of IPv6 address 70 //config: format is the same as ours. 71 //config: Another problem is that s_client prints debug information 72 //config: to stderr, and it needs to be suppressed. This means 73 //config: all error messages get suppressed too. 74 //config: openssl is also a big binary, often dynamically linked 75 //config: against ~15 libraries. 76 //config: 77 //config:config FEATURE_WGET_SSL_HELPER 78 //config: bool "Try to connect to HTTPS using ssl_helper" 79 //config: default y 80 //config: depends on WGET 81 //config: help 82 //config: Choose how wget establishes SSL connection for https:// URLs. 83 //config: 84 //config: Busybox itself contains no SSL code. wget will spawn 85 //config: a helper program to talk over HTTPS. 86 //config: 87 //config: ssl_helper is a tool which can be built statically 88 //config: from busybox sources against a small embedded SSL library. 89 //config: Please see networking/ssl_helper/README. 90 //config: It does not require double host resolution and emits 91 //config: error messages to stderr. 92 //config: 93 //config: Precompiled static binary may be available at 94 //config: http://busybox.net/downloads/binaries/ 95 96 //applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) 97 98 //kbuild:lib-$(CONFIG_WGET) += wget.o 99 12 100 //usage:#define wget_trivial_usage 13 101 //usage: IF_FEATURE_WGET_LONG_OPTIONS( … … 15 103 //usage: " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" 16 104 /* Since we ignore these opts, we don't show them in --help */ 17 /* //usage: " [--no-check-certificate] [--no-cache]" */ 105 /* //usage: " [--no-check-certificate] [--no-cache] [--passive-ftp] [-t TRIES]" */ 106 /* //usage: " [-nv] [-nc] [-nH] [-np]" */ 18 107 //usage: " [-U|--user-agent AGENT]" IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." 19 108 //usage: ) … … 39 128 #if 0 40 129 # define log_io(...) bb_error_msg(__VA_ARGS__) 130 # define SENDFMT(fp, fmt, ...) \ 131 do { \ 132 log_io("> " fmt, ##__VA_ARGS__); \ 133 fprintf(fp, fmt, ##__VA_ARGS__); \ 134 } while (0); 41 135 #else 42 136 # define log_io(...) ((void)0) 137 # define SENDFMT(fp, fmt, ...) fprintf(fp, fmt, ##__VA_ARGS__) 43 138 #endif 44 139 … … 47 142 char *allocated; 48 143 const char *path; 49 const char *user; 144 char *user; 145 const char *protocol; 50 146 char *host; 51 147 int port; 52 smallint is_ftp;53 148 }; 54 149 static const char P_FTP[] ALIGN1 = "ftp"; 150 static const char P_HTTP[] ALIGN1 = "http"; 151 #if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER 152 static const char P_HTTPS[] ALIGN1 = "https"; 153 #endif 154 155 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 156 /* User-specified headers prevent using our corresponding built-in headers. */ 157 enum { 158 HDR_HOST = (1<<0), 159 HDR_USER_AGENT = (1<<1), 160 HDR_RANGE = (1<<2), 161 HDR_AUTH = (1<<3) * ENABLE_FEATURE_WGET_AUTHENTICATION, 162 HDR_PROXY_AUTH = (1<<4) * ENABLE_FEATURE_WGET_AUTHENTICATION, 163 }; 164 static const char wget_user_headers[] ALIGN1 = 165 "Host:\0" 166 "User-Agent:\0" 167 "Range:\0" 168 # if ENABLE_FEATURE_WGET_AUTHENTICATION 169 "Authorization:\0" 170 "Proxy-Authorization:\0" 171 # endif 172 ; 173 # define USR_HEADER_HOST (G.user_headers & HDR_HOST) 174 # define USR_HEADER_USER_AGENT (G.user_headers & HDR_USER_AGENT) 175 # define USR_HEADER_RANGE (G.user_headers & HDR_RANGE) 176 # define USR_HEADER_AUTH (G.user_headers & HDR_AUTH) 177 # define USR_HEADER_PROXY_AUTH (G.user_headers & HDR_PROXY_AUTH) 178 #else /* No long options, no user-headers :( */ 179 # define USR_HEADER_HOST 0 180 # define USR_HEADER_USER_AGENT 0 181 # define USR_HEADER_RANGE 0 182 # define USR_HEADER_AUTH 0 183 # define USR_HEADER_PROXY_AUTH 0 184 #endif 55 185 56 186 /* Globals */ … … 63 193 bb_progress_t pmt; 64 194 #endif 65 195 char *dir_prefix; 66 196 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 67 char *post_data; 68 char *extra_headers; 69 #endif 70 char *fname_out; /* where to direct output (-O) */ 71 const char *proxy_flag; /* Use proxies if env vars are set */ 72 const char *user_agent; /* "User-Agent" header field */ 197 char *post_data; 198 char *extra_headers; 199 unsigned char user_headers; /* Headers mentioned by the user */ 200 #endif 201 char *fname_out; /* where to direct output (-O) */ 202 const char *proxy_flag; /* Use proxies if env vars are set */ 203 const char *user_agent; /* "User-Agent" header field */ 73 204 #if ENABLE_FEATURE_WGET_TIMEOUT 74 205 unsigned timeout_seconds; 206 bool die_if_timed_out; 75 207 #endif 76 208 int output_fd; … … 87 219 #define G (*ptr_to_globals) 88 220 #define INIT_G() do { \ 89 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 90 IF_FEATURE_WGET_TIMEOUT(G.timeout_seconds = 900;) \ 221 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 222 } while (0) 223 #define FINI_G() do { \ 224 FREE_PTR_TO_GLOBALS(); \ 91 225 } while (0) 92 226 … … 196 330 } 197 331 332 #if ENABLE_FEATURE_WGET_TIMEOUT 333 static void alarm_handler(int sig UNUSED_PARAM) 334 { 335 /* This is theoretically unsafe (uses stdio and malloc in signal handler) */ 336 if (G.die_if_timed_out) 337 bb_error_msg_and_die("download timed out"); 338 } 339 static void set_alarm(void) 340 { 341 if (G.timeout_seconds) { 342 alarm(G.timeout_seconds); 343 G.die_if_timed_out = 1; 344 } 345 } 346 # define clear_alarm() ((void)(G.die_if_timed_out = 0)) 347 #else 348 # define set_alarm() ((void)0) 349 # define clear_alarm() ((void)0) 350 #endif 351 198 352 static FILE *open_socket(len_and_sockaddr *lsa) 199 353 { 354 int fd; 200 355 FILE *fp; 356 357 set_alarm(); 358 fd = xconnect_stream(lsa); 359 clear_alarm(); 201 360 202 361 /* glibc 2.4 seems to try seeking on it - ??! */ 203 362 /* hopefully it understands what ESPIPE means... */ 204 fp = fdopen( xconnect_stream(lsa), "r+");205 if ( fp == NULL)363 fp = fdopen(fd, "r+"); 364 if (!fp) 206 365 bb_perror_msg_and_die(bb_msg_memory_exhausted); 207 366 … … 215 374 char *buf_ptr; 216 375 376 set_alarm(); 217 377 if (fgets(G.wget_buf, sizeof(G.wget_buf) - 1, fp) == NULL) 218 378 bb_perror_msg_and_die("error getting response"); 379 clear_alarm(); 219 380 220 381 buf_ptr = strchrnul(G.wget_buf, '\n'); … … 257 418 h->allocated = url = xstrdup(src_url); 258 419 259 if (strncmp(url, "http://", 7) == 0) { 260 h->port = bb_lookup_port("http", "tcp", 80); 261 h->host = url + 7; 262 h->is_ftp = 0; 263 } else if (strncmp(url, "ftp://", 6) == 0) { 264 h->port = bb_lookup_port("ftp", "tcp", 21); 265 h->host = url + 6; 266 h->is_ftp = 1; 267 } else 268 bb_error_msg_and_die("not an http or ftp url: %s", sanitize_string(url)); 420 h->protocol = P_FTP; 421 p = strstr(url, "://"); 422 if (p) { 423 *p = '\0'; 424 h->host = p + 3; 425 if (strcmp(url, P_FTP) == 0) { 426 h->port = bb_lookup_port(P_FTP, "tcp", 21); 427 } else 428 #if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER 429 if (strcmp(url, P_HTTPS) == 0) { 430 h->port = bb_lookup_port(P_HTTPS, "tcp", 443); 431 h->protocol = P_HTTPS; 432 } else 433 #endif 434 if (strcmp(url, P_HTTP) == 0) { 435 http: 436 h->port = bb_lookup_port(P_HTTP, "tcp", 80); 437 h->protocol = P_HTTP; 438 } else { 439 *p = ':'; 440 bb_error_msg_and_die("not an http or ftp url: %s", sanitize_string(url)); 441 } 442 } else { 443 // GNU wget is user-friendly and falls back to http:// 444 h->host = url; 445 goto http; 446 } 269 447 270 448 // FYI: … … 298 476 } 299 477 300 // We used to set h->user to NULL here, but this interferes301 // with handling of code 302 ("object was moved")302 303 478 sp = strrchr(h->host, '@'); 304 479 if (sp != NULL) { … … 309 484 // Standard wget and curl do this too. 310 485 *sp = '\0'; 311 h->user = percent_decode_in_place(h->host, /*strict:*/ 0); 486 free(h->user); 487 h->user = xstrdup(percent_decode_in_place(h->host, /*strict:*/ 0)); 312 488 h->host = sp + 1; 313 489 } 314 315 sp = h->host; 490 /* else: h->user remains NULL, or as set by original request 491 * before redirect (if we are here after a redirect). 492 */ 316 493 } 317 494 … … 329 506 330 507 /* convert the header name to lower case */ 331 for (s = G.wget_buf; isalnum(*s) || *s == '-' || *s == '.'; ++s) { 332 /* tolower for "A-Z", no-op for "0-9a-z-." */ 508 for (s = G.wget_buf; isalnum(*s) || *s == '-' || *s == '.' || *s == '_'; ++s) { 509 /* 510 * No-op for 20-3f and 60-7f. "0-9a-z-." are in these ranges. 511 * 40-5f range ("@A-Z[\]^_") maps to 60-7f. 512 * "A-Z" maps to "a-z". 513 * "@[\]" can't occur in header names. 514 * "^_" maps to "~,DEL" (which is wrong). 515 * "^" was never seen yet, "_" was seen from web.archive.org 516 * (x-archive-orig-x_commoncrawl_Signature: HEXSTRING). 517 */ 333 518 *s |= 0x20; 334 519 } … … 441 626 } 442 627 628 #if ENABLE_FEATURE_WGET_OPENSSL 629 static int spawn_https_helper_openssl(const char *host, unsigned port) 630 { 631 char *allocated = NULL; 632 int sp[2]; 633 int pid; 634 IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;) 635 636 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) 637 /* Kernel can have AF_UNIX support disabled */ 638 bb_perror_msg_and_die("socketpair"); 639 640 if (!strchr(host, ':')) 641 host = allocated = xasprintf("%s:%u", host, port); 642 643 fflush_all(); 644 pid = xvfork(); 645 if (pid == 0) { 646 /* Child */ 647 char *argv[6]; 648 649 close(sp[0]); 650 xmove_fd(sp[1], 0); 651 xdup2(0, 1); 652 /* 653 * openssl s_client -quiet -connect www.kernel.org:443 2>/dev/null 654 * It prints some debug stuff on stderr, don't know how to suppress it. 655 * Work around by dev-nulling stderr. We lose all error messages :( 656 */ 657 xmove_fd(2, 3); 658 xopen("/dev/null", O_RDWR); 659 argv[0] = (char*)"openssl"; 660 argv[1] = (char*)"s_client"; 661 argv[2] = (char*)"-quiet"; 662 argv[3] = (char*)"-connect"; 663 argv[4] = (char*)host; 664 argv[5] = NULL; 665 BB_EXECVP(argv[0], argv); 666 xmove_fd(3, 2); 667 # if ENABLE_FEATURE_WGET_SSL_HELPER 668 child_failed = 1; 669 xfunc_die(); 670 # else 671 bb_perror_msg_and_die("can't execute '%s'", argv[0]); 672 # endif 673 /* notreached */ 674 } 675 676 /* Parent */ 677 free(allocated); 678 close(sp[1]); 679 # if ENABLE_FEATURE_WGET_SSL_HELPER 680 if (child_failed) { 681 close(sp[0]); 682 return -1; 683 } 684 # endif 685 return sp[0]; 686 } 687 #endif 688 689 /* See networking/ssl_helper/README how to build one */ 690 #if ENABLE_FEATURE_WGET_SSL_HELPER 691 static void spawn_https_helper_small(int network_fd) 692 { 693 int sp[2]; 694 int pid; 695 696 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) 697 /* Kernel can have AF_UNIX support disabled */ 698 bb_perror_msg_and_die("socketpair"); 699 700 pid = BB_MMU ? xfork() : xvfork(); 701 if (pid == 0) { 702 /* Child */ 703 char *argv[3]; 704 705 close(sp[0]); 706 xmove_fd(sp[1], 0); 707 xdup2(0, 1); 708 xmove_fd(network_fd, 3); 709 /* 710 * A simple ssl/tls helper 711 */ 712 argv[0] = (char*)"ssl_helper"; 713 argv[1] = (char*)"-d3"; 714 argv[2] = NULL; 715 BB_EXECVP(argv[0], argv); 716 bb_perror_msg_and_die("can't execute '%s'", argv[0]); 717 /* notreached */ 718 } 719 720 /* Parent */ 721 close(sp[1]); 722 xmove_fd(sp[0], network_fd); 723 } 724 #endif 725 443 726 static void NOINLINE retrieve_file_data(FILE *dfp) 444 727 { … … 509 792 second_cnt = G.timeout_seconds; 510 793 #endif 511 continue;794 goto bump; 512 795 } 513 796 … … 542 825 */ 543 826 } 827 #endif 828 bump: 544 829 /* Need to do it _every_ second for "stalled" indicator 545 830 * to be shown properly. 546 831 */ 547 832 progress_meter(PROGRESS_BUMP); 548 #endif549 833 } /* while (reading data) */ 550 834 … … 613 897 use_proxy = (strcmp(G.proxy_flag, "off") != 0); 614 898 if (use_proxy) { 615 proxy = getenv(target.is_ftp ? "ftp_proxy" : "http_proxy"); 899 proxy = getenv(target.protocol == P_FTP ? "ftp_proxy" : "http_proxy"); 900 //FIXME: what if protocol is https? Ok to use http_proxy? 616 901 use_proxy = (proxy && proxy[0]); 617 902 if (use_proxy) … … 673 958 G.got_clen = 0; 674 959 G.chunked = 0; 675 if (use_proxy || !target.is_ftp) {960 if (use_proxy || target.protocol != P_FTP) { 676 961 /* 677 962 * HTTP session … … 680 965 int status; 681 966 682 683 /* Open socket to http server */ 967 /* Open socket to http(s) server */ 968 #if ENABLE_FEATURE_WGET_OPENSSL 969 /* openssl (and maybe ssl_helper) support is configured */ 970 if (target.protocol == P_HTTPS) { 971 /* openssl-based helper 972 * Inconvenient API since we can't give it an open fd 973 */ 974 int fd = spawn_https_helper_openssl(server.host, server.port); 975 # if ENABLE_FEATURE_WGET_SSL_HELPER 976 if (fd < 0) { /* no openssl? try ssl_helper */ 977 sfp = open_socket(lsa); 978 spawn_https_helper_small(fileno(sfp)); 979 goto socket_opened; 980 } 981 # else 982 /* We don't check for exec("openssl") failure in this case */ 983 # endif 984 sfp = fdopen(fd, "r+"); 985 if (!sfp) 986 bb_perror_msg_and_die(bb_msg_memory_exhausted); 987 goto socket_opened; 988 } 684 989 sfp = open_socket(lsa); 685 990 socket_opened: 991 #elif ENABLE_FEATURE_WGET_SSL_HELPER 992 /* Only ssl_helper support is configured */ 993 sfp = open_socket(lsa); 994 if (target.protocol == P_HTTPS) 995 spawn_https_helper_small(fileno(sfp)); 996 #else 997 /* ssl (https) support is not configured */ 998 sfp = open_socket(lsa); 999 #endif 686 1000 /* Send HTTP request */ 687 1001 if (use_proxy) { 688 fprintf(sfp, "GET %stp://%s/%s HTTP/1.1\r\n",689 target. is_ftp ? "f" : "ht", target.host,1002 SENDFMT(sfp, "GET %s://%s/%s HTTP/1.1\r\n", 1003 target.protocol, target.host, 690 1004 target.path); 691 1005 } else { 692 if (option_mask32 & WGET_OPT_POST_DATA)693 fprintf(sfp, "POST /%s HTTP/1.1\r\n", target.path);694 else695 fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path);696 }697 698 fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n",699 target.host, G.user_agent);1006 SENDFMT(sfp, "%s /%s HTTP/1.1\r\n", 1007 (option_mask32 & WGET_OPT_POST_DATA) ? "POST" : "GET", 1008 target.path); 1009 } 1010 if (!USR_HEADER_HOST) 1011 SENDFMT(sfp, "Host: %s\r\n", target.host); 1012 if (!USR_HEADER_USER_AGENT) 1013 SENDFMT(sfp, "User-Agent: %s\r\n", G.user_agent); 700 1014 701 1015 /* Ask server to close the connection as soon as we are done 702 1016 * (IOW: we do not intend to send more requests) 703 1017 */ 704 fprintf(sfp, "Connection: close\r\n");1018 SENDFMT(sfp, "Connection: close\r\n"); 705 1019 706 1020 #if ENABLE_FEATURE_WGET_AUTHENTICATION 707 if (target.user ) {708 fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6,1021 if (target.user && !USR_HEADER_AUTH) { 1022 SENDFMT(sfp, "Proxy-Authorization: Basic %s\r\n"+6, 709 1023 base64enc(target.user)); 710 1024 } 711 if (use_proxy && server.user ) {712 fprintf(sfp, "Proxy-Authorization: Basic %s\r\n",1025 if (use_proxy && server.user && !USR_HEADER_PROXY_AUTH) { 1026 SENDFMT(sfp, "Proxy-Authorization: Basic %s\r\n", 713 1027 base64enc(server.user)); 714 1028 } 715 1029 #endif 716 1030 717 if (G.beg_range != 0 )718 fprintf(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range);1031 if (G.beg_range != 0 && !USR_HEADER_RANGE) 1032 SENDFMT(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range); 719 1033 720 1034 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 721 if (G.extra_headers) 1035 if (G.extra_headers) { 1036 log_io(G.extra_headers); 722 1037 fputs(G.extra_headers, sfp); 1038 } 723 1039 724 1040 if (option_mask32 & WGET_OPT_POST_DATA) { 725 fprintf(sfp,1041 SENDFMT(sfp, 726 1042 "Content-Type: application/x-www-form-urlencoded\r\n" 727 1043 "Content-Length: %u\r\n" … … 733 1049 #endif 734 1050 { 735 fprintf(sfp, "\r\n");1051 SENDFMT(sfp, "\r\n"); 736 1052 } 737 1053 … … 848 1164 parse_url(str, &target); 849 1165 if (!use_proxy) { 1166 /* server.user remains untouched */ 850 1167 free(server.allocated); 851 1168 server.allocated = NULL; … … 866 1183 /* For HTTP, data is pumped over the same connection */ 867 1184 dfp = sfp; 868 869 1185 } else { 870 1186 /* … … 897 1213 free(server.allocated); 898 1214 free(target.allocated); 1215 free(server.user); 1216 free(target.user); 899 1217 free(fname_out_alloc); 900 1218 free(redirected_path); … … 915 1233 "proxy\0" Required_argument "Y" 916 1234 "user-agent\0" Required_argument "U" 917 #if ENABLE_FEATURE_WGET_TIMEOUT 918 "timeout\0" Required_argument "T" 919 #endif 1235 IF_FEATURE_WGET_TIMEOUT( 1236 "timeout\0" Required_argument "T") 920 1237 /* Ignored: */ 921 // "tries\0" Required_argument "t" 1238 IF_DESKTOP( "tries\0" Required_argument "t") 1239 "header\0" Required_argument "\xff" 1240 "post-data\0" Required_argument "\xfe" 922 1241 /* Ignored (we always use PASV): */ 923 "passive-ftp\0" No_argument "\xff" 924 "header\0" Required_argument "\xfe" 925 "post-data\0" Required_argument "\xfd" 1242 IF_DESKTOP( "passive-ftp\0" No_argument "\xf0") 926 1243 /* Ignored (we don't do ssl) */ 927 "no-check-certificate\0" No_argument "\xfc" 1244 IF_DESKTOP( "no-check-certificate\0" No_argument "\xf0") 928 1245 /* Ignored (we don't support caching) */ 929 "no-cache\0" No_argument "\xfb" 1246 IF_DESKTOP( "no-cache\0" No_argument "\xf0") 1247 IF_DESKTOP( "no-verbose\0" No_argument "\xf0") 1248 IF_DESKTOP( "no-clobber\0" No_argument "\xf0") 1249 IF_DESKTOP( "no-host-directories\0" No_argument "\xf0") 1250 IF_DESKTOP( "no-parent\0" No_argument "\xf0") 930 1251 ; 931 1252 #endif … … 937 1258 INIT_G(); 938 1259 939 IF_FEATURE_WGET_TIMEOUT(G.timeout_seconds = 900;) 1260 #if ENABLE_FEATURE_WGET_TIMEOUT 1261 G.timeout_seconds = 900; 1262 signal(SIGALRM, alarm_handler); 1263 #endif 940 1264 G.proxy_flag = "on"; /* use proxies if env vars are set */ 941 1265 G.user_agent = "Wget"; /* "User-Agent" header field */ … … 944 1268 applet_long_options = wget_longopts; 945 1269 #endif 946 opt_complementary = "-1" IF_FEATURE_WGET_TIMEOUT(":T+") IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); 947 getopt32(argv, "csqO:P:Y:U:T:" /*ignored:*/ "t:", 948 &G.fname_out, &G.dir_prefix, 1270 opt_complementary = "-1" /* at least one URL */ 1271 IF_FEATURE_WGET_TIMEOUT(":T+") /* -T NUM */ 1272 IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */ 1273 getopt32(argv, "csqO:P:Y:U:T:" 1274 /*ignored:*/ "t:" 1275 /*ignored:*/ "n::" 1276 /* wget has exactly four -n<letter> opts, all of which we can ignore: 1277 * -nv --no-verbose: be moderately quiet (-q is full quiet) 1278 * -nc --no-clobber: abort if exists, neither download to FILE.n nor overwrite FILE 1279 * -nH --no-host-directories: wget -r http://host/ won't create host/ 1280 * -np --no-parent 1281 * "n::" above says that we accept -n[ARG]. 1282 * Specifying "n:" would be a bug: "-n ARG" would eat ARG! 1283 */ 1284 , &G.fname_out, &G.dir_prefix, 949 1285 &G.proxy_flag, &G.user_agent, 950 1286 IF_FEATURE_WGET_TIMEOUT(&G.timeout_seconds) IF_NOT_FEATURE_WGET_TIMEOUT(NULL), 951 NULL /* -t RETRIES */ 1287 NULL, /* -t RETRIES */ 1288 NULL /* -n[ARG] */ 952 1289 IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) 953 1290 IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data) … … 957 1294 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 958 1295 if (headers_llist) { 959 int size = 1;960 char * cp;1296 int size = 0; 1297 char *hdr; 961 1298 llist_t *ll = headers_llist; 962 1299 while (ll) { … … 964 1301 ll = ll->link; 965 1302 } 966 G.extra_headers = cp = xmalloc(size);1303 G.extra_headers = hdr = xmalloc(size + 1); 967 1304 while (headers_llist) { 968 cp += sprintf(cp, "%s\r\n", (char*)llist_pop(&headers_llist)); 1305 int bit; 1306 const char *words; 1307 1308 size = sprintf(hdr, "%s\r\n", 1309 (char*)llist_pop(&headers_llist)); 1310 /* a bit like index_in_substrings but don't match full key */ 1311 bit = 1; 1312 words = wget_user_headers; 1313 while (*words) { 1314 if (strstr(hdr, words) == hdr) { 1315 G.user_headers |= bit; 1316 break; 1317 } 1318 bit <<= 1; 1319 words += strlen(words) + 1; 1320 } 1321 hdr += size; 969 1322 } 970 1323 } … … 988 1341 xclose(G.output_fd); 989 1342 1343 #if ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_WGET_LONG_OPTIONS 1344 free(G.extra_headers); 1345 #endif 1346 FINI_G(); 1347 990 1348 return EXIT_SUCCESS; 991 1349 } -
branches/3.3/mindi-busybox/networking/zcip.c
r3232 r3621 31 31 //usage: "\n -q Quit after obtaining address" 32 32 //usage: "\n -r 169.254.x.x Request this address first" 33 //usage: "\n -l x.x.0.0 Use this range instead of 169.254" 33 34 //usage: "\n -v Verbose" 35 //usage: "\n" 36 //usage: "\n$LOGGING=none Suppress logging" 37 //usage: "\n$LOGGING=syslog Log to syslog" 34 38 //usage: "\n" 35 39 //usage: "\nWith no -q, runs continuously monitoring for ARP conflicts," … … 37 41 38 42 #include "libbb.h" 43 #include "common_bufsiz.h" 39 44 #include <netinet/ether.h> 40 45 #include <net/if.h> … … 53 58 54 59 enum { 55 /* 169.254.0.0 */ 56 LINKLOCAL_ADDR = 0xa9fe0000, 57 58 /* protocol timeout parameters, specified in seconds */ 60 /* 0-1 seconds before sending 1st probe */ 59 61 PROBE_WAIT = 1, 62 /* 1-2 seconds between probes */ 60 63 PROBE_MIN = 1, 61 64 PROBE_MAX = 2, 62 PROBE_NUM = 3, 63 MAX_CONFLICTS = 10,64 RATE_LIMIT_INTERVAL = 60,65 ANNOUNCE_WAIT = 2,66 ANNOUNCE_NUM= 2,67 ANNOUNCE_INTERVAL = 2,68 DEFEND_INTERVAL = 10 65 PROBE_NUM = 3, /* total probes to send */ 66 ANNOUNCE_INTERVAL = 2, /* 2 seconds between announces */ 67 ANNOUNCE_NUM = 3, /* announces to send */ 68 /* if probe/announce sees a conflict, multiply RANDOM(NUM_CONFLICT) by... */ 69 CONFLICT_MULTIPLIER = 2, 70 /* if we monitor and see a conflict, how long is defend state? */ 71 DEFEND_INTERVAL = 10, 69 72 }; 70 73 … … 72 75 enum { 73 76 PROBE = 0, 74 RATE_LIMIT_PROBE,75 77 ANNOUNCE, 76 78 MONITOR, … … 86 88 87 89 struct globals { 88 struct sockaddr saddr; 89 struct ether_addr eth_addr; 90 struct sockaddr iface_sockaddr; 91 struct ether_addr our_ethaddr; 92 uint32_t localnet_ip; 90 93 } FIX_ALIASING; 91 #define G (*(struct globals*)&bb_common_bufsiz1) 92 #define saddr (G.saddr ) 93 #define eth_addr (G.eth_addr) 94 #define INIT_G() do { } while (0) 94 #define G (*(struct globals*)bb_common_bufsiz1) 95 #define INIT_G() do { setup_common_bufsiz(); } while (0) 95 96 96 97 … … 99 100 * the first and last 256 addresses are reserved. 100 101 */ 101 static uint32_t pick (void)102 static uint32_t pick_nip(void) 102 103 { 103 104 unsigned tmp; … … 106 107 tmp = rand() & IN_CLASSB_HOST; 107 108 } while (tmp > (IN_CLASSB_HOST - 0x0200)); 108 return htonl((LINKLOCAL_ADDR + 0x0100) + tmp); 109 return htonl((G.localnet_ip + 0x0100) + tmp); 110 } 111 112 static const char *nip_to_a(uint32_t nip) 113 { 114 struct in_addr in; 115 in.s_addr = nip; 116 return inet_ntoa(in); 109 117 } 110 118 … … 112 120 * Broadcast an ARP packet. 113 121 */ 114 static void arp(122 static void send_arp_request( 115 123 /* int op, - always ARPOP_REQUEST */ 116 /* const struct ether_addr *source_eth, - always & eth_addr */117 struct in_addr source_ip,118 const struct ether_addr *target_eth, struct in_addr target_ip)124 /* const struct ether_addr *source_eth, - always &G.our_ethaddr */ 125 uint32_t source_nip, 126 const struct ether_addr *target_eth, uint32_t target_nip) 119 127 { 120 128 enum { op = ARPOP_REQUEST }; 121 #define source_eth (& eth_addr)129 #define source_eth (&G.our_ethaddr) 122 130 123 131 struct arp_packet p; … … 136 144 p.arp.arp_op = htons(op); 137 145 memcpy(&p.arp.arp_sha, source_eth, ETH_ALEN); 138 memcpy(&p.arp.arp_spa, &source_ ip, sizeof(p.arp.arp_spa));146 memcpy(&p.arp.arp_spa, &source_nip, 4); 139 147 memcpy(&p.arp.arp_tha, target_eth, ETH_ALEN); 140 memcpy(&p.arp.arp_tpa, &target_ ip, sizeof(p.arp.arp_tpa));148 memcpy(&p.arp.arp_tpa, &target_nip, 4); 141 149 142 150 // send it 143 // Even though sock_fd is already bound to saddr, just send()151 // Even though sock_fd is already bound to G.iface_sockaddr, just send() 144 152 // won't work, because "socket is not connected" 145 153 // (and connect() won't fix that, "operation not supported"). 146 // Thus we sendto() to saddr. I wonder which sockaddr154 // Thus we sendto() to G.iface_sockaddr. I wonder which sockaddr 147 155 // (from bind() or from sendto()?) kernel actually uses 148 156 // to determine iface to emit the packet from... 149 xsendto(sock_fd, &p, sizeof(p), & saddr, sizeof(saddr));157 xsendto(sock_fd, &p, sizeof(p), &G.iface_sockaddr, sizeof(G.iface_sockaddr)); 150 158 #undef source_eth 151 159 } … … 155 163 * argv[0]:intf argv[1]:script_name argv[2]:junk argv[3]:NULL 156 164 */ 157 static int run(char *argv[3], const char *param, struct in_addr *ip)165 static int run(char *argv[3], const char *param, uint32_t nip) 158 166 { 159 167 int status; 160 c har *addr = addr; /* for gcc */168 const char *addr = addr; /* for gcc */ 161 169 const char *fmt = "%s %s %s" + 3; 162 170 … … 165 173 VDBG("%s run %s %s\n", argv[0], argv[1], argv[2]); 166 174 167 if ( ip) {168 addr = inet_ntoa(*ip);175 if (nip != 0) { 176 addr = nip_to_a(nip); 169 177 xsetenv("ip", addr); 170 178 fmt -= 3; 171 179 } 172 bb_ info_msg(fmt, argv[2], argv[0], addr);180 bb_error_msg(fmt, argv[2], argv[0], addr); 173 181 174 182 status = spawn_and_wait(argv + 1); … … 187 195 static ALWAYS_INLINE unsigned random_delay_ms(unsigned secs) 188 196 { 189 return rand() % (secs * 1000);197 return (unsigned)rand() % (secs * 1000); 190 198 } 191 199 … … 196 204 int zcip_main(int argc UNUSED_PARAM, char **argv) 197 205 { 206 char *r_opt; 207 const char *l_opt = "169.254.0.0"; 198 208 int state; 199 char *r_opt;209 int nsent; 200 210 unsigned opts; 201 211 202 // ugly trick, but I want these zeroed in one go212 // Ugly trick, but I want these zeroed in one go 203 213 struct { 204 const struct in_addr null_ip; 205 const struct ether_addr null_addr; 206 struct in_addr ip; 214 const struct ether_addr null_ethaddr; 207 215 struct ifreq ifr; 208 int timeout_ms; /* must be signed */ 209 unsigned conflicts; 210 unsigned nprobes; 211 unsigned nclaims; 212 int ready; 216 uint32_t chosen_nip; 217 int conflicts; 218 int timeout_ms; // must be signed 213 219 int verbose; 214 220 } L; 215 #define null_ip (L.null_ip ) 216 #define null_addr (L.null_addr ) 217 #define ip (L.ip ) 218 #define ifr (L.ifr ) 219 #define timeout_ms (L.timeout_ms) 220 #define conflicts (L.conflicts ) 221 #define nprobes (L.nprobes ) 222 #define nclaims (L.nclaims ) 223 #define ready (L.ready ) 224 #define verbose (L.verbose ) 221 #define null_ethaddr (L.null_ethaddr) 222 #define ifr (L.ifr ) 223 #define chosen_nip (L.chosen_nip ) 224 #define conflicts (L.conflicts ) 225 #define timeout_ms (L.timeout_ms ) 226 #define verbose (L.verbose ) 225 227 226 228 memset(&L, 0, sizeof(L)); … … 229 231 #define FOREGROUND (opts & 1) 230 232 #define QUIT (opts & 2) 231 // parse commandline: prog [options] ifname script233 // Parse commandline: prog [options] ifname script 232 234 // exactly 2 args; -v accumulates and implies -f 233 235 opt_complementary = "=2:vv:vf"; 234 opts = getopt32(argv, "fqr: v", &r_opt, &verbose);236 opts = getopt32(argv, "fqr:l:v", &r_opt, &l_opt, &verbose); 235 237 #if !BB_MMU 236 238 // on NOMMU reexec early (or else we will rerun things twice) … … 238 240 bb_daemonize_or_rexec(0 /*was: DAEMON_CHDIR_ROOT*/, argv); 239 241 #endif 240 // open an ARP socket242 // Open an ARP socket 241 243 // (need to do it before openlog to prevent openlog from taking 242 244 // fd 3 (sock_fd==3)) … … 247 249 logmode |= LOGMODE_SYSLOG; 248 250 } 251 bb_logenv_override(); 252 253 { // -l n.n.n.n 254 struct in_addr net; 255 if (inet_aton(l_opt, &net) == 0 256 || (net.s_addr & htonl(IN_CLASSB_NET)) != net.s_addr 257 ) { 258 bb_error_msg_and_die("invalid network address"); 259 } 260 G.localnet_ip = ntohl(net.s_addr); 261 } 249 262 if (opts & 4) { // -r n.n.n.n 263 struct in_addr ip; 250 264 if (inet_aton(r_opt, &ip) == 0 251 || (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR265 || (ntohl(ip.s_addr) & IN_CLASSB_NET) != G.localnet_ip 252 266 ) { 253 267 bb_error_msg_and_die("invalid link address"); 254 268 } 269 chosen_nip = ip.s_addr; 255 270 } 256 271 argv += optind - 1; … … 265 280 xsetenv("interface", argv_intf); 266 281 267 // initialize the interface (modprobe, ifup, etc)268 if (run(argv, "init", NULL))282 // Initialize the interface (modprobe, ifup, etc) 283 if (run(argv, "init", 0)) 269 284 return EXIT_FAILURE; 270 285 271 // initialize saddr272 // saddr is: { u16 sa_family; u8 sa_data[14]; }273 //memset(& saddr, 0, sizeof(saddr));286 // Initialize G.iface_sockaddr 287 // G.iface_sockaddr is: { u16 sa_family; u8 sa_data[14]; } 288 //memset(&G.iface_sockaddr, 0, sizeof(G.iface_sockaddr)); 274 289 //TODO: are we leaving sa_family == 0 (AF_UNSPEC)?! 275 safe_strncpy( saddr.sa_data, argv_intf, sizeof(saddr.sa_data));276 277 // bind to the interface's ARP socket278 xbind(sock_fd, & saddr, sizeof(saddr));279 280 // get the interface's ethernet address290 safe_strncpy(G.iface_sockaddr.sa_data, argv_intf, sizeof(G.iface_sockaddr.sa_data)); 291 292 // Bind to the interface's ARP socket 293 xbind(sock_fd, &G.iface_sockaddr, sizeof(G.iface_sockaddr)); 294 295 // Get the interface's ethernet address 281 296 //memset(&ifr, 0, sizeof(ifr)); 282 297 strncpy_IFNAMSIZ(ifr.ifr_name, argv_intf); 283 298 xioctl(sock_fd, SIOCGIFHWADDR, &ifr); 284 memcpy(& eth_addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);285 286 // start with some stable ip address, either a function of299 memcpy(&G.our_ethaddr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN); 300 301 // Start with some stable ip address, either a function of 287 302 // the hardware address or else the last address we used. 288 303 // we are taking low-order four bytes, as top-order ones … … 292 307 { 293 308 uint32_t t; 294 move_from_unaligned32(t, ((char *)& eth_addr + 2));309 move_from_unaligned32(t, ((char *)&G.our_ethaddr + 2)); 295 310 srand(t); 296 311 } 297 if (ip.s_addr == 0)298 ip.s_addr = pick();299 300 312 // FIXME cases to handle: 301 313 // - zcip already running! 302 314 // - link already has local address... just defend/update 303 315 304 // daemonize now; don't delay system startup316 // Daemonize now; don't delay system startup 305 317 if (!FOREGROUND) { 306 318 #if BB_MMU 307 319 bb_daemonize(0 /*was: DAEMON_CHDIR_ROOT*/); 308 320 #endif 309 bb_ info_msg("start, interface %s", argv_intf);310 } 311 312 // run the dynamic address negotiation protocol,321 bb_error_msg("start, interface %s", argv_intf); 322 } 323 324 // Run the dynamic address negotiation protocol, 313 325 // restarting after address conflicts: 314 326 // - start with some address we want to try 315 327 // - short random delay 316 328 // - arp probes to see if another host uses it 329 // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff arp who-has 169.254.194.171 tell 0.0.0.0 317 330 // - arp announcements that we're claiming it 331 // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff arp who-has 169.254.194.171 (00:04:e2:64:23:c2) tell 169.254.194.171 318 332 // - use it 319 333 // - defend it, within limits … … 323 337 // - poll error (when does this happen?) 324 338 // - read error (when does this happen?) 325 // - sendto error (in arp()) (when does this happen?)339 // - sendto error (in send_arp_request()) (when does this happen?) 326 340 // - revents & POLLERR (link down). run "<script> deconfig" first 341 if (chosen_nip == 0) { 342 new_nip_and_PROBE: 343 chosen_nip = pick_nip(); 344 } 345 nsent = 0; 327 346 state = PROBE; 328 347 while (1) { 329 348 struct pollfd fds[1]; 330 unsigned deadline_us ;349 unsigned deadline_us = deadline_us; 331 350 struct arp_packet p; 332 int source_ip_conflict;333 int target_ip_conflict;351 int ip_conflict; 352 int n; 334 353 335 354 fds[0].fd = sock_fd; … … 337 356 fds[0].revents = 0; 338 357 339 // poll, being ready to adjust current timeout358 // Poll, being ready to adjust current timeout 340 359 if (!timeout_ms) { 341 360 timeout_ms = random_delay_ms(PROBE_WAIT); … … 344 363 // ones we'd care about. 345 364 } 346 // set deadline_us to the point in time when we timeout 347 deadline_us = MONOTONIC_US() + timeout_ms * 1000; 348 349 VDBG("...wait %d %s nprobes=%u, nclaims=%u\n", 350 timeout_ms, argv_intf, nprobes, nclaims); 351 352 switch (safe_poll(fds, 1, timeout_ms)) { 353 354 default: 365 if (timeout_ms >= 0) { 366 // Set deadline_us to the point in time when we timeout 367 deadline_us = MONOTONIC_US() + timeout_ms * 1000; 368 } 369 370 VDBG("...wait %d %s nsent=%u\n", 371 timeout_ms, argv_intf, nsent); 372 373 n = safe_poll(fds, 1, timeout_ms); 374 if (n < 0) { 355 375 //bb_perror_msg("poll"); - done in safe_poll 356 376 return EXIT_FAILURE; 357 358 // timeout 359 case 0: 360 VDBG("state = %d\n", state); 377 } 378 if (n == 0) { // timed out? 379 VDBG("state:%d\n", state); 361 380 switch (state) { 362 381 case PROBE: 363 // timeouts in the PROBE state mean no conflicting ARP packets364 // have been received, sowe can progress through the states365 if (n probes< PROBE_NUM) {366 n probes++;382 // No conflicting ARP packets were seen: 383 // we can progress through the states 384 if (nsent < PROBE_NUM) { 385 nsent++; 367 386 VDBG("probe/%u %s@%s\n", 368 nprobes, argv_intf, inet_ntoa(ip)); 369 arp(/* ARPOP_REQUEST, */ 370 /* ð_addr, */ null_ip, 371 &null_addr, ip); 387 nsent, argv_intf, nip_to_a(chosen_nip)); 372 388 timeout_ms = PROBE_MIN * 1000; 373 389 timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN); 390 send_arp_request(0, &null_ethaddr, chosen_nip); 391 continue; 374 392 } 375 else { 376 // Switch to announce state. 377 state = ANNOUNCE; 378 nclaims = 0; 393 // Switch to announce state 394 nsent = 0; 395 state = ANNOUNCE; 396 goto send_announce; 397 case ANNOUNCE: 398 // No conflicting ARP packets were seen: 399 // we can progress through the states 400 if (nsent < ANNOUNCE_NUM) { 401 send_announce: 402 nsent++; 379 403 VDBG("announce/%u %s@%s\n", 380 nclaims, argv_intf, inet_ntoa(ip)); 381 arp(/* ARPOP_REQUEST, */ 382 /* ð_addr, */ ip, 383 ð_addr, ip); 404 nsent, argv_intf, nip_to_a(chosen_nip)); 384 405 timeout_ms = ANNOUNCE_INTERVAL * 1000; 406 send_arp_request(chosen_nip, &G.our_ethaddr, chosen_nip); 407 continue; 385 408 } 386 break; 387 case RATE_LIMIT_PROBE: 388 // timeouts in the RATE_LIMIT_PROBE state mean no conflicting ARP packets 389 // have been received, so we can move immediately to the announce state 390 state = ANNOUNCE; 391 nclaims = 0; 392 VDBG("announce/%u %s@%s\n", 393 nclaims, argv_intf, inet_ntoa(ip)); 394 arp(/* ARPOP_REQUEST, */ 395 /* ð_addr, */ ip, 396 ð_addr, ip); 397 timeout_ms = ANNOUNCE_INTERVAL * 1000; 398 break; 399 case ANNOUNCE: 400 // timeouts in the ANNOUNCE state mean no conflicting ARP packets 401 // have been received, so we can progress through the states 402 if (nclaims < ANNOUNCE_NUM) { 403 nclaims++; 404 VDBG("announce/%u %s@%s\n", 405 nclaims, argv_intf, inet_ntoa(ip)); 406 arp(/* ARPOP_REQUEST, */ 407 /* ð_addr, */ ip, 408 ð_addr, ip); 409 timeout_ms = ANNOUNCE_INTERVAL * 1000; 410 } 411 else { 412 // Switch to monitor state. 413 state = MONITOR; 414 // link is ok to use earlier 415 // FIXME update filters 416 run(argv, "config", &ip); 417 ready = 1; 418 conflicts = 0; 419 timeout_ms = -1; // Never timeout in the monitor state. 420 421 // NOTE: all other exit paths 422 // should deconfig ... 423 if (QUIT) 424 return EXIT_SUCCESS; 425 } 426 break; 427 case DEFEND: 428 // We won! No ARP replies, so just go back to monitor. 409 // Switch to monitor state 410 // FIXME update filters 411 run(argv, "config", chosen_nip); 412 // NOTE: all other exit paths should deconfig... 413 if (QUIT) 414 return EXIT_SUCCESS; 415 // fall through: switch to MONITOR 416 default: 417 // case DEFEND: 418 // case MONITOR: (shouldn't happen, MONITOR timeout is infinite) 419 // Defend period ended with no ARP replies - we won 420 timeout_ms = -1; // never timeout in monitor state 429 421 state = MONITOR; 430 timeout_ms = -1;431 conflicts = 0;432 break;433 default:434 // Invalid, should never happen. Restart the whole protocol.435 state = PROBE;436 ip.s_addr = pick();437 timeout_ms = 0;438 nprobes = 0;439 nclaims = 0;440 break;441 } // switch (state)442 break; // case 0 (timeout)443 444 // packets arriving, or link went down445 case 1:446 // We need to adjust the timeout in case we didn't receive447 // a conflicting packet.448 if (timeout_ms > 0) {449 unsigned diff = deadline_us - MONOTONIC_US();450 if ((int)(diff) < 0) {451 // Current time is greater than the expected timeout time.452 // Should never happen.453 VDBG("missed an expected timeout\n");454 timeout_ms = 0;455 } else {456 VDBG("adjusting timeout\n");457 timeout_ms = (diff / 1000) | 1; /* never 0 */458 }459 }460 461 if ((fds[0].revents & POLLIN) == 0) {462 if (fds[0].revents & POLLERR) {463 // FIXME: links routinely go down;464 // this shouldn't necessarily exit.465 bb_error_msg("iface %s is down", argv_intf);466 if (ready) {467 run(argv, "deconfig", &ip);468 }469 return EXIT_FAILURE;470 }471 422 continue; 472 423 } 473 474 // read ARP packet 475 if (safe_read(sock_fd, &p, sizeof(p)) < 0) { 476 bb_perror_msg_and_die(bb_msg_read_error); 424 } 425 426 // Packet arrived, or link went down. 427 // We need to adjust the timeout in case we didn't receive 428 // a conflicting packet. 429 if (timeout_ms > 0) { 430 unsigned diff = deadline_us - MONOTONIC_US(); 431 if ((int)(diff) < 0) { 432 // Current time is greater than the expected timeout time. 433 diff = 0; 477 434 } 478 if (p.eth.ether_type != htons(ETHERTYPE_ARP)) 479 continue; 435 VDBG("adjusting timeout\n"); 436 timeout_ms = (diff / 1000) | 1; // never 0 437 } 438 439 if ((fds[0].revents & POLLIN) == 0) { 440 if (fds[0].revents & POLLERR) { 441 // FIXME: links routinely go down; 442 // this shouldn't necessarily exit. 443 bb_error_msg("iface %s is down", argv_intf); 444 if (state >= MONITOR) { 445 // Only if we are in MONITOR or DEFEND 446 run(argv, "deconfig", chosen_nip); 447 } 448 return EXIT_FAILURE; 449 } 450 continue; 451 } 452 453 // Read ARP packet 454 if (safe_read(sock_fd, &p, sizeof(p)) < 0) { 455 bb_perror_msg_and_die(bb_msg_read_error); 456 } 457 458 if (p.eth.ether_type != htons(ETHERTYPE_ARP)) 459 continue; 460 if (p.arp.arp_op != htons(ARPOP_REQUEST) 461 && p.arp.arp_op != htons(ARPOP_REPLY) 462 ) { 463 continue; 464 } 480 465 #ifdef DEBUG 481 { 482 struct ether_addr *sha = (struct ether_addr *) p.arp.arp_sha; 483 struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha; 484 struct in_addr *spa = (struct in_addr *) p.arp.arp_spa; 485 struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa; 486 VDBG("%s recv arp type=%d, op=%d,\n", 487 argv_intf, ntohs(p.eth.ether_type), 488 ntohs(p.arp.arp_op)); 489 VDBG("\tsource=%s %s\n", 490 ether_ntoa(sha), 491 inet_ntoa(*spa)); 492 VDBG("\ttarget=%s %s\n", 493 ether_ntoa(tha), 494 inet_ntoa(*tpa)); 495 } 466 { 467 struct ether_addr *sha = (struct ether_addr *) p.arp.arp_sha; 468 struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha; 469 struct in_addr *spa = (struct in_addr *) p.arp.arp_spa; 470 struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa; 471 VDBG("source=%s %s\n", ether_ntoa(sha), inet_ntoa(*spa)); 472 VDBG("target=%s %s\n", ether_ntoa(tha), inet_ntoa(*tpa)); 473 } 496 474 #endif 497 if (p.arp.arp_op != htons(ARPOP_REQUEST) 498 && p.arp.arp_op != htons(ARPOP_REPLY)) 499 continue; 500 501 source_ip_conflict = 0; 502 target_ip_conflict = 0; 503 504 if (memcmp(p.arp.arp_spa, &ip.s_addr, sizeof(struct in_addr)) == 0 505 && memcmp(&p.arp.arp_sha, ð_addr, ETH_ALEN) != 0 506 ) { 507 source_ip_conflict = 1; 475 ip_conflict = 0; 476 if (memcmp(&p.arp.arp_sha, &G.our_ethaddr, ETH_ALEN) != 0) { 477 if (memcmp(p.arp.arp_spa, &chosen_nip, 4) == 0) { 478 // A probe or reply with source_ip == chosen ip 479 ip_conflict = 1; 508 480 } 509 481 if (p.arp.arp_op == htons(ARPOP_REQUEST) 510 && memcmp(p.arp.arp_ tpa, &ip.s_addr, sizeof(struct in_addr)) == 0511 && memcmp( &p.arp.arp_tha, ð_addr, ETH_ALEN) != 0482 && memcmp(p.arp.arp_spa, &const_int_0, 4) == 0 483 && memcmp(p.arp.arp_tpa, &chosen_nip, 4) == 0 512 484 ) { 513 target_ip_conflict = 1; 485 // A probe with source_ip == 0.0.0.0, target_ip == chosen ip: 486 // another host trying to claim this ip! 487 ip_conflict |= 2; 514 488 } 515 516 VDBG("state = %d, source ip conflict = %d, target ip conflict = %d\n", 517 state, source_ip_conflict, target_ip_conflict); 518 switch (state) { 519 case PROBE: 520 case ANNOUNCE: 521 // When probing or announcing, check for source IP conflicts 522 // and other hosts doing ARP probes (target IP conflicts). 523 if (source_ip_conflict || target_ip_conflict) { 524 conflicts++; 525 if (conflicts >= MAX_CONFLICTS) { 526 VDBG("%s ratelimit\n", argv_intf); 527 timeout_ms = RATE_LIMIT_INTERVAL * 1000; 528 state = RATE_LIMIT_PROBE; 529 } 530 531 // restart the whole protocol 532 ip.s_addr = pick(); 533 timeout_ms = 0; 534 nprobes = 0; 535 nclaims = 0; 536 } 537 break; 538 case MONITOR: 539 // If a conflict, we try to defend with a single ARP probe. 540 if (source_ip_conflict) { 541 VDBG("monitor conflict -- defending\n"); 542 state = DEFEND; 543 timeout_ms = DEFEND_INTERVAL * 1000; 544 arp(/* ARPOP_REQUEST, */ 545 /* ð_addr, */ ip, 546 ð_addr, ip); 547 } 548 break; 549 case DEFEND: 550 // Well, we tried. Start over (on conflict). 551 if (source_ip_conflict) { 552 state = PROBE; 553 VDBG("defend conflict -- starting over\n"); 554 ready = 0; 555 run(argv, "deconfig", &ip); 556 557 // restart the whole protocol 558 ip.s_addr = pick(); 559 timeout_ms = 0; 560 nprobes = 0; 561 nclaims = 0; 562 } 563 break; 564 default: 565 // Invalid, should never happen. Restart the whole protocol. 566 VDBG("invalid state -- starting over\n"); 567 state = PROBE; 568 ip.s_addr = pick(); 569 timeout_ms = 0; 570 nprobes = 0; 571 nclaims = 0; 572 break; 573 } // switch state 574 break; // case 1 (packets arriving) 575 } // switch poll 489 } 490 VDBG("state:%d ip_conflict:%d\n", state, ip_conflict); 491 if (!ip_conflict) 492 continue; 493 494 // Either src or target IP conflict exists 495 if (state <= ANNOUNCE) { 496 // PROBE or ANNOUNCE 497 conflicts++; 498 timeout_ms = PROBE_MIN * 1000 499 + CONFLICT_MULTIPLIER * random_delay_ms(conflicts); 500 goto new_nip_and_PROBE; 501 } 502 503 // MONITOR or DEFEND: only src IP conflict is a problem 504 if (ip_conflict & 1) { 505 if (state == MONITOR) { 506 // Src IP conflict, defend with a single ARP probe 507 VDBG("monitor conflict - defending\n"); 508 timeout_ms = DEFEND_INTERVAL * 1000; 509 state = DEFEND; 510 send_arp_request(chosen_nip, &G.our_ethaddr, chosen_nip); 511 continue; 512 } 513 // state == DEFEND 514 // Another src IP conflict, start over 515 VDBG("defend conflict - starting over\n"); 516 run(argv, "deconfig", chosen_nip); 517 conflicts = 0; 518 timeout_ms = 0; 519 goto new_nip_and_PROBE; 520 } 521 // Note: if we only have a target IP conflict here (ip_conflict & 2), 522 // IOW: if we just saw this sort of ARP packet: 523 // aa:bb:cc:dd:ee:ff > xx:xx:xx:xx:xx:xx arp who-has <chosen_nip> tell 0.0.0.0 524 // we expect _kernel_ to respond to that, because <chosen_nip> 525 // is (expected to be) configured on this iface. 576 526 } // while (1) 577 527 #undef argv_intf
Note:
See TracChangeset
for help on using the changeset viewer.