Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/networking
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- Location:
- branches/3.2/mindi-busybox/networking
- Files:
-
- 67 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/networking/Config.src
r2725 r3232 52 52 bool "arp" 53 53 default y 54 depends onPLATFORM_LINUX54 select PLATFORM_LINUX 55 55 help 56 56 Manipulate the system ARP cache. … … 59 59 bool "arping" 60 60 default y 61 depends onPLATFORM_LINUX61 select PLATFORM_LINUX 62 62 help 63 63 Ping hosts by ARP packets. … … 66 66 bool "brctl" 67 67 default y 68 depends onPLATFORM_LINUX68 select PLATFORM_LINUX 69 69 help 70 70 Manage ethernet bridges. … … 83 83 84 84 config FEATURE_BRCTL_SHOW 85 bool "Support show , showmac and showstp"85 bool "Support show" 86 86 default y 87 87 depends on BRCTL && FEATURE_BRCTL_FANCY 88 88 help 89 89 Add support for option which prints the current config: 90 show macs, showstp, show90 show 91 91 92 92 config DNSD … … 99 99 bool "ether-wake" 100 100 default y 101 depends onPLATFORM_LINUX101 select PLATFORM_LINUX 102 102 help 103 103 Send a magic packet to wake up sleeping machines. … … 200 200 Utilizes password settings from /etc/httpd.conf for basic 201 201 authentication on a per url basis. 202 Example for httpd.conf file: 203 /adm:toor:PaSsWd 202 204 203 205 config FEATURE_HTTPD_AUTH_MD5 … … 206 208 depends on FEATURE_HTTPD_BASIC_AUTH 207 209 help 208 Enables basic per URL authentication from /etc/httpd.conf 209 using md5 passwords. 210 Enables encrypted passwords, and wildcard user/passwords 211 in httpd.conf file. 212 User '*' means 'any system user name is ok', 213 password of '*' means 'use system password for this user' 214 Examples: 215 /adm:toor:$1$P/eKnWXS$aI1aPGxT.dJD5SzqAKWrF0 216 /adm:root:* 217 /wiki:*:* 210 218 211 219 config FEATURE_HTTPD_CGI … … 224 232 This option enables support for running scripts through an 225 233 interpreter. Turn this on if you want PHP scripts to work 226 properly. You need to supply an additional line in your httpd227 configfile:234 properly. You need to supply an additional line in your 235 httpd.conf file: 228 236 *.php:/path/to/your/php 229 237 … … 282 290 bool "ifconfig" 283 291 default y 284 depends onPLATFORM_LINUX292 select PLATFORM_LINUX 285 293 help 286 294 Ifconfig is used to configure the kernel-resident network interfaces. … … 330 338 bool "ifenslave" 331 339 default y 332 depends onPLATFORM_LINUX340 select PLATFORM_LINUX 333 341 help 334 342 Userspace application to bind several interfaces … … 338 346 bool "ifplugd" 339 347 default y 340 depends onPLATFORM_LINUX348 select PLATFORM_LINUX 341 349 help 342 350 Network interface plug detection daemon. … … 380 388 bool "Use busybox ip applet" 381 389 default y 382 depends on FEATURE_IFUPDOWN_IP && PLATFORM_LINUX 390 depends on FEATURE_IFUPDOWN_IP 391 select PLATFORM_LINUX 383 392 select IP 384 393 select FEATURE_IP_ADDRESS … … 499 508 bool "ip" 500 509 default y 501 depends onPLATFORM_LINUX510 select PLATFORM_LINUX 502 511 help 503 512 The "ip" applet is a TCP/IP interface configuration and routing … … 612 621 Support long options for the ipcalc applet. 613 622 614 config NAMEIF615 bool "nameif"616 default y617 depends on PLATFORM_LINUX618 select FEATURE_SYSLOG619 help620 nameif is used to rename network interface by its MAC address.621 Renamed interfaces MUST be in the down state.622 It is possible to use a file (default: /etc/mactab)623 with list of new interface names and MACs.624 Maximum interface name length: IFNAMSIZ = 16625 File fields are separated by space or tab.626 File format:627 # Comment628 new_interface_name XX:XX:XX:XX:XX:XX629 630 config FEATURE_NAMEIF_EXTENDED631 bool "Extended nameif"632 default y633 depends on NAMEIF634 help635 This extends the nameif syntax to support the bus_info and driver636 checks. The syntax is compatible to the normal nameif.637 File format:638 new_interface_name driver=asix bus=usb-0000:00:08.2-3639 new_interface_name bus=usb-0000:00:08.2-3 00:80:C8:38:91:B5640 new_interface_name mac=00:80:C8:38:91:B5641 new_interface_name 00:80:C8:38:91:B5642 643 623 config NETSTAT 644 624 bool "netstat" 645 625 default y 646 depends onPLATFORM_LINUX626 select PLATFORM_LINUX 647 627 help 648 628 netstat prints information about the Linux networking subsystem. … … 673 653 bool "ntpd" 674 654 default y 675 depends onPLATFORM_LINUX655 select PLATFORM_LINUX 676 656 help 677 657 The NTP client/server daemon. … … 685 665 ntpd will be usable only as a NTP client. 686 666 687 config PING688 bool "ping"689 default y690 depends on PLATFORM_LINUX691 help692 ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to693 elicit an ICMP ECHO_RESPONSE from a host or gateway.694 695 config PING6696 bool "ping6"697 default y698 depends on FEATURE_IPV6 && PING699 help700 This will give you a ping that can talk IPv6.701 702 config FEATURE_FANCY_PING703 bool "Enable fancy ping output"704 default y705 depends on PING706 help707 Make the output from the ping applet include statistics, and at the708 same time provide full support for ICMP packets.709 710 667 config PSCAN 711 668 bool "pscan" … … 717 674 bool "route" 718 675 default y 719 depends onPLATFORM_LINUX676 select PLATFORM_LINUX 720 677 help 721 678 Route displays or manipulates the kernel's IP routing tables. … … 724 681 bool "slattach" 725 682 default y 726 depends onPLATFORM_LINUX683 select PLATFORM_LINUX 727 684 help 728 685 slattach is a small utility to attach network interfaces to serial … … 911 868 bool "traceroute" 912 869 default y 913 depends onPLATFORM_LINUX870 select PLATFORM_LINUX 914 871 help 915 872 Utility to trace the route of IP packets. … … 948 905 bool "tunctl" 949 906 default y 950 depends onPLATFORM_LINUX907 select PLATFORM_LINUX 951 908 help 952 909 tunctl creates or deletes tun devices. … … 981 938 bool "vconfig" 982 939 default y 983 depends onPLATFORM_LINUX940 select PLATFORM_LINUX 984 941 help 985 942 Creates, removes, and configures VLAN interfaces … … 989 946 default y 990 947 help 991 wget is a utility for non-interactive download of files from HTTP ,992 HTTPS,and FTP servers.948 wget is a utility for non-interactive download of files from HTTP 949 and FTP servers. 993 950 994 951 config FEATURE_WGET_STATUSBAR … … 1028 985 bool "zcip" 1029 986 default y 1030 depends onPLATFORM_LINUX987 select PLATFORM_LINUX 1031 988 select FEATURE_SYSLOG 1032 989 help -
branches/3.2/mindi-busybox/networking/Kbuild.src
r2725 r3232 31 31 lib-$(CONFIG_NSLOOKUP) += nslookup.o 32 32 lib-$(CONFIG_NTPD) += ntpd.o 33 lib-$(CONFIG_PING) += ping.o34 lib-$(CONFIG_PING6) += ping.o35 33 lib-$(CONFIG_PSCAN) += pscan.o 36 34 lib-$(CONFIG_ROUTE) += route.o -
branches/3.2/mindi-busybox/networking/arp.c
r2725 r3232 14 14 */ 15 15 16 //usage:#define arp_trivial_usage 17 //usage: "\n[-vn] [-H HWTYPE] [-i IF] -a [HOSTNAME]" 18 //usage: "\n[-v] [-i IF] -d HOSTNAME [pub]" 19 //usage: "\n[-v] [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [temp]" 20 //usage: "\n[-v] [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [netmask MASK] pub" 21 //usage: "\n[-v] [-H HWTYPE] [-i IF] -Ds HOSTNAME IFACE [netmask MASK] pub" 22 //usage:#define arp_full_usage "\n\n" 23 //usage: "Manipulate ARP cache\n" 24 //usage: "\n -a Display (all) hosts" 25 //usage: "\n -s Set new ARP entry" 26 //usage: "\n -d Delete a specified entry" 27 //usage: "\n -v Verbose" 28 //usage: "\n -n Don't resolve names" 29 //usage: "\n -i IF Network interface" 30 //usage: "\n -D Read <hwaddr> from given device" 31 //usage: "\n -A,-p AF Protocol family" 32 //usage: "\n -H HWTYPE Hardware address type" 33 16 34 #include "libbb.h" 17 35 #include "inet_common.h" … … 197 215 /* Get the hardware address to a specified interface name */ 198 216 static void arp_getdevhw(char *ifname, struct sockaddr *sa, 199 217 const struct hwtype *hwt) 200 218 { 201 219 struct ifreq ifr; … … 216 234 } 217 235 bb_error_msg("device '%s' has HW address %s '%s'", 218 219 236 ifname, xhw->name, 237 xhw->print((unsigned char *) &ifr.ifr_hwaddr.sa_data)); 220 238 } 221 239 } … … 328 346 static void 329 347 arp_disp(const char *name, char *ip, int type, int arp_flags, 330 348 char *hwa, char *mask, char *dev) 331 349 { 332 350 static const int arp_masks[] = { … … 411 429 * because fgets above reads limited amount of data */ 412 430 num = sscanf(line, "%s 0x%x 0x%x %s %s %s\n", 413 431 ip, &type, &flags, hwa, mask, dev); 414 432 if (num < 4) 415 433 break; … … 444 462 if (option_mask32 & ARP_OPT_v) 445 463 printf("Entries: %d\tSkipped: %d\tFound: %d\n", 446 464 entries, entries - shown, shown); 447 465 448 466 if (!shown) { … … 500 518 if (hw->alen <= 0) { 501 519 bb_error_msg_and_die("%s: %s without ARP support", 502 520 hw->name, "hardware type"); 503 521 } 504 522 -
branches/3.2/mindi-busybox/networking/arping.c
r2725 r3232 6 6 * Busybox port: Nick Fedchik <nick@fedchik.org.ua> 7 7 */ 8 9 //usage:#define arping_trivial_usage 10 //usage: "[-fqbDUA] [-c CNT] [-w TIMEOUT] [-I IFACE] [-s SRC_IP] DST_IP" 11 //usage:#define arping_full_usage "\n\n" 12 //usage: "Send ARP requests/replies\n" 13 //usage: "\n -f Quit on first ARP reply" 14 //usage: "\n -q Quiet" 15 //usage: "\n -b Keep broadcasting, don't go unicast" 16 //usage: "\n -D Duplicated address detection mode" 17 //usage: "\n -U Unsolicited ARP mode, update your neighbors" 18 //usage: "\n -A ARP answer mode, update your neighbors" 19 //usage: "\n -c N Stop after sending N ARP requests" 20 //usage: "\n -w TIMEOUT Time to wait for ARP reply, seconds" 21 //usage: "\n -I IFACE Interface to use (default eth0)" 22 //usage: "\n -s SRC_IP Sender IP address" 23 //usage: "\n DST_IP Target IP address" 8 24 9 25 #include <arpa/inet.h> -
branches/3.2/mindi-busybox/networking/brctl.c
r2725 r3232 13 13 * At the time of this writing this was considered a feature. 14 14 */ 15 16 //usage:#define brctl_trivial_usage 17 //usage: "COMMAND [BRIDGE [INTERFACE]]" 18 //usage:#define brctl_full_usage "\n\n" 19 //usage: "Manage ethernet bridges\n" 20 //usage: "\nCommands:" 21 //usage: IF_FEATURE_BRCTL_SHOW( 22 //usage: "\n show Show a list of bridges" 23 //usage: ) 24 //usage: "\n addbr BRIDGE Create BRIDGE" 25 //usage: "\n delbr BRIDGE Delete BRIDGE" 26 //usage: "\n addif BRIDGE IFACE Add IFACE to BRIDGE" 27 //usage: "\n delif BRIDGE IFACE Delete IFACE from BRIDGE" 28 //usage: IF_FEATURE_BRCTL_FANCY( 29 //usage: "\n setageing BRIDGE TIME Set ageing time" 30 //usage: "\n setfd BRIDGE TIME Set bridge forward delay" 31 //usage: "\n sethello BRIDGE TIME Set hello time" 32 //usage: "\n setmaxage BRIDGE TIME Set max message age" 33 //usage: "\n setpathcost BRIDGE COST Set path cost" 34 //usage: "\n setportprio BRIDGE PRIO Set port priority" 35 //usage: "\n setbridgeprio BRIDGE PRIO Set bridge priority" 36 //usage: "\n stp BRIDGE [1/yes/on|0/no/off] STP on/off" 37 //usage: ) 38 15 39 #include "libbb.h" 16 40 #include <linux/sockios.h> … … 44 68 45 69 /* FIXME: These 4 funcs are not really clean and could be improved */ 46 static ALWAYS_INLINE void strtotimeval(struct timeval *tv,70 static ALWAYS_INLINE void bb_strtotimeval(struct timeval *tv, 47 71 const char *time_str) 48 72 { … … 81 105 { 82 106 struct timeval tv; 83 strtotimeval(&tv, time_str);107 bb_strtotimeval(&tv, time_str); 84 108 return tv_to_jiffies(&tv); 85 109 } … … 106 130 "setpathcost\0" "setportprio\0" "setbridgeprio\0" 107 131 ) 108 IF_FEATURE_BRCTL_SHOW("show macs\0" "show\0");132 IF_FEATURE_BRCTL_SHOW("show\0"); 109 133 110 134 enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif 111 135 IF_FEATURE_BRCTL_FANCY(, 112 113 114 136 ARG_stp, 137 ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage, 138 ARG_setpathcost, ARG_setportprio, ARG_setbridgeprio 115 139 ) 116 IF_FEATURE_BRCTL_SHOW(, ARG_show macs, ARG_show)140 IF_FEATURE_BRCTL_SHOW(, ARG_show) 117 141 }; 118 142 … … 262 286 memset(ifidx, 0, sizeof ifidx); 263 287 arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long)ifidx, 264 288 MAX_PORTS); 265 289 xioctl(fd, SIOCDEVPRIVATE, &ifr); 266 290 for (i = 0; i < MAX_PORTS; i++) { -
branches/3.2/mindi-busybox/networking/dnsd.c
r2725 r3232 17 17 * the first porting of oao' scdns to busybox also. 18 18 */ 19 20 //usage:#define dnsd_trivial_usage 21 //usage: "[-dvs] [-c CONFFILE] [-t TTL_SEC] [-p PORT] [-i ADDR]" 22 //usage:#define dnsd_full_usage "\n\n" 23 //usage: "Small static DNS server daemon\n" 24 //usage: "\n -c FILE Config file" 25 //usage: "\n -t SEC TTL" 26 //usage: "\n -p PORT Listen on PORT" 27 //usage: "\n -i ADDR Listen on ADDR" 28 //usage: "\n -d Daemonize" 29 //usage: "\n -v Verbose" 30 //usage: "\n -s Send successful replies only. Use this if you want" 31 //usage: "\n to use /etc/resolv.conf with two nameserver lines:" 32 //usage: "\n nameserver DNSD_SERVER" 33 //usage: "\n nameserver NORMAL_DNS_SERVER" 19 34 20 35 #include "libbb.h" -
branches/3.2/mindi-busybox/networking/ether-wake.c
r2725 r3232 50 50 * 51 51 * The author may be reached as becker@scyld, or C/O 52 * 53 * 54 * 52 * Scyld Computing Corporation 53 * 914 Bay Ridge Road, Suite 220 54 * Annapolis MD 21403 55 55 * 56 56 * Notes: … … 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" 69 //usage:#define ether_wake_full_usage "\n\n" 70 //usage: "Send a magic packet to wake up sleeping machines.\n" 71 //usage: "MAC must be a station address (00:11:22:33:44:55) or\n" 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 iface Interface to use (default eth0)" 75 //usage: "\n -p pass Append four or six byte password PW to the packet" 76 77 #include "libbb.h" 68 78 #include <netpacket/packet.h> 69 #include <net/ethernet.h>70 79 #include <netinet/ether.h> 71 80 #include <linux/if.h> 72 73 #include "libbb.h"74 81 75 82 /* Note: PF_INET, SOCK_DGRAM, IPPROTO_UDP would allow SIOCGIFHWADDR to … … 107 114 * IP address string 108 115 * MAC address string 109 */116 */ 110 117 static void get_dest_addr(const char *hostid, struct ether_addr *eaddr) 111 118 { … … 232 239 unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data; 233 240 printf("The hardware address (SIOCGIFHWADDR) of %s is type %d " 234 235 236 241 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n\n", ifname, 242 if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1], 243 hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); 237 244 } 238 245 # endif -
branches/3.2/mindi-busybox/networking/ftpd.c
r2725 r3232 12 12 * You have to run this daemon via inetd. 13 13 */ 14 15 //usage:#define ftpd_trivial_usage 16 //usage: "[-wvS] [-t N] [-T N] [DIR]" 17 //usage:#define ftpd_full_usage "\n\n" 18 //usage: "Anonymous FTP server\n" 19 //usage: "\n" 20 //usage: "ftpd should be used as an inetd service.\n" 21 //usage: "ftpd's line for inetd.conf:\n" 22 //usage: " 21 stream tcp nowait root ftpd ftpd /files/to/serve\n" 23 //usage: "It also can be ran from tcpsvd:\n" 24 //usage: " tcpsvd -vE 0.0.0.0 21 ftpd /files/to/serve\n" 25 //usage: "\n -w Allow upload" 26 //usage: "\n -v Log errors to stderr. -vv: verbose log" 27 //usage: "\n -S Log errors to syslog. -SS: verbose log" 28 //usage: "\n -t,-T Idle and absolute timeouts" 29 //usage: "\n DIR Change root to this directory" 14 30 15 31 #include "libbb.h" … … 207 223 *(uint32_t *) G.msg_err = status; 208 224 xwrite(STDOUT_FILENO, G.msg_err, sizeof("NNN " MSG_ERR) - 1); 209 if (G.verbose > 1)225 if (G.verbose > 0) 210 226 verbose_log(G.msg_err); 211 227 } … … 417 433 setsockopt_reuseaddr(fd); 418 434 419 set_nport( G.local_addr, 0);435 set_nport(&G.local_addr->u.sa, 0); 420 436 xbind(fd, &G.local_addr->u.sa, G.local_addr->len); 421 437 xlisten(fd, 1); … … 526 542 #else 527 543 G.port_addr = get_peer_lsa(STDIN_FILENO); 528 set_nport( G.port_addr, htons(port));544 set_nport(&G.port_addr->u.sa, htons(port)); 529 545 #endif 530 546 WRITE_OK(FTP_PORTOK); … … 806 822 sprintf(buf, STR(FTP_STATFILE_OK)" %04u%02u%02u%02u%02u%02u\r\n", 807 823 broken_out.tm_year + 1900, 808 broken_out.tm_mon ,824 broken_out.tm_mon + 1, 809 825 broken_out.tm_mday, 810 826 broken_out.tm_hour, … … 912 928 || !S_ISREG(statbuf.st_mode) 913 929 ) { 930 free(tempname); 914 931 WRITE_ERR(FTP_UPLOADFAIL); 915 932 if (local_file_fd >= 0) … … 1164 1181 1165 1182 if (argv[optind]) { 1166 xchdir(argv[optind]); 1167 chroot("."); 1183 xchroot(argv[optind]); 1168 1184 } 1169 1185 -
branches/3.2/mindi-busybox/networking/ftpgetput.c
r2725 r3232 14 14 */ 15 15 16 //usage:#define ftpget_trivial_usage 17 //usage: "[OPTIONS] HOST [LOCAL_FILE] REMOTE_FILE" 18 //usage:#define ftpget_full_usage "\n\n" 19 //usage: "Download a file via FTP\n" 20 //usage: IF_FEATURE_FTPGETPUT_LONG_OPTIONS( 21 //usage: "\n -c,--continue Continue previous transfer" 22 //usage: "\n -v,--verbose Verbose" 23 //usage: "\n -u,--username USER Username" 24 //usage: "\n -p,--password PASS Password" 25 //usage: "\n -P,--port NUM Port" 26 //usage: ) 27 //usage: IF_NOT_FEATURE_FTPGETPUT_LONG_OPTIONS( 28 //usage: "\n -c Continue previous transfer" 29 //usage: "\n -v Verbose" 30 //usage: "\n -u USER Username" 31 //usage: "\n -p PASS Password" 32 //usage: "\n -P NUM Port" 33 //usage: ) 34 //usage: 35 //usage:#define ftpput_trivial_usage 36 //usage: "[OPTIONS] HOST [REMOTE_FILE] LOCAL_FILE" 37 //usage:#define ftpput_full_usage "\n\n" 38 //usage: "Upload a file to a FTP server\n" 39 //usage: IF_FEATURE_FTPGETPUT_LONG_OPTIONS( 40 //usage: "\n -v,--verbose Verbose" 41 //usage: "\n -u,--username USER Username" 42 //usage: "\n -p,--password PASS Password" 43 //usage: "\n -P,--port NUM Port" 44 //usage: ) 45 //usage: IF_NOT_FEATURE_FTPGETPUT_LONG_OPTIONS( 46 //usage: "\n -v Verbose" 47 //usage: "\n -u USER Username" 48 //usage: "\n -p PASS Password" 49 //usage: "\n -P NUM Port number" 50 //usage: ) 51 16 52 #include "libbb.h" 17 53 … … 23 59 int verbose_flag; 24 60 int do_continue; 25 char buf[ 1]; /* actually [BUFSZ] */61 char buf[4]; /* actually [BUFSZ] */ 26 62 } FIX_ALIASING; 27 63 #define G (*(struct globals*)&bb_common_bufsiz1) … … 68 104 69 105 do { 70 strcpy(buf, "EOF"); 106 strcpy(buf, "EOF"); /* for ftp_die */ 71 107 if (fgets(buf, BUFSZ - 2, control_stream) == NULL) { 72 108 ftp_die(NULL); … … 152 188 port_num += xatoul_range(buf_ptr + 1, 0, 255) * 256; 153 189 154 set_nport( lsa, htons(port_num));190 set_nport(&lsa->u.sa, htons(port_num)); 155 191 return xconnect_stream(lsa); 156 192 } … … 279 315 int ftpgetput_main(int argc UNUSED_PARAM, char **argv) 280 316 { 281 unsigned opt;282 317 const char *port = "ftp"; 283 318 /* socket to ftp server */ … … 308 343 #endif 309 344 opt_complementary = "-2:vv:cc"; /* must have 2 to 3 params; -v and -c count */ 310 opt =getopt32(argv, "cvu:p:P:", &user, &password, &port,345 getopt32(argv, "cvu:p:P:", &user, &password, &port, 311 346 &verbose_flag, &do_continue); 312 347 argv += optind; -
branches/3.2/mindi-busybox/networking/hostname.c
r2725 r3232 10 10 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 11 11 */ 12 13 //usage:#define hostname_trivial_usage 14 //usage: "[OPTIONS] [HOSTNAME | -F FILE]" 15 //usage:#define hostname_full_usage "\n\n" 16 //usage: "Get or set hostname or DNS domain name\n" 17 //usage: "\n -s Short" 18 //usage: "\n -i Addresses for the hostname" 19 //usage: "\n -d DNS domain name" 20 //usage: "\n -f Fully qualified domain name" 21 //usage: "\n -F FILE Use FILE's content as hostname" 22 //usage: 23 //usage:#define hostname_example_usage 24 //usage: "$ hostname\n" 25 //usage: "sage\n" 26 //usage: 27 //usage:#define dnsdomainname_trivial_usage NOUSAGE_STR 28 //usage:#define dnsdomainname_full_usage "" 29 12 30 #include "libbb.h" 13 31 … … 136 154 struct in_addr **h_addr_list = (struct in_addr **)hp->h_addr_list; 137 155 while (*h_addr_list) { 138 printf( "%s", inet_ntoa(**h_addr_list));156 printf(h_addr_list[1] ? "%s " : "%s", inet_ntoa(**h_addr_list)); 139 157 h_addr_list++; 140 158 } -
branches/3.2/mindi-busybox/networking/httpd.c
r2725 r3232 21 21 * The server changes directory to the location of the script and executes it 22 22 * after setting QUERY_STRING and other environment variables. 23 * 24 * If directory URL is given, no index.html is found and CGI support is enabled, 25 * cgi-bin/index.cgi will be run. Directory to list is ../$QUERY_STRING. 26 * See httpd_indexcgi.c for an example GCI code. 23 27 * 24 28 * Doc: … … 51 55 * /adm:admin:setup # Require user admin, pwd setup on urls starting with /adm/ 52 56 * /adm:toor:PaSsWd # or user toor, pwd PaSsWd on urls starting with /adm/ 57 * /adm:root:* # or user root, pwd from /etc/passwd on urls starting with /adm/ 58 * /wiki:*:* # or any user from /etc/passwd with according pwd on urls starting with /wiki/ 53 59 * .au:audio/basic # additional mime type for audio.au files 54 60 * *.php:/path/php # run xxx.php through an interpreter … … 72 78 * A:* # (optional line added for clarity) 73 79 * 74 * If a sub directory contains a config fileit is parsed and merged with80 * If a sub directory contains config file, it is parsed and merged with 75 81 * any existing settings as if it was appended to the original configuration. 76 82 * … … 94 100 /* TODO: use TCP_CORK, parse_config() */ 95 101 102 //usage:#define httpd_trivial_usage 103 //usage: "[-ifv[v]]" 104 //usage: " [-c CONFFILE]" 105 //usage: " [-p [IP:]PORT]" 106 //usage: IF_FEATURE_HTTPD_SETUID(" [-u USER[:GRP]]") 107 //usage: IF_FEATURE_HTTPD_BASIC_AUTH(" [-r REALM]") 108 //usage: " [-h HOME]\n" 109 //usage: "or httpd -d/-e" IF_FEATURE_HTTPD_AUTH_MD5("/-m") " STRING" 110 //usage:#define httpd_full_usage "\n\n" 111 //usage: "Listen for incoming HTTP requests\n" 112 //usage: "\n -i Inetd mode" 113 //usage: "\n -f Don't daemonize" 114 //usage: "\n -v[v] Verbose" 115 //usage: "\n -p [IP:]PORT Bind to IP:PORT (default *:80)" 116 //usage: IF_FEATURE_HTTPD_SETUID( 117 //usage: "\n -u USER[:GRP] Set uid/gid after binding to port") 118 //usage: IF_FEATURE_HTTPD_BASIC_AUTH( 119 //usage: "\n -r REALM Authentication Realm for Basic Authentication") 120 //usage: "\n -h HOME Home directory (default .)" 121 //usage: "\n -c FILE Configuration file (default {/etc,HOME}/httpd.conf)" 122 //usage: IF_FEATURE_HTTPD_AUTH_MD5( 123 //usage: "\n -m STRING MD5 crypt STRING") 124 //usage: "\n -e STRING HTML encode STRING" 125 //usage: "\n -d STRING URL decode STRING" 126 96 127 #include "libbb.h" 128 #if ENABLE_PAM 129 /* PAM may include <locale.h>. We may need to undefine bbox's stub define: */ 130 # undef setlocale 131 /* For some obscure reason, PAM is not in pam/xxx, but in security/xxx. 132 * Apparently they like to confuse people. */ 133 # include <security/pam_appl.h> 134 # include <security/pam_misc.h> 135 #endif 97 136 #if ENABLE_FEATURE_HTTPD_USE_SENDFILE 98 137 # include <sys/sendfile.h> … … 310 349 #else 311 350 enum { 312 range_start = 0,351 range_start = -1, 313 352 range_end = MAXINT(off_t) - 1, 314 353 range_len = MAXINT(off_t), … … 332 371 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 333 372 IF_FEATURE_HTTPD_BASIC_AUTH(g_realm = "Web Server Authentication";) \ 373 IF_FEATURE_HTTPD_RANGES(range_start = -1;) \ 334 374 bind_addr_or_port = "80"; \ 335 375 index_page = index_html; \ … … 757 797 config_error: 758 798 bb_error_msg("config error '%s' in '%s'", buf, filename); 759 760 761 799 } /* while (fgets) */ 800 801 fclose(f); 762 802 } 763 803 … … 791 831 } 792 832 #endif 793 794 /*795 * Given a URL encoded string, convert it to plain ascii.796 * Since decoding always makes strings smaller, the decode is done in-place.797 * Thus, callers should xstrdup() the argument if they do not want the798 * argument modified. The return is the original pointer, allowing this799 * function to be easily used as arguments to other functions.800 *801 * string The first string to decode.802 * option_d 1 if called for httpd -d803 *804 * Returns a pointer to the decoded string (same as input).805 */806 static unsigned hex_to_bin(unsigned char c)807 {808 unsigned v;809 810 v = c - '0';811 if (v <= 9)812 return v;813 /* c | 0x20: letters to lower case, non-letters814 * to (potentially different) non-letters */815 v = (unsigned)(c | 0x20) - 'a';816 if (v <= 5)817 return v + 10;818 return ~0;819 /* For testing:820 void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); }821 int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f');822 t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; }823 */824 }825 static char *decodeString(char *orig, int option_d)826 {827 /* note that decoded string is always shorter than original */828 char *string = orig;829 char *ptr = string;830 char c;831 832 while ((c = *ptr++) != '\0') {833 unsigned v;834 835 if (option_d && c == '+') {836 *string++ = ' ';837 continue;838 }839 if (c != '%') {840 *string++ = c;841 continue;842 }843 v = hex_to_bin(ptr[0]);844 if (v > 15) {845 bad_hex:846 if (!option_d)847 return NULL;848 *string++ = '%';849 continue;850 }851 v = (v * 16) | hex_to_bin(ptr[1]);852 if (v > 255)853 goto bad_hex;854 if (!option_d && (v == '/' || v == '\0')) {855 /* caller takes it as indication of invalid856 * (dangerous wrt exploits) chars */857 return orig + 1;858 }859 *string++ = v;860 ptr += 2;861 }862 *string = '\0';863 return orig;864 }865 833 866 834 #if ENABLE_FEATURE_HTTPD_BASIC_AUTH … … 1066 1034 static void send_headers_and_exit(int responseNum) 1067 1035 { 1036 IF_FEATURE_HTTPD_GZIP(content_gzip = 0;) 1068 1037 send_headers(responseNum); 1069 1038 log_and_exit(); … … 1298 1267 * Parameters: 1299 1268 * const char *url The requested URL (with leading /). 1269 * const char *orig_uri The original URI before rewriting (if any) 1300 1270 * int post_len Length of the POST body. 1301 1271 * const char *cookie For set HTTP_COOKIE. … … 1304 1274 static void send_cgi_and_exit( 1305 1275 const char *url, 1276 const char *orig_uri, 1306 1277 const char *request, 1307 1278 int post_len, … … 1310 1281 static void send_cgi_and_exit( 1311 1282 const char *url, 1283 const char *orig_uri, 1312 1284 const char *request, 1313 1285 int post_len, … … 1317 1289 struct fd_pair fromCgi; /* CGI -> httpd pipe */ 1318 1290 struct fd_pair toCgi; /* httpd -> CGI pipe */ 1319 char *script ;1291 char *script, *last_slash; 1320 1292 int pid; 1321 1293 … … 1331 1303 1332 1304 /* Check for [dirs/]script.cgi/PATH_INFO */ 1333 script = (char*)url;1305 last_slash = script = (char*)url; 1334 1306 while ((script = strchr(script + 1, '/')) != NULL) { 1307 int dir; 1335 1308 *script = '\0'; 1336 if (!is_directory(url + 1, 1, NULL)) { 1309 dir = is_directory(url + 1, /*followlinks:*/ 1); 1310 *script = '/'; 1311 if (!dir) { 1337 1312 /* not directory, found script.cgi/PATH_INFO */ 1338 *script = '/';1339 1313 break; 1340 1314 } 1341 *script = '/'; /* is directory, find next '/' */ 1315 /* is directory, find next '/' */ 1316 last_slash = script; 1342 1317 } 1343 1318 setenv1("PATH_INFO", script); /* set to /PATH_INFO or "" */ 1344 1319 setenv1("REQUEST_METHOD", request); 1345 1320 if (g_query) { 1346 putenv(xasprintf("%s=%s?%s", "REQUEST_URI", url, g_query));1321 putenv(xasprintf("%s=%s?%s", "REQUEST_URI", orig_uri, g_query)); 1347 1322 } else { 1348 setenv1("REQUEST_URI", url);1323 setenv1("REQUEST_URI", orig_uri); 1349 1324 } 1350 1325 if (script != NULL) … … 1420 1395 } 1421 1396 1422 if ( !pid) {1397 if (pid == 0) { 1423 1398 /* Child process */ 1424 1399 char *argv[3]; … … 1436 1411 1437 1412 /* Chdiring to script's dir */ 1438 script = strrchr(url, '/');1413 script = last_slash; 1439 1414 if (script != url) { /* paranoia */ 1440 1415 *script = '\0'; 1441 1416 if (chdir(url + 1) != 0) { 1442 bb_perror_msg("c hdir(%s)", url + 1);1417 bb_perror_msg("can't change directory to '%s'", url + 1); 1443 1418 goto error_execing_cgi; 1444 1419 } … … 1616 1591 || content_gzip /* we are sending compressed page: can't do ranges */ ///why? 1617 1592 ) { 1618 range_start = 0;1593 range_start = -1; 1619 1594 } 1620 1595 range_len = MAXINT(off_t); 1621 if (range_start ) {1622 if (!range_end ) {1596 if (range_start >= 0) { 1597 if (!range_end || range_end > file_size - 1) { 1623 1598 range_end = file_size - 1; 1624 1599 } … … 1627 1602 ) { 1628 1603 lseek(fd, 0, SEEK_SET); 1629 range_start = 0;1604 range_start = -1; 1630 1605 } else { 1631 1606 range_len = range_end - range_start + 1; … … 1650 1625 goto fin; 1651 1626 } 1652 IF_FEATURE_HTTPD_RANGES(range_len -= sz;)1627 IF_FEATURE_HTTPD_RANGES(range_len -= count;) 1653 1628 if (count == 0 || range_len == 0) 1654 1629 log_and_exit(); … … 1701 1676 1702 1677 #if ENABLE_FEATURE_HTTPD_BASIC_AUTH 1678 1679 # if ENABLE_PAM 1680 struct pam_userinfo { 1681 const char *name; 1682 const char *pw; 1683 }; 1684 1685 static int pam_talker(int num_msg, 1686 const struct pam_message **msg, 1687 struct pam_response **resp, 1688 void *appdata_ptr) 1689 { 1690 int i; 1691 struct pam_userinfo *userinfo = (struct pam_userinfo *) appdata_ptr; 1692 struct pam_response *response; 1693 1694 if (!resp || !msg || !userinfo) 1695 return PAM_CONV_ERR; 1696 1697 /* allocate memory to store response */ 1698 response = xzalloc(num_msg * sizeof(*response)); 1699 1700 /* copy values */ 1701 for (i = 0; i < num_msg; i++) { 1702 const char *s; 1703 1704 switch (msg[i]->msg_style) { 1705 case PAM_PROMPT_ECHO_ON: 1706 s = userinfo->name; 1707 break; 1708 case PAM_PROMPT_ECHO_OFF: 1709 s = userinfo->pw; 1710 break; 1711 case PAM_ERROR_MSG: 1712 case PAM_TEXT_INFO: 1713 s = ""; 1714 break; 1715 default: 1716 free(response); 1717 return PAM_CONV_ERR; 1718 } 1719 response[i].resp = xstrdup(s); 1720 if (PAM_SUCCESS != 0) 1721 response[i].resp_retcode = PAM_SUCCESS; 1722 } 1723 *resp = response; 1724 return PAM_SUCCESS; 1725 } 1726 # endif 1727 1703 1728 /* 1704 1729 * Config file entries are of the form "/<path>:<user>:<passwd>". … … 1710 1735 * Returns 1 if user_and_passwd is OK. 1711 1736 */ 1712 static int check_user_passwd(const char *path, c onst char *user_and_passwd)1737 static int check_user_passwd(const char *path, char *user_and_passwd) 1713 1738 { 1714 1739 Htaccess *cur; … … 1718 1743 const char *dir_prefix; 1719 1744 size_t len; 1745 int r; 1720 1746 1721 1747 dir_prefix = cur->before_colon; … … 1733 1759 if (len != 1 /* dir_prefix "/" matches all, don't need to check */ 1734 1760 && (strncmp(dir_prefix, path, len) != 0 1735 || (path[len] != '/' && path[len] != '\0')) 1761 || (path[len] != '/' && path[len] != '\0') 1762 ) 1736 1763 ) { 1737 1764 continue; … … 1742 1769 1743 1770 if (ENABLE_FEATURE_HTTPD_AUTH_MD5) { 1744 char *md5_passwd; 1745 1746 md5_passwd = strchr(cur->after_colon, ':'); 1747 if (md5_passwd && md5_passwd[1] == '$' && md5_passwd[2] == '1' 1748 && md5_passwd[3] == '$' && md5_passwd[4] 1771 char *colon_after_user; 1772 const char *passwd; 1773 # if ENABLE_FEATURE_SHADOWPASSWDS && !ENABLE_PAM 1774 char sp_buf[256]; 1775 # endif 1776 1777 colon_after_user = strchr(user_and_passwd, ':'); 1778 if (!colon_after_user) 1779 goto bad_input; 1780 1781 /* compare "user:" */ 1782 if (cur->after_colon[0] != '*' 1783 && strncmp(cur->after_colon, user_and_passwd, 1784 colon_after_user - user_and_passwd + 1) != 0 1749 1785 ) { 1786 continue; 1787 } 1788 /* this cfg entry is '*' or matches username from peer */ 1789 1790 passwd = strchr(cur->after_colon, ':'); 1791 if (!passwd) 1792 goto bad_input; 1793 passwd++; 1794 if (passwd[0] == '*') { 1795 # if ENABLE_PAM 1796 struct pam_userinfo userinfo; 1797 struct pam_conv conv_info = { &pam_talker, (void *) &userinfo }; 1798 pam_handle_t *pamh; 1799 1800 *colon_after_user = '\0'; 1801 userinfo.name = user_and_passwd; 1802 userinfo.pw = colon_after_user + 1; 1803 r = pam_start("httpd", user_and_passwd, &conv_info, &pamh) != PAM_SUCCESS; 1804 if (r == 0) { 1805 r = pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK) != PAM_SUCCESS 1806 || pam_acct_mgmt(pamh, PAM_DISALLOW_NULL_AUTHTOK) != PAM_SUCCESS 1807 ; 1808 pam_end(pamh, PAM_SUCCESS); 1809 } 1810 *colon_after_user = ':'; 1811 goto end_check_passwd; 1812 # else 1813 # if ENABLE_FEATURE_SHADOWPASSWDS 1814 /* Using _r function to avoid pulling in static buffers */ 1815 struct spwd spw; 1816 # endif 1817 struct passwd *pw; 1818 1819 *colon_after_user = '\0'; 1820 pw = getpwnam(user_and_passwd); 1821 *colon_after_user = ':'; 1822 if (!pw || !pw->pw_passwd) 1823 continue; 1824 passwd = pw->pw_passwd; 1825 # if ENABLE_FEATURE_SHADOWPASSWDS 1826 if ((passwd[0] == 'x' || passwd[0] == '*') && !passwd[1]) { 1827 /* getspnam_r may return 0 yet set result to NULL. 1828 * At least glibc 2.4 does this. Be extra paranoid here. */ 1829 struct spwd *result = NULL; 1830 r = getspnam_r(pw->pw_name, &spw, sp_buf, sizeof(sp_buf), &result); 1831 if (r == 0 && result) 1832 passwd = result->sp_pwdp; 1833 } 1834 # endif 1835 /* In this case, passwd is ALWAYS encrypted: 1836 * it came from /etc/passwd or /etc/shadow! 1837 */ 1838 goto check_encrypted; 1839 # endif /* ENABLE_PAM */ 1840 } 1841 /* Else: passwd is from httpd.conf, it is either plaintext or encrypted */ 1842 1843 if (passwd[0] == '$' && isdigit(passwd[1])) { 1750 1844 char *encrypted; 1751 int r, user_len_p1; 1752 1753 md5_passwd++; 1754 user_len_p1 = md5_passwd - cur->after_colon; 1755 /* comparing "user:" */ 1756 if (strncmp(cur->after_colon, user_and_passwd, user_len_p1) != 0) { 1757 continue; 1758 } 1759 1845 # if !ENABLE_PAM 1846 check_encrypted: 1847 # endif 1848 /* encrypt pwd from peer and check match with local one */ 1760 1849 encrypted = pw_encrypt( 1761 user_and_passwd + user_len_p1 /* cleartext pwd from user */, 1762 md5_passwd /*salt */, 1 /* cleanup */); 1763 r = strcmp(encrypted, md5_passwd); 1850 /* pwd (from peer): */ colon_after_user + 1, 1851 /* salt: */ passwd, 1852 /* cleanup: */ 0 1853 ); 1854 r = strcmp(encrypted, passwd); 1764 1855 free(encrypted); 1765 if (r == 0) 1766 goto set_remoteuser_var; /* Ok */ 1767 continue; 1768 } 1769 } 1770 1856 } else { 1857 /* local passwd is from httpd.conf and it's plaintext */ 1858 r = strcmp(colon_after_user + 1, passwd); 1859 } 1860 goto end_check_passwd; 1861 } 1862 bad_input: 1771 1863 /* Comparing plaintext "user:pass" in one go */ 1772 if (strcmp(cur->after_colon, user_and_passwd) == 0) { 1773 set_remoteuser_var: 1864 r = strcmp(cur->after_colon, user_and_passwd); 1865 end_check_passwd: 1866 if (r == 0) { 1774 1867 remoteuser = xstrndup(user_and_passwd, 1775 strchrnul(user_and_passwd, ':') - user_and_passwd); 1868 strchrnul(user_and_passwd, ':') - user_and_passwd 1869 ); 1776 1870 return 1; /* Ok */ 1777 1871 } … … 1912 2006 1913 2007 /* Extract url args if present */ 1914 g_query = NULL;2008 /* g_query = NULL; - already is */ 1915 2009 tptr = strchr(urlcopy, '?'); 1916 2010 if (tptr) { … … 1920 2014 1921 2015 /* Decode URL escape sequences */ 1922 tptr = decodeString(urlcopy, 0);2016 tptr = percent_decode_in_place(urlcopy, /*strict:*/ 1); 1923 2017 if (tptr == NULL) 1924 2018 send_headers_and_exit(HTTP_BAD_REQUEST); … … 1932 2026 * but don't strdup, retain trailing slash, protect root */ 1933 2027 urlp = tptr = urlcopy; 1934 do{2028 for (;;) { 1935 2029 if (*urlp == '/') { 1936 2030 /* skip duplicate (or initial) slash */ 1937 2031 if (*tptr == '/') { 1938 continue;2032 goto next_char; 1939 2033 } 1940 2034 if (*tptr == '.') { 1941 /* skip extra "/./" */ 1942 if (tptr[1] == '/' || !tptr[1]) { 1943 continue; 2035 if (tptr[1] == '.' && (tptr[2] == '/' || tptr[2] == '\0')) { 2036 /* "..": be careful */ 2037 /* protect root */ 2038 if (urlp == urlcopy) 2039 send_headers_and_exit(HTTP_BAD_REQUEST); 2040 /* omit previous dir */ 2041 while (*--urlp != '/') 2042 continue; 2043 /* skip to "./" or ".<NUL>" */ 2044 tptr++; 1944 2045 } 1945 /* "..": be careful */ 1946 if (tptr[1] == '.' && (tptr[2] == '/' || !tptr[2])) { 1947 ++tptr; 1948 if (urlp == urlcopy) /* protect root */ 1949 send_headers_and_exit(HTTP_BAD_REQUEST); 1950 while (*--urlp != '/') /* omit previous dir */; 1951 continue; 2046 if (tptr[1] == '/' || tptr[1] == '\0') { 2047 /* skip extra "/./" */ 2048 goto next_char; 1952 2049 } 1953 2050 } 1954 2051 } 1955 2052 *++urlp = *tptr; 1956 } while (*++tptr); 1957 *++urlp = '\0'; /* terminate after last character */ 2053 if (*urlp == '\0') 2054 break; 2055 next_char: 2056 tptr++; 2057 } 1958 2058 1959 2059 /* If URL is a directory, add '/' */ 1960 2060 if (urlp[-1] != '/') { 1961 if (is_directory(urlcopy + 1, 1, NULL)) {2061 if (is_directory(urlcopy + 1, /*followlinks:*/ 1)) { 1962 2062 found_moved_temporarily = urlcopy; 1963 2063 } … … 1973 2073 /* have path1/path2 */ 1974 2074 *tptr = '\0'; 1975 if (is_directory(urlcopy + 1, 1, NULL)) {2075 if (is_directory(urlcopy + 1, /*followlinks:*/ 1)) { 1976 2076 /* may have subdir config */ 1977 2077 parse_conf(urlcopy + 1, SUBDIR_PARSE); … … 2072 2172 range_start = BB_STRTOOFF(s, &s, 10); 2073 2173 if (s[0] != '-' || range_start < 0) { 2074 range_start = 0;2174 range_start = -1; 2075 2175 } else if (s[1]) { 2076 2176 range_end = BB_STRTOOFF(s+1, NULL, 10); 2077 2177 if (errno || range_end < range_start) 2078 range_start = 0;2178 range_start = -1; 2079 2179 } 2080 2180 } … … 2110 2210 2111 2211 #if ENABLE_FEATURE_HTTPD_BASIC_AUTH 2112 /* Case: no "Authorization:" was seen, but page doesrequire passwd.2212 /* Case: no "Authorization:" was seen, but page might require passwd. 2113 2213 * Check that with dummy user:pass */ 2114 2214 if (authorized < 0) 2115 authorized = check_user_passwd(urlcopy, ":");2215 authorized = check_user_passwd(urlcopy, (char *) ""); 2116 2216 if (!authorized) 2117 2217 send_headers_and_exit(HTTP_UNAUTHORIZED); … … 2159 2259 send_headers_and_exit(HTTP_FORBIDDEN); 2160 2260 } 2161 send_cgi_and_exit(urlcopy, prequest, length, cookie, content_type); 2162 } 2163 #endif 2164 2165 if (urlp[-1] == '/') 2261 send_cgi_and_exit(urlcopy, urlcopy, prequest, length, cookie, content_type); 2262 } 2263 #endif 2264 2265 if (urlp[-1] == '/') { 2266 /* When index_page string is appended to <dir>/ URL, it overwrites 2267 * the query string. If we fall back to call /cgi-bin/index.cgi, 2268 * query string would be lost and not available to the CGI. 2269 * Work around it by making a deep copy. 2270 */ 2271 if (ENABLE_FEATURE_HTTPD_CGI) 2272 g_query = xstrdup(g_query); /* ok for NULL too */ 2166 2273 strcpy(urlp, index_page); 2274 } 2167 2275 if (stat(tptr, &sb) == 0) { 2168 2276 #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR … … 2172 2280 for (cur = script_i; cur; cur = cur->next) { 2173 2281 if (strcmp(cur->before_colon + 1, suffix) == 0) { 2174 send_cgi_and_exit(urlcopy, prequest, length, cookie, content_type);2282 send_cgi_and_exit(urlcopy, urlcopy, prequest, length, cookie, content_type); 2175 2283 } 2176 2284 } … … 2185 2293 * Try cgi-bin/index.cgi */ 2186 2294 if (access("/cgi-bin/index.cgi"+1, X_OK) == 0) { 2187 urlp[0] = '\0'; 2188 g_query = urlcopy; 2189 send_cgi_and_exit("/cgi-bin/index.cgi", prequest, length, cookie, content_type); 2295 urlp[0] = '\0'; /* remove index_page */ 2296 send_cgi_and_exit("/cgi-bin/index.cgi", urlcopy, prequest, length, cookie, content_type); 2190 2297 } 2191 2298 } … … 2286 2393 re_exec(argv_copy); 2287 2394 } 2395 argv_copy[0][0] &= 0x7f; 2288 2396 /* parent, or vfork failed */ 2289 2397 close(n); … … 2379 2487 ); 2380 2488 if (opt & OPT_DECODE_URL) { 2381 fputs( decodeString(url_for_decode, 1), stdout);2489 fputs(percent_decode_in_place(url_for_decode, /*strict:*/ 0), stdout); 2382 2490 return 0; 2383 2491 } … … 2394 2502 salt[1] = '1'; 2395 2503 salt[2] = '$'; 2396 crypt_make_salt(salt + 3, 4 , 0);2397 puts(pw_encrypt(pass, salt, 1));2504 crypt_make_salt(salt + 3, 4); 2505 puts(pw_encrypt(pass, salt, /*cleanup:*/ 0)); 2398 2506 return 0; 2399 2507 } -
branches/3.2/mindi-busybox/networking/httpd_indexcgi.c
r2725 r3232 36 36 */ 37 37 38 #define _GNU_SOURCE 1 /* for strchrnul */ 38 39 #include <sys/types.h> 39 40 #include <sys/stat.h> … … 222 223 int odd; 223 224 DIR *dirp; 224 char *QUERY_STRING; 225 226 QUERY_STRING = getenv("QUERY_STRING"); 227 if (!QUERY_STRING 228 || QUERY_STRING[0] != '/' 229 || strstr(QUERY_STRING, "//") 230 || strstr(QUERY_STRING, "/../") 231 || strcmp(strrchr(QUERY_STRING, '/'), "/..") == 0 225 char *location; 226 227 location = getenv("REQUEST_URI"); 228 if (!location) 229 return 1; 230 231 /* drop URL arguments if any */ 232 strchrnul(location, '?')[0] = '\0'; 233 234 if (location[0] != '/' 235 || strstr(location, "//") 236 || strstr(location, "/../") 237 || strcmp(strrchr(location, '/'), "/..") == 0 232 238 ) { 233 239 return 1; … … 235 241 236 242 if (chdir("..") 237 || ( QUERY_STRING[1] && chdir(QUERY_STRING+ 1))243 || (location[1] && chdir(location + 1)) 238 244 ) { 239 245 return 1; … … 272 278 "<html><head><title>Index of "); 273 279 /* Guard against directories with &, > etc */ 274 fmt_html( QUERY_STRING);280 fmt_html(location); 275 281 fmt_str( 276 282 "</title>\n" … … 279 285 "<body>" "\n" 280 286 "<h1>Index of "); 281 fmt_html( QUERY_STRING);287 fmt_html(location); 282 288 fmt_str( 283 289 "</h1>" "\n" -
branches/3.2/mindi-busybox/networking/httpd_ssi.c
r2725 r3232 53 53 static char* skip_whitespace(char *s) 54 54 { 55 55 while (*s == ' ' || *s == '\t') ++s; 56 56 57 57 return s; 58 58 } 59 59 … … 134 134 135 135 /* Print everything after directive */ 136 136 if (end) { 137 137 fputs(end, stdout); 138 138 free(end); -
branches/3.2/mindi-busybox/networking/ifconfig.c
r2725 r3232 27 27 */ 28 28 29 //usage:#define ifconfig_trivial_usage 30 //usage: IF_FEATURE_IFCONFIG_STATUS("[-a]") " interface [address]" 31 //usage:#define ifconfig_full_usage "\n\n" 32 //usage: "Configure a network interface\n" 33 //usage: "\n" 34 //usage: IF_FEATURE_IPV6( 35 //usage: " [add ADDRESS[/PREFIXLEN]]\n") 36 //usage: IF_FEATURE_IPV6( 37 //usage: " [del ADDRESS[/PREFIXLEN]]\n") 38 //usage: " [[-]broadcast [ADDRESS]] [[-]pointopoint [ADDRESS]]\n" 39 //usage: " [netmask ADDRESS] [dstaddr ADDRESS]\n" 40 //usage: IF_FEATURE_IFCONFIG_SLIP( 41 //usage: " [outfill NN] [keepalive NN]\n") 42 //usage: " " IF_FEATURE_IFCONFIG_HW("[hw ether" IF_FEATURE_HWIB("|infiniband")" ADDRESS] ") "[metric NN] [mtu NN]\n" 43 //usage: " [[-]trailers] [[-]arp] [[-]allmulti]\n" 44 //usage: " [multicast] [[-]promisc] [txqueuelen NN] [[-]dynamic]\n" 45 //usage: IF_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ( 46 //usage: " [mem_start NN] [io_addr NN] [irq NN]\n") 47 //usage: " [up|down] ..." 48 49 #include "libbb.h" 50 #include "inet_common.h" 29 51 #include <net/if.h> 30 52 #include <net/if_arp.h> 31 53 #include <netinet/in.h> 32 #if defined(__GLIBC__) && __GLIBC__ >=2 && __GLIBC_MINOR__ >= 1 33 #include <netpacket/packet.h> 34 #include <net/ethernet.h> 35 #else 36 #include <sys/types.h> 37 #include <netinet/if_ether.h> 38 #endif 39 #include "libbb.h" 40 #include "inet_common.h" 54 #ifdef HAVE_NET_ETHERNET_H 55 # include <net/ethernet.h> 56 #endif 41 57 42 58 #if ENABLE_FEATURE_IFCONFIG_SLIP … … 159 175 160 176 161 /*162 * Set up the tables. Warning! They must have corresponding order!163 */164 165 177 struct arg1opt { 166 178 const char *name; … … 182 194 183 195 #define ifreq_offsetof(x) offsetof(struct ifreq, x) 196 197 /* 198 * Set up the tables. Warning! They must have corresponding order! 199 */ 184 200 185 201 static const struct arg1opt Arg1Opt[] = { … … 205 221 { "SIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.irq) }, 206 222 #endif 207 /* Last entry if for unmatched (possibly hostname) arg. */208 223 #if ENABLE_FEATURE_IPV6 209 224 { "SIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */ 210 225 { "DIFADDR", SIOCDIFADDR, ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */ 211 226 #endif 227 /* Last entry is for unmatched (assumed to be hostname/address) arg. */ 212 228 { "SIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr) }, 213 229 }; … … 250 266 }; 251 267 252 /*253 * A couple of prototypes.254 */255 268 #if ENABLE_FEATURE_IFCONFIG_HW 256 static int in_ether(const char *bufp, struct sockaddr *sap); 257 #endif 258 259 /* 260 * Our main function. 261 */ 269 /* 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 #endif 310 262 311 int ifconfig_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 263 312 int ifconfig_main(int argc UNUSED_PARAM, char **argv) … … 315 364 316 365 /* Process the remaining arguments. */ 317 while (*++argv != (char *)NULL) {366 while (*++argv != NULL) { 318 367 p = *argv; 319 368 mask = N_MASK; … … 341 390 if (mask & ARG_MASK) { 342 391 mask = op->arg_flags; 343 a1op = Arg1Opt + (op - OptArray);344 392 if (mask & A_NETMASK & did_flags) 345 393 bb_show_usage(); 394 a1op = Arg1Opt + (op - OptArray); 346 395 if (*++argv == NULL) { 347 396 if (mask & A_ARG_REQ) … … 356 405 if (mask & A_CAST_RESOLVE) { 357 406 #endif 358 #if ENABLE_FEATURE_IPV6359 char *prefix;360 int prefix_len = 0;361 #endif362 /*safe_strncpy(host, *argv, (sizeof host));*/363 407 host = *argv; 364 #if ENABLE_FEATURE_IPV6 365 prefix = strchr(host, '/'); 366 if (prefix) { 367 prefix_len = xatou_range(prefix + 1, 0, 128); 368 *prefix = '\0'; 369 } 370 #endif 408 if (strcmp(host, "inet") == 0) 409 continue; /* compat stuff */ 371 410 sai.sin_family = AF_INET; 372 411 sai.sin_port = 0; … … 376 415 } 377 416 #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS 378 else if ((host[0] == '+' && !host[1]) && (mask & A_BROADCAST) 417 else if ((host[0] == '+' && !host[1]) 418 && (mask & A_BROADCAST) 379 419 && (did_flags & (A_NETMASK|A_HOSTNAME)) == (A_NETMASK|A_HOSTNAME) 380 420 ) { … … 385 425 else { 386 426 len_and_sockaddr *lsa; 387 if (strcmp(host, "inet") == 0) 388 continue; /* compat stuff */ 427 #if ENABLE_FEATURE_IPV6 428 char *prefix; 429 int prefix_len = 0; 430 prefix = strchr(host, '/'); 431 if (prefix) { 432 prefix_len = xatou_range(prefix + 1, 0, 128); 433 *prefix = '\0'; 434 } 435 resolve: 436 #endif 389 437 lsa = xhost2sockaddr(host, 0); 390 438 #if ENABLE_FEATURE_IPV6 439 if (lsa->u.sa.sa_family != AF_INET6 && prefix) { 440 /* TODO: we do not support "ifconfig eth0 up 1.2.3.4/17". 441 * For now, just make it fail instead of silently ignoring "/17" part: 442 */ 443 *prefix = '/'; 444 goto resolve; 445 } 391 446 if (lsa->u.sa.sa_family == AF_INET6) { 392 447 int sockfd6; 393 448 struct in6_ifreq ifr6; 394 449 395 memcpy((char *) &ifr6.ifr6_addr,396 (char *) &(lsa->u.sin6.sin6_addr),397 sizeof(struct in6_addr));398 399 /* Create a channel to the NET kernel. */400 450 sockfd6 = xsocket(AF_INET6, SOCK_DGRAM, 0); 401 xioctl(sockfd6, SIO GIFINDEX, &ifr);451 xioctl(sockfd6, SIOCGIFINDEX, &ifr); 402 452 ifr6.ifr6_ifindex = ifr.ifr_ifindex; 403 453 ifr6.ifr6_prefixlen = prefix_len; 454 memcpy(&ifr6.ifr6_addr, 455 &lsa->u.sin6.sin6_addr, 456 sizeof(struct in6_addr)); 404 457 ioctl_or_perror_and_die(sockfd6, a1op->selector, &ifr6, "SIOC%s", a1op->name); 405 458 if (ENABLE_FEATURE_CLEAN_UP) … … 422 475 } else { /* A_CAST_HOST_COPY_IN_ETHER */ 423 476 /* This is the "hw" arg case. */ 424 smalluint hw_class = index_in_substrings("ether\0"477 smalluint hw_class = index_in_substrings("ether\0" 425 478 IF_FEATURE_HWIB("infiniband\0"), *argv) + 1; 426 479 if (!hw_class || !*++argv) 427 480 bb_show_usage(); 428 /*safe_strncpy(host, *argv, sizeof(host));*/429 481 host = *argv; 430 482 if (hw_class == 1 ? in_ether(host, &sa) : in_ib(host, &sa)) … … 433 485 } 434 486 #endif 435 memcpy( (( (char *)&ifr) + a1op->ifr_offset),436 487 memcpy( ((char *)&ifr) + a1op->ifr_offset, 488 p, sizeof(struct sockaddr)); 437 489 } else { 438 490 /* FIXME: error check?? */ … … 443 495 xioctl(sockfd, SIOCGIFMAP, &ifr); 444 496 if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR) 445 *( (unsigned char *) p)= i;497 *(unsigned char *) p = i; 446 498 else if (mask & A_MAP_USHORT) 447 *( (unsigned short *) p)= i;499 *(unsigned short *) p = i; 448 500 else 449 *( (unsigned long *) p)= i;501 *(unsigned long *) p = i; 450 502 } else 451 503 #endif 452 504 if (mask & A_CAST_CHAR_PTR) 453 *( (caddr_t *) p)= (caddr_t) i;505 *(caddr_t *) p = (caddr_t) i; 454 506 else /* A_CAST_INT */ 455 *( (int *) p)= i;507 *(int *) p = i; 456 508 } 457 509 … … 479 531 continue; 480 532 mask = N_SET; 481 } 533 } /* if (mask & ARG_MASK) */ 482 534 483 535 xioctl(sockfd, SIOCGIFFLAGS, &ifr); … … 494 546 return 0; 495 547 } 496 497 #if ENABLE_FEATURE_IFCONFIG_HW498 /* Input an Ethernet address and convert to binary. */499 static int in_ether(const char *bufp, struct sockaddr *sap)500 {501 char *ptr;502 int i, j;503 unsigned char val;504 unsigned char c;505 506 sap->sa_family = ARPHRD_ETHER;507 ptr = (char *) sap->sa_data;508 509 i = 0;510 do {511 j = val = 0;512 513 /* We might get a semicolon here - not required. */514 if (i && (*bufp == ':')) {515 bufp++;516 }517 518 do {519 c = *bufp;520 if (((unsigned char)(c - '0')) <= 9) {521 c -= '0';522 } else if (((unsigned char)((c|0x20) - 'a')) <= 5) {523 c = (c|0x20) - ('a'-10);524 } else if (j && (c == ':' || c == 0)) {525 break;526 } else {527 return -1;528 }529 ++bufp;530 val <<= 4;531 val += c;532 } while (++j < 2);533 *ptr++ = val;534 } while (++i < ETH_ALEN);535 536 return *bufp; /* Error if we don't end at end of string. */537 }538 #endif -
branches/3.2/mindi-busybox/networking/ifenslave.c
r2725 r3232 98 98 * set version to 1.1.0 99 99 */ 100 101 //usage:#define ifenslave_trivial_usage 102 //usage: "[-cdf] MASTER_IFACE SLAVE_IFACE..." 103 //usage:#define ifenslave_full_usage "\n\n" 104 //usage: "Configure network interfaces for parallel routing\n" 105 //usage: "\n -c,--change-active Change active slave" 106 //usage: "\n -d,--detach Remove slave interface from bonding device" 107 //usage: "\n -f,--force Force, even if interface is not Ethernet" 108 /* //usage: "\n -r,--receive-slave Create a receive-only slave" */ 109 //usage: 110 //usage:#define ifenslave_example_usage 111 //usage: "To create a bond device, simply follow these three steps:\n" 112 //usage: "- ensure that the required drivers are properly loaded:\n" 113 //usage: " # modprobe bonding ; modprobe <3c59x|eepro100|pcnet32|tulip|...>\n" 114 //usage: "- assign an IP address to the bond device:\n" 115 //usage: " # ifconfig bond0 <addr> netmask <mask> broadcast <bcast>\n" 116 //usage: "- attach all the interfaces you need to the bond device:\n" 117 //usage: " # ifenslave bond0 eth0 eth1 eth2\n" 118 //usage: " If bond0 didn't have a MAC address, it will take eth0's. Then, all\n" 119 //usage: " interfaces attached AFTER this assignment will get the same MAC addr.\n\n" 120 //usage: " To detach a dead interface without setting the bond device down:\n" 121 //usage: " # ifenslave -d bond0 eth1\n\n" 122 //usage: " To set the bond device down and automatically release all the slaves:\n" 123 //usage: " # ifconfig bond0 down\n\n" 124 //usage: " To change active slave:\n" 125 //usage: " # ifenslave -c bond0 eth0\n" 100 126 101 127 #include "libbb.h" … … 245 271 ifr.ifr_addr.sa_family = AF_INET; 246 272 memset(ifr.ifr_addr.sa_data, 0, 247 273 sizeof(ifr.ifr_addr.sa_data)); 248 274 } 249 275 … … 521 547 /* Neither -c[hange] nor -d[etach] -> it's "enslave" then; 522 548 * and -f[orce] is not there too. Check that it's ethernet. */ 523 if (!(opt & (OPT_d|OPT_c|OPT_f)) {549 if (!(opt & (OPT_d|OPT_c|OPT_f))) { 524 550 /* The family '1' is ARPHRD_ETHER for ethernet. */ 525 551 if (master.hwaddr.ifr_hwaddr.sa_family != 1) { -
branches/3.2/mindi-busybox/networking/ifplugd.c
r2725 r3232 7 7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 10 //usage:#define ifplugd_trivial_usage 11 //usage: "[OPTIONS]" 12 //usage:#define ifplugd_full_usage "\n\n" 13 //usage: "Network interface plug detection daemon\n" 14 //usage: "\n -n Don't daemonize" 15 //usage: "\n -s Don't log to syslog" 16 //usage: "\n -i IFACE Interface" 17 //usage: "\n -f/-F Treat link detection error as link down/link up" 18 //usage: "\n (otherwise exit on error)" 19 //usage: "\n -a Don't up interface at each link probe" 20 //usage: "\n -M Monitor creation/destruction of interface" 21 //usage: "\n (otherwise it must exist)" 22 //usage: "\n -r PROG Script to run" 23 //usage: "\n -x ARG Extra argument for script" 24 //usage: "\n -I Don't exit on nonzero exit code from script" 25 //usage: "\n -p Don't run \"up\" script on startup" 26 //usage: "\n -q Don't run \"down\" script on exit" 27 //usage: "\n -l Always run script on startup" 28 //usage: "\n -t SECS Poll time in seconds" 29 //usage: "\n -u SECS Delay before running script after link up" 30 //usage: "\n -d SECS Delay after link down" 31 //usage: "\n -m MODE API mode (mii, priv, ethtool, wlan, iff, auto)" 32 //usage: "\n -k Kill running daemon" 33 9 34 #include "libbb.h" 10 35 … … 13 38 #include <linux/mii.h> 14 39 #include <linux/ethtool.h> 15 #include <net/ethernet.h> 40 #ifdef HAVE_NET_ETHERNET_H 41 # include <net/ethernet.h> 42 #endif 16 43 #include <linux/netlink.h> 17 44 #include <linux/rtnetlink.h> … … 132 159 static smallint detect_link_mii(void) 133 160 { 134 struct ifreq ifreq; 135 struct mii_ioctl_data *mii = (void *)&ifreq.ifr_data; 136 137 set_ifreq_to_ifname(&ifreq); 138 139 if (network_ioctl(SIOCGMIIPHY, &ifreq, "SIOCGMIIPHY") < 0) { 161 /* char buffer instead of bona-fide struct avoids aliasing warning */ 162 char buf[sizeof(struct ifreq)]; 163 struct ifreq *const ifreq = (void *)buf; 164 165 struct mii_ioctl_data *mii = (void *)&ifreq->ifr_data; 166 167 set_ifreq_to_ifname(ifreq); 168 169 if (network_ioctl(SIOCGMIIPHY, ifreq, "SIOCGMIIPHY") < 0) { 140 170 return IFSTATUS_ERR; 141 171 } … … 143 173 mii->reg_num = 1; 144 174 145 if (network_ioctl(SIOCGMIIREG, &ifreq, "SIOCGMIIREG") < 0) {175 if (network_ioctl(SIOCGMIIREG, ifreq, "SIOCGMIIREG") < 0) { 146 176 return IFSTATUS_ERR; 147 177 } … … 152 182 static smallint detect_link_priv(void) 153 183 { 154 struct ifreq ifreq; 155 struct mii_ioctl_data *mii = (void *)&ifreq.ifr_data; 156 157 set_ifreq_to_ifname(&ifreq); 158 159 if (network_ioctl(SIOCDEVPRIVATE, &ifreq, "SIOCDEVPRIVATE") < 0) { 184 /* char buffer instead of bona-fide struct avoids aliasing warning */ 185 char buf[sizeof(struct ifreq)]; 186 struct ifreq *const ifreq = (void *)buf; 187 188 struct mii_ioctl_data *mii = (void *)&ifreq->ifr_data; 189 190 set_ifreq_to_ifname(ifreq); 191 192 if (network_ioctl(SIOCDEVPRIVATE, ifreq, "SIOCDEVPRIVATE") < 0) { 160 193 return IFSTATUS_ERR; 161 194 } … … 163 196 mii->reg_num = 1; 164 197 165 if (network_ioctl(SIOCDEVPRIVATE+1, &ifreq, "SIOCDEVPRIVATE+1") < 0) {198 if (network_ioctl(SIOCDEVPRIVATE+1, ifreq, "SIOCDEVPRIVATE+1") < 0) { 166 199 return IFSTATUS_ERR; 167 200 } … … 519 552 520 553 #if ENABLE_FEATURE_PIDFILE 521 pidfile_name = xasprintf( _PATH_VARRUN"ifplugd.%s.pid", G.iface);554 pidfile_name = xasprintf(CONFIG_PID_FILE_PATH "/ifplugd.%s.pid", G.iface); 522 555 pid_from_pidfile = read_pid(pidfile_name); 523 556 -
branches/3.2/mindi-busybox/networking/ifupdown.c
r2725 r3232 18 18 */ 19 19 20 //usage:#define ifup_trivial_usage 21 //usage: "[-an"IF_FEATURE_IFUPDOWN_MAPPING("m")"vf] [-i FILE] IFACE..." 22 //usage:#define ifup_full_usage "\n\n" 23 //usage: " -a De/configure all interfaces automatically" 24 //usage: "\n -i FILE Use FILE for interface definitions" 25 //usage: "\n -n Print out what would happen, but don't do it" 26 //usage: IF_FEATURE_IFUPDOWN_MAPPING( 27 //usage: "\n (note: doesn't disable mappings)" 28 //usage: "\n -m Don't run any mappings" 29 //usage: ) 30 //usage: "\n -v Print out what would happen before doing it" 31 //usage: "\n -f Force de/configuration" 32 //usage: 33 //usage:#define ifdown_trivial_usage 34 //usage: "[-an"IF_FEATURE_IFUPDOWN_MAPPING("m")"vf] [-i FILE] IFACE..." 35 //usage:#define ifdown_full_usage "\n\n" 36 //usage: " -a De/configure all interfaces automatically" 37 //usage: "\n -i FILE Use FILE for interface definitions" 38 //usage: "\n -n Print out what would happen, but don't do it" 39 //usage: IF_FEATURE_IFUPDOWN_MAPPING( 40 //usage: "\n (note: doesn't disable mappings)" 41 //usage: "\n -m Don't run any mappings" 42 //usage: ) 43 //usage: "\n -v Print out what would happen before doing it" 44 //usage: "\n -f Force de/configuration" 45 20 46 #include "libbb.h" 21 47 /* After libbb.h, since it needs sys/types.h on some systems */ … … 24 50 25 51 #define MAX_OPT_DEPTH 10 26 #define EUNBALBRACK 1000127 #define EUNDEFVAR 1000228 #define EUNBALPER 1000029 52 30 53 #if ENABLE_FEATURE_IFUPDOWN_MAPPING … … 62 85 char *script; 63 86 64 int max_mappings;65 87 int n_mappings; 66 88 char **mapping; … … 77 99 78 100 char *iface; 79 int max_options;80 101 int n_options; 81 102 struct variable_t *option; … … 107 128 char **my_environ; 108 129 const char *startup_PATH; 130 char *shell; 109 131 } FIX_ALIASING; 110 132 #define G (*(struct globals*)&bb_common_bufsiz1) 111 133 #define INIT_G() do { } while (0) 134 135 136 static const char keywords_up_down[] ALIGN1 = 137 "up\0" 138 "down\0" 139 "pre-up\0" 140 "post-down\0" 141 ; 112 142 113 143 … … 201 231 { 202 232 size_t old_pos[MAX_OPT_DEPTH] = { 0 }; 203 int okay[MAX_OPT_DEPTH] = { 1 };233 smallint okay[MAX_OPT_DEPTH] = { 1 }; 204 234 int opt_depth = 1; 205 235 char *result = NULL; … … 212 242 break; 213 243 case '\\': 214 if (command[1]) { 215 addstr(&result, command + 1, 1); 216 command += 2; 217 } else { 218 addstr(&result, command, 1); 244 if (command[1]) 219 245 command++; 220 } 246 addstr(&result, command, 1); 247 command++; 221 248 break; 222 249 case '[': … … 227 254 command += 2; 228 255 } else { 229 addstr(&result, "[", 1);256 addstr(&result, command, 1); 230 257 command++; 231 258 } … … 239 266 command += 2; 240 267 } else { 241 addstr(&result, "]", 1);268 addstr(&result, command, 1); 242 269 command++; 243 270 } … … 251 278 nextpercent = strchr(command, '%'); 252 279 if (!nextpercent) { 253 errno = EUNBALPER;280 /* Unterminated %var% */ 254 281 free(result); 255 282 return NULL; … … 296 323 297 324 if (opt_depth > 1) { 298 errno = EUNBALBRACK;325 /* Unbalanced bracket */ 299 326 free(result); 300 327 return NULL; … … 302 329 303 330 if (!okay[0]) { 304 errno = EUNDEFVAR;331 /* Undefined variable and we aren't in a bracket */ 305 332 free(result); 306 333 return NULL; … … 369 396 result += execute("ip link set[[ mtu %mtu%]][[ addr %hwaddress%]] %iface% up", ifd, exec); 370 397 /* Was: "[[ ip ....%gateway% ]]". Removed extra spaces w/o checking */ 371 result += execute("[[ip route add ::/0 via %gateway%]] ", ifd, exec);398 result += execute("[[ip route add ::/0 via %gateway%]][[ prio %metric%]]", ifd, exec); 372 399 # else 373 400 result = execute("ifconfig %iface%[[ media %media%]][[ hw %hwaddress%]][[ mtu %mtu%]] up", ifd, exec); 374 401 result += execute("ifconfig %iface% add %address%/%netmask%", ifd, exec); 375 result += execute("[[route -A inet6 add ::/0 gw %gateway% ]]", ifd, exec);402 result += execute("[[route -A inet6 add ::/0 gw %gateway%[[ metric %metric%]]]]", ifd, exec); 376 403 # endif 377 404 return ((result == 3) ? 3 : 0); … … 456 483 "dev %iface%[[ peer %pointopoint%]][[ label %label%]]", ifd, exec); 457 484 result += execute("ip link set[[ mtu %mtu%]][[ addr %hwaddress%]] %iface% up", ifd, exec); 458 result += execute("[[ip route add default via %gateway% dev %iface% ]]", ifd, exec);485 result += execute("[[ip route add default via %gateway% dev %iface%[[ prio %metric%]]]]", ifd, exec); 459 486 return ((result == 3) ? 3 : 0); 460 487 # else … … 466 493 "[[ broadcast %broadcast%]][[ pointopoint %pointopoint%]] ", 467 494 ifd, exec); 468 result += execute("[[route add default gw %gateway% %iface%]]", ifd, exec);495 result += execute("[[route add default gw %gateway%[[ metric %metric%]] %iface%]]", ifd, exec); 469 496 return ((result == 3) ? 3 : 0); 470 497 # endif … … 777 804 currmap->match[currmap->n_matches++] = xstrdup(first_word); 778 805 } 779 /*currmap->max_mappings = 0; - done by xzalloc */780 806 /*currmap->n_mappings = 0;*/ 781 807 /*currmap->mapping = NULL;*/ … … 862 888 bb_error_msg_and_die("option with empty value \"%s\"", buf); 863 889 864 if (strcmp(first_word, "up") != 0 865 && strcmp(first_word, "down") != 0 866 && strcmp(first_word, "pre-up") != 0 867 && strcmp(first_word, "post-down") != 0 868 ) { 890 if (strcmp(first_word, "post-up") == 0) 891 first_word += 5; /* "up" */ 892 else if (strcmp(first_word, "pre-down") == 0) 893 first_word += 4; /* "down" */ 894 895 /* If not one of "up", "down",... words... */ 896 if (index_in_strings(keywords_up_down, first_word) < 0) { 869 897 int i; 870 898 for (i = 0; i < currif->n_options; i++) { … … 873 901 } 874 902 } 875 if (currif->n_options >= currif->max_options) {876 currif->max_options += 10;877 currif->option = xrealloc(currif->option,878 sizeof(*currif->option) * currif->max_options);879 }880 903 debug_noise("\t%s=%s\n", first_word, rest_of_line); 904 currif->option = xrealloc_vector(currif->option, 4, currif->n_options); 881 905 currif->option[currif->n_options].name = xstrdup(first_word); 882 906 currif->option[currif->n_options].value = xstrdup(rest_of_line); … … 890 914 currmap->script = xstrdup(next_word(&rest_of_line)); 891 915 } else if (strcmp(first_word, "map") == 0) { 892 if (currmap->n_mappings >= currmap->max_mappings) { 893 currmap->max_mappings = currmap->max_mappings * 2 + 1; 894 currmap->mapping = xrealloc(currmap->mapping, 895 sizeof(char *) * currmap->max_mappings); 896 } 916 currmap->mapping = xrealloc_vector(currmap->mapping, 2, currmap->n_mappings); 897 917 currmap->mapping[currmap->n_mappings] = xstrdup(next_word(&rest_of_line)); 898 918 currmap->n_mappings++; … … 941 961 } 942 962 943 static void set_environ(struct interface_defn_t *iface, const char *mode )963 static void set_environ(struct interface_defn_t *iface, const char *mode, const char *opt) 944 964 { 945 965 int i; … … 954 974 955 975 /* note: last element will stay NULL: */ 956 G.my_environ = xzalloc(sizeof(char *) * (iface->n_options + 6));976 G.my_environ = xzalloc(sizeof(char *) * (iface->n_options + 7)); 957 977 pp = G.my_environ; 958 978 959 979 for (i = 0; i < iface->n_options; i++) { 960 if (strcmp(iface->option[i].name, "up") == 0 961 || strcmp(iface->option[i].name, "down") == 0 962 || strcmp(iface->option[i].name, "pre-up") == 0 963 || strcmp(iface->option[i].name, "post-down") == 0 964 ) { 980 if (index_in_strings(keywords_up_down, iface->option[i].name) >= 0) { 965 981 continue; 966 982 } … … 972 988 *pp++ = setlocalenv("%s=%s", "METHOD", iface->method->name); 973 989 *pp++ = setlocalenv("%s=%s", "MODE", mode); 990 *pp++ = setlocalenv("%s=%s", "PHASE", opt); 974 991 if (G.startup_PATH) 975 992 *pp++ = setlocalenv("%s=%s", "PATH", G.startup_PATH); … … 987 1004 fflush_all(); 988 1005 child = vfork(); 989 switch (child) { 990 case -1: /* failure */ 1006 if (child < 0) /* failure */ 991 1007 return 0; 992 case 0:/* child */993 execle( DEFAULT_SHELL, DEFAULT_SHELL, "-c", str, (char *) NULL, G.my_environ);1008 if (child == 0) { /* child */ 1009 execle(G.shell, G.shell, "-c", str, (char *) NULL, G.my_environ); 994 1010 _exit(127); 995 1011 } … … 1027 1043 { 1028 1044 if (!iface->method->up(iface, check)) return -1; 1029 set_environ(iface, "start" );1045 set_environ(iface, "start", "pre-up"); 1030 1046 if (!execute_all(iface, "pre-up")) return 0; 1031 1047 if (!iface->method->up(iface, doit)) return 0; 1048 set_environ(iface, "start", "post-up"); 1032 1049 if (!execute_all(iface, "up")) return 0; 1033 1050 return 1; … … 1036 1053 static int iface_down(struct interface_defn_t *iface) 1037 1054 { 1038 if (!iface->method->down(iface, check)) return -1;1039 set_environ(iface, "stop" );1055 if (!iface->method->down(iface, check)) return -1; 1056 set_environ(iface, "stop", "pre-down"); 1040 1057 if (!execute_all(iface, "down")) return 0; 1041 1058 if (!iface->method->down(iface, doit)) return 0; 1059 set_environ(iface, "stop", "post-down"); 1042 1060 if (!execute_all(iface, "post-down")) return 0; 1043 1061 return 1; … … 1166 1184 1167 1185 G.startup_PATH = getenv("PATH"); 1186 G.shell = xstrdup(get_shell_name()); 1168 1187 1169 1188 cmds = iface_down; … … 1221 1240 if (iface_state) { 1222 1241 bb_error_msg("interface %s already configured", iface); 1223 continue;1242 goto next; 1224 1243 } 1225 1244 } else { … … 1227 1246 if (!iface_state) { 1228 1247 bb_error_msg("interface %s not configured", iface); 1229 continue;1248 goto next; 1230 1249 } 1231 1250 } … … 1291 1310 llist_t *iface_state = find_iface_state(state_list, iface); 1292 1311 1293 if (cmds == iface_up ) {1294 char * constnewiface = xasprintf("%s=%s", iface, liface);1295 if ( iface_state == NULL) {1312 if (cmds == iface_up && !any_failures) { 1313 char *newiface = xasprintf("%s=%s", iface, liface); 1314 if (!iface_state) { 1296 1315 llist_add_to_end(&state_list, newiface); 1297 1316 } else { … … 1317 1336 llist_free(state_list, free); 1318 1337 } 1338 next: 1339 free(iface); 1340 free(liface); 1319 1341 } 1320 1342 -
branches/3.2/mindi-busybox/networking/inetd.c
r2725 r3232 155 155 */ 156 156 157 //usage:#define inetd_trivial_usage 158 //usage: "[-fe] [-q N] [-R N] [CONFFILE]" 159 //usage:#define inetd_full_usage "\n\n" 160 //usage: "Listen for network connections and launch programs\n" 161 //usage: "\n -f Run in foreground" 162 //usage: "\n -e Log to stderr" 163 //usage: "\n -q N Socket listen queue (default: 128)" 164 //usage: "\n -R N Pause services after N connects/min" 165 //usage: "\n (default: 0 - disabled)" 166 157 167 #include <syslog.h> 168 #include <sys/resource.h> /* setrlimit */ 169 #include <sys/socket.h> /* un.h may need this */ 158 170 #include <sys/un.h> 159 171 … … 161 173 162 174 #if ENABLE_FEATURE_INETD_RPC 163 #include <rpc/rpc.h> 164 #include <rpc/pmap_clnt.h> 175 # if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_RPC__) 176 # error "You need to build uClibc with UCLIBC_HAS_RPC for NFS support" 177 # endif 178 # include <rpc/rpc.h> 179 # include <rpc/pmap_clnt.h> 165 180 #endif 166 181 … … 171 186 #define ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN 0 172 187 #endif 173 174 #define _PATH_INETDPID "/var/run/inetd.pid"175 188 176 189 #define CNT_INTERVAL 60 /* servers in CNT_INTERVAL sec. */ … … 345 358 } while (0) 346 359 360 #if 1 361 # define dbg(...) ((void)0) 362 #else 363 # define dbg(...) \ 364 do { \ 365 int dbg_fd = open("inetd_debug.log", O_WRONLY | O_CREAT | O_APPEND, 0666); \ 366 if (dbg_fd >= 0) { \ 367 fdprintf(dbg_fd, "%d: ", getpid()); \ 368 fdprintf(dbg_fd, __VA_ARGS__); \ 369 close(dbg_fd); \ 370 } \ 371 } while (0) 372 #endif 373 347 374 static void maybe_close(int fd) 348 375 { 349 if (fd >= 0) 376 if (fd >= 0) { 350 377 close(fd); 378 dbg("closed fd:%d\n", fd); 379 } 351 380 } 352 381 … … 452 481 if (fd >= 0) { 453 482 FD_CLR(fd, &allsock); 483 dbg("stopped listening on fd:%d\n", fd); 454 484 maxsock = -1; 485 dbg("maxsock:%d\n", maxsock); 455 486 } 456 487 } … … 460 491 if (fd >= 0) { 461 492 FD_SET(fd, &allsock); 493 dbg("started listening on fd:%d\n", fd); 462 494 if (maxsock >= 0 && fd > maxsock) { 463 495 prev_maxsock = maxsock = fd; 496 dbg("maxsock:%d\n", maxsock); 464 497 if ((rlim_t)fd > rlim_ofile_cur - FD_MARGIN) 465 498 bump_nofile(); … … 480 513 fd++; 481 514 } 515 dbg("recalculated maxsock:%d\n", maxsock); 482 516 prev_maxsock = maxsock; 483 517 if ((rlim_t)maxsock > rlim_ofile_cur - FD_MARGIN) … … 502 536 /* zero out the port for all RPC services; let bind() 503 537 * find one. */ 504 set_nport( sep->se_lsa, 0);538 set_nport(&sep->se_lsa->u.sa, 0); 505 539 506 540 /* for RPC services, attempt to use a reserved port … … 537 571 return; 538 572 } 539 if (sep->se_socktype == SOCK_STREAM) 573 574 if (sep->se_socktype == SOCK_STREAM) { 540 575 listen(fd, global_queuelen); 576 dbg("new sep->se_fd:%d (stream)\n", fd); 577 } else { 578 dbg("new sep->se_fd:%d (!stream)\n", fd); 579 } 541 580 542 581 add_fd_to_set(fd); … … 960 999 if (LONE_CHAR(sep->se_local_hostname, '*')) { 961 1000 lsa = xzalloc_lsa(sep->se_family); 962 set_nport( lsa, port);1001 set_nport(&lsa->u.sa, port); 963 1002 } else { 964 1003 lsa = host_and_af2sockaddr(sep->se_local_hostname, … … 1000 1039 block_CHLD_HUP_ALRM(&omask); 1001 1040 sepp = &serv_list; 1002 while ((sep = *sepp) ) {1041 while ((sep = *sepp) != NULL) { 1003 1042 if (sep->se_checked) { 1004 1043 sepp = &sep->se_next; … … 1092 1131 close(sep->se_fd); 1093 1132 } 1094 remove_pidfile( _PATH_INETDPID);1133 remove_pidfile(CONFIG_PID_FILE_PATH "/inetd.pid"); 1095 1134 exit(EXIT_SUCCESS); 1096 1135 } … … 1141 1180 } 1142 1181 1143 write_pidfile( _PATH_INETDPID);1182 write_pidfile(CONFIG_PID_FILE_PATH "/inetd.pid"); 1144 1183 1145 1184 /* never fails under Linux (except if you pass it bad arguments) */ … … 1154 1193 sigaddset(&sa.sa_mask, SIGCHLD); 1155 1194 sigaddset(&sa.sa_mask, SIGHUP); 1195 //FIXME: explain why no SA_RESTART 1196 //FIXME: retry_network_setup is unsafe to run in signal handler (many reasons)! 1156 1197 sa.sa_handler = retry_network_setup; 1157 1198 sigaction_set(SIGALRM, &sa); 1199 //FIXME: reread_config_file is unsafe to run in signal handler(many reasons)! 1158 1200 sa.sa_handler = reread_config_file; 1159 1201 sigaction_set(SIGHUP, &sa); 1202 //FIXME: reap_child is unsafe to run in signal handler (uses stdio)! 1160 1203 sa.sa_handler = reap_child; 1161 1204 sigaction_set(SIGCHLD, &sa); 1205 //FIXME: clean_up_and_exit is unsafe to run in signal handler (uses stdio)! 1162 1206 sa.sa_handler = clean_up_and_exit; 1163 1207 sigaction_set(SIGTERM, &sa); … … 1189 1233 continue; 1190 1234 } 1235 dbg("ready_fd_cnt:%d\n", ready_fd_cnt); 1191 1236 1192 1237 for (sep = serv_list; ready_fd_cnt && sep; sep = sep->se_next) { … … 1194 1239 continue; 1195 1240 1241 dbg("ready fd:%d\n", sep->se_fd); 1196 1242 ready_fd_cnt--; 1197 1243 ctrl = sep->se_fd; … … 1201 1247 if (sep->se_socktype == SOCK_STREAM) { 1202 1248 ctrl = accepted_fd = accept(sep->se_fd, NULL, NULL); 1249 dbg("accepted_fd:%d\n", accepted_fd); 1203 1250 if (ctrl < 0) { 1204 1251 if (errno != EINTR) … … 1221 1268 * Parent must create and use new socket instead. */ 1222 1269 new_udp_fd = socket(sep->se_family, SOCK_DGRAM, 0); 1270 dbg("new_udp_fd:%d\n", new_udp_fd); 1223 1271 if (new_udp_fd < 0) { /* error: eat packet, forget about it */ 1224 1272 udp_err: … … 1227 1275 } 1228 1276 setsockopt_reuseaddr(new_udp_fd); 1229 /* TODO: better do bind after vfork in parent,1277 /* TODO: better do bind after fork in parent, 1230 1278 * so that we don't have two wildcard bound sockets 1231 1279 * even for a brief moment? */ 1232 1280 if (bind(new_udp_fd, &sep->se_lsa->u.sa, sep->se_lsa->len) < 0) { 1281 dbg("bind(new_udp_fd) failed\n"); 1233 1282 close(new_udp_fd); 1234 1283 goto udp_err; 1235 1284 } 1285 dbg("bind(new_udp_fd) succeeded\n"); 1236 1286 } 1237 1287 } … … 1261 1311 rearm_alarm(); /* will revive it in RETRYTIME sec */ 1262 1312 restore_sigmask(&omask); 1313 maybe_close(new_udp_fd); 1263 1314 maybe_close(accepted_fd); 1264 1315 continue; /* -> check next fd in fd set */ … … 1281 1332 sleep(1); 1282 1333 restore_sigmask(&omask); 1334 maybe_close(new_udp_fd); 1283 1335 maybe_close(accepted_fd); 1284 1336 continue; /* -> check next fd in fd set */ … … 1287 1339 pid--; /* -1: "we did fork and we are child" */ 1288 1340 } 1289 /* if pid == 0 here, we never forked*/1341 /* if pid == 0 here, we didn't fork */ 1290 1342 1291 1343 if (pid > 0) { /* parent */ 1292 1344 if (sep->se_wait) { 1293 /* tcp wait: we passed listeningsocket to child,1345 /* wait: we passed socket to child, 1294 1346 * will wait for child to terminate */ 1295 1347 sep->se_wait = pid; … … 1300 1352 * we created and will use new, unconnected one */ 1301 1353 xmove_fd(new_udp_fd, sep->se_fd); 1354 dbg("moved new_udp_fd:%d to sep->se_fd:%d\n", new_udp_fd, sep->se_fd); 1302 1355 } 1303 1356 restore_sigmask(&omask); … … 1306 1359 } 1307 1360 1308 /* we are either child or didn't vfork at all */1361 /* we are either child or didn't fork at all */ 1309 1362 #ifdef INETD_BUILTINS_ENABLED 1310 1363 if (sep->se_builtin) { 1311 if (pid) { /* "pid" is -1: we did vfork */1364 if (pid) { /* "pid" is -1: we did fork */ 1312 1365 close(sep->se_fd); /* listening socket */ 1366 dbg("closed sep->se_fd:%d\n", sep->se_fd); 1313 1367 logmode = LOGMODE_NONE; /* make xwrite etc silent */ 1314 1368 } … … 1318 1372 else 1319 1373 sep->se_builtin->bi_dgram_fn(ctrl, sep); 1320 if (pid) /* we did vfork */1374 if (pid) /* we did fork */ 1321 1375 _exit(EXIT_FAILURE); 1322 1376 maybe_close(accepted_fd); … … 1328 1382 /* "nowait" udp */ 1329 1383 if (new_udp_fd >= 0) { 1330 len_and_sockaddr *lsa = xzalloc_lsa(sep->se_family); 1384 len_and_sockaddr *lsa; 1385 int r; 1386 1387 close(new_udp_fd); 1388 dbg("closed new_udp_fd:%d\n", new_udp_fd); 1389 lsa = xzalloc_lsa(sep->se_family); 1331 1390 /* peek at the packet and remember peer addr */ 1332 intr = recvfrom(ctrl, NULL, 0, MSG_PEEK|MSG_DONTWAIT,1391 r = recvfrom(ctrl, NULL, 0, MSG_PEEK|MSG_DONTWAIT, 1333 1392 &lsa->u.sa, &lsa->len); 1334 1393 if (r < 0) … … 1338 1397 * and bare write()/send() will work on it */ 1339 1398 connect(ctrl, &lsa->u.sa, lsa->len); 1399 dbg("connected ctrl:%d to remote peer\n", ctrl); 1340 1400 free(lsa); 1341 1401 } … … 1355 1415 goto do_exit1; 1356 1416 } 1357 if (pwd->pw_uid ) {1417 if (pwd->pw_uid != 0) { 1358 1418 if (sep->se_group) 1359 1419 pwd->pw_gid = grp->gr_gid; … … 1374 1434 xmove_fd(ctrl, STDIN_FILENO); 1375 1435 xdup2(STDIN_FILENO, STDOUT_FILENO); 1436 dbg("moved ctrl:%d to fd 0,1[,2]\n", ctrl); 1376 1437 /* manpages of inetd I managed to find either say 1377 1438 * that stderr is also redirected to the network, … … 1386 1447 sigaction_set(SIGPIPE, &saved_pipe_handler); 1387 1448 restore_sigmask(&omask); 1449 dbg("execing:'%s'\n", sep->se_program); 1388 1450 BB_EXECVP(sep->se_program, sep->se_argv); 1389 1451 bb_perror_msg("can't execute '%s'", sep->se_program); -
branches/3.2/mindi-busybox/networking/interface.c
r2725 r3232 28 28 * - gettext instead of catgets for i18n 29 29 * 10/1998 - Andi Kleen. Use interface list primitives. 30 * 30 * 20001008 - Bernd Eckenfels, Patch from RH for setting mtu 31 31 * (default AF was wrong) 32 32 */ 33 34 #include "libbb.h" 35 #include "inet_common.h" 33 36 #include <net/if.h> 34 37 #include <net/if_arp.h> 35 #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined(_NEWLIB_VERSION)38 #ifdef HAVE_NET_ETHERNET_H 36 39 # include <net/ethernet.h> 37 #else 38 # include <linux/if_ether.h> 39 #endif 40 #include "libbb.h" 41 #include "inet_common.h" 40 #endif 42 41 43 42 #if ENABLE_FEATURE_HWIB … … 952 951 sap.sin6_family = AF_INET6; 953 952 printf(" inet6 addr: %s/%d", 954 955 953 INET6_sprint((struct sockaddr *) &sap, 1), 954 plen); 956 955 printf(" Scope:"); 957 956 switch (scope & IPV6_ADDR_SCOPE_MASK) { … … 1021 1020 if (ptr->has_ip) { 1022 1021 printf(" %s addr:%s ", ap->name, 1023 1022 ap->sprint(&ptr->addr, 1)); 1024 1023 if (ptr->flags & IFF_POINTOPOINT) { 1025 1024 printf(" P-t-P:%s ", ap->sprint(&ptr->dstaddr, 1)); … … 1104 1103 1105 1104 printf("RX packets:%llu errors:%lu dropped:%lu overruns:%lu frame:%lu\n", 1106 1107 1108 1105 ptr->stats.rx_packets, ptr->stats.rx_errors, 1106 ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors, 1107 ptr->stats.rx_frame_errors); 1109 1108 if (can_compress) 1110 1109 printf(" compressed:%lu\n", 1111 1110 ptr->stats.rx_compressed); 1112 1111 printf(" "); 1113 1112 printf("TX packets:%llu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n", 1114 1115 1116 1113 ptr->stats.tx_packets, ptr->stats.tx_errors, 1114 ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors, 1115 ptr->stats.tx_carrier_errors); 1117 1116 printf(" collisions:%lu ", ptr->stats.collisions); 1118 1117 if (can_compress) … … 1131 1130 if (ptr->map.irq) 1132 1131 printf("Interrupt:%d ", ptr->map.irq); 1133 if (ptr->map.base_addr >= 0x100) /* Only print devices using it for 1134 I/O maps */ 1132 if (ptr->map.base_addr >= 0x100) /* Only print devices using it for I/O maps */ 1135 1133 printf("Base address:0x%lx ", 1136 1134 (unsigned long) ptr->map.base_addr); 1137 1135 if (ptr->map.mem_start) { 1138 1136 printf("Memory:%lx-%lx ", ptr->map.mem_start, 1139 1137 ptr->map.mem_end); 1140 1138 } 1141 1139 if (ptr->map.dma) … … 1170 1168 #ifdef UNUSED 1171 1169 static int for_all_interfaces(int (*doit) (struct interface *, void *), 1172 1170 void *cookie) 1173 1171 { 1174 1172 struct interface *ife; -
branches/3.2/mindi-busybox/networking/ip.c
r2725 r3232 9 9 * Bernhard Reutner-Fischer rewrote to use index_in_substr_array 10 10 */ 11 12 /* would need to make the " | " optional depending on more than one selected: */ 13 //usage:#define ip_trivial_usage 14 //usage: "[OPTIONS] {" 15 //usage: IF_FEATURE_IP_ADDRESS("address | ") 16 //usage: IF_FEATURE_IP_ROUTE("route | ") 17 //usage: IF_FEATURE_IP_LINK("link | ") 18 //usage: IF_FEATURE_IP_TUNNEL("tunnel | ") 19 //usage: IF_FEATURE_IP_RULE("rule") 20 //usage: "} {COMMAND}" 21 //usage:#define ip_full_usage "\n\n" 22 //usage: "ip [OPTIONS] OBJECT {COMMAND}\n" 23 //usage: "where OBJECT := {" 24 //usage: IF_FEATURE_IP_ADDRESS("address | ") 25 //usage: IF_FEATURE_IP_ROUTE("route | ") 26 //usage: IF_FEATURE_IP_LINK("link | ") 27 //usage: IF_FEATURE_IP_TUNNEL("tunnel | ") 28 //usage: IF_FEATURE_IP_RULE("rule") 29 //usage: "}\n" 30 //usage: "OPTIONS := { -f[amily] { inet | inet6 | link } | -o[neline] }" 31 //usage: 32 //usage:#define ipaddr_trivial_usage 33 //usage: "{ {add|del} IFADDR dev STRING | {show|flush}\n" 34 //usage: " [dev STRING] [to PREFIX] }" 35 //usage:#define ipaddr_full_usage "\n\n" 36 //usage: "ipaddr {add|delete} IFADDR dev STRING\n" 37 //usage: "ipaddr {show|flush} [dev STRING] [scope SCOPE-ID]\n" 38 //usage: " [to PREFIX] [label PATTERN]\n" 39 //usage: " IFADDR := PREFIX | ADDR peer PREFIX\n" 40 //usage: " [broadcast ADDR] [anycast ADDR]\n" 41 //usage: " [label STRING] [scope SCOPE-ID]\n" 42 //usage: " SCOPE-ID := [host | link | global | NUMBER]" 43 //usage: 44 //usage:#define iplink_trivial_usage 45 //usage: "{ set DEVICE { up | down | arp { on | off } | show [DEVICE] }" 46 //usage:#define iplink_full_usage "\n\n" 47 //usage: "iplink set DEVICE { up | down | arp | multicast { on | off } |\n" 48 //usage: " dynamic { on | off } |\n" 49 //usage: " mtu MTU }\n" 50 //usage: "iplink show [DEVICE]" 51 //usage: 52 //usage:#define iproute_trivial_usage 53 //usage: "{ list | flush | add | del | change | append |\n" 54 //usage: " replace | test } ROUTE" 55 //usage:#define iproute_full_usage "\n\n" 56 //usage: "iproute { list | flush } SELECTOR\n" 57 //usage: "iproute get ADDRESS [from ADDRESS iif STRING]\n" 58 //usage: " [oif STRING] [tos TOS]\n" 59 //usage: "iproute { add | del | change | append | replace | test } ROUTE\n" 60 //usage: " SELECTOR := [root PREFIX] [match PREFIX] [proto RTPROTO]\n" 61 //usage: " ROUTE := [TYPE] PREFIX [tos TOS] [proto RTPROTO] [metric METRIC]" 62 //usage: 63 //usage:#define iprule_trivial_usage 64 //usage: "{[list | add | del] RULE}" 65 //usage:#define iprule_full_usage "\n\n" 66 //usage: "iprule [list | add | del] SELECTOR ACTION\n" 67 //usage: " SELECTOR := [from PREFIX] [to PREFIX] [tos TOS] [fwmark FWMARK]\n" 68 //usage: " [dev STRING] [pref NUMBER]\n" 69 //usage: " ACTION := [table TABLE_ID] [nat ADDRESS]\n" 70 //usage: " [prohibit | reject | unreachable]\n" 71 //usage: " [realms [SRCREALM/]DSTREALM]\n" 72 //usage: " TABLE_ID := [local | main | default | NUMBER]" 73 //usage: 74 //usage:#define iptunnel_trivial_usage 75 //usage: "{ add | change | del | show } [NAME]\n" 76 //usage: " [mode { ipip | gre | sit }]\n" 77 //usage: " [remote ADDR] [local ADDR] [ttl TTL]" 78 //usage:#define iptunnel_full_usage "\n\n" 79 //usage: "iptunnel { add | change | del | show } [NAME]\n" 80 //usage: " [mode { ipip | gre | sit }] [remote ADDR] [local ADDR]\n" 81 //usage: " [[i|o]seq] [[i|o]key KEY] [[i|o]csum]\n" 82 //usage: " [ttl TTL] [tos TOS] [[no]pmtudisc] [dev PHYS_DEV]" 11 83 12 84 #include "libbb.h" -
branches/3.2/mindi-busybox/networking/ipcalc.c
r2725 r3232 12 12 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 13 13 */ 14 15 //usage:#define ipcalc_trivial_usage 16 //usage: "[OPTIONS] ADDRESS[[/]NETMASK] [NETMASK]" 17 //usage:#define ipcalc_full_usage "\n\n" 18 //usage: "Calculate IP network settings from a IP address\n" 19 //usage: IF_FEATURE_IPCALC_LONG_OPTIONS( 20 //usage: "\n -b,--broadcast Display calculated broadcast address" 21 //usage: "\n -n,--network Display calculated network address" 22 //usage: "\n -m,--netmask Display default netmask for IP" 23 //usage: IF_FEATURE_IPCALC_FANCY( 24 //usage: "\n -p,--prefix Display the prefix for IP/NETMASK" 25 //usage: "\n -h,--hostname Display first resolved host name" 26 //usage: "\n -s,--silent Don't ever display error messages" 27 //usage: ) 28 //usage: ) 29 //usage: IF_NOT_FEATURE_IPCALC_LONG_OPTIONS( 30 //usage: "\n -b Display calculated broadcast address" 31 //usage: "\n -n Display calculated network address" 32 //usage: "\n -m Display default netmask for IP" 33 //usage: IF_FEATURE_IPCALC_FANCY( 34 //usage: "\n -p Display the prefix for IP/NETMASK" 35 //usage: "\n -h Display first resolved host name" 36 //usage: "\n -s Don't ever display error messages" 37 //usage: ) 38 //usage: ) 39 14 40 #include "libbb.h" 15 41 /* After libbb.h, because on some systems it needs other includes */ -
branches/3.2/mindi-busybox/networking/isrv_identd.c
r2725 r3232 7 7 * Licensed under GPLv2, see file LICENSE in this source tree. 8 8 */ 9 10 //usage:#define fakeidentd_trivial_usage 11 //usage: "[-fiw] [-b ADDR] [STRING]" 12 //usage:#define fakeidentd_full_usage "\n\n" 13 //usage: "Provide fake ident (auth) service\n" 14 //usage: "\n -f Run in foreground" 15 //usage: "\n -i Inetd mode" 16 //usage: "\n -w Inetd 'wait' mode" 17 //usage: "\n -b ADDR Bind to specified address" 18 //usage: "\n STRING Ident answer string (default: nobody)" 9 19 10 20 #include "libbb.h" -
branches/3.2/mindi-busybox/networking/libiproute/ipaddress.c
r2725 r3232 163 163 } 164 164 #endif 165 /* IFLA_OPERSTATE was added to kernel with the same commit as IFF_DORMANT */ 166 #ifdef IFF_DORMANT 165 167 if (tb[IFLA_OPERSTATE]) { 166 168 static const char operstate_labels[] ALIGN1 = … … 170 172 *(uint8_t *)RTA_DATA(tb[IFLA_OPERSTATE]))); 171 173 } 174 #endif 172 175 if (G_filter.showqueue) 173 176 print_queuelen((char*)RTA_DATA(tb[IFLA_IFNAME])); … … 312 315 printf("brd %s ", 313 316 rt_addr_n2a(ifa->ifa_family, 314 RTA_DATA(rta_tb[IFA_BROADCAST]), 315 abuf, sizeof(abuf))); 317 RTA_DATA(rta_tb[IFA_BROADCAST]), 318 abuf, sizeof(abuf)) 319 ); 316 320 } 317 321 if (rta_tb[IFA_ANYCAST]) { 318 322 printf("any %s ", 319 323 rt_addr_n2a(ifa->ifa_family, 320 RTA_DATA(rta_tb[IFA_ANYCAST]), 321 abuf, sizeof(abuf))); 324 RTA_DATA(rta_tb[IFA_ANYCAST]), 325 abuf, sizeof(abuf)) 326 ); 322 327 } 323 328 printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1)); -
branches/3.2/mindi-busybox/networking/libiproute/iplink.c
r2725 r3232 8 8 #include <net/if_packet.h> 9 9 #include <netpacket/packet.h> 10 #include <net /ethernet.h>10 #include <netinet/if_ether.h> 11 11 12 12 #include "ip_common.h" /* #include "libbb.h" is inside */ -
branches/3.2/mindi-busybox/networking/libiproute/iproute.c
r2725 r3232 32 32 //int typemask; - unused 33 33 //int tos, tosmask; - unused 34 int iif , iifmask;35 int oif , oifmask;34 int iif; 35 int oif; 36 36 //int realm, realmmask; - unused 37 37 //inet_prefix rprefsrc; - read-only … … 83 83 struct rtmsg *r = NLMSG_DATA(n); 84 84 int len = n->nlmsg_len; 85 struct rtattr * 85 struct rtattr *tb[RTA_MAX+1]; 86 86 char abuf[256]; 87 87 inet_prefix dst; … … 160 160 161 161 memset(tb, 0, sizeof(tb)); 162 memset(&src, 0, sizeof(src)); 163 memset(&dst, 0, sizeof(dst)); 162 164 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len); 165 166 if (tb[RTA_SRC]) { 167 src.bitlen = r->rtm_src_len; 168 src.bytelen = (r->rtm_family == AF_INET6 ? 16 : 4); 169 memcpy(src.data, RTA_DATA(tb[RTA_SRC]), src.bytelen); 170 } 171 if (tb[RTA_DST]) { 172 dst.bitlen = r->rtm_dst_len; 173 dst.bytelen = (r->rtm_family == AF_INET6 ? 16 : 4); 174 memcpy(dst.data, RTA_DATA(tb[RTA_DST]), dst.bytelen); 175 } 163 176 164 177 if (G_filter.rdst.family … … 183 196 return 0; 184 197 } 185 if (G_filter.flushb 186 && r->rtm_family == AF_INET6 187 && r->rtm_dst_len == 0 188 && r->rtm_type == RTN_UNREACHABLE 189 && tb[RTA_PRIORITY] 190 && *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1 191 ) { 192 return 0; 198 if (G_filter.oif != 0) { 199 if (!tb[RTA_OIF]) 200 return 0; 201 if (G_filter.oif != *(int*)RTA_DATA(tb[RTA_OIF])) 202 return 0; 193 203 } 194 204 195 205 if (G_filter.flushb) { 196 206 struct nlmsghdr *fn; 207 208 /* We are creating route flush commands */ 209 210 if (r->rtm_family == AF_INET6 211 && r->rtm_dst_len == 0 212 && r->rtm_type == RTN_UNREACHABLE 213 && tb[RTA_PRIORITY] 214 && *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1 215 ) { 216 return 0; 217 } 218 197 219 if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) { 198 220 if (flush_update()) 199 221 bb_error_msg_and_die("flush"); 200 222 } 201 fn = ( struct nlmsghdr*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp));223 fn = (void*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp)); 202 224 memcpy(fn, n, n->nlmsg_len); 203 225 fn->nlmsg_type = RTM_DELROUTE; … … 208 230 return 0; 209 231 } 232 233 /* We are printing routes */ 210 234 211 235 if (n->nlmsg_type == RTM_DELROUTE) { … … 258 282 abuf, sizeof(abuf))); 259 283 } 260 if (tb[RTA_OIF] && G_filter.oifmask != -1) {284 if (tb[RTA_OIF]) { 261 285 printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF]))); 262 286 } 287 288 /* Todo: parse & show "proto kernel", "scope link" here */ 263 289 264 290 if (tb[RTA_PREFSRC] && /*G_filter.rprefsrc.bitlen - always 0*/ 0 != host_len) { … … 293 319 } 294 320 } 295 if (tb[RTA_IIF] && G_filter.iif mask != -1) {321 if (tb[RTA_IIF] && G_filter.iif == 0) { 296 322 printf(" iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF]))); 297 323 } … … 414 440 } 415 441 if ((**argv < '0' || **argv > '9') 416 && rtnl_rtntype_a2n(&type, *argv) == 0) { 442 && rtnl_rtntype_a2n(&type, *argv) == 0 443 ) { 417 444 NEXT_ARG(); 418 445 req.r.rtm_type = type; … … 663 690 idx = xll_name_to_index(id); 664 691 G_filter.iif = idx; 665 G_filter.iifmask = -1;666 692 } 667 693 if (od) { 668 694 idx = xll_name_to_index(od); 669 695 G_filter.oif = idx; 670 G_filter.oifmask = -1;671 696 } 672 697 } -
branches/3.2/mindi-busybox/networking/libiproute/iprule.c
r2725 r3232 74 74 if (r->rtm_src_len != host_len) { 75 75 printf("%s/%u", rt_addr_n2a(r->rtm_family, 76 77 76 RTA_DATA(tb[RTA_SRC]), 77 abuf, sizeof(abuf)), 78 78 r->rtm_src_len 79 79 ); 80 80 } else { 81 81 fputs(format_host(r->rtm_family, 82 RTA_PAYLOAD(tb[RTA_SRC]), 83 RTA_DATA(tb[RTA_SRC]), 84 abuf, sizeof(abuf)), stdout); 82 RTA_PAYLOAD(tb[RTA_SRC]), 83 RTA_DATA(tb[RTA_SRC]), 84 abuf, sizeof(abuf)), 85 stdout 86 ); 85 87 } 86 88 } else if (r->rtm_src_len) { -
branches/3.2/mindi-busybox/networking/libiproute/iptunnel.c
r2725 r3232 439 439 if (p->iph.tos & ~1) 440 440 printf("%c%s ", p->iph.tos & 1 ? '/' : ' ', 441 441 rtnl_dsfield_n2a(p->iph.tos & ~1, b1)); 442 442 } 443 443 if (!(p->iph.frag_off & htons(IP_DF))) -
branches/3.2/mindi-busybox/networking/libiproute/libnetlink.c
r2725 r3232 56 56 } 57 57 58 //TODO: pass rth->fd instead of full rth? 58 59 int FAST_FUNC rtnl_send(struct rtnl_handle *rth, char *buf, int len) 59 60 { … … 393 394 tb[rta->rta_type] = rta; 394 395 } 395 rta = RTA_NEXT(rta, len);396 rta = RTA_NEXT(rta, len); 396 397 } 397 398 if (len) { -
branches/3.2/mindi-busybox/networking/libiproute/ll_proto.c
r2725 r3232 13 13 #include "utils.h" 14 14 15 #if defined(__GLIBC__) && __GLIBC__ >=2 && __GLIBC_MINOR__ >= 1 16 #include <net/ethernet.h> 17 #else 18 #include <linux/if_ether.h> 19 #endif 15 #include <netinet/if_ether.h> 20 16 21 #if !ENABLE_WERROR 22 #warning de-bloat 23 #endif 24 /* Before re-enabling this, please (1) conditionalize exotic protocols 25 * on CONFIG_something, and (2) decouple strings and numbers 26 * (use llproto_ids[] = n,n,n..; and llproto_names[] = "loop\0" "pup\0" ...;) 27 */ 17 /* Please conditionalize exotic protocols on CONFIG_something */ 28 18 29 #define __PF(f,n) { ETH_P_##f, #n }, 30 static struct { 31 int id; 32 const char *name; 33 } llproto_names[] = { 19 static const uint16_t llproto_ids[] = { 20 #define __PF(f,n) ETH_P_##f, 34 21 __PF(LOOP,loop) 35 22 __PF(PUP,pup) … … 91 78 #endif 92 79 93 { 0x8100, "802.1Q" },94 { ETH_P_IP, "ipv4" }, 80 0x8100, 81 ETH_P_IP 95 82 }; 83 #undef __PF 84 85 /* Keep declarations above and below in sync! */ 86 87 static const char llproto_names[] = 88 #define __PF(f,n) #n "\0" 89 __PF(LOOP,loop) 90 __PF(PUP,pup) 91 #ifdef ETH_P_PUPAT 92 __PF(PUPAT,pupat) 93 #endif 94 __PF(IP,ip) 95 __PF(X25,x25) 96 __PF(ARP,arp) 97 __PF(BPQ,bpq) 98 #ifdef ETH_P_IEEEPUP 99 __PF(IEEEPUP,ieeepup) 100 #endif 101 #ifdef ETH_P_IEEEPUPAT 102 __PF(IEEEPUPAT,ieeepupat) 103 #endif 104 __PF(DEC,dec) 105 __PF(DNA_DL,dna_dl) 106 __PF(DNA_RC,dna_rc) 107 __PF(DNA_RT,dna_rt) 108 __PF(LAT,lat) 109 __PF(DIAG,diag) 110 __PF(CUST,cust) 111 __PF(SCA,sca) 112 __PF(RARP,rarp) 113 __PF(ATALK,atalk) 114 __PF(AARP,aarp) 115 __PF(IPX,ipx) 116 __PF(IPV6,ipv6) 117 #ifdef ETH_P_PPP_DISC 118 __PF(PPP_DISC,ppp_disc) 119 #endif 120 #ifdef ETH_P_PPP_SES 121 __PF(PPP_SES,ppp_ses) 122 #endif 123 #ifdef ETH_P_ATMMPOA 124 __PF(ATMMPOA,atmmpoa) 125 #endif 126 #ifdef ETH_P_ATMFATE 127 __PF(ATMFATE,atmfate) 128 #endif 129 130 __PF(802_3,802_3) 131 __PF(AX25,ax25) 132 __PF(ALL,all) 133 __PF(802_2,802_2) 134 __PF(SNAP,snap) 135 __PF(DDCMP,ddcmp) 136 __PF(WAN_PPP,wan_ppp) 137 __PF(PPP_MP,ppp_mp) 138 __PF(LOCALTALK,localtalk) 139 __PF(PPPTALK,ppptalk) 140 __PF(TR_802_2,tr_802_2) 141 __PF(MOBITEX,mobitex) 142 __PF(CONTROL,control) 143 __PF(IRDA,irda) 144 #ifdef ETH_P_ECONET 145 __PF(ECONET,econet) 146 #endif 147 148 "802.1Q" "\0" 149 "ipv4" "\0" 150 ; 96 151 #undef __PF 97 152 … … 101 156 unsigned i; 102 157 id = ntohs(id); 103 for (i = 0; i < ARRAY_SIZE(llproto_ names); i++) {104 if (llproto_names[i].id== id)105 return llproto_names[i].name;158 for (i = 0; i < ARRAY_SIZE(llproto_ids); i++) { 159 if (llproto_ids[i] == id) 160 return nth_string(llproto_names, i); 106 161 } 107 snprintf(buf, len, "[% d]", id);162 snprintf(buf, len, "[%u]", id); 108 163 return buf; 109 164 } … … 112 167 { 113 168 unsigned i; 114 for (i = 0; i < ARRAY_SIZE(llproto_names); i++) { 115 if (strcasecmp(llproto_names[i].name, buf) == 0) { 116 i = llproto_names[i].id; 117 goto good; 118 } 169 const char *name = llproto_names; 170 for (i = 0; i < ARRAY_SIZE(llproto_ids); i++) { 171 if (strcasecmp(name, buf) == 0) { 172 i = llproto_ids[i]; 173 goto good; 174 } 175 name += strlen(name) + 1; 119 176 } 177 errno = 0; 120 178 i = bb_strtou(buf, NULL, 0); 121 179 if (errno || i > 0xffff) -
branches/3.2/mindi-busybox/networking/libiproute/ll_types.c
r2725 r3232 8 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 9 9 */ 10 #include <sys/socket.h> /* linux/if_arp.h needs it on some systems */ 10 11 #include <arpa/inet.h> 11 12 #include <linux/if_arp.h> -
branches/3.2/mindi-busybox/networking/libiproute/utils.c
r2725 r3232 84 84 } 85 85 86 addr->family = AF_INET;87 86 if (family != AF_UNSPEC && family != AF_INET) 88 87 return -1; 88 89 /* Try to parse it as IPv4 */ 90 addr->family = AF_INET; 91 #if 0 /* Doesn't handle e.g. "10.10", for example, "ip r l root 10.10/16" */ 89 92 if (inet_pton(AF_INET, name, addr->data) <= 0) 90 93 return -1; 94 #else 95 { 96 unsigned i = 0; 97 unsigned n = 0; 98 const char *cp = name - 1; 99 while (*++cp) { 100 if ((unsigned char)(*cp - '0') <= 9) { 101 n = 10 * n + (unsigned char)(*cp - '0'); 102 if (n >= 256) 103 return -1; 104 ((uint8_t*)addr->data)[i] = n; 105 continue; 106 } 107 if (*cp == '.' && ++i <= 3) { 108 n = 0; 109 continue; 110 } 111 return -1; 112 } 113 } 114 #endif 91 115 addr->bytelen = 4; 92 116 addr->bitlen = -1; 117 93 118 return 0; 94 119 } 95 120 96 static int get_prefix_1(inet_prefix *dst, char *arg, int family) 97 { 98 int err; 99 unsigned plen; 121 static void get_prefix_1(inet_prefix *dst, char *arg, int family) 122 { 100 123 char *slash; 101 124 … … 109 132 /*dst->bytelen = 0; - done by memset */ 110 133 /*dst->bitlen = 0;*/ 111 return 0;134 return; 112 135 } 113 136 … … 115 138 if (slash) 116 139 *slash = '\0'; 117 err = get_addr_1(dst, arg, family); 118 if ( err== 0) {140 141 if (get_addr_1(dst, arg, family) == 0) { 119 142 dst->bitlen = (dst->family == AF_INET6) ? 128 : 32; 120 143 if (slash) { 144 unsigned plen; 121 145 inet_prefix netmask_pfx; 122 146 … … 124 148 plen = bb_strtou(slash + 1, NULL, 0); 125 149 if ((errno || plen > dst->bitlen) 126 && (get_addr_1(&netmask_pfx, slash + 1, family))) 127 err = -1; 128 else if (netmask_pfx.family == AF_INET) { 150 && get_addr_1(&netmask_pfx, slash + 1, family) != 0 151 ) { 152 goto bad; 153 } 154 if (netmask_pfx.family == AF_INET) { 129 155 /* fill in prefix length of dotted quad */ 130 156 uint32_t mask = ntohl(netmask_pfx.data[0]); … … 132 158 133 159 /* a valid netmask must be 2^n - 1 */ 134 if (!(host & (host + 1))) { 135 for (plen = 0; mask; mask <<= 1) 136 ++plen; 137 if (plen <= dst->bitlen) { 138 dst->bitlen = plen; 139 /* dst->flags |= PREFIXLEN_SPECIFIED; */ 140 } else 141 err = -1; 142 } else 143 err = -1; 144 } else { 145 /* plain prefix */ 146 dst->bitlen = plen; 147 } 148 } 149 } 160 if (host & (host + 1)) 161 goto bad; 162 163 for (plen = 0; mask; mask <<= 1) 164 ++plen; 165 if (plen > dst->bitlen) 166 goto bad; 167 /* dst->flags |= PREFIXLEN_SPECIFIED; */ 168 } 169 dst->bitlen = plen; 170 } 171 } 172 150 173 if (slash) 151 174 *slash = '/'; 152 return err; 175 return; 176 bad: 177 bb_error_msg_and_die("an %s %s is expected rather than \"%s\"", "inet", "prefix", arg); 153 178 } 154 179 … … 164 189 } 165 190 166 intget_prefix(inet_prefix *dst, char *arg, int family)191 void get_prefix(inet_prefix *dst, char *arg, int family) 167 192 { 168 193 if (family == AF_PACKET) { 169 194 bb_error_msg_and_die("\"%s\" may be inet %s, but it is not allowed in this context", arg, "prefix"); 170 195 } 171 if (get_prefix_1(dst, arg, family)) { 172 bb_error_msg_and_die("an %s %s is expected rather than \"%s\"", "inet", "prefix", arg); 173 } 174 return 0; 196 get_prefix_1(dst, arg, family); 175 197 } 176 198 … … 205 227 } 206 228 207 int inet_addr_match( inet_prefix *a,inet_prefix *b, int bits)208 { 209 uint32_t *a1 = a->data;210 uint32_t *a2 = b->data;229 int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits) 230 { 231 const uint32_t *a1 = a->data; 232 const uint32_t *a2 = b->data; 211 233 int words = bits >> 5; 212 234 -
branches/3.2/mindi-busybox/networking/libiproute/utils.h
r2725 r3232 59 59 extern uint32_t get_addr32(char *name); 60 60 extern int get_addr_1(inet_prefix *dst, char *arg, int family); 61 /*extern intget_prefix_1(inet_prefix *dst, char *arg, int family);*/61 /*extern void get_prefix_1(inet_prefix *dst, char *arg, int family);*/ 62 62 extern int get_addr(inet_prefix *dst, char *arg, int family); 63 extern intget_prefix(inet_prefix *dst, char *arg, int family);63 extern void get_prefix(inet_prefix *dst, char *arg, int family); 64 64 65 65 extern unsigned get_unsigned(char *arg, const char *errmsg); … … 78 78 void duparg(const char *, const char *) NORETURN; 79 79 void duparg2(const char *, const char *) NORETURN; 80 int inet_addr_match( inet_prefix *a,inet_prefix *b, int bits);80 int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits); 81 81 82 82 const char *dnet_ntop(int af, const void *addr, char *str, size_t len); -
branches/3.2/mindi-busybox/networking/nameif.c
r2725 r3232 11 11 */ 12 12 13 //config:config NAMEIF 14 //config: bool "nameif" 15 //config: default y 16 //config: select PLATFORM_LINUX 17 //config: select FEATURE_SYSLOG 18 //config: help 19 //config: nameif is used to rename network interface by its MAC address. 20 //config: Renamed interfaces MUST be in the down state. 21 //config: It is possible to use a file (default: /etc/mactab) 22 //config: with list of new interface names and MACs. 23 //config: Maximum interface name length: IFNAMSIZ = 16 24 //config: File fields are separated by space or tab. 25 //config: File format: 26 //config: # Comment 27 //config: new_interface_name XX:XX:XX:XX:XX:XX 28 //config: 29 //config:config FEATURE_NAMEIF_EXTENDED 30 //config: bool "Extended nameif" 31 //config: default y 32 //config: depends on NAMEIF 33 //config: help 34 //config: This extends the nameif syntax to support the bus_info, driver, 35 //config: phyaddr selectors. The syntax is compatible to the normal nameif. 36 //config: File format: 37 //config: new_interface_name driver=asix bus=usb-0000:00:08.2-3 38 //config: new_interface_name bus=usb-0000:00:08.2-3 00:80:C8:38:91:B5 39 //config: new_interface_name phy_address=2 00:80:C8:38:91:B5 40 //config: new_interface_name mac=00:80:C8:38:91:B5 41 //config: new_interface_name 00:80:C8:38:91:B5 42 43 //usage:#define nameif_trivial_usage 44 //usage: IF_NOT_FEATURE_NAMEIF_EXTENDED( 45 //usage: "[-s] [-c FILE] [IFNAME HWADDR]..." 46 //usage: ) 47 //usage: IF_FEATURE_NAMEIF_EXTENDED( 48 //usage: "[-s] [-c FILE] [IFNAME SELECTOR]..." 49 //usage: ) 50 //usage:#define nameif_full_usage "\n\n" 51 //usage: "Rename network interface while it in the down state." 52 //usage: IF_NOT_FEATURE_NAMEIF_EXTENDED( 53 //usage: "\nThe device with address HWADDR is renamed to IFACE." 54 //usage: ) 55 //usage: IF_FEATURE_NAMEIF_EXTENDED( 56 //usage: "\nThe device matched by SELECTOR is renamed to IFACE." 57 //usage: "\nSELECTOR can be a combination of:" 58 //usage: "\n driver=STRING" 59 //usage: "\n bus=STRING" 60 //usage: "\n phy_address=NUM" 61 //usage: "\n [mac=]XX:XX:XX:XX:XX:XX" 62 //usage: ) 63 //usage: "\n" 64 //usage: "\n -c FILE Configuration file (default: /etc/mactab)" 65 //usage: "\n -s Log to syslog" 66 //usage: 67 //usage:#define nameif_example_usage 68 //usage: "$ nameif -s dmz0 00:A0:C9:8C:F6:3F\n" 69 //usage: " or\n" 70 //usage: "$ nameif -c /etc/my_mactab_file\n" 71 13 72 #include "libbb.h" 14 73 #include <syslog.h> … … 39 98 char *bus_info; 40 99 char *driver; 100 int32_t phy_address; 41 101 #endif 42 102 } ethtable_t; … … 60 120 uint32_t regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */ 61 121 }; 122 123 struct ethtool_cmd { 124 uint32_t cmd; 125 uint32_t supported; /* Features this interface supports */ 126 uint32_t advertising; /* Features this interface advertises */ 127 uint16_t speed; /* The forced speed, 10Mb, 100Mb, gigabit */ 128 uint8_t duplex; /* Duplex, half or full */ 129 uint8_t port; /* Which connector port */ 130 uint8_t phy_address; 131 uint8_t transceiver; /* Which transceiver to use */ 132 uint8_t autoneg; /* Enable or disable autonegotiation */ 133 uint32_t maxtxpkt; /* Tx pkts before generating tx int */ 134 uint32_t maxrxpkt; /* Rx pkts before generating rx int */ 135 uint16_t speed_hi; 136 uint16_t reserved2; 137 uint32_t reserved[3]; 138 }; 139 140 #define ETHTOOL_GSET 0x00000001 /* Get settings. */ 62 141 #define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */ 63 142 #endif … … 75 154 selector = skip_whitespace(selector); 76 155 #if ENABLE_FEATURE_NAMEIF_EXTENDED 156 ch->phy_address = -1; 77 157 if (*selector == '\0') 78 158 break; … … 88 168 ch->driver = xstrdup(selector + 7); 89 169 found_selector++; 170 } else if (strncmp(selector, "phyaddr=", 8) == 0) { 171 ch->phy_address = xatoi_positive(selector + 8); 172 found_selector++; 90 173 } else { 91 174 #endif … … 134 217 135 218 int nameif_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 136 int nameif_main(int argc , char **argv)219 int nameif_main(int argc UNUSED_PARAM, char **argv) 137 220 { 138 221 ethtable_t *clist = NULL; … … 149 232 logmode |= LOGMODE_SYSLOG; 150 233 } 151 argc -= optind;152 234 argv += optind; 153 235 154 if (argc & 1) 155 bb_show_usage(); 156 157 if (argc) { 158 while (*argv) { 159 char *ifname = xstrdup(*argv++); 160 prepend_new_eth_table(&clist, ifname, *argv++); 161 } 236 if (argv[0]) { 237 do { 238 if (!argv[1]) 239 bb_show_usage(); 240 prepend_new_eth_table(&clist, argv[0], argv[1]); 241 argv += 2; 242 } while (*argv); 162 243 } else { 163 244 parser = config_open(fname); … … 174 255 #if ENABLE_FEATURE_NAMEIF_EXTENDED 175 256 struct ethtool_drvinfo drvinfo; 176 #endif 177 if (parser->lineno < 2) 257 struct ethtool_cmd eth_settings; 258 #endif 259 if (parser->lineno <= 2) 178 260 continue; /* Skip the first two lines */ 179 261 … … 183 265 184 266 #if ENABLE_FEATURE_NAMEIF_EXTENDED 267 /* Check for phy address */ 268 memset(ð_settings, 0, sizeof(eth_settings)); 269 eth_settings.cmd = ETHTOOL_GSET; 270 ifr.ifr_data = (caddr_t) ð_settings; 271 ioctl(ctl_sk, SIOCETHTOOL, &ifr); 272 185 273 /* Check for driver etc. */ 186 memset(&drvinfo, 0, sizeof( struct ethtool_drvinfo));274 memset(&drvinfo, 0, sizeof(drvinfo)); 187 275 drvinfo.cmd = ETHTOOL_GDRVINFO; 188 276 ifr.ifr_data = (caddr_t) &drvinfo; … … 198 286 continue; 199 287 if (ch->driver && strcmp(ch->driver, drvinfo.driver) != 0) 288 continue; 289 if (ch->phy_address != -1 && ch->phy_address != eth_settings.phy_address) 200 290 continue; 201 291 #endif -
branches/3.2/mindi-busybox/networking/nbd-client.c
r2725 r3232 8 8 #include <linux/fs.h> 9 9 10 //applet:IF_NBDCLIENT(APPLET_ODDNAME(nbd-client, nbdclient, _BB_DIR_USR_SBIN, _BB_SUID_DROP, nbdclient))10 //applet:IF_NBDCLIENT(APPLET_ODDNAME(nbd-client, nbdclient, BB_DIR_USR_SBIN, BB_SUID_DROP, nbdclient)) 11 11 12 12 //kbuild:lib-$(CONFIG_NBDCLIENT) += nbd-client.o -
branches/3.2/mindi-busybox/networking/nc.c
r2725 r3232 50 50 //usage: 51 51 //usage:#if ENABLE_NC_SERVER || ENABLE_NC_EXTRA 52 //usage:#define NC_OPTIONS_STR "\n \nOptions:"52 //usage:#define NC_OPTIONS_STR "\n" 53 53 //usage:#else 54 54 //usage:#define NC_OPTIONS_STR … … 121 121 ** it cannot handle "... -e PROG -prog-opt" */ 122 122 while ((opt = getopt(argc, argv, 123 123 "" IF_NC_SERVER("lp:") IF_NC_EXTRA("w:i:f:e:") )) > 0 124 124 ) { 125 125 if (ENABLE_NC_SERVER && opt == 'l') -
branches/3.2/mindi-busybox/networking/nc_bloaty.c
r2725 r3232 61 61 //usage: ) 62 62 //usage:#define nc_full_usage "\n\n" 63 //usage: "Options:" 64 //usage: "\n -e PROG Run PROG after connect (must be last)" 63 //usage: " -e PROG Run PROG after connect (must be last)" 65 64 //usage: IF_NC_SERVER( 66 65 //usage: "\n -l Listen mode, for inbound connects" … … 117 116 unsigned wrote_net; /* total net bytes */ 118 117 #endif 118 char *proggie0saved; 119 119 /* ouraddr is never NULL and goes through three states as we progress: 120 120 1 - local address before bind (IP/port possibly zero) … … 129 129 jmp_buf jbuf; /* timer crud */ 130 130 131 /* will malloc up the following globals: */132 131 fd_set ding1; /* for select loop */ 133 132 fd_set ding2; … … 161 160 /* Must match getopt32 call! */ 162 161 enum { 163 OPT_h = (1 << 0), 164 OPT_n = (1 << 1), 165 OPT_p = (1 << 2), 166 OPT_s = (1 << 3), 167 OPT_u = (1 << 4), 168 OPT_v = (1 << 5), 169 OPT_w = (1 << 6), 170 OPT_l = (1 << 7) * ENABLE_NC_SERVER, 171 OPT_i = (1 << (7+ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 172 OPT_o = (1 << (8+ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 173 OPT_z = (1 << (9+ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 162 OPT_n = (1 << 0), 163 OPT_p = (1 << 1), 164 OPT_s = (1 << 2), 165 OPT_u = (1 << 3), 166 OPT_v = (1 << 4), 167 OPT_w = (1 << 5), 168 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, 174 172 }; 175 173 … … 265 263 static int doexec(char **proggie) 266 264 { 265 if (G.proggie0saved) 266 proggie[0] = G.proggie0saved; 267 267 xmove_fd(netfd, 0); 268 268 dup2(0, 1); 269 269 /* dup2(0, 2); - do we *really* want this? NO! 270 270 * exec'ed prog can do it yourself, if needed */ 271 execvp(proggie[0], proggie); 272 bb_perror_msg_and_die("can't execute '%s'", proggie[0]); 271 BB_EXECVP_or_die(proggie); 273 272 } 274 273 … … 388 387 /* "nc -nl -p LPORT RHOST" (w/o RPORT!): 389 388 * we should accept any remote port */ 390 set_nport(&remend , 0); /* blot out remote port# */389 set_nport(&remend.u.sa, 0); /* blot out remote port# */ 391 390 } 392 391 r = memcmp(&remend.u.sa, &themaddr->u.sa, remend.len); 393 set_nport(&remend , sv_port); /* restore */392 set_nport(&remend.u.sa, sv_port); /* restore */ 394 393 if (r != 0) { 395 394 /* nc 1.10 bails out instead, and its error message … … 431 430 rr = getsockopt(netfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x); 432 431 if (rr >= 0 && x) { /* we've got options, lessee em... */ 433 bin2hex(bigbuf_net, optbuf, x); 434 bigbuf_net[2*x] = '\0'; 432 *bin2hex(bigbuf_net, optbuf, x) = '\0'; 435 433 fprintf(stderr, "IP options: %s\n", bigbuf_net); 436 434 } … … 488 486 o_wait = 5; /* enough that we'll notice?? */ 489 487 rr = xsocket(ouraddr->u.sa.sa_family, SOCK_STREAM, 0); 490 set_nport( themaddr, htons(SLEAZE_PORT));488 set_nport(&themaddr->u.sa, htons(SLEAZE_PORT)); 491 489 connect_w_timeout(rr); 492 490 /* don't need to restore themaddr's port, it's not used anymore */ … … 730 728 char *str_p, *str_s; 731 729 IF_NC_EXTRA(char *str_i, *str_o;) 732 char *themdotted = themdotted; /* gcc*/730 char *themdotted = themdotted; /* for compiler */ 733 731 char **proggie; 734 732 int x; … … 758 756 goto e_found; 759 757 } 758 /* -<other_opts>e PROG [ARGS] ? */ 759 /* (aboriginal linux uses this form) */ 760 if (proggie[0][0] == '-') { 761 char *optpos = *proggie + 1; 762 /* Skip all valid opts w/o params */ 763 optpos = optpos + strspn(optpos, "nuv"IF_NC_SERVER("l")IF_NC_EXTRA("z")); 764 if (*optpos == 'e' && !optpos[1]) { 765 *optpos = '\0'; 766 proggie++; 767 G.proggie0saved = *proggie; 768 *proggie = NULL; /* terminate argv for getopt32 */ 769 goto e_found; 770 } 771 } 760 772 } 761 773 proggie = NULL; … … 764 776 // -g -G -t -r deleted, unimplemented -a deleted too 765 777 opt_complementary = "?2:vv:w+"; /* max 2 params; -v is a counter; -w N */ 766 getopt32(argv, " hnp:s:uvw:" IF_NC_SERVER("l")778 getopt32(argv, "np:s:uvw:" IF_NC_SERVER("l") 767 779 IF_NC_EXTRA("i:o:z"), 768 780 &str_p, &str_s, &o_wait … … 815 827 x); 816 828 if (o_lport) 817 set_nport( ouraddr, htons(o_lport));829 set_nport(&ouraddr->u.sa, htons(o_lport)); 818 830 } 819 831 xmove_fd(x, netfd); -
branches/3.2/mindi-busybox/networking/netstat.c
r2725 r3232 22 22 //usage:#define netstat_full_usage "\n\n" 23 23 //usage: "Display networking information\n" 24 //usage: "\nOptions:"25 24 //usage: IF_ROUTE( 26 25 //usage: "\n -r Routing table" … … 189 188 if (pn->inode == inode) { 190 189 /* Some warning should be appropriate here 191 190 * as we got multiple processes for one i-node */ 192 191 return; 193 192 } -
branches/3.2/mindi-busybox/networking/nslookup.c
r2725 r3232 11 11 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 12 12 */ 13 14 //usage:#define nslookup_trivial_usage 15 //usage: "[HOST] [SERVER]" 16 //usage:#define nslookup_full_usage "\n\n" 17 //usage: "Query the nameserver for the IP address of the given HOST\n" 18 //usage: "optionally using a specified DNS server" 19 //usage: 20 //usage:#define nslookup_example_usage 21 //usage: "$ nslookup localhost\n" 22 //usage: "Server: default\n" 23 //usage: "Address: default\n" 24 //usage: "\n" 25 //usage: "Name: debian\n" 26 //usage: "Address: 127.0.0.1\n" 13 27 14 28 #include <resolv.h> … … 67 81 rc = getaddrinfo(hostname, NULL /*service*/, &hint, &result); 68 82 69 if ( !rc) {83 if (rc == 0) { 70 84 struct addrinfo *cur = result; 71 85 unsigned cnt = 0; … … 95 109 #endif 96 110 } 97 if (ENABLE_FEATURE_CLEAN_UP )111 if (ENABLE_FEATURE_CLEAN_UP && result) 98 112 freeaddrinfo(result); 99 113 return (rc != 0); -
branches/3.2/mindi-busybox/networking/ntpd.c
r2725 r3232 28 28 *********************************************************************** 29 29 */ 30 31 //usage:#define ntpd_trivial_usage 32 //usage: "[-dnqNw"IF_FEATURE_NTPD_SERVER("l")"] [-S PROG] [-p PEER]..." 33 //usage:#define ntpd_full_usage "\n\n" 34 //usage: "NTP client/server\n" 35 //usage: "\n -d Verbose" 36 //usage: "\n -n Do not daemonize" 37 //usage: "\n -q Quit after clock is set" 38 //usage: "\n -N Run at high priority" 39 //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 //usage: "\n -S PROG Run PROG after stepping time, stratum change, and every 11 mins" 44 //usage: "\n -p PEER Obtain time from PEER (may be repeated)" 45 30 46 #include "libbb.h" 31 47 #include <math.h> 32 48 #include <netinet/ip.h> /* For IPTOS_LOWDELAY definition */ 49 #include <sys/resource.h> /* setpriority */ 33 50 #include <sys/timex.h> 34 51 #ifndef IPTOS_LOWDELAY … … 92 109 #define BURSTPOLL 0 /* initial poll */ 93 110 #define MINPOLL 5 /* minimum poll interval. std ntpd uses 6 (6: 64 sec) */ 94 #define BIGPOLL 10 /* drop to lower poll at any trouble (10: 17 min) */ 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_). 113 */ 114 #define BIGPOLL 10 /* 2^10 sec ~= 17 min */ 95 115 #define MAXPOLL 12 /* maximum poll interval (12: 1.1h, 17: 36.4h). std ntpd uses 17 */ 96 116 /* Actively lower poll when we see such big offsets. 97 117 * With STEP_THRESHOLD = 0.125, it means we try to sync more aggressively 98 * if offset increases over 0.03sec */99 #define POLLDOWN_OFFSET (STEP_THRESHOLD / 4)118 * if offset increases over ~0.04 sec */ 119 #define POLLDOWN_OFFSET (STEP_THRESHOLD / 3) 100 120 #define MINDISP 0.01 /* minimum dispersion (sec) */ 101 121 #define MAXDISP 16 /* maximum dispersion (sec) */ … … 109 129 /* Poll-adjust threshold. 110 130 * When we see that offset is small enough compared to discipline jitter, 111 * we grow a counter: += MINPOLL. When itgoes over POLLADJ_LIMIT,131 * we grow a counter: += MINPOLL. When counter goes over POLLADJ_LIMIT, 112 132 * we poll_exp++. If offset isn't small, counter -= poll_exp*2, 113 * and when it goes below -POLLADJ_LIMIT, we poll_exp-- 114 * ( bumped from 30 to 36since otherwise I often see poll_exp going *2* steps down)133 * and when it goes below -POLLADJ_LIMIT, we poll_exp--. 134 * (Bumped from 30 to 40 since otherwise I often see poll_exp going *2* steps down) 115 135 */ 116 #define POLLADJ_LIMIT 36117 /* If offset < POLLADJ_GATE * discipline_jitter, then we canincrease136 #define POLLADJ_LIMIT 40 137 /* If offset < discipline_jitter * POLLADJ_GATE, then we decide to increase 118 138 * poll interval (we think we can't improve timekeeping 119 139 * by staying at smaller poll). 120 140 */ 121 141 #define POLLADJ_GATE 4 142 #define TIMECONST_HACK_GATE 2 122 143 /* Compromise Allan intercept (sec). doc uses 1500, std ntpd uses 512 */ 123 144 #define ALLAN 512 … … 193 214 194 215 typedef struct { 216 double d_offset; 195 217 double d_recv_time; 196 double d_offset;197 218 double d_dispersion; 198 219 } datapoint_t; … … 201 222 len_and_sockaddr *p_lsa; 202 223 char *p_dotted; 203 /* when to send new query (if p_fd == -1)204 * or when receive times out (if p_fd >= 0): */205 224 int p_fd; 206 225 int datapoint_idx; … … 209 228 uint8_t lastpkt_stratum; 210 229 uint8_t reachable_bits; 230 /* when to send new query (if p_fd == -1) 231 * or when receive times out (if p_fd >= 0): */ 211 232 double next_action_time; 212 233 double p_xmttime; … … 239 260 OPT_S = (1 << 6), 240 261 OPT_l = (1 << 7) * ENABLE_FEATURE_NTPD_SERVER, 262 /* We hijack some bits for other purposes */ 263 OPT_qq = (1 << 31), 241 264 }; 242 265 … … 255 278 #if ENABLE_FEATURE_NTPD_SERVER 256 279 int listen_fd; 280 # define G_listen_fd (G.listen_fd) 281 #else 282 # define G_listen_fd (-1) 257 283 #endif 258 284 unsigned verbose; 259 285 unsigned peer_cnt; 260 286 /* refid: 32-bit code identifying the particular server or reference clock 261 * in stratum 0 packets this is a four-character ASCII string, 262 * called the kiss code, used for debugging and monitoring 263 * in stratum 1 packets this is a four-character ASCII string 264 * assigned to the reference clock by IANA. Example: "GPS " 265 * in stratum 2+ packets, it's IPv4 address or 4 first bytes of MD5 hash of IPv6 287 * in stratum 0 packets this is a four-character ASCII string, 288 * called the kiss code, used for debugging and monitoring 289 * in stratum 1 packets this is a four-character ASCII string 290 * assigned to the reference clock by IANA. Example: "GPS " 291 * in stratum 2+ packets, it's IPv4 address or 4 first bytes 292 * of MD5 hash of IPv6 266 293 */ 267 294 uint32_t refid; … … 272 299 * system clock hardware representation is to the nanosecond. 273 300 * 274 * Delays, jitters of various kinds are clampe rdown to precision.301 * Delays, jitters of various kinds are clamped down to precision. 275 302 * 276 303 * If precision_sec is too large, discipline_jitter gets clamped to it 277 * and if offset is much smaller than discipline_jitter, poll interval278 * grows even though we really can benefit from staying at smaller one,279 * collecting non-lagged datapoits and correcting theoffset.304 * and if offset is smaller than discipline_jitter * POLLADJ_GATE, poll 305 * interval grows even though we really can benefit from staying at 306 * smaller one, collecting non-lagged datapoits and correcting offset. 280 307 * (Lagged datapoits exist when poll_exp is large but we still have 281 308 * systematic offset error - the time distance between datapoints 282 * is significa t and older datapoints have smaller offsets.309 * is significant and older datapoints have smaller offsets. 283 310 * This makes our offset estimation a bit smaller than reality) 284 311 * Due to this effect, setting G_precision_sec close to … … 286 313 * too big and we will step. I observed it with -6. 287 314 * 288 * OTOH, setting precision too small would result in futile attempts289 * to syncronize to theunachievable precision.315 * OTOH, setting precision_sec far too small would result in futile 316 * attempts to syncronize to an unachievable precision. 290 317 * 291 318 * -6 is 1/64 sec, -7 is 1/128 sec and so on. 292 */ 293 #define G_precision_exp -8 294 #define G_precision_sec (1.0 / (1 << (- G_precision_exp))) 319 * -8 is 1/256 ~= 0.003906 (worked well for me --vda) 320 * -9 is 1/512 ~= 0.001953 (let's try this for some time) 321 */ 322 #define G_precision_exp -9 323 /* 324 * G_precision_exp is used only for construction outgoing packets. 325 * It's ok to set G_precision_sec to a slightly different value 326 * (One which is "nicer looking" in logs). 327 * Exact value would be (1.0 / (1 << (- G_precision_exp))): 328 */ 329 #define G_precision_sec 0.002 295 330 uint8_t stratum; 296 331 /* Bool. After set to 1, never goes back to 0: */ … … 310 345 double last_update_recv_time; // s.t 311 346 double discipline_jitter; // c.jitter 347 /* Since we only compare it with ints, can simplify code 348 * by not making this variable floating point: 349 */ 350 unsigned offset_to_jitter_ratio; 312 351 //double cluster_offset; // s.offset 313 352 //double cluster_jitter; // s.jitter … … 483 522 { 484 523 int i, idx; 524 double sum, wavg; 525 datapoint_t *fdp; 526 527 #if 0 528 /* Simulations have shown that use of *averaged* offset for p->filter_offset 529 * is in fact worse than simply using last received one: with large poll intervals 530 * (>= 2048) averaging code uses offset values which are outdated by hours, 531 * and time/frequency correction goes totally wrong when fed essentially bogus offsets. 532 */ 485 533 int got_newest; 486 double minoff, maxoff, w avg, sum, w;534 double minoff, maxoff, w; 487 535 double x = x; /* for compiler */ 488 536 double oldest_off = oldest_off; … … 491 539 double newest_age = newest_age; 492 540 493 minoff = maxoff = p->filter_datapoint[0].d_offset; 541 fdp = p->filter_datapoint; 542 543 minoff = maxoff = fdp[0].d_offset; 494 544 for (i = 1; i < NUM_DATAPOINTS; i++) { 495 if (minoff > p->filter_datapoint[i].d_offset)496 minoff = p->filter_datapoint[i].d_offset;497 if (maxoff < p->filter_datapoint[i].d_offset)498 maxoff = p->filter_datapoint[i].d_offset;499 } 500 501 idx = p->datapoint_idx; /* most recent datapoint */545 if (minoff > fdp[i].d_offset) 546 minoff = fdp[i].d_offset; 547 if (maxoff < fdp[i].d_offset) 548 maxoff = fdp[i].d_offset; 549 } 550 551 idx = p->datapoint_idx; /* most recent datapoint's index */ 502 552 /* Average offset: 503 553 * Drop two outliers and take weighted average of the rest: … … 521 571 bb_error_msg("datapoint[%d]: off:%f disp:%f(%f) age:%f%s", 522 572 i, 523 p->filter_datapoint[idx].d_offset,524 p->filter_datapoint[idx].d_dispersion, dispersion(&p->filter_datapoint[idx]),525 G.cur_time - p->filter_datapoint[idx].d_recv_time,526 (minoff == p->filter_datapoint[idx].d_offset || maxoff == p->filter_datapoint[idx].d_offset)573 fdp[idx].d_offset, 574 fdp[idx].d_dispersion, dispersion(&fdp[idx]), 575 G.cur_time - fdp[idx].d_recv_time, 576 (minoff == fdp[idx].d_offset || maxoff == fdp[idx].d_offset) 527 577 ? " (outlier by offset)" : "" 528 578 ); 529 579 } 530 580 531 sum += dispersion(& p->filter_datapoint[idx]) / (2 << i);532 533 if (minoff == p->filter_datapoint[idx].d_offset) {581 sum += dispersion(&fdp[idx]) / (2 << i); 582 583 if (minoff == fdp[idx].d_offset) { 534 584 minoff -= 1; /* so that we don't match it ever again */ 535 585 } else 536 if (maxoff == p->filter_datapoint[idx].d_offset) {586 if (maxoff == fdp[idx].d_offset) { 537 587 maxoff += 1; 538 588 } else { 539 oldest_off = p->filter_datapoint[idx].d_offset;540 oldest_age = G.cur_time - p->filter_datapoint[idx].d_recv_time;589 oldest_off = fdp[idx].d_offset; 590 oldest_age = G.cur_time - fdp[idx].d_recv_time; 541 591 if (!got_newest) { 542 592 got_newest = 1; … … 570 620 } 571 621 p->filter_offset = wavg; 622 623 #else 624 625 fdp = p->filter_datapoint; 626 idx = p->datapoint_idx; /* most recent datapoint's index */ 627 628 /* filter_offset: simply use the most recent value */ 629 p->filter_offset = fdp[idx].d_offset; 630 631 /* n-1 632 * --- dispersion(i) 633 * filter_dispersion = \ ------------- 634 * / (i+1) 635 * --- 2 636 * i=0 637 */ 638 wavg = 0; 639 sum = 0; 640 for (i = 0; i < NUM_DATAPOINTS; i++) { 641 sum += dispersion(&fdp[idx]) / (2 << i); 642 wavg += fdp[idx].d_offset; 643 idx = (idx - 1) & (NUM_DATAPOINTS - 1); 644 } 645 wavg /= NUM_DATAPOINTS; 646 p->filter_dispersion = sum; 647 #endif 572 648 573 649 /* +----- -----+ ^ 1/2 … … 584 660 sum = 0; 585 661 for (i = 0; i < NUM_DATAPOINTS; i++) { 586 sum += SQUARE(wavg - p->filter_datapoint[i].d_offset);662 sum += SQUARE(wavg - fdp[i].d_offset); 587 663 } 588 664 sum = SQRT(sum / NUM_DATAPOINTS); 589 665 p->filter_jitter = sum > G_precision_sec ? sum : G_precision_sec; 590 666 591 VERB3 bb_error_msg("filter offset:% f(corr:%e)disp:%f jitter:%f",592 p->filter_offset, x,667 VERB3 bb_error_msg("filter offset:%+f disp:%f jitter:%f", 668 p->filter_offset, 593 669 p->filter_dispersion, 594 670 p->filter_jitter); … … 605 681 p->filter_datapoint[i].d_recv_time += offset; 606 682 if (p->filter_datapoint[i].d_offset != 0) { 607 p->filter_datapoint[i].d_offset += offset; 683 p->filter_datapoint[i].d_offset -= offset; 684 //bb_error_msg("p->filter_datapoint[%d].d_offset %f -> %f", 685 // i, 686 // p->filter_datapoint[i].d_offset + offset, 687 // p->filter_datapoint[i].d_offset); 608 688 } 609 689 } else { … … 702 782 } 703 783 784 /* Emit message _before_ attempted send. Think of a very short 785 * roundtrip networks: we need to go back to recv loop ASAP, 786 * to reduce delay. Printing messages after send works against that. 787 */ 788 VERB1 bb_error_msg("sending query to %s", p->p_dotted); 789 704 790 /* 705 791 * Send out a random 64-bit number as our transmit time. The NTP … … 729 815 730 816 p->reachable_bits <<= 1; 731 VERB1 bb_error_msg("sent query to %s", p->p_dotted);732 817 set_next(p, RESPONSE_INTERVAL); 733 818 } … … 791 876 llist_t *item; 792 877 double dtime; 793 struct timeval tv ;794 char buf[ 80];878 struct timeval tvc, tvn; 879 char buf[sizeof("yyyy-mm-dd hh:mm:ss") + /*paranoia:*/ 4]; 795 880 time_t tval; 796 881 797 gettimeofday(&tv, NULL); /* never fails */ 798 dtime = offset + tv.tv_sec; 799 dtime += 1.0e-6 * tv.tv_usec; 800 d_to_tv(dtime, &tv); 801 802 if (settimeofday(&tv, NULL) == -1) 882 gettimeofday(&tvc, NULL); /* never fails */ 883 dtime = tvc.tv_sec + (1.0e-6 * tvc.tv_usec) + offset; 884 d_to_tv(dtime, &tvn); 885 if (settimeofday(&tvn, NULL) == -1) 803 886 bb_perror_msg_and_die("settimeofday"); 804 887 805 tval = tv.tv_sec; 806 strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y", localtime(&tval)); 807 808 bb_error_msg("setting clock to %s (offset %fs)", buf, offset); 888 VERB2 { 889 tval = tvc.tv_sec; 890 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&tval)); 891 bb_error_msg("current time is %s.%06u", buf, (unsigned)tvc.tv_usec); 892 } 893 tval = tvn.tv_sec; 894 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&tval)); 895 bb_error_msg("setting time to %s.%06u (offset %+fs)", buf, (unsigned)tvn.tv_usec, offset); 809 896 810 897 /* Correct various fields which contain time-relative values: */ 898 899 /* Globals: */ 900 G.cur_time += offset; 901 G.last_update_recv_time += offset; 902 G.last_script_run += offset; 811 903 812 904 /* p->lastpkt_recv_time, p->next_action_time and such: */ … … 814 906 peer_t *pp = (peer_t *) item->data; 815 907 reset_peer_stats(pp, offset); 816 //bb_error_msg("offset:% f pp->next_action_time:%f -> %f",908 //bb_error_msg("offset:%+f pp->next_action_time:%f -> %f", 817 909 // offset, pp->next_action_time, pp->next_action_time + offset); 818 910 pp->next_action_time += offset; 819 } 820 /* Globals: */ 821 G.cur_time += offset; 822 G.last_update_recv_time += offset; 823 G.last_script_run += offset; 911 if (pp->p_fd >= 0) { 912 /* We wait for reply from this peer too. 913 * But due to step we are doing, reply's data is no longer 914 * useful (in fact, it'll be bogus). Stop waiting for it. 915 */ 916 close(pp->p_fd); 917 pp->p_fd = -1; 918 set_next(pp, RETRY_INTERVAL); 919 } 920 } 824 921 } 825 922 … … 883 980 // if (p->refid == p->dstaddr || p->refid == s.refid) 884 981 // return 0; 885 982 return 1; 886 983 } 887 984 static peer_t* … … 1150 1247 G.last_update_peer = p; 1151 1248 keep_old: 1152 VERB3 bb_error_msg("selected peer %s filter_offset:% f age:%f",1249 VERB3 bb_error_msg("selected peer %s filter_offset:%+f age:%f", 1153 1250 p->p_dotted, 1154 1251 p->filter_offset, … … 1241 1338 case STATE_SYNC: 1242 1339 /* The first outlyer: ignore it, switch to SPIK state */ 1243 VERB3 bb_error_msg("offset:% f - spike detected", offset);1340 VERB3 bb_error_msg("offset:%+f - spike detected", offset); 1244 1341 G.discipline_state = STATE_SPIK; 1245 1342 return -1; /* "decrease poll interval" */ … … 1278 1375 * intervals. 1279 1376 */ 1280 VERB3 bb_error_msg("stepping time by % f; poll_exp=MINPOLL", offset);1377 VERB3 bb_error_msg("stepping time by %+f; poll_exp=MINPOLL", offset); 1281 1378 step_time(offset); 1282 1379 if (option_mask32 & OPT_q) { … … 1297 1394 } 1298 1395 #endif 1299 set_new_values(STATE_SYNC, /*offset:*/ 0, recv_time); 1396 abs_offset = offset = 0; 1397 set_new_values(STATE_SYNC, offset, recv_time); 1300 1398 1301 1399 } else { /* abs_offset <= STEP_THRESHOLD */ 1302 1400 1303 1401 if (G.poll_exp < MINPOLL && G.initial_poll_complete) { 1304 VERB3 bb_error_msg("small offset:% f, disabling burst mode", offset);1402 VERB3 bb_error_msg("small offset:%+f, disabling burst mode", offset); 1305 1403 G.polladj_count = 0; 1306 1404 G.poll_exp = MINPOLL; … … 1311 1409 */ 1312 1410 etemp = SQUARE(G.discipline_jitter); 1313 dtemp = SQUARE( MAXD(fabs(offset - G.last_update_offset), G_precision_sec));1411 dtemp = SQUARE(offset - G.last_update_offset); 1314 1412 G.discipline_jitter = SQRT(etemp + (dtemp - etemp) / AVG); 1315 VERB3 bb_error_msg("discipline jitter=%f", G.discipline_jitter);1316 1413 1317 1414 switch (G.discipline_state) { … … 1390 1487 } 1391 1488 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 1392 1493 G.reftime = G.cur_time; 1393 1494 G.ntp_status = p->lastpkt_status; … … 1401 1502 /* We are in STATE_SYNC now, but did not do adjtimex yet. 1402 1503 * (Any other state does not reach this, they all return earlier) 1403 * By this time, freq_drift and G.last_update_offset are set1504 * By this time, freq_drift and offset are set 1404 1505 * to values suitable for adjtimex. 1405 1506 */ … … 1427 1528 if (adjtimex(&tmx) < 0) 1428 1529 bb_perror_msg_and_die("adjtimex"); 1429 VERB3 bb_error_msg("p adjtimex freq:%ld offset:%ld constant:%ld status:0x%x",1430 tmx.freq, tmx.offset, tmx. constant, tmx.status);1530 bb_error_msg("p adjtimex freq:%ld offset:%+ld status:0x%x tc:%ld", 1531 tmx.freq, tmx.offset, tmx.status, tmx.constant); 1431 1532 } 1432 1533 … … 1440 1541 /* 65536 is one ppm */ 1441 1542 tmx.freq = G.discipline_freq_drift * 65536e6; 1442 tmx.offset = G.last_update_offset * 1000000; /* usec */1443 1543 #endif 1444 1544 tmx.modes = ADJ_OFFSET | ADJ_STATUS | ADJ_TIMECONST;// | ADJ_MAXERROR | ADJ_ESTERROR; 1445 tmx.offset = (G.last_update_offset * 1000000); /* usec */ 1446 /* + (G.last_update_offset < 0 ? -0.5 : 0.5) - too small to bother */ 1545 tmx.offset = (offset * 1000000); /* usec */ 1447 1546 tmx.status = STA_PLL; 1448 1547 if (G.ntp_status & LI_PLUSSEC) … … 1450 1549 if (G.ntp_status & LI_MINUSSEC) 1451 1550 tmx.status |= STA_DEL; 1551 1452 1552 tmx.constant = G.poll_exp - 4; 1453 //tmx.esterror = (u_int32)(clock_jitter * 1e6); 1454 //tmx.maxerror = (u_int32)((sys_rootdelay / 2 + sys_rootdisp) * 1e6); 1553 /* EXPERIMENTAL. 1554 * The below if statement should be unnecessary, but... 1555 * It looks like Linux kernel's PLL is far too gentle in changing 1556 * tmx.freq in response to clock offset. Offset keeps growing 1557 * and eventually we fall back to smaller poll intervals. 1558 * We can make correction more agressive (about x2) by supplying 1559 * PLL time constant which is one less than the real one. 1560 * To be on a safe side, let's do it only if offset is significantly 1561 * larger than jitter. 1562 */ 1563 if (tmx.constant > 0 && G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE) 1564 tmx.constant--; 1565 1566 //tmx.esterror = (uint32_t)(clock_jitter * 1e6); 1567 //tmx.maxerror = (uint32_t)((sys_rootdelay / 2 + sys_rootdisp) * 1e6); 1455 1568 rc = adjtimex(&tmx); 1456 1569 if (rc < 0) … … 1459 1572 * Not sure why. Perhaps it is normal. 1460 1573 */ 1461 VERB3 bb_error_msg("adjtimex:%d freq:%ld offset:%ld constant:%ld status:0x%x", 1462 rc, tmx.freq, tmx.offset, tmx.constant, tmx.status); 1463 #if 0 1464 VERB3 { 1465 /* always gives the same output as above msg */ 1466 memset(&tmx, 0, sizeof(tmx)); 1467 if (adjtimex(&tmx) < 0) 1468 bb_perror_msg_and_die("adjtimex"); 1469 VERB3 bb_error_msg("c adjtimex freq:%ld offset:%ld constant:%ld status:0x%x", 1470 tmx.freq, tmx.offset, tmx.constant, tmx.status); 1471 } 1472 #endif 1574 VERB3 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x", 1575 rc, tmx.freq, tmx.offset, tmx.status); 1473 1576 G.kernel_freq_drift = tmx.freq / 65536; 1474 VERB2 bb_error_msg("update peer:%s, offset:%f, clock drift:%ld ppm",1475 p->p_dotted, G.last_update_offset, G.kernel_freq_drift);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); 1476 1579 1477 1580 return 1; /* "ok to increase poll interval" */ … … 1532 1635 //TODO: always do this? 1533 1636 interval = retry_interval(); 1534 goto set_next_and_ close_sock;1637 goto set_next_and_ret; 1535 1638 } 1536 1639 xfunc_die(); … … 1539 1642 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE) { 1540 1643 bb_error_msg("malformed packet received from %s", p->p_dotted); 1541 goto bail;1644 return; 1542 1645 } 1543 1646 … … 1545 1648 || msg.m_orgtime.fractionl != p->p_xmt_msg.m_xmttime.fractionl 1546 1649 ) { 1547 goto bail; 1548 } 1650 /* Somebody else's packet */ 1651 return; 1652 } 1653 1654 /* We do not expect any more packets from this peer for now. 1655 * Closing the socket informs kernel about it. 1656 * We open a new socket when we send a new query. 1657 */ 1658 close(p->p_fd); 1659 p->p_fd = -1; 1549 1660 1550 1661 if ((msg.m_status & LI_ALARM) == LI_ALARM … … 1556 1667 // "RATE" - peer is overloaded, reduce polling freq 1557 1668 interval = poll_interval(0); 1558 bb_error_msg("reply from %s: notsynced, next query in %us", p->p_dotted, interval);1559 goto set_next_and_ close_sock;1669 bb_error_msg("reply from %s: peer is unsynced, next query in %us", p->p_dotted, interval); 1670 goto set_next_and_ret; 1560 1671 } 1561 1672 … … 1609 1720 /* 1st datapoint ever - replicate offset in every element */ 1610 1721 int i; 1611 for (i = 1; i < NUM_DATAPOINTS; i++) {1722 for (i = 0; i < NUM_DATAPOINTS; i++) { 1612 1723 p->filter_datapoint[i].d_offset = datapoint->d_offset; 1613 1724 } … … 1616 1727 p->reachable_bits |= 1; 1617 1728 if ((MAX_VERBOSE && G.verbose) || (option_mask32 & OPT_w)) { 1618 bb_error_msg("reply from %s: reach 0x%02x offset %f delay %f status 0x%02x strat %d refid 0x%08x rootdelay %f",1729 bb_error_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x", 1619 1730 p->p_dotted, 1620 p->reachable_bits,1621 1731 datapoint->d_offset, 1622 1732 p->lastpkt_delay, … … 1624 1734 p->lastpkt_stratum, 1625 1735 p->lastpkt_refid, 1626 p->lastpkt_rootdelay 1736 p->lastpkt_rootdelay, 1737 p->reachable_bits 1627 1738 /* not shown: m_ppoll, m_precision_exp, m_rootdisp, 1628 1739 * m_reftime, m_orgtime, m_rectime, m_xmttime … … 1643 1754 */ 1644 1755 if (fabs(q->filter_offset) >= POLLDOWN_OFFSET) { 1645 VERB3 bb_error_msg("offset:% f > POLLDOWN_OFFSET", q->filter_offset);1756 VERB3 bb_error_msg("offset:%+f > POLLDOWN_OFFSET", q->filter_offset); 1646 1757 goto poll_down; 1647 1758 } … … 1657 1768 * helps calm the dance. Works best using burst mode. 1658 1769 */ 1659 VERB4 if (rc > 0) { 1660 bb_error_msg("offset:%f POLLADJ_GATE*discipline_jitter:%f poll:%s", 1661 q->filter_offset, POLLADJ_GATE * G.discipline_jitter, 1662 fabs(q->filter_offset) < POLLADJ_GATE * G.discipline_jitter 1663 ? "grows" : "falls" 1664 ); 1665 } 1666 if (rc > 0 && fabs(q->filter_offset) < POLLADJ_GATE * G.discipline_jitter) { 1770 if (rc > 0 && G.offset_to_jitter_ratio <= POLLADJ_GATE) { 1667 1771 /* was += G.poll_exp but it is a bit 1668 1772 * too optimistic for my taste at high poll_exp's */ … … 1710 1814 interval = poll_interval(0); 1711 1815 1712 set_next_and_ close_sock:1816 set_next_and_ret: 1713 1817 set_next(p, interval); 1714 /* We do not expect any more packets from this peer for now.1715 * Closing the socket informs kernel about it.1716 * We open a new socket when we send a new query.1717 */1718 close(p->p_fd);1719 p->p_fd = -1;1720 bail:1721 return;1722 1818 } 1723 1819 … … 1727 1823 { 1728 1824 ssize_t size; 1729 uint8_t version;1825 //uint8_t version; 1730 1826 len_and_sockaddr *to; 1731 1827 struct sockaddr *from; … … 1734 1830 l_fixedpt_t query_xmttime; 1735 1831 1736 to = get_sock_lsa(G .listen_fd);1832 to = get_sock_lsa(G_listen_fd); 1737 1833 from = xzalloc(to->len); 1738 1834 1739 size = recv_from_to(G .listen_fd, &msg, sizeof(msg), MSG_DONTWAIT, from, &to->u.sa, to->len);1835 size = recv_from_to(G_listen_fd, &msg, sizeof(msg), MSG_DONTWAIT, from, &to->u.sa, to->len); 1740 1836 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE) { 1741 1837 char *addr; … … 1756 1852 /* Build a reply packet */ 1757 1853 memset(&msg, 0, sizeof(msg)); 1758 msg.m_status = G.stratum < MAXSTRAT ? G.ntp_status: LI_ALARM;1854 msg.m_status = G.stratum < MAXSTRAT ? (G.ntp_status & LI_MASK) : LI_ALARM; 1759 1855 msg.m_status |= (query_status & VERSION_MASK); 1760 1856 msg.m_status |= ((query_status & MODE_MASK) == MODE_CLIENT) ? 1761 1857 MODE_SERVER : MODE_SYM_PAS; 1762 1858 msg.m_stratum = G.stratum; 1763 1859 msg.m_ppoll = G.poll_exp; … … 1775 1871 //simple code does not do this, fix simple code! 1776 1872 msg.m_rootdisp = d_to_sfp(G.rootdisp); 1777 version = (query_status & VERSION_MASK); /* ... >> VERSION_SHIFT - done below instead */1873 //version = (query_status & VERSION_MASK); /* ... >> VERSION_SHIFT - done below instead */ 1778 1874 msg.m_refid = G.refid; // (version > (3 << VERSION_SHIFT)) ? G.refid : G.refid3; 1779 1875 1780 1876 /* We reply from the local address packet was sent to, 1781 1877 * this makes to/from look swapped here: */ 1782 do_sendto(G .listen_fd,1878 do_sendto(G_listen_fd, 1783 1879 /*from:*/ &to->u.sa, /*to:*/ from, /*addrlen:*/ to->len, 1784 1880 &msg, size); … … 1919 2015 } 1920 2016 #if ENABLE_FEATURE_NTPD_SERVER 1921 G .listen_fd = -1;2017 G_listen_fd = -1; 1922 2018 if (opts & OPT_l) { 1923 G .listen_fd = create_and_bind_dgram_or_die(NULL, 123);1924 socket_want_pktinfo(G .listen_fd);1925 setsockopt(G .listen_fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY));2019 G_listen_fd = create_and_bind_dgram_or_die(NULL, 123); 2020 socket_want_pktinfo(G_listen_fd); 2021 setsockopt(G_listen_fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY)); 1926 2022 } 1927 2023 #endif … … 1931 2027 1932 2028 /* If network is up, syncronization occurs in ~10 seconds. 1933 * We give "ntpd -q" a full minute to finish, then we exit. 2029 * We give "ntpd -q" 10 seconds to get first reply, 2030 * then another 50 seconds to finish syncing. 1934 2031 * 1935 2032 * I tested ntpd 4.2.6p1 and apparently it never exits … … 1938 2035 * after a reasonably small period of polling, or fail. 1939 2036 */ 1940 if (opts & OPT_q) 1941 alarm(60); 2037 if (opts & OPT_q) { 2038 option_mask32 |= OPT_qq; 2039 alarm(10); 2040 } 1942 2041 1943 2042 bb_signals(0 … … 1982 2081 cnt = G.peer_cnt * (INITIAL_SAMPLES + 1); 1983 2082 2083 write_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid"); 2084 1984 2085 while (!bb_got_signal) { 1985 2086 llist_t *item; … … 1994 2095 i = 0; 1995 2096 #if ENABLE_FEATURE_NTPD_SERVER 1996 if (G .listen_fd != -1) {1997 pfd[0].fd = G .listen_fd;2097 if (G_listen_fd != -1) { 2098 pfd[0].fd = G_listen_fd; 1998 2099 pfd[0].events = POLLIN; 1999 2100 i++; … … 2040 2141 2041 2142 /* Here we may block */ 2042 VERB2 bb_error_msg("poll %us, sockets:%u, poll interval:%us", timeout, i, 1 << G.poll_exp); 2143 VERB2 { 2144 if (i > (ENABLE_FEATURE_NTPD_SERVER && G_listen_fd != -1)) { 2145 /* We wait for at least one reply. 2146 * Poll for it, without wasting time for message. 2147 * Since replies often come under 1 second, this also 2148 * reduces clutter in logs. 2149 */ 2150 nfds = poll(pfd, i, 1000); 2151 if (nfds != 0) 2152 goto did_poll; 2153 if (--timeout <= 0) 2154 goto did_poll; 2155 } 2156 bb_error_msg("poll:%us sockets:%u interval:%us", timeout, i, 1 << G.poll_exp); 2157 } 2043 2158 nfds = poll(pfd, i, timeout * 1000); 2159 did_poll: 2044 2160 gettime1900d(); /* sets G.cur_time */ 2045 2161 if (nfds <= 0) { … … 2066 2182 for (; nfds != 0 && j < i; j++) { 2067 2183 if (pfd[j].revents /* & (POLLIN|POLLERR)*/) { 2184 /* 2185 * At init, alarm was set to 10 sec. 2186 * Now we did get a reply. 2187 * Increase timeout to 50 seconds to finish syncing. 2188 */ 2189 if (option_mask32 & OPT_qq) { 2190 option_mask32 &= ~OPT_qq; 2191 alarm(50); 2192 } 2068 2193 nfds--; 2069 2194 recv_and_process_peer_pkt(idx2peer[j]); … … 2073 2198 } /* while (!bb_got_signal) */ 2074 2199 2200 remove_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid"); 2075 2201 kill_myself_with_sig(bb_got_signal); 2076 2202 } … … 2203 2329 if (!(pll_status & STA_PPSTIME)) 2204 2330 report_event(EVNT_KERN, 2205 2331 NULL, "PPS enabled"); 2206 2332 ntv.status |= STA_PPSTIME | STA_PPSFREQ; 2207 2333 } else { 2208 2334 if (pll_status & STA_PPSTIME) 2209 2335 report_event(EVNT_KERN, 2210 NULL, "PPS disabled"); 2211 ntv.status &= ~(STA_PPSTIME | 2212 STA_PPSFREQ); 2336 NULL, "PPS disabled"); 2337 ntv.status &= ~(STA_PPSTIME | STA_PPSFREQ); 2213 2338 } 2214 2339 if (sys_leap == LEAP_ADDSECOND) … … 2226 2351 if (!(ntv.status & STA_PPSSIGNAL)) 2227 2352 report_event(EVNT_KERN, NULL, 2228 2353 "PPS no signal"); 2229 2354 } 2230 2355 pll_status = ntv.status; -
branches/3.2/mindi-busybox/networking/ntpd_simple.c
r2725 r3232 8 8 #include "libbb.h" 9 9 #include <netinet/ip.h> /* For IPTOS_LOWDELAY definition */ 10 #include <sys/resource.h> /* setpriority */ 10 11 #ifndef IPTOS_LOWDELAY 11 12 # define IPTOS_LOWDELAY 0x10 … … 710 711 msg.m_status |= (query_status & VERSION_MASK); 711 712 msg.m_status |= ((query_status & MODE_MASK) == MODE_CLIENT) ? 712 713 MODE_SERVER : MODE_SYM_PAS; 713 714 msg.m_stratum = G.stratum; 714 715 msg.m_ppoll = query_ppoll; -
branches/3.2/mindi-busybox/networking/ping.c
r2725 r3232 29 29 #include <netinet/ip_icmp.h> 30 30 #include "libbb.h" 31 32 #ifdef __BIONIC__ 33 /* should be in netinet/ip_icmp.h */ 34 # define ICMP_DEST_UNREACH 3 /* Destination Unreachable */ 35 # define ICMP_SOURCE_QUENCH 4 /* Source Quench */ 36 # define ICMP_REDIRECT 5 /* Redirect (change route) */ 37 # define ICMP_ECHO 8 /* Echo Request */ 38 # define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */ 39 # define ICMP_PARAMETERPROB 12 /* Parameter Problem */ 40 # define ICMP_TIMESTAMP 13 /* Timestamp Request */ 41 # define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */ 42 # define ICMP_INFO_REQUEST 15 /* Information Request */ 43 # define ICMP_INFO_REPLY 16 /* Information Reply */ 44 # define ICMP_ADDRESS 17 /* Address Mask Request */ 45 # define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */ 46 #endif 47 48 //config:config PING 49 //config: bool "ping" 50 //config: default y 51 //config: select PLATFORM_LINUX 52 //config: help 53 //config: ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to 54 //config: elicit an ICMP ECHO_RESPONSE from a host or gateway. 55 //config: 56 //config:config PING6 57 //config: bool "ping6" 58 //config: default y 59 //config: depends on FEATURE_IPV6 && PING 60 //config: help 61 //config: This will give you a ping that can talk IPv6. 62 //config: 63 //config:config FEATURE_FANCY_PING 64 //config: bool "Enable fancy ping output" 65 //config: default y 66 //config: depends on PING 67 //config: help 68 //config: Make the output from the ping applet include statistics, and at the 69 //config: same time provide full support for ICMP packets. 70 71 /* Needs socket(AF_INET, SOCK_RAW, IPPROTO_ICMP), therefore BB_SUID_MAYBE: */ 72 //applet:IF_PING(APPLET(ping, BB_DIR_BIN, BB_SUID_MAYBE)) 73 //applet:IF_PING6(APPLET(ping6, BB_DIR_BIN, BB_SUID_MAYBE)) 74 75 //kbuild:lib-$(CONFIG_PING) += ping.o 76 //kbuild:lib-$(CONFIG_PING6) += ping.o 77 78 //usage:#if !ENABLE_FEATURE_FANCY_PING 79 //usage:# define ping_trivial_usage 80 //usage: "HOST" 81 //usage:# define ping_full_usage "\n\n" 82 //usage: "Send ICMP ECHO_REQUEST packets to network hosts" 83 //usage:# define ping6_trivial_usage 84 //usage: "HOST" 85 //usage:# define ping6_full_usage "\n\n" 86 //usage: "Send ICMP ECHO_REQUEST packets to network hosts" 87 //usage:#else 88 //usage:# define ping_trivial_usage 89 //usage: "[OPTIONS] HOST" 90 //usage:# define ping_full_usage "\n\n" 91 //usage: "Send ICMP ECHO_REQUEST packets to network hosts\n" 92 //usage: "\n -4,-6 Force IP or IPv6 name resolution" 93 //usage: "\n -c CNT Send only CNT pings" 94 //usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)" 95 //usage: "\n -t TTL Set TTL" 96 //usage: "\n -I IFACE/IP Use interface or IP address as source" 97 //usage: "\n -W SEC Seconds to wait for the first response (default:10)" 98 //usage: "\n (after all -c CNT packets are sent)" 99 //usage: "\n -w SEC Seconds until ping exits (default:infinite)" 100 //usage: "\n (can exit earlier with -c CNT)" 101 //usage: "\n -q Quiet, only displays output at start" 102 //usage: "\n and when finished" 103 //usage: 104 //usage:# define ping6_trivial_usage 105 //usage: "[OPTIONS] HOST" 106 //usage:# define ping6_full_usage "\n\n" 107 //usage: "Send ICMP ECHO_REQUEST packets to network hosts\n" 108 //usage: "\n -c CNT Send only CNT pings" 109 //usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)" 110 //usage: "\n -I IFACE/IP Use interface or IP address as source" 111 //usage: "\n -q Quiet, only displays output at start" 112 //usage: "\n and when finished" 113 //usage: 114 //usage:#endif 115 //usage: 116 //usage:#define ping_example_usage 117 //usage: "$ ping localhost\n" 118 //usage: "PING slag (127.0.0.1): 56 data bytes\n" 119 //usage: "64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=20.1 ms\n" 120 //usage: "\n" 121 //usage: "--- debian ping statistics ---\n" 122 //usage: "1 packets transmitted, 1 packets received, 0% packet loss\n" 123 //usage: "round-trip min/avg/max = 20.1/20.1/20.1 ms\n" 124 //usage:#define ping6_example_usage 125 //usage: "$ ping6 ip6-localhost\n" 126 //usage: "PING ip6-localhost (::1): 56 data bytes\n" 127 //usage: "64 bytes from ::1: icmp6_seq=0 ttl=64 time=20.1 ms\n" 128 //usage: "\n" 129 //usage: "--- ip6-localhost ping statistics ---\n" 130 //usage: "1 packets transmitted, 1 packets received, 0% packet loss\n" 131 //usage: "round-trip min/avg/max = 20.1/20.1/20.1 ms\n" 31 132 32 133 #if ENABLE_PING6 … … 49 150 }; 50 151 51 /* Common routines */52 53 static int in_cksum(unsigned short *buf, int sz)54 {55 int nleft = sz;56 int sum = 0;57 unsigned short *w = buf;58 unsigned short ans = 0;59 60 while (nleft > 1) {61 sum += *w++;62 nleft -= 2;63 }64 65 if (nleft == 1) {66 *(unsigned char *) (&ans) = *(unsigned char *) w;67 sum += ans;68 }69 70 sum = (sum >> 16) + (sum & 0xFFFF);71 sum += (sum >> 16);72 ans = ~sum;73 return ans;74 }75 76 152 #if !ENABLE_FEATURE_FANCY_PING 77 153 … … 101 177 memset(pkt, 0, sizeof(G.packet)); 102 178 pkt->icmp_type = ICMP_ECHO; 103 pkt->icmp_cksum = in _cksum((unsigned short *) pkt, sizeof(G.packet));179 pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, sizeof(G.packet)); 104 180 105 181 xsendto(pingsock, G.packet, DEFDATALEN + ICMP_MINLEN, &lsa->u.sa, lsa->len); … … 224 300 /* Full(er) version */ 225 301 226 #define OPT_STRING ("qvc:s: w:W:I:4" IF_PING6("6"))302 #define OPT_STRING ("qvc:s:t:w:W:I:4" IF_PING6("6")) 227 303 enum { 228 304 OPT_QUIET = 1 << 0, … … 230 306 OPT_c = 1 << 2, 231 307 OPT_s = 1 << 3, 232 OPT_w = 1 << 4, 233 OPT_W = 1 << 5, 234 OPT_I = 1 << 6, 235 OPT_IPV4 = 1 << 7, 236 OPT_IPV6 = (1 << 8) * ENABLE_PING6, 308 OPT_t = 1 << 4, 309 OPT_w = 1 << 5, 310 OPT_W = 1 << 6, 311 OPT_I = 1 << 7, 312 OPT_IPV4 = 1 << 8, 313 OPT_IPV6 = (1 << 9) * ENABLE_PING6, 237 314 }; 238 315 … … 245 322 unsigned datalen; 246 323 unsigned pingcount; /* must be int-sized */ 324 unsigned opt_ttl; 247 325 unsigned long ntransmitted, nreceived, nrepeats; 248 326 uint16_t myid; … … 276 354 #define nrepeats (G.nrepeats ) 277 355 #define pingcount (G.pingcount ) 356 #define opt_ttl (G.opt_ttl ) 278 357 #define myid (G.myid ) 279 358 #define tmin (G.tmin ) … … 330 409 } 331 410 332 static void sendping_tail(void (*sp)(int), const void *pkt,int size_pkt)411 static void sendping_tail(void (*sp)(int), int size_pkt) 333 412 { 334 413 int sz; … … 337 416 ntransmitted++; 338 417 418 size_pkt += datalen; 419 339 420 /* sizeof(pingaddr) can be larger than real sa size, but I think 340 421 * it doesn't matter */ 341 sz = xsendto(pingsock, pkt, size_pkt, &pingaddr.sa, sizeof(pingaddr));422 sz = xsendto(pingsock, G.snd_packet, size_pkt, &pingaddr.sa, sizeof(pingaddr)); 342 423 if (sz != size_pkt) 343 424 bb_error_msg_and_die(bb_msg_write_error); … … 388 469 *(uint32_t*)&pkt->icmp_dun = monotonic_us(); 389 470 390 pkt->icmp_cksum = in _cksum((unsigned short *) pkt, datalen + ICMP_MINLEN);391 392 sendping_tail(sendping4, pkt, datalen +ICMP_MINLEN);471 pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, datalen + ICMP_MINLEN); 472 473 sendping_tail(sendping4, ICMP_MINLEN); 393 474 } 394 475 #if ENABLE_PING6 … … 407 488 *(uint32_t*)(&pkt->icmp6_data8[4]) = monotonic_us(); 408 489 409 //TODO? pkt->icmp_cksum = in _cksum(...);410 411 sendping_tail(sendping6, pkt, datalen +sizeof(struct icmp6_hdr));490 //TODO? pkt->icmp_cksum = inet_cksum(...); 491 492 sendping_tail(sendping6, sizeof(struct icmp6_hdr)); 412 493 } 413 494 #endif … … 533 614 } 534 615 #if ENABLE_PING6 535 static void unpack6(char *packet, int sz, /*struct sockaddr_in6 *from,*/int hoplimit)616 static void unpack6(char *packet, int sz, struct sockaddr_in6 *from, int hoplimit) 536 617 { 537 618 struct icmp6_hdr *icmppkt; … … 553 634 tp = (uint32_t *) &icmppkt->icmp6_data8[4]; 554 635 unpack_tail(sz, tp, 555 inet_ntop(AF_INET6, & pingaddr.sin6.sin6_addr,636 inet_ntop(AF_INET6, &from->sin6_addr, 556 637 buf, sizeof(buf)), 557 638 recv_seq, hoplimit); … … 586 667 sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */ 587 668 setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt)); 669 670 if (opt_ttl != 0) { 671 setsockopt(pingsock, IPPROTO_IP, IP_TTL, &opt_ttl, sizeof(opt_ttl)); 672 /* above doesnt affect packets sent to bcast IP, so... */ 673 setsockopt(pingsock, IPPROTO_IP, IP_MULTICAST_TTL, &opt_ttl, sizeof(opt_ttl)); 674 } 588 675 589 676 signal(SIGINT, print_stats_and_exit); … … 638 725 } 639 726 if (setsockopt(pingsock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, 640 727 sizeof(filt)) < 0) 641 728 bb_error_msg_and_die("setsockopt(ICMP6_FILTER)"); 642 729 } … … 697 784 } 698 785 } 699 unpack6(G.rcv_packet, c, /*&from,*/hoplimit);786 unpack6(G.rcv_packet, c, &from, hoplimit); 700 787 if (pingcount && nreceived >= pingcount) 701 788 break; … … 736 823 INIT_G(); 737 824 738 /* exactly one argument needed; -v and -q don't mix; -c NUM, - w NUM, -W NUM */739 opt_complementary = "=1:q--v:v--q:c+: w+:W+";740 opt |= getopt32(argv, OPT_STRING, &pingcount, &str_s, & deadline, &timeout, &str_I);825 /* exactly one argument needed; -v and -q don't mix; -c NUM, -t NUM, -w NUM, -W NUM */ 826 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); 741 828 if (opt & OPT_s) 742 829 datalen = xatou16(str_s); // -s -
branches/3.2/mindi-busybox/networking/pscan.c
r2725 r3232 6 6 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 7 */ 8 9 //usage:#define pscan_trivial_usage 10 //usage: "[-cb] [-p MIN_PORT] [-P MAX_PORT] [-t TIMEOUT] [-T MIN_RTT] HOST" 11 //usage:#define pscan_full_usage "\n\n" 12 //usage: "Scan a host, print all open ports\n" 13 //usage: "\n -c Show closed ports too" 14 //usage: "\n -b Show blocked ports too" 15 //usage: "\n -p Scan from this port (default 1)" 16 //usage: "\n -P Scan up to this port (default 1024)" 17 //usage: "\n -t Timeout (default 5000 ms)" 18 //usage: "\n -T Minimum rtt (default 5 ms, increase for congested hosts)" 8 19 9 20 #include "libbb.h" … … 77 88 78 89 /* The SOCK_STREAM socket type is implemented on the TCP/IP protocol. */ 79 set_nport( lsap, htons(port));90 set_nport(&lsap->u.sa, htons(port)); 80 91 s = xsocket(lsap->u.sa.sa_family, SOCK_STREAM, 0); 81 92 /* We need unblocking socket so we don't need to wait for ETIMEOUT. */ -
branches/3.2/mindi-busybox/networking/route.c
r2725 r3232 26 26 */ 27 27 28 //usage:#define route_trivial_usage 29 //usage: "[{add|del|delete}]" 30 //usage:#define route_full_usage "\n\n" 31 //usage: "Edit kernel routing tables\n" 32 //usage: "\n -n Don't resolve names" 33 //usage: "\n -e Display other/more information" 34 //usage: "\n -A inet" IF_FEATURE_IPV6("{6}") " Select address family" 35 28 36 #include <net/route.h> 29 37 #include <net/if.h> … … 154 162 static NOINLINE void INET_setroute(int action, char **args) 155 163 { 156 struct rtentry rt; 164 /* char buffer instead of bona-fide struct avoids aliasing warning */ 165 char rt_buf[sizeof(struct rtentry)]; 166 struct rtentry *const rt = (void *)rt_buf; 167 157 168 const char *netmask = NULL; 158 169 int skfd, isnet, xflag; … … 167 178 168 179 /* Clean out the RTREQ structure. */ 169 memset( &rt, 0, sizeof(rt));180 memset(rt, 0, sizeof(*rt)); 170 181 171 182 { … … 179 190 180 191 prefix_len = xatoul_range(prefix+1, 0, 32); 181 mask_in_addr( rt) = htonl( ~(0xffffffffUL >> prefix_len));192 mask_in_addr(*rt) = htonl( ~(0xffffffffUL >> prefix_len)); 182 193 *prefix = '\0'; 183 194 #if HAVE_NEW_ADDRT 184 rt .rt_genmask.sa_family = AF_INET;195 rt->rt_genmask.sa_family = AF_INET; 185 196 #endif 186 197 } else { … … 189 200 } 190 201 /* Prefer hostname lookup is -host flag (xflag==1) was given. */ 191 isnet = INET_resolve(target, (struct sockaddr_in *) &rt .rt_dst,202 isnet = INET_resolve(target, (struct sockaddr_in *) &rt->rt_dst, 192 203 (xflag & HOST_FLAG)); 193 204 if (isnet < 0) { … … 205 216 206 217 /* Fill in the other fields. */ 207 rt .rt_flags = ((isnet) ? RTF_UP : (RTF_UP | RTF_HOST));218 rt->rt_flags = ((isnet) ? RTF_UP : (RTF_UP | RTF_HOST)); 208 219 209 220 while (*args) { … … 212 223 213 224 if (k & KW_IPVx_FLAG_ONLY) { 214 rt .rt_flags |= flags_ipvx[k & 3];225 rt->rt_flags |= flags_ipvx[k & 3]; 215 226 continue; 216 227 } … … 218 229 #if HAVE_NEW_ADDRT 219 230 if (k == KW_IPVx_METRIC) { 220 rt .rt_metric = xatoul(args_m1) + 1;231 rt->rt_metric = xatoul(args_m1) + 1; 221 232 continue; 222 233 } … … 226 237 struct sockaddr mask; 227 238 228 if (mask_in_addr( rt)) {239 if (mask_in_addr(*rt)) { 229 240 bb_show_usage(); 230 241 } … … 235 246 bb_error_msg_and_die("resolving %s", netmask); 236 247 } 237 rt .rt_genmask = full_mask(mask);248 rt->rt_genmask = full_mask(mask); 238 249 continue; 239 250 } 240 251 241 252 if (k == KW_IPVx_GATEWAY) { 242 if (rt .rt_flags & RTF_GATEWAY) {253 if (rt->rt_flags & RTF_GATEWAY) { 243 254 bb_show_usage(); 244 255 } 245 256 246 257 isnet = INET_resolve(args_m1, 247 (struct sockaddr_in *) &rt.rt_gateway, 1);248 rt .rt_flags |= RTF_GATEWAY;258 (struct sockaddr_in *) &rt->rt_gateway, 1); 259 rt->rt_flags |= RTF_GATEWAY; 249 260 250 261 if (isnet) { … … 258 269 259 270 if (k == KW_IPVx_MSS) { /* Check valid MSS bounds. */ 260 rt .rt_flags |= RTF_MSS;261 rt .rt_mss = xatoul_range(args_m1, 64, 32768);271 rt->rt_flags |= RTF_MSS; 272 rt->rt_mss = xatoul_range(args_m1, 64, 32768); 262 273 continue; 263 274 } 264 275 265 276 if (k == KW_IPVx_WINDOW) { /* Check valid window bounds. */ 266 rt .rt_flags |= RTF_WINDOW;267 rt .rt_window = xatoul_range(args_m1, 128, INT_MAX);277 rt->rt_flags |= RTF_WINDOW; 278 rt->rt_window = xatoul_range(args_m1, 128, INT_MAX); 268 279 continue; 269 280 } … … 271 282 #ifdef RTF_IRTT 272 283 if (k == KW_IPVx_IRTT) { 273 rt .rt_flags |= RTF_IRTT;274 rt .rt_irtt = xatoul(args_m1);275 rt .rt_irtt *= (sysconf(_SC_CLK_TCK) / 100); /* FIXME */284 rt->rt_flags |= RTF_IRTT; 285 rt->rt_irtt = xatoul(args_m1); 286 rt->rt_irtt *= (sysconf(_SC_CLK_TCK) / 100); /* FIXME */ 276 287 #if 0 /* FIXME: do we need to check anything of this? */ 277 if (rt .rt_irtt < 1 || rt.rt_irtt > (120 * HZ)) {288 if (rt->rt_irtt < 1 || rt->rt_irtt > (120 * HZ)) { 278 289 bb_error_msg_and_die("bad irtt"); 279 290 } … … 285 296 /* Device is special in that it can be the last arg specified 286 297 * and doesn't requre the dev/device keyword in that case. */ 287 if (!rt .rt_dev && ((k == KW_IPVx_DEVICE) || (!k && !*++args))) {298 if (!rt->rt_dev && ((k == KW_IPVx_DEVICE) || (!k && !*++args))) { 288 299 /* Don't use args_m1 here since args may have changed! */ 289 rt .rt_dev = args[-1];300 rt->rt_dev = args[-1]; 290 301 continue; 291 302 } … … 296 307 297 308 #ifdef RTF_REJECT 298 if ((rt .rt_flags & RTF_REJECT) && !rt.rt_dev) {299 rt .rt_dev = (char*)"lo";309 if ((rt->rt_flags & RTF_REJECT) && !rt->rt_dev) { 310 rt->rt_dev = (char*)"lo"; 300 311 } 301 312 #endif 302 313 303 314 /* sanity checks.. */ 304 if (mask_in_addr( rt)) {305 uint32_t mask = mask_in_addr( rt);315 if (mask_in_addr(*rt)) { 316 uint32_t mask = mask_in_addr(*rt); 306 317 307 318 mask = ~ntohl(mask); 308 if ((rt .rt_flags & RTF_HOST) && mask != 0xffffffff) {319 if ((rt->rt_flags & RTF_HOST) && mask != 0xffffffff) { 309 320 bb_error_msg_and_die("netmask %.8x and host route conflict", 310 321 (unsigned int) mask); … … 313 324 bb_error_msg_and_die("bogus netmask %s", netmask); 314 325 } 315 mask = ((struct sockaddr_in *) &rt .rt_dst)->sin_addr.s_addr;316 if (mask & ~(uint32_t)mask_in_addr( rt)) {326 mask = ((struct sockaddr_in *) &rt->rt_dst)->sin_addr.s_addr; 327 if (mask & ~(uint32_t)mask_in_addr(*rt)) { 317 328 bb_error_msg_and_die("netmask and route address conflict"); 318 329 } … … 320 331 321 332 /* Fill out netmask if still unset */ 322 if ((action == RTACTION_ADD) && (rt .rt_flags & RTF_HOST)) {323 mask_in_addr( rt) = 0xffffffff;333 if ((action == RTACTION_ADD) && (rt->rt_flags & RTF_HOST)) { 334 mask_in_addr(*rt) = 0xffffffff; 324 335 } 325 336 … … 328 339 329 340 if (action == RTACTION_ADD) 330 xioctl(skfd, SIOCADDRT, &rt);341 xioctl(skfd, SIOCADDRT, rt); 331 342 else 332 xioctl(skfd, SIOCDELRT, &rt);343 xioctl(skfd, SIOCDELRT, rt); 333 344 334 345 if (ENABLE_FEATURE_CLEAN_UP) close(skfd); … … 399 410 } 400 411 memcpy(&rt.rtmsg_gateway, sa6.sin6_addr.s6_addr, 401 412 sizeof(struct in6_addr)); 402 413 rt.rtmsg_flags |= RTF_GATEWAY; 403 414 continue; … … 425 436 memset(&ifr, 0, sizeof(ifr)); 426 437 strncpy_IFNAMSIZ(ifr.ifr_name, devname); 427 xioctl(skfd, SIO GIFINDEX, &ifr);438 xioctl(skfd, SIOCGIFINDEX, &ifr); 428 439 rt.rtmsg_ifindex = ifr.ifr_ifindex; 429 440 } … … 488 499 489 500 printf("Kernel IP routing table\n" 490 501 "Destination Gateway Genmask Flags %s Iface\n", 491 502 netstatfmt ? " MSS Window irtt" : "Metric Ref Use"); 492 503 493 504 if (fscanf(fp, "%*[^\n]\n") < 0) { /* Skip the first line. */ 494 goto ERROR; 505 goto ERROR; /* Empty or missing line, or read error. */ 495 506 } 496 507 while (1) { 497 508 int r; 498 509 r = fscanf(fp, "%63s%lx%lx%X%d%d%d%lx%d%d%d\n", 499 500 510 devname, &d, &g, &flgs, &ref, &use, &metric, &m, 511 &mtu, &win, &ir); 501 512 if (r != 11) { 502 513 if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */ … … 535 546 } 536 547 } 548 fclose(fp); 537 549 } 538 550 … … 556 568 557 569 printf("Kernel IPv6 routing table\n%-44s%-40s" 558 559 570 "Flags Metric Ref Use Iface\n", 571 "Destination", "Next Hop"); 560 572 561 573 while (1) { … … 602 614 603 615 r = 0; 604 do{616 while (1) { 605 617 inet_pton(AF_INET6, addr6x + r, 606 618 (struct sockaddr *) &snaddr6.sin6_addr); 607 619 snaddr6.sin6_family = AF_INET6; 608 620 naddr6 = INET6_rresolve((struct sockaddr_in6 *) &snaddr6, 609 610 621 0x0fff /* Apparently, upstream never resolves. */ 622 ); 611 623 612 624 if (!r) { /* 1st pass */ … … 621 633 break; 622 634 } 623 } while (1); 624 } 635 } 636 } 637 fclose(fp); 625 638 } 626 639 -
branches/3.2/mindi-busybox/networking/slattach.c
r2725 r3232 13 13 * - The -F options allows disabling of RTS/CTS flow control. 14 14 */ 15 16 //usage:#define slattach_trivial_usage 17 //usage: "[-cehmLF] [-s SPEED] [-p PROTOCOL] DEVICE" 18 //usage:#define slattach_full_usage "\n\n" 19 //usage: "Attach network interface(s) to serial line(s)\n" 20 //usage: "\n -p PROT Set protocol (slip, cslip, slip6, clisp6 or adaptive)" 21 //usage: "\n -s SPD Set line speed" 22 //usage: "\n -e Exit after initializing device" 23 //usage: "\n -h Exit when the carrier is lost" 24 //usage: "\n -c PROG Run PROG when the line is hung up" 25 //usage: "\n -m Do NOT initialize the line in raw 8 bits mode" 26 //usage: "\n -L Enable 3-wire operation" 27 //usage: "\n -F Disable RTS/CTS flow control" 15 28 16 29 #include "libbb.h" -
branches/3.2/mindi-busybox/networking/tc.c
r2725 r3232 7 7 * Bernhard Reutner-Fischer adjusted for busybox 8 8 */ 9 10 //usage:#define tc_trivial_usage 11 /* //usage: "[OPTIONS] OBJECT CMD [dev STRING]" */ 12 //usage: "OBJECT CMD [dev STRING]" 13 //usage:#define tc_full_usage "\n\n" 14 //usage: "OBJECT: {qdisc|class|filter}\n" 15 //usage: "CMD: {add|del|change|replace|show}\n" 16 //usage: "\n" 17 //usage: "qdisc [ handle QHANDLE ] [ root |"IF_FEATURE_TC_INGRESS(" ingress |")" parent CLASSID ]\n" 18 /* //usage: "[ estimator INTERVAL TIME_CONSTANT ]\n" */ 19 //usage: " [ [ QDISC_KIND ] [ help | OPTIONS ] ]\n" 20 //usage: " QDISC_KIND := { [p|b]fifo | tbf | prio | cbq | red | etc. }\n" 21 //usage: "qdisc show [ dev STRING ]"IF_FEATURE_TC_INGRESS(" [ingress]")"\n" 22 //usage: "class [ classid CLASSID ] [ root | parent CLASSID ]\n" 23 //usage: " [ [ QDISC_KIND ] [ help | OPTIONS ] ]\n" 24 //usage: "class show [ dev STRING ] [ root | parent CLASSID ]\n" 25 //usage: "filter [ pref PRIO ] [ protocol PROTO ]\n" 26 /* //usage: "\t[ estimator INTERVAL TIME_CONSTANT ]\n" */ 27 //usage: " [ root | classid CLASSID ] [ handle FILTERID ]\n" 28 //usage: " [ [ FILTER_TYPE ] [ help | OPTIONS ] ]\n" 29 //usage: "filter show [ dev STRING ] [ root | parent CLASSID ]" 9 30 10 31 #include "libbb.h" … … 38 59 struct globals { 39 60 int filter_ifindex; 40 __u32filter_qdisc;41 __u32filter_parent;42 __u32filter_prio;43 __u32filter_proto;61 uint32_t filter_qdisc; 62 uint32_t filter_parent; 63 uint32_t filter_prio; 64 uint32_t filter_proto; 44 65 } FIX_ALIASING; 45 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 }; 46 70 #define filter_ifindex (G.filter_ifindex) 47 71 #define filter_qdisc (G.filter_qdisc) … … 49 73 #define filter_prio (G.filter_prio) 50 74 #define filter_proto (G.filter_proto) 51 52 void BUG_tc_globals_too_big(void); 53 #define INIT_G() do { \ 54 if (sizeof(G) > COMMON_BUFSIZE) \ 55 BUG_tc_globals_too_big(); \ 56 } while (0) 75 #define INIT_G() do { } while (0) 57 76 58 77 /* Allocates a buffer containing the name of a class id. … … 76 95 77 96 /* Get a qdisc handle. Return 0 on success, !0 otherwise. */ 78 static int get_qdisc_handle( __u32*h, const char *str) {79 __u32maj;97 static int get_qdisc_handle(uint32_t *h, const char *str) { 98 uint32_t maj; 80 99 char *p; 81 100 … … 95 114 96 115 /* Get class ID. Return 0 on success, !0 otherwise. */ 97 static int get_tc_classid( __u32*h, const char *str) {98 __u32maj, min;116 static int get_tc_classid(uint32_t *h, const char *str) { 117 uint32_t maj, min; 99 118 char *p; 100 119 … … 373 392 else if (msg->tcm_parent) { 374 393 classid = print_tc_classid(filter_qdisc ? 375 394 TC_H_MIN(msg->tcm_parent) : msg->tcm_parent); 376 395 printf("parent %s ", classid); 377 396 if (ENABLE_FEATURE_CLEAN_UP) … … 495 514 filter_parent = TC_H_ROOT; 496 515 } else if (arg == ARG_parent) { 497 __u32handle;516 uint32_t handle; 498 517 if (msg.tcm_parent) 499 518 duparg(*argv, "parent"); … … 508 527 /* reject LONG_MIN || LONG_MAX */ 509 528 /* TODO: for fw 510 if ((slash = strchr(handle, '/')) != NULL) 529 slash = strchr(handle, '/'); 530 if (slash != NULL) 511 531 *slash = '\0'; 512 532 */ 513 533 msg.tcm_handle = get_u32(*argv, "handle"); 514 /* if (slash) {if (get_u32( __u32&mask, slash+1, NULL)) inv mask; addattr32(n, MAX_MSG, TCA_FW_MASK, mask); */534 /* if (slash) {if (get_u32(uint32_t &mask, slash+1, NULL)) inv mask; addattr32(n, MAX_MSG, TCA_FW_MASK, mask); */ 515 535 } else if (arg == ARG_classid && obj == OBJ_class && cmd == CMD_change){ 516 536 } else if (arg == ARG_pref || arg == ARG_prio) { /* filter::list */ -
branches/3.2/mindi-busybox/networking/tcpudp.c
r2725 r3232 30 30 */ 31 31 32 //usage:#define tcpsvd_trivial_usage 33 //usage: "[-hEv] [-c N] [-C N[:MSG]] [-b N] [-u USER] [-l NAME] IP PORT PROG" 34 /* with not-implemented options: */ 35 /* //usage: "[-hpEvv] [-c N] [-C N[:MSG]] [-b N] [-u USER] [-l NAME] [-i DIR|-x CDB] [-t SEC] IP PORT PROG" */ 36 //usage:#define tcpsvd_full_usage "\n\n" 37 //usage: "Create TCP socket, bind to IP:PORT and listen\n" 38 //usage: "for incoming connection. Run PROG for each connection.\n" 39 //usage: "\n IP IP to listen on, 0 = all" 40 //usage: "\n PORT Port to listen on" 41 //usage: "\n PROG ARGS Program to run" 42 //usage: "\n -l NAME Local hostname (else looks up local hostname in DNS)" 43 //usage: "\n -u USER[:GRP] Change to user/group after bind" 44 //usage: "\n -c N Handle up to N connections simultaneously" 45 //usage: "\n -b N Allow a backlog of approximately N TCP SYNs" 46 //usage: "\n -C N[:MSG] Allow only up to N connections from the same IP" 47 //usage: "\n New connections from this IP address are closed" 48 //usage: "\n immediately. MSG is written to the peer before close" 49 //usage: "\n -h Look up peer's hostname" 50 //usage: "\n -E Don't set up environment variables" 51 //usage: "\n -v Verbose" 52 //usage: 53 //usage:#define udpsvd_trivial_usage 54 //usage: "[-hEv] [-c N] [-u USER] [-l NAME] IP PORT PROG" 55 //usage:#define udpsvd_full_usage "\n\n" 56 //usage: "Create UDP socket, bind to IP:PORT and wait\n" 57 //usage: "for incoming packets. Run PROG for each packet,\n" 58 //usage: "redirecting all further packets with same peer ip:port to it.\n" 59 //usage: "\n IP IP to listen on, 0 = all" 60 //usage: "\n PORT Port to listen on" 61 //usage: "\n PROG ARGS Program to run" 62 //usage: "\n -l NAME Local hostname (else looks up local hostname in DNS)" 63 //usage: "\n -u USER[:GRP] Change to user/group after bind" 64 //usage: "\n -c N Handle up to N connections simultaneously" 65 //usage: "\n -h Look up peer's hostname" 66 //usage: "\n -E Don't set up environment variables" 67 //usage: "\n -v Verbose" 68 32 69 #include "libbb.h" 33 70 … … 388 425 * (otherwise we can move socket to fd #0 only if bind succeeds) */ 389 426 close(0); 390 set_nport( localp, htons(local_port));427 set_nport(&localp->u.sa, htons(local_port)); 391 428 xmove_fd(xsocket(localp->u.sa.sa_family, SOCK_DGRAM, 0), 0); 392 429 setsockopt_reuseaddr(0); /* crucial */ -
branches/3.2/mindi-busybox/networking/telnet.c
r2725 r3232 22 22 */ 23 23 24 //usage:#if ENABLE_FEATURE_TELNET_AUTOLOGIN 25 //usage:#define telnet_trivial_usage 26 //usage: "[-a] [-l USER] HOST [PORT]" 27 //usage:#define telnet_full_usage "\n\n" 28 //usage: "Connect to telnet server\n" 29 //usage: "\n -a Automatic login with $USER variable" 30 //usage: "\n -l USER Automatic login as USER" 31 //usage: 32 //usage:#else 33 //usage:#define telnet_trivial_usage 34 //usage: "HOST [PORT]" 35 //usage:#define telnet_full_usage "\n\n" 36 //usage: "Connect to telnet server" 37 //usage:#endif 38 24 39 #include <arpa/telnet.h> 25 40 #include <netinet/in.h> 26 41 #include "libbb.h" 27 42 43 #ifdef __BIONIC__ 44 /* should be in arpa/telnet.h */ 45 # define IAC 255 /* interpret as command: */ 46 # define DONT 254 /* you are not to use option */ 47 # define DO 253 /* please, you use option */ 48 # define WONT 252 /* I won't use option */ 49 # define WILL 251 /* I will use option */ 50 # define SB 250 /* interpret as subnegotiation */ 51 # define SE 240 /* end sub negotiation */ 52 # define TELOPT_ECHO 1 /* echo */ 53 # define TELOPT_SGA 3 /* suppress go ahead */ 54 # define TELOPT_TTYPE 24 /* terminal type */ 55 # define TELOPT_NAWS 31 /* window size */ 56 #endif 57 28 58 #ifdef DOTRACE 29 # define TRACE(x, y) do { if (x) printf y; } while (0)59 # define TRACE(x, y) do { if (x) printf y; } while (0) 30 60 #else 31 # define TRACE(x, y)61 # define TRACE(x, y) 32 62 #endif 33 63 … … 157 187 static void handle_net_output(int len) 158 188 { 159 /* here we could do smart tricks how to handle 0xFF:s in output160 * stream like writing twice every sequence of FF:s (thus doing161 * many write()s. But I think interactive telnet application does162 * not need to be 100% 8-bit clean, so changing every 0xff:s to163 * 0x7f:s164 *165 * 2002-mar-21, Przemyslaw Czerpak (druzus@polbox.com)166 * I don't agree.167 * first - I cannot use programs like sz/rz168 * second - the 0x0D is sent as one character and if the next169 * char is 0x0A then it's eaten by a server side.170 * third - why do you have to make 'many write()s'?171 * I don't understand.172 * So I implemented it. It's really useful for me. I hope that173 * other people will find it interesting too.174 */175 189 byte outbuf[2 * DATABUFSIZE]; 176 byte *p = (byte*)G.buf; 177 int j = 0; 178 179 for (; len > 0; len--, p++) { 180 byte c = *p; 190 byte *dst = outbuf; 191 byte *src = (byte*)G.buf; 192 byte *end = src + len; 193 194 while (src < end) { 195 byte c = *src++; 181 196 if (c == 0x1d) { 182 197 con_escape(); 183 198 return; 184 199 } 185 outbuf[j++]= c;200 *dst = c; 186 201 if (c == IAC) 187 outbuf[j++] = c; /* IAC -> IAC IAC */ 188 else if (c == '\r') 189 outbuf[j++] = '\0'; /* CR -> CR NUL */ 190 } 191 if (j > 0) 192 full_write(netfd, outbuf, j); 202 *++dst = c; /* IAC -> IAC IAC */ 203 else 204 if (c == '\r' || c == '\n') { 205 /* Enter key sends '\r' in raw mode and '\n' in cooked one. 206 * 207 * See RFC 1123 3.3.1 Telnet End-of-Line Convention. 208 * Using CR LF instead of other allowed possibilities 209 * like CR NUL - easier to talk to HTTP/SMTP servers. 210 */ 211 *dst = '\r'; /* Enter -> CR LF */ 212 *++dst = '\n'; 213 } 214 dst++; 215 } 216 if (dst - outbuf != 0) 217 full_write(netfd, outbuf, dst - outbuf); 193 218 } 194 219 … … 369 394 #endif 370 395 371 static char const escapecharis[] ALIGN1 = "\r\nEscape character is ";372 373 396 static void setConMode(void) 374 397 { … … 376 399 if (G.charmode == CHM_TRY) { 377 400 G.charmode = CHM_ON; 378 printf("\r\nEntering character mode%s'^]'.\r\n", escapecharis); 401 printf("\r\nEntering %s mode" 402 "\r\nEscape character is '^%c'.\r\n", "character", ']'); 379 403 rawmode(); 380 404 } … … 382 406 if (G.charmode != CHM_OFF) { 383 407 G.charmode = CHM_OFF; 384 printf("\r\nEntering line mode%s'^C'.\r\n", escapecharis); 408 printf("\r\nEntering %s mode" 409 "\r\nEscape character is '^%c'.\r\n", "line", 'C'); 385 410 cookmode(); 386 411 } -
branches/3.2/mindi-busybox/networking/telnetd.c
r2725 r3232 21 21 * Set process group corrections, initial busybox port 22 22 */ 23 24 //usage:#define telnetd_trivial_usage 25 //usage: "[OPTIONS]" 26 //usage:#define telnetd_full_usage "\n\n" 27 //usage: "Handle incoming telnet connections" 28 //usage: IF_NOT_FEATURE_TELNETD_STANDALONE(" via inetd") "\n" 29 //usage: "\n -l LOGIN Exec LOGIN on connect" 30 //usage: "\n -f ISSUE_FILE Display ISSUE_FILE instead of /etc/issue" 31 //usage: "\n -K Close connection as soon as login exits" 32 //usage: "\n (normally wait until all programs close slave pty)" 33 //usage: IF_FEATURE_TELNETD_STANDALONE( 34 //usage: "\n -p PORT Port to listen on" 35 //usage: "\n -b ADDR[:PORT] Address to bind to" 36 //usage: "\n -F Run in foreground" 37 //usage: "\n -i Inetd mode" 38 //usage: IF_FEATURE_TELNETD_INETD_WAIT( 39 //usage: "\n -w SEC Inetd 'wait' mode, linger time SEC" 40 //usage: "\n -S Log to syslog (implied by -i or without -F and -w)" 41 //usage: ) 42 //usage: ) 43 23 44 #define DEBUG 0 24 45 … … 31 52 #endif 32 53 #include <arpa/telnet.h> 33 34 #if ENABLE_FEATURE_UTMP35 # include <utmp.h> /* LOGIN_PROCESS */36 #endif37 54 38 55 … … 109 126 * Many client implementations send \r\n when 110 127 * the user hits the CarriageReturn key. 128 * See RFC 1123 3.3.1 Telnet End-of-Line Convention. 111 129 */ 112 130 if (c == '\r' && ptr < end && (*ptr == '\n' || *ptr == '\0')) … … 315 333 bb_signals((1 << SIGCHLD) + (1 << SIGPIPE), SIG_DFL); 316 334 335 pid = getpid(); 336 317 337 if (ENABLE_FEATURE_UTMP) { 318 338 len_and_sockaddr *lsa = get_peer_lsa(sock); … … 336 356 xdup2(0, 1); 337 357 xdup2(0, 2); 338 pid = getpid();339 358 tcsetpgrp(0, pid); /* switch this tty's process group to us */ 340 359 -
branches/3.2/mindi-busybox/networking/tftp.c
r2725 r3232 19 19 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 20 20 */ 21 22 //usage:#define tftp_trivial_usage 23 //usage: "[OPTIONS] HOST [PORT]" 24 //usage:#define tftp_full_usage "\n\n" 25 //usage: "Transfer a file from/to tftp server\n" 26 //usage: "\n -l FILE Local FILE" 27 //usage: "\n -r FILE Remote FILE" 28 //usage: IF_FEATURE_TFTP_GET( 29 //usage: "\n -g Get file" 30 //usage: ) 31 //usage: IF_FEATURE_TFTP_PUT( 32 //usage: "\n -p Put file" 33 //usage: ) 34 //usage: IF_FEATURE_TFTP_BLOCKSIZE( 35 //usage: "\n -b SIZE Transfer blocks of SIZE octets" 36 //usage: ) 37 //usage: 38 //usage:#define tftpd_trivial_usage 39 //usage: "[-cr] [-u USER] [DIR]" 40 //usage:#define tftpd_full_usage "\n\n" 41 //usage: "Transfer a file on tftp client's request\n" 42 //usage: "\n" 43 //usage: "tftpd should be used as an inetd service.\n" 44 //usage: "tftpd's line for inetd.conf:\n" 45 //usage: " 69 dgram udp nowait root tftpd tftpd -l /files/to/serve\n" 46 //usage: "It also can be ran from udpsvd:\n" 47 //usage: " udpsvd -vE 0.0.0.0 69 tftpd /files/to/serve\n" 48 //usage: "\n -r Prohibit upload" 49 //usage: "\n -c Allow file creation via upload" 50 //usage: "\n -u Access files as USER" 51 //usage: "\n -l Log to syslog (inetd mode requires this)" 52 21 53 #include "libbb.h" 54 #include <syslog.h> 22 55 23 56 #if ENABLE_FEATURE_TFTP_GET || ENABLE_FEATURE_TFTP_PUT … … 60 93 TFTPD_OPT_c = (1 << 9) * ENABLE_TFTPD, 61 94 TFTPD_OPT_u = (1 << 10) * ENABLE_TFTPD, 95 TFTPD_OPT_l = (1 << 11) * ENABLE_TFTPD, 62 96 }; 63 97 … … 83 117 /* u16 TFTP_ERROR; u16 reason; both network-endian, then error text: */ 84 118 uint8_t error_pkt[4 + 32]; 85 char *user_opt;119 struct passwd *pw; 86 120 /* used in tftpd_main(), a bit big for stack: */ 87 121 char block_buf[TFTP_BLKSIZE_DEFAULT]; … … 97 131 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; 98 132 }; 99 #define block_buf (G.block_buf )100 #define user_opt (G.user_opt )101 #define error_pkt (G.error_pkt )102 133 #define INIT_G() do { } while (0) 103 134 104 #define error_pkt_reason (error_pkt[3])105 #define error_pkt_str (error_pkt + 4)135 #define G_error_pkt_reason (G.error_pkt[3]) 136 #define G_error_pkt_str ((char*)(G.error_pkt + 4)) 106 137 107 138 #if ENABLE_FEATURE_TFTP_PROGRESS_BAR 108 139 static void tftp_progress_update(void) 109 140 { 110 bb_progress_update(&G.pmt, G.file,0, G.pos, G.size);141 bb_progress_update(&G.pmt, 0, G.pos, G.size); 111 142 } 112 143 static void tftp_progress_init(void) 113 144 { 114 bb_progress_init(&G.pmt );145 bb_progress_init(&G.pmt, G.file); 115 146 tftp_progress_update(); 116 147 } 117 148 static void tftp_progress_done(void) 118 149 { 119 if ( G.pmt.inited) {150 if (is_bb_progress_inited(&G.pmt)) { 120 151 tftp_progress_update(); 121 152 bb_putchar_stderr('\n'); 122 G.pmt.inited = 0;153 bb_progress_free(&G.pmt); 123 154 } 124 155 } … … 239 270 240 271 /* Is there an error already? Send pkt and bail out */ 241 if ( error_pkt_reason ||error_pkt_str[0])272 if (G_error_pkt_reason || G_error_pkt_str[0]) 242 273 goto send_err_pkt; 243 274 244 if (user_opt) { 245 struct passwd *pw = xgetpwnam(user_opt); 246 change_identity(pw); /* initgroups, setgid, setuid */ 275 if (G.pw) { 276 change_identity(G.pw); /* initgroups, setgid, setuid */ 247 277 } 248 278 } … … 296 326 local_fd = open(local_file, open_mode, 0666); 297 327 if (local_fd < 0) { 298 error_pkt_reason = ERR_NOFILE;299 strcpy( (char*)error_pkt_str, "can't open file");328 G_error_pkt_reason = ERR_NOFILE; 329 strcpy(G_error_pkt_str, "can't open file"); 300 330 goto send_err_pkt; 301 331 } … … 423 453 } 424 454 cp += len; 455 IF_FEATURE_TFTP_PROGRESS_BAR(G.pos += len;) 425 456 } 426 457 send_pkt: … … 444 475 445 476 #if ENABLE_FEATURE_TFTP_PROGRESS_BAR 446 if (ENABLE_TFTP && remote_file) /* tftp */ 447 G.pos = (block_nr - 1) * (uoff_t)blksize; 448 if (G.pmt.inited) 477 if (is_bb_progress_inited(&G.pmt)) 449 478 tftp_progress_update(); 450 479 #endif … … 543 572 blksize = tftp_blksize_check(res, blksize); 544 573 if (blksize < 0) { 545 error_pkt_reason = ERR_BAD_OPT;574 G_error_pkt_reason = ERR_BAD_OPT; 546 575 goto send_err_pkt; 547 576 } … … 582 611 int sz = full_write(local_fd, &rbuf[4], len - 4); 583 612 if (sz != len - 4) { 584 strcpy( (char*)error_pkt_str, bb_msg_write_error);585 error_pkt_reason = ERR_WRITE;613 strcpy(G_error_pkt_str, bb_msg_write_error); 614 G_error_pkt_reason = ERR_WRITE; 586 615 goto send_err_pkt; 587 616 } … … 589 618 finished = 1; 590 619 } 620 IF_FEATURE_TFTP_PROGRESS_BAR(G.pos += sz;) 591 621 continue; /* send ACK */ 592 622 } … … 631 661 632 662 send_read_err_pkt: 633 strcpy( (char*)error_pkt_str, bb_msg_read_error);663 strcpy(G_error_pkt_str, bb_msg_read_error); 634 664 send_err_pkt: 635 if ( error_pkt_str[0])636 bb_error_msg("%s", (char*)error_pkt_str);637 error_pkt[1] = TFTP_ERROR;638 xsendto(socket_fd, error_pkt, 4 + 1 + strlen((char*)error_pkt_str),665 if (G_error_pkt_str[0]) 666 bb_error_msg("%s", G_error_pkt_str); 667 G.error_pkt[1] = TFTP_ERROR; 668 xsendto(socket_fd, G.error_pkt, 4 + 1 + strlen(G_error_pkt_str), 639 669 &peer_lsa->u.sa, peer_lsa->len); 640 670 return EXIT_FAILURE; … … 728 758 len_and_sockaddr *our_lsa; 729 759 len_and_sockaddr *peer_lsa; 730 char *local_file, *mode ;760 char *local_file, *mode, *user_opt; 731 761 const char *error_msg; 732 762 int opt, result, opcode; … … 750 780 751 781 /* Shifting to not collide with TFTP_OPTs */ 752 opt = option_mask32 = TFTPD_OPT | (getopt32(argv, "rcu: ", &user_opt) << 8);782 opt = option_mask32 = TFTPD_OPT | (getopt32(argv, "rcu:l", &user_opt) << 8); 753 783 argv += optind; 754 if (argv[0]) 755 xchdir(argv[0]); 756 757 result = recv_from_to(STDIN_FILENO, block_buf, sizeof(block_buf), 784 if (opt & TFTPD_OPT_l) { 785 openlog(applet_name, LOG_PID, LOG_DAEMON); 786 logmode = LOGMODE_SYSLOG; 787 } 788 if (opt & TFTPD_OPT_u) { 789 /* Must be before xchroot */ 790 G.pw = xgetpwnam(user_opt); 791 } 792 if (argv[0]) { 793 xchroot(argv[0]); 794 } 795 796 result = recv_from_to(STDIN_FILENO, G.block_buf, sizeof(G.block_buf), 758 797 0 /* flags */, 759 798 &peer_lsa->u.sa, &our_lsa->u.sa, our_lsa->len); 760 799 761 800 error_msg = "malformed packet"; 762 opcode = ntohs(*(uint16_t*) block_buf);763 if (result < 4 || result >= sizeof( block_buf)764 || block_buf[result-1] != '\0'801 opcode = ntohs(*(uint16_t*)G.block_buf); 802 if (result < 4 || result >= sizeof(G.block_buf) 803 || G.block_buf[result-1] != '\0' 765 804 || (IF_FEATURE_TFTP_PUT(opcode != TFTP_RRQ) /* not download */ 766 805 IF_GETPUT(&&) … … 770 809 goto err; 771 810 } 772 local_file = block_buf + 2;811 local_file = G.block_buf + 2; 773 812 if (local_file[0] == '.' || strstr(local_file, "/.")) { 774 813 error_msg = "dot in file name"; … … 776 815 } 777 816 mode = local_file + strlen(local_file) + 1; 778 if (mode >= block_buf + result || strcmp(mode, "octet") != 0) { 817 /* RFC 1350 says mode string is case independent */ 818 if (mode >= G.block_buf + result || strcasecmp(mode, "octet") != 0) { 779 819 goto err; 780 820 } … … 783 823 char *res; 784 824 char *opt_str = mode + sizeof("octet"); 785 int opt_len = block_buf + result - opt_str;825 int opt_len = G.block_buf + result - opt_str; 786 826 if (opt_len > 0) { 787 827 res = tftp_get_option("blksize", opt_str, opt_len); … … 789 829 blksize = tftp_blksize_check(res, 65564); 790 830 if (blksize < 0) { 791 error_pkt_reason = ERR_BAD_OPT;831 G_error_pkt_reason = ERR_BAD_OPT; 792 832 /* will just send error pkt */ 793 833 goto do_proto; … … 807 847 if (opt & TFTPD_OPT_r) { 808 848 /* This would mean "disk full" - not true */ 809 /* error_pkt_reason = ERR_WRITE;*/849 /*G_error_pkt_reason = ERR_WRITE;*/ 810 850 error_msg = bb_msg_write_error; 811 851 goto err; … … 816 856 } 817 857 818 /* NB: if error_pkt_str orerror_pkt_reason is set up,858 /* NB: if G_error_pkt_str or G_error_pkt_reason is set up, 819 859 * tftp_protocol() just sends one error pkt and returns */ 820 860 … … 831 871 return result; 832 872 err: 833 strcpy( (char*)error_pkt_str, error_msg);873 strcpy(G_error_pkt_str, error_msg); 834 874 goto do_proto; 835 875 } -
branches/3.2/mindi-busybox/networking/traceroute.c
r2725 r3232 211 211 */ 212 212 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" 216 //usage: " [-z PAUSE_MSEC] HOST [BYTES]" 217 //usage:#define traceroute_full_usage "\n\n" 218 //usage: "Trace the route to HOST\n" 219 //usage: IF_TRACEROUTE6( 220 //usage: "\n -4,-6 Force IP or IPv6 name resolution" 221 //usage: ) 222 //usage: "\n -F Set the don't fragment bit" 223 //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: "\n -n Print numeric addresses" 227 //usage: "\n -r Bypass routing tables, send directly to HOST" 228 //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" 231 //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 seconds to wait for a response (default 3)" 236 //usage: "\n -g Loose source route gateway (8 max)" 237 //usage: 238 //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" 241 //usage: " HOST [BYTES]" 242 //usage:#define traceroute6_full_usage "\n\n" 243 //usage: "Trace the route to HOST\n" 244 //usage: "\n -d Set SO_DEBUG options to socket" 245 //usage: "\n -n Print numeric addresses" 246 //usage: "\n -r Bypass routing tables, send directly to HOST" 247 //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)" 255 213 256 #define TRACEROUTE_SO_DEBUG 0 214 257 … … 248 291 249 292 250 #define OPT_STRING "FIlnrdvxt:i:m:p:q:s:w:z:f:" \ 251 IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:") \ 252 "4" IF_TRACEROUTE6("6") 293 #define OPT_STRING \ 294 "FIlnrdvxt:i:m:p:q:s:w:z:f:" \ 295 IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:") \ 296 "4" IF_TRACEROUTE6("6") 253 297 enum { 254 298 OPT_DONT_FRAGMNT = (1 << 0), /* F */ … … 354 398 355 399 static int 356 wait_for_reply(len_and_sockaddr *from_lsa, struct sockaddr *to )400 wait_for_reply(len_and_sockaddr *from_lsa, struct sockaddr *to, unsigned *timestamp_us, int *left_ms) 357 401 { 358 402 struct pollfd pfd[1]; … … 361 405 pfd[0].fd = rcvsock; 362 406 pfd[0].events = POLLIN; 363 if (safe_poll(pfd, 1, waittime * 1000) > 0) { 407 if (*left_ms >= 0 && safe_poll(pfd, 1, *left_ms) > 0) { 408 unsigned t; 409 364 410 read_len = recv_from_to(rcvsock, 365 411 recv_pkt, sizeof(recv_pkt), 366 /*flags:*/ 0,412 /*flags:*/ MSG_DONTWAIT, 367 413 &from_lsa->u.sa, to, from_lsa->len); 414 t = monotonic_us(); 415 *left_ms -= (t - *timestamp_us) / 1000; 416 *timestamp_us = t; 368 417 } 369 418 370 419 return read_len; 371 }372 373 /*374 * Checksum routine for Internet Protocol family headers (C Version)375 */376 static uint16_t377 in_cksum(uint16_t *addr, int len)378 {379 int nleft = len;380 uint16_t *w = addr;381 uint16_t answer;382 int sum = 0;383 384 /*385 * Our algorithm is simple, using a 32 bit accumulator (sum),386 * we add sequential 16 bit words to it, and at the end, fold387 * back all the carry bits from the top 16 bits into the lower388 * 16 bits.389 */390 while (nleft > 1) {391 sum += *w++;392 nleft -= 2;393 }394 395 /* mop up an odd byte, if necessary */396 if (nleft == 1)397 sum += *(unsigned char *)w;398 399 /* add back carry outs from top 16 bits to low 16 bits */400 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */401 sum += (sum >> 16); /* add carry */402 answer = ~sum; /* truncate to 16 bits */403 return answer;404 420 } 405 421 … … 430 446 /* Always calculate checksum for icmp packets */ 431 447 outicmp->icmp_cksum = 0; 432 outicmp->icmp_cksum = in _cksum((uint16_t *)outicmp,448 outicmp->icmp_cksum = inet_cksum((uint16_t *)outicmp, 433 449 packlen - (sizeof(*outip) + optlen)); 434 450 if (outicmp->icmp_cksum == 0) … … 483 499 out = outdata; 484 500 len -= sizeof(*outudp); 485 set_nport( dest_lsa, htons(port + seq));501 set_nport(&dest_lsa->u.sa, htons(port + seq)); 486 502 } 487 503 } … … 686 702 687 703 read_len -= sizeof(struct icmp6_hdr); 688 for (i = 0; i < read_len 704 for (i = 0; i < read_len; i++) { 689 705 if (i % 16 == 0) 690 706 printf("%04x:", i); … … 752 768 #endif 753 769 { 754 read_len -= ((struct ip*)recv_pkt)->ip_hl << 2; 770 struct ip *ip4packet = (struct ip*)recv_pkt; 771 read_len -= ip4packet->ip_hl << 2; 755 772 } 756 773 printf(" %d bytes to %s", read_len, ina); … … 774 791 common_traceroute_main(int op, char **argv) 775 792 { 776 int i;777 793 int minpacket; 778 794 int tos = 0; … … 928 944 if (lsrr > 0) { 929 945 unsigned char optlist[MAX_IPOPTLEN]; 946 unsigned size; 930 947 931 948 /* final hop */ … … 937 954 /* loose source route option */ 938 955 optlist[1] = IPOPT_LSRR; 939 i= lsrr * sizeof(gwlist[0]);940 optlist[2] = i+ 3;956 size = lsrr * sizeof(gwlist[0]); 957 optlist[2] = size + 3; 941 958 /* pointer to LSRR addresses */ 942 959 optlist[3] = IPOPT_MINOFF; 943 memcpy(optlist + 4, gwlist, i);960 memcpy(optlist + 4, gwlist, size); 944 961 945 962 if (setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, 946 (char *)optlist, i+ sizeof(gwlist[0])) < 0) {963 (char *)optlist, size + sizeof(gwlist[0])) < 0) { 947 964 bb_perror_msg_and_die("IP_OPTIONS"); 948 965 } … … 1018 1035 if (op & OPT_DEVICE) 1019 1036 setsockopt_bindtodevice(probe_fd, device); 1020 set_nport( dest_lsa, htons(1025));1037 set_nport(&dest_lsa->u.sa, htons(1025)); 1021 1038 /* dummy connect. makes kernel pick source IP (and port) */ 1022 1039 xconnect(probe_fd, &dest_lsa->u.sa, dest_lsa->len); 1023 set_nport( dest_lsa, htons(port));1040 set_nport(&dest_lsa->u.sa, htons(port)); 1024 1041 1025 1042 /* read IP and port */ … … 1031 1048 1032 1049 /* bind our sockets to this IP (but not port) */ 1033 set_nport( source_lsa, 0);1050 set_nport(&source_lsa->u.sa, 0); 1034 1051 xbind(sndsock, &source_lsa->u.sa, source_lsa->len); 1035 1052 xbind(rcvsock, &source_lsa->u.sa, source_lsa->len); … … 1058 1075 int gotlastaddr = 0; /* flags */ 1059 1076 int got_there = 0; 1060 int first = 1;1061 1077 1062 1078 printf("%2d", ttl); … … 1065 1081 unsigned t1; 1066 1082 unsigned t2; 1083 int left_ms; 1067 1084 struct ip *ip; 1068 1085 1069 if (!first && pausemsecs > 0) 1086 fflush_all(); 1087 if (probe != 0 && pausemsecs > 0) 1070 1088 usleep(pausemsecs * 1000); 1071 fflush_all(); 1072 1073 t1 = monotonic_us(); 1089 1074 1090 send_probe(++seq, ttl); 1075 1076 first = 0; 1077 while ((read_len = wait_for_reply(from_lsa, to)) != 0) { 1078 t2 = monotonic_us(); 1079 i = packet_ok(read_len, from_lsa, to, seq); 1091 t2 = t1 = monotonic_us(); 1092 1093 left_ms = waittime * 1000; 1094 while ((read_len = wait_for_reply(from_lsa, to, &t2, &left_ms)) != 0) { 1095 int icmp_code; 1096 1097 /* Recv'ed a packet, or read error */ 1098 /* t2 = monotonic_us() - set by wait_for_reply */ 1099 1100 if (read_len < 0) 1101 continue; 1102 icmp_code = packet_ok(read_len, from_lsa, to, seq); 1080 1103 /* Skip short packet */ 1081 if (i == 0)1104 if (icmp_code == 0) 1082 1105 continue; 1083 1106 … … 1098 1121 1099 1122 /* time exceeded in transit */ 1100 if (i == -1)1101 break; 1102 i --;1103 switch (i ) {1123 if (icmp_code == -1) 1124 break; 1125 icmp_code--; 1126 switch (icmp_code) { 1104 1127 #if ENABLE_TRACEROUTE6 1105 1128 case ICMP6_DST_UNREACH_NOPORT << 8: … … 1174 1197 break; 1175 1198 default: 1176 printf(" !<%d>", i );1199 printf(" !<%d>", icmp_code); 1177 1200 ++unreachable; 1178 1201 break; 1179 1202 } 1180 1203 break; 1181 } 1204 } /* while (wait and read a packet) */ 1205 1182 1206 /* there was no packet at all? */ 1183 1207 if (read_len == 0) 1184 1208 printf(" *"); 1185 } 1209 } /* for (nprobes) */ 1210 1186 1211 bb_putchar('\n'); 1187 1212 if (got_there -
branches/3.2/mindi-busybox/networking/tunctl.c
r2725 r3232 10 10 * Licensed under GPLv2, see file LICENSE in this source tree. 11 11 */ 12 13 //usage:#define tunctl_trivial_usage 14 //usage: "[-f device] ([-t name] | -d name)" IF_FEATURE_TUNCTL_UG(" [-u owner] [-g group] [-b]") 15 //usage:#define tunctl_full_usage "\n\n" 16 //usage: "Create or delete tun interfaces\n" 17 //usage: "\n -f name tun device (/dev/net/tun)" 18 //usage: "\n -t name Create iface 'name'" 19 //usage: "\n -d name Delete iface 'name'" 20 //usage: IF_FEATURE_TUNCTL_UG( 21 //usage: "\n -u owner Set iface owner" 22 //usage: "\n -g group Set iface group" 23 //usage: "\n -b Brief output" 24 //usage: ) 25 //usage: 26 //usage:#define tunctl_example_usage 27 //usage: "# tunctl\n" 28 //usage: "# tunctl -d tun0\n" 29 12 30 #include <netinet/in.h> 13 31 #include <net/if.h> -
branches/3.2/mindi-busybox/networking/udhcp/Config.src
r2725 r3232 9 9 bool "udhcp server (udhcpd)" 10 10 default y 11 depends onPLATFORM_LINUX11 select PLATFORM_LINUX 12 12 help 13 13 udhcpd is a DHCP server geared primarily toward embedded systems, … … 40 40 time a new lease has been accepted, thus eliminating the need 41 41 to send SIGUSR1 for the initial writing or updating. Any timed 42 rewriting remains undisturbed 42 rewriting remains undisturbed. 43 44 config FEATURE_UDHCPD_BASE_IP_ON_MAC 45 bool "Select IP address based on client MAC" 46 default n 47 depends on UDHCPD 48 help 49 If selected, udhcpd will base its selection of IP address to offer 50 on the client's hardware address. Otherwise udhcpd uses the next 51 consecutive free address. 52 53 This reduces the frequency of IP address changes for clients 54 which let their lease expire, and makes consecutive DHCPOFFERS 55 for the same client to (almost always) contain the same 56 IP address. 43 57 44 58 config DHCPD_LEASES_FILE … … 53 67 bool "udhcp client (udhcpc)" 54 68 default y 55 depends onPLATFORM_LINUX69 select PLATFORM_LINUX 56 70 help 57 71 udhcpc is a DHCP client geared primarily toward embedded systems, … … 73 87 config FEATURE_UDHCP_PORT 74 88 bool "Enable '-P port' option for udhcpd and udhcpc" 75 default y89 default n 76 90 depends on UDHCPD || UDHCPC 77 91 help … … 99 113 search lists via option 119, specified in RFC 3397, 100 114 and SIP servers option 120, specified in RFC 3361. 115 116 config FEATURE_UDHCP_8021Q 117 bool "Support for 802.1Q VLAN parameters" 118 default y 119 depends on UDHCPD || UDHCPC 120 help 121 If selected, both client and server will support passing of VLAN 122 ID and priority via options 132 and 133 as per 802.1Q. 101 123 102 124 config UDHCPC_DEFAULT_SCRIPT -
branches/3.2/mindi-busybox/networking/udhcp/arpping.c
r2725 r3232 119 119 } 120 120 } 121 timeout_ms -= (unsigned)monotonic_ms() - prevTime; 122 } while (timeout_ms > 0); 121 timeout_ms -= (unsigned)monotonic_ms() - prevTime + 1; 122 123 /* We used to check "timeout_ms > 0", but 124 * this is more under/overflow-resistant 125 * (people did see overflows here when system time jumps): 126 */ 127 } while ((unsigned)timeout_ms <= 2000); 123 128 124 129 ret: -
branches/3.2/mindi-busybox/networking/udhcp/common.c
r2725 r3232 30 30 // { OPTION_IP | OPTION_LIST , 0x08 }, /* DHCP_COOKIE_SERVER */ 31 31 { OPTION_IP | OPTION_LIST , 0x09 }, /* DHCP_LPR_SERVER */ 32 { OPTION_STRING 32 { OPTION_STRING_HOST | OPTION_REQ, 0x0c }, /* DHCP_HOST_NAME */ 33 33 { OPTION_U16 , 0x0d }, /* DHCP_BOOT_SIZE */ 34 { OPTION_STRING 34 { OPTION_STRING_HOST | OPTION_REQ, 0x0f }, /* DHCP_DOMAIN_NAME */ 35 35 { OPTION_IP , 0x10 }, /* DHCP_SWAP_SERVER */ 36 36 { OPTION_STRING , 0x11 }, /* DHCP_ROOT_PATH */ 37 37 { OPTION_U8 , 0x17 }, /* DHCP_IP_TTL */ 38 38 { OPTION_U16 , 0x1a }, /* DHCP_MTU */ 39 //TODO: why do we request DHCP_BROADCAST? Can't we assume that 40 //in the unlikely case it is different from typical N.N.255.255, 41 //server would let us know anyway? 39 42 { OPTION_IP | OPTION_REQ, 0x1c }, /* DHCP_BROADCAST */ 40 43 { OPTION_IP_PAIR | OPTION_LIST , 0x21 }, /* DHCP_ROUTES */ 41 { OPTION_STRING 44 { OPTION_STRING_HOST , 0x28 }, /* DHCP_NIS_DOMAIN */ 42 45 { OPTION_IP | OPTION_LIST , 0x29 }, /* DHCP_NIS_SERVER */ 43 46 { OPTION_IP | OPTION_LIST | OPTION_REQ, 0x2a }, /* DHCP_NTP_SERVER */ … … 47 50 { OPTION_STRING , 0x38 }, /* DHCP_ERR_MESSAGE */ 48 51 //TODO: must be combined with 'sname' and 'file' handling: 49 { OPTION_STRING 52 { OPTION_STRING_HOST , 0x42 }, /* DHCP_TFTP_SERVER_NAME */ 50 53 { OPTION_STRING , 0x43 }, /* DHCP_BOOT_FILE */ 51 54 //TODO: not a string, but a set of LASCII strings: … … 55 58 { OPTION_SIP_SERVERS , 0x78 }, /* DHCP_SIP_SERVERS */ 56 59 #endif 57 { OPTION_STATIC_ROUTES , 0x79 }, /* DHCP_STATIC_ROUTES */ 58 { OPTION_STATIC_ROUTES , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ 60 { OPTION_STATIC_ROUTES | OPTION_LIST , 0x79 }, /* DHCP_STATIC_ROUTES */ 61 #if ENABLE_FEATURE_UDHCP_8021Q 62 { OPTION_U16 , 0x84 }, /* DHCP_VLAN_ID */ 63 { OPTION_U8 , 0x85 }, /* DHCP_VLAN_PRIORITY */ 64 #endif 65 { OPTION_6RD , 0xd4 }, /* DHCP_6RD */ 66 { OPTION_STATIC_ROUTES | OPTION_LIST , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ 59 67 { OPTION_STRING , 0xfc }, /* DHCP_WPAD */ 60 68 … … 116 124 "sipsrv" "\0" /* DHCP_SIP_SERVERS */ 117 125 #endif 118 // doesn't work in udhcpd.conf since OPTION_STATIC_ROUTES119 // is not handled yet by "string->option" conversion code:120 126 "staticroutes" "\0"/* DHCP_STATIC_ROUTES */ 127 #if ENABLE_FEATURE_UDHCP_8021Q 128 "vlanid" "\0" /* DHCP_VLAN_ID */ 129 "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY */ 130 #endif 131 "ip6rd" "\0" /* DHCP_6RD */ 121 132 "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ 122 133 "wpad" "\0" /* DHCP_WPAD */ … … 136 147 // [OPTION_BOOLEAN] = 1, 137 148 [OPTION_STRING] = 1, /* ignored by udhcp_str2optset */ 149 [OPTION_STRING_HOST] = 1, /* ignored by udhcp_str2optset */ 138 150 #if ENABLE_FEATURE_UDHCP_RFC3397 139 151 [OPTION_DNS_STRING] = 1, /* ignored by both udhcp_str2optset and xmalloc_optname_optval */ … … 147 159 /* Just like OPTION_STRING, we use minimum length here */ 148 160 [OPTION_STATIC_ROUTES] = 5, 161 [OPTION_6RD] = 22, /* ignored by udhcp_str2optset */ 149 162 }; 150 163 … … 324 337 if (!lsa) 325 338 return 0; 326 *(uint32_t*)arg = lsa->u.sin.sin_addr.s_addr; 339 /* arg maybe unaligned */ 340 move_to_unaligned32((uint32_t*)arg, lsa->u.sin.sin_addr.s_addr); 327 341 free(lsa); 328 342 return 1; … … 404 418 405 419 existing->data = xrealloc(existing->data, OPT_DATA + 1 + old_len + length); 406 if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING) { 420 if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING 421 || (optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING_HOST 422 ) { 407 423 /* add space separator between STRING options in a list */ 408 424 existing->data[OPT_DATA + old_len] = ' '; … … 421 437 { 422 438 struct option_set **opt_list = arg; 423 char *opt, *val , *endptr;439 char *opt, *val; 424 440 char *str; 425 441 const struct dhcp_optflag *optflag; … … 427 443 unsigned optcode; 428 444 int retval, length; 429 char buffer[8] ALIGNED(4); 445 /* IP_PAIR needs 8 bytes, STATIC_ROUTES needs 9 max */ 446 char buffer[9] ALIGNED(4); 430 447 uint16_t *result_u16 = (uint16_t *) buffer; 431 448 uint32_t *result_u32 = (uint32_t *) buffer; … … 468 485 break; 469 486 case OPTION_STRING: 487 case OPTION_STRING_HOST: 470 488 #if ENABLE_FEATURE_UDHCP_RFC3397 471 489 case OPTION_DNS_STRING: … … 484 502 // } 485 503 case OPTION_U8: 486 buffer[0] = strtoul(val, &endptr, 0);487 retval = (e ndptr[0] == '\0');504 buffer[0] = bb_strtou32(val, NULL, 0); 505 retval = (errno == 0); 488 506 break; 489 507 /* htonX are macros in older libc's, using temp var … … 491 509 /* TODO: use bb_strtoX? */ 492 510 case OPTION_U16: { 493 u nsigned long tmp = strtoul(val, &endptr, 0);511 uint32_t tmp = bb_strtou32(val, NULL, 0); 494 512 *result_u16 = htons(tmp); 495 retval = (e ndptr[0] == '\0'/*&& tmp < 0x10000*/);513 retval = (errno == 0 /*&& tmp < 0x10000*/); 496 514 break; 497 515 } 498 516 // case OPTION_S16: { 499 // long tmp = strtol(val, &endptr, 0);517 // long tmp = bb_strtoi32(val, NULL, 0); 500 518 // *result_u16 = htons(tmp); 501 // retval = (e ndptr[0] == '\0');519 // retval = (errno == 0); 502 520 // break; 503 521 // } 504 522 case OPTION_U32: { 505 u nsigned long tmp = strtoul(val, &endptr, 0);523 uint32_t tmp = bb_strtou32(val, NULL, 0); 506 524 *result_u32 = htonl(tmp); 507 retval = (e ndptr[0] == '\0');525 retval = (errno == 0); 508 526 break; 509 527 } 510 528 case OPTION_S32: { 511 long tmp = strtol(val, &endptr, 0);529 int32_t tmp = bb_strtoi32(val, NULL, 0); 512 530 *result_u32 = htonl(tmp); 513 retval = (endptr[0] == '\0'); 531 retval = (errno == 0); 532 break; 533 } 534 case OPTION_STATIC_ROUTES: { 535 /* Input: "a.b.c.d/m" */ 536 /* Output: mask(1 byte),pfx(0-4 bytes),gw(4 bytes) */ 537 unsigned mask; 538 char *slash = strchr(val, '/'); 539 if (slash) { 540 *slash = '\0'; 541 retval = udhcp_str2nip(val, buffer + 1); 542 buffer[0] = mask = bb_strtou(slash + 1, NULL, 10); 543 val = strtok(NULL, ", \t/-"); 544 if (!val || mask > 32 || errno) 545 retval = 0; 546 if (retval) { 547 length = ((mask + 7) >> 3) + 5; 548 retval = udhcp_str2nip(val, buffer + (length - 4)); 549 } 550 } 514 551 break; 515 552 } … … 522 559 if (retval) 523 560 attach_option(opt_list, optflag, opt, length); 524 } while (retval && optflag->flags & OPTION_LIST);561 } while (retval && (optflag->flags & OPTION_LIST)); 525 562 526 563 return retval; 527 564 } 565 566 /* note: ip is a pointer to an IPv6 in network order, possibly misaliged */ 567 int FAST_FUNC sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) 568 { 569 char hexstrbuf[16 * 2]; 570 bin2hex(hexstrbuf, (void*)ip, 16); 571 return sprintf(dest, /* "%s" */ 572 "%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s", 573 /* pre, */ 574 hexstrbuf + 0 * 4, 575 hexstrbuf + 1 * 4, 576 hexstrbuf + 2 * 4, 577 hexstrbuf + 3 * 4, 578 hexstrbuf + 4 * 4, 579 hexstrbuf + 5 * 4, 580 hexstrbuf + 6 * 4, 581 hexstrbuf + 7 * 4 582 ); 583 } -
branches/3.2/mindi-busybox/networking/udhcp/common.h
r2725 r3232 15 15 PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 16 16 17 extern const uint8_t MAC_BCAST_ADDR[6] ; /* six all-ones */17 extern const uint8_t MAC_BCAST_ADDR[6] ALIGN2; /* six all-ones */ 18 18 19 19 … … 81 81 OPTION_IP_PAIR, 82 82 OPTION_STRING, 83 /* Opts of STRING_HOST type will be sanitized before they are passed 84 * to udhcpc script's environment: */ 85 OPTION_STRING_HOST, 83 86 // OPTION_BOOLEAN, 84 87 OPTION_U8, … … 89 92 OPTION_BIN, 90 93 OPTION_STATIC_ROUTES, 94 OPTION_6RD, 91 95 #if ENABLE_FEATURE_UDHCP_RFC3397 92 96 OPTION_DNS_STRING, /* RFC1035 compressed domain name list */ … … 104 108 * http://www.iana.org/assignments/bootp-dhcp-parameters/ 105 109 * Commented out options are handled by common option machinery, 106 * uncommented ones have sp acial cases (grep for them to see).110 * uncommented ones have special cases (grep for them to see). 107 111 */ 108 112 #define DHCP_PADDING 0x00 … … 146 150 //#define DHCP_SIP_SERVERS 0x78 /* RFC 3361. flag byte, then: 0: domain names, 1: IP addrs */ 147 151 //#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 */ 148 154 //#define DHCP_MS_STATIC_ROUTES 0xf9 /* Microsoft's pre-RFC 3442 code for 0x79? */ 149 155 //#define DHCP_WPAD 0xfc /* MSIE's Web Proxy Autodiscovery Protocol */ … … 182 188 183 189 extern const struct dhcp_optflag dhcp_optflags[]; 184 extern const char dhcp_option_strings[] ;185 extern const uint8_t dhcp_option_lengths[] ;190 extern const char dhcp_option_strings[] ALIGN1; 191 extern const uint8_t dhcp_option_lengths[] ALIGN1; 186 192 187 193 unsigned FAST_FUNC udhcp_option_idx(const char *name); … … 247 253 248 254 #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 255 # define IF_UDHCP_VERBOSE(...) __VA_ARGS__ 249 256 extern unsigned dhcp_verbose; 250 257 # define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0) … … 262 269 # endif 263 270 #else 271 # define IF_UDHCP_VERBOSE(...) 264 272 # define udhcp_dump_packet(...) ((void)0) 265 273 # define log1(...) ((void)0) … … 275 283 /* 2nd param is "struct option_set**" */ 276 284 int FAST_FUNC udhcp_str2optset(const char *str, void *arg); 277 278 uint16_t udhcp_checksum(void *addr, int count) FAST_FUNC;279 285 280 286 void udhcp_init_header(struct dhcp_packet *packet, char type) FAST_FUNC; … … 306 312 const char *interface) FAST_FUNC; 307 313 314 /* note: ip is a pointer to an IPv6 in network order, possibly misaliged */ 315 int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) FAST_FUNC; 316 308 317 POP_SAVED_FUNCTION_VISIBILITY 309 318 -
branches/3.2/mindi-busybox/networking/udhcp/dhcpc.c
r2725 r3232 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 /* "struct client_config_t client_config" is in bb_common_bufsiz1 */ 33 34 35 #if ENABLE_LONG_OPTS 36 static const char udhcpc_longopts[] ALIGN1 = 37 "clientid-none\0" No_argument "C" 38 "vendorclass\0" Required_argument "V" 39 "hostname\0" Required_argument "H" 40 "fqdn\0" Required_argument "F" 41 "interface\0" Required_argument "i" 42 "now\0" No_argument "n" 43 "pidfile\0" Required_argument "p" 44 "quit\0" No_argument "q" 45 "release\0" No_argument "R" 46 "request\0" Required_argument "r" 47 "script\0" Required_argument "s" 48 "timeout\0" Required_argument "T" 49 "retries\0" Required_argument "t" 50 "tryagain\0" Required_argument "A" 51 "syslog\0" No_argument "S" 52 "request-option\0" Required_argument "O" 53 "no-default-options\0" No_argument "o" 54 "foreground\0" No_argument "f" 55 "background\0" No_argument "b" 56 "broadcast\0" No_argument "B" 57 IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a") 58 IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P") 59 ; 35 60 #endif 36 #include <linux/filter.h> 37 38 /* struct client_config_t client_config is in bb_common_bufsiz1 */ 61 /* Must match getopt32 option string order */ 62 enum { 63 OPT_C = 1 << 0, 64 OPT_V = 1 << 1, 65 OPT_H = 1 << 2, 66 OPT_h = 1 << 3, 67 OPT_F = 1 << 4, 68 OPT_i = 1 << 5, 69 OPT_n = 1 << 6, 70 OPT_p = 1 << 7, 71 OPT_q = 1 << 8, 72 OPT_R = 1 << 9, 73 OPT_r = 1 << 10, 74 OPT_s = 1 << 11, 75 OPT_T = 1 << 12, 76 OPT_t = 1 << 13, 77 OPT_S = 1 << 14, 78 OPT_A = 1 << 15, 79 OPT_O = 1 << 16, 80 OPT_o = 1 << 17, 81 OPT_x = 1 << 18, 82 OPT_f = 1 << 19, 83 OPT_B = 1 << 20, 84 /* The rest has variable bit positions, need to be clever */ 85 OPTBIT_B = 20, 86 USE_FOR_MMU( OPTBIT_b,) 87 IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,) 88 IF_FEATURE_UDHCP_PORT( OPTBIT_P,) 89 USE_FOR_MMU( OPT_b = 1 << OPTBIT_b,) 90 IF_FEATURE_UDHCPC_ARPING(OPT_a = 1 << OPTBIT_a,) 91 IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,) 92 }; 39 93 40 94 … … 46 100 [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2, 47 101 [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "), 102 [OPTION_6RD ] = sizeof("32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "), 48 103 [OPTION_STRING ] = 1, 104 [OPTION_STRING_HOST ] = 1, 49 105 #if ENABLE_FEATURE_UDHCP_RFC3397 50 106 [OPTION_DNS_STRING ] = 1, /* unused */ … … 81 137 } 82 138 139 /* Check if a given label represents a valid DNS label 140 * Return pointer to the first character after the label upon success, 141 * NULL otherwise. 142 * See RFC1035, 2.3.1 143 */ 144 /* We don't need to be particularly anal. For example, allowing _, hyphen 145 * at the end, or leading and trailing dots would be ok, since it 146 * can't be used for attacks. (Leading hyphen can be, if someone uses 147 * cmd "$hostname" 148 * in the script: then hostname may be treated as an option) 149 */ 150 static const char *valid_domain_label(const char *label) 151 { 152 unsigned char ch; 153 unsigned pos = 0; 154 155 for (;;) { 156 ch = *label; 157 if ((ch|0x20) < 'a' || (ch|0x20) > 'z') { 158 if (pos == 0) { 159 /* label must begin with letter */ 160 return NULL; 161 } 162 if (ch < '0' || ch > '9') { 163 if (ch == '\0' || ch == '.') 164 return label; 165 /* DNS allows only '-', but we are more permissive */ 166 if (ch != '-' && ch != '_') 167 return NULL; 168 } 169 } 170 label++; 171 pos++; 172 //Do we want this? 173 //if (pos > 63) /* NS_MAXLABEL; labels must be 63 chars or less */ 174 // return NULL; 175 } 176 } 177 178 /* Check if a given name represents a valid DNS name */ 179 /* See RFC1035, 2.3.1 */ 180 static int good_hostname(const char *name) 181 { 182 //const char *start = name; 183 184 for (;;) { 185 name = valid_domain_label(name); 186 if (!name) 187 return 0; 188 if (!name[0]) 189 return 1; 190 //Do we want this? 191 //return ((name - start) < 1025); /* NS_MAXDNAME */ 192 name++; 193 } 194 } 195 83 196 /* Create "opt_name=opt_value" string */ 84 197 static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_optflag *optflag, const char *opt_name) … … 88 201 char *dest, *ret; 89 202 90 /* option points to OPT_DATA, need to go back andget OPT_LEN */91 len = option[ OPT_LEN - OPT_DATA];203 /* option points to OPT_DATA, need to go back to get OPT_LEN */ 204 len = option[-OPT_DATA + OPT_LEN]; 92 205 93 206 type = optflag->flags & OPTION_TYPE_MASK; 94 207 optlen = dhcp_option_lengths[type]; 95 upper_length = len_of_option_as_string[type] * ((unsigned)len / (unsigned)optlen); 208 upper_length = len_of_option_as_string[type] 209 * ((unsigned)(len + optlen - 1) / (unsigned)optlen); 96 210 97 211 dest = ret = xmalloc(upper_length + strlen(opt_name) + 2); … … 99 213 100 214 while (len >= optlen) { 101 unsigned ip_ofs = 0;102 103 215 switch (type) { 216 case OPTION_IP: 104 217 case OPTION_IP_PAIR: 105 218 dest += sprint_nip(dest, "", option); 106 *dest++ = '/'; 107 ip_ofs = 4; 108 /* fall through */ 109 case OPTION_IP: 110 dest += sprint_nip(dest, "", option + ip_ofs); 219 if (type == OPTION_IP) 220 break; 221 dest += sprint_nip(dest, "/", option + 4); 111 222 break; 112 223 // case OPTION_BOOLEAN: … … 130 241 break; 131 242 } 243 /* Note: options which use 'return' instead of 'break' 244 * (for example, OPTION_STRING) skip the code which handles 245 * the case of list of options. 246 */ 132 247 case OPTION_STRING: 248 case OPTION_STRING_HOST: 133 249 memcpy(dest, option, len); 134 250 dest[len] = '\0'; 135 return ret; /* Short circuit this case */ 251 if (type == OPTION_STRING_HOST && !good_hostname(dest)) 252 safe_strncpy(dest, "bad", len); 253 return ret; 136 254 case OPTION_STATIC_ROUTES: { 137 255 /* Option binary format: … … 178 296 return ret; 179 297 } 298 case OPTION_6RD: 299 /* Option binary format (see RFC 5969): 300 * 0 1 2 3 301 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 302 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 303 * | OPTION_6RD | option-length | IPv4MaskLen | 6rdPrefixLen | 304 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 305 * | 6rdPrefix | 306 * ... (16 octets) ... 307 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 308 * ... 6rdBRIPv4Address(es) ... 309 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 310 * We convert it to a string 311 * "IPv4MaskLen 6rdPrefixLen 6rdPrefix 6rdBRIPv4Address..." 312 * 313 * Sanity check: ensure that our length is at least 22 bytes, that 314 * IPv4MaskLen <= 32, 315 * 6rdPrefixLen <= 128, 316 * 6rdPrefixLen + (32 - IPv4MaskLen) <= 128 317 * (2nd condition need no check - it follows from 1st and 3rd). 318 * Else, return envvar with empty value ("optname=") 319 */ 320 if (len >= (1 + 1 + 16 + 4) 321 && option[0] <= 32 322 && (option[1] + 32 - option[0]) <= 128 323 ) { 324 /* IPv4MaskLen */ 325 dest += sprintf(dest, "%u ", *option++); 326 /* 6rdPrefixLen */ 327 dest += sprintf(dest, "%u ", *option++); 328 /* 6rdPrefix */ 329 dest += sprint_nip6(dest, /* "", */ option); 330 option += 16; 331 len -= 1 + 1 + 16 + 4; 332 /* "+ 4" above corresponds to the length of IPv4 addr 333 * we consume in the loop below */ 334 while (1) { 335 /* 6rdBRIPv4Address(es) */ 336 dest += sprint_nip(dest, " ", option); 337 option += 4; 338 len -= 4; /* do we have yet another 4+ bytes? */ 339 if (len < 0) 340 break; /* no */ 341 } 342 } 343 344 return ret; 180 345 #if ENABLE_FEATURE_UDHCP_RFC3397 181 346 case OPTION_DNS_STRING: … … 217 382 #endif 218 383 } /* switch */ 384 385 /* If we are here, try to format any remaining data 386 * in the option as another, similarly-formatted option 387 */ 219 388 option += optlen; 220 389 len -= optlen; … … 222 391 // Should we bail out/warn if we see multi-ip option which is 223 392 // not allowed to be such (for example, DHCP_BROADCAST)? - 224 if (len < = 0/* || !(optflag->flags & OPTION_LIST) */)393 if (len < optlen /* || !(optflag->flags & OPTION_LIST) */) 225 394 break; 226 395 *dest++ = ' '; 227 396 *dest = '\0'; 228 } 397 } /* while */ 398 229 399 return ret; 230 400 } … … 239 409 uint8_t *temp; 240 410 uint8_t overload = 0; 411 412 #define BITMAP unsigned 413 #define BBITS (sizeof(BITMAP) * 8) 414 #define BMASK(i) (1 << (i & (sizeof(BITMAP) * 8 - 1))) 415 #define FOUND_OPTS(i) (found_opts[(unsigned)i / BBITS]) 416 BITMAP found_opts[256 / BBITS]; 417 418 memset(found_opts, 0, sizeof(found_opts)); 241 419 242 420 /* We need 6 elements for: … … 251 429 /* +1 element for each option, +2 for subnet option: */ 252 430 if (packet) { 253 for (i = 0; dhcp_optflags[i].code; i++) { 254 if (udhcp_get_option(packet, dhcp_optflags[i].code)) { 255 if (dhcp_optflags[i].code == DHCP_SUBNET) 256 envc++; /* for mton */ 431 /* note: do not search for "pad" (0) and "end" (255) options */ 432 //TODO: change logic to scan packet _once_ 433 for (i = 1; i < 255; i++) { 434 temp = udhcp_get_option(packet, i); 435 if (temp) { 436 if (i == DHCP_OPTION_OVERLOAD) 437 overload = *temp; 438 else if (i == DHCP_SUBNET) 439 envc++; /* for $mask */ 257 440 envc++; 441 /*if (i != DHCP_MESSAGE_TYPE)*/ 442 FOUND_OPTS(i) |= BMASK(i); 258 443 } 259 444 } 260 temp = udhcp_get_option(packet, DHCP_OPTION_OVERLOAD); 261 if (temp) 262 overload = *temp; 263 } 264 curr = envp = xzalloc(sizeof(char *) * envc); 445 } 446 curr = envp = xzalloc(sizeof(envp[0]) * envc); 265 447 266 448 *curr = xasprintf("interface=%s", client_config.interface); … … 270 452 return envp; 271 453 454 /* Export BOOTP fields. Fields we don't (yet?) export: 455 * uint8_t op; // always BOOTREPLY 456 * uint8_t htype; // hardware address type. 1 = 10mb ethernet 457 * uint8_t hlen; // hardware address length 458 * uint8_t hops; // used by relay agents only 459 * uint32_t xid; 460 * uint16_t secs; // elapsed since client began acquisition/renewal 461 * uint16_t flags; // only one flag so far: bcast. Never set by server 462 * uint32_t ciaddr; // client IP (usually == yiaddr. can it be different 463 * // if during renew server wants to give us differn IP?) 464 * uint32_t gateway_nip; // relay agent IP address 465 * uint8_t chaddr[16]; // link-layer client hardware address (MAC) 466 * TODO: export gateway_nip as $giaddr? 467 */ 468 /* Most important one: yiaddr as $ip */ 272 469 *curr = xmalloc(sizeof("ip=255.255.255.255")); 273 470 sprint_nip(*curr, "ip=", (uint8_t *) &packet->yiaddr); 274 471 putenv(*curr++); 275 276 opt_name = dhcp_option_strings;277 i = 0;278 while (*opt_name) {279 temp = udhcp_get_option(packet, dhcp_optflags[i].code);280 if (!temp)281 goto next;282 *curr = xmalloc_optname_optval(temp, &dhcp_optflags[i], opt_name);283 putenv(*curr++);284 if (dhcp_optflags[i].code == DHCP_SUBNET) {285 /* Subnet option: make things like "$ip/$mask" possible */286 uint32_t subnet;287 move_from_unaligned32(subnet, temp);288 *curr = xasprintf("mask=%d", mton(subnet));289 putenv(*curr++);290 }291 next:292 opt_name += strlen(opt_name) + 1;293 i++;294 }295 472 if (packet->siaddr_nip) { 473 /* IP address of next server to use in bootstrap */ 296 474 *curr = xmalloc(sizeof("siaddr=255.255.255.255")); 297 475 sprint_nip(*curr, "siaddr=", (uint8_t *) &packet->siaddr_nip); … … 308 486 putenv(*curr++); 309 487 } 488 489 /* Export known DHCP options */ 490 opt_name = dhcp_option_strings; 491 i = 0; 492 while (*opt_name) { 493 uint8_t code = dhcp_optflags[i].code; 494 BITMAP *found_ptr = &FOUND_OPTS(code); 495 BITMAP found_mask = BMASK(code); 496 if (!(*found_ptr & found_mask)) 497 goto next; 498 *found_ptr &= ~found_mask; /* leave only unknown options */ 499 temp = udhcp_get_option(packet, code); 500 *curr = xmalloc_optname_optval(temp, &dhcp_optflags[i], opt_name); 501 putenv(*curr++); 502 if (code == DHCP_SUBNET) { 503 /* Subnet option: make things like "$ip/$mask" possible */ 504 uint32_t subnet; 505 move_from_unaligned32(subnet, temp); 506 *curr = xasprintf("mask=%u", mton(subnet)); 507 putenv(*curr++); 508 } 509 next: 510 opt_name += strlen(opt_name) + 1; 511 i++; 512 } 513 /* Export unknown options */ 514 for (i = 0; i < 256;) { 515 BITMAP bitmap = FOUND_OPTS(i); 516 if (!bitmap) { 517 i += BBITS; 518 continue; 519 } 520 if (bitmap & BMASK(i)) { 521 unsigned len, ofs; 522 523 temp = udhcp_get_option(packet, i); 524 /* udhcp_get_option returns ptr to data portion, 525 * need to go back to get len 526 */ 527 len = temp[-OPT_DATA + OPT_LEN]; 528 *curr = xmalloc(sizeof("optNNN=") + 1 + len*2); 529 ofs = sprintf(*curr, "opt%u=", i); 530 *bin2hex(*curr + ofs, (void*) temp, len) = '\0'; 531 putenv(*curr++); 532 } 533 i++; 534 } 535 310 536 return envp; 311 537 } … … 316 542 char **envp, **curr; 317 543 char *argv[3]; 318 319 if (client_config.script == NULL)320 return;321 544 322 545 envp = fill_envp(packet); … … 347 570 static void init_packet(struct dhcp_packet *packet, char type) 348 571 { 572 uint16_t secs; 573 349 574 /* Fill in: op, htype, hlen, cookie fields; message type option: */ 350 575 udhcp_init_header(packet, type); 351 576 352 577 packet->xid = random_xid(); 578 579 client_config.last_secs = monotonic_sec(); 580 if (client_config.first_secs == 0) 581 client_config.first_secs = client_config.last_secs; 582 secs = client_config.last_secs - client_config.first_secs; 583 packet->secs = htons(secs); 353 584 354 585 memcpy(packet->chaddr, client_config.client_mac, 6); … … 359 590 static void add_client_options(struct dhcp_packet *packet) 360 591 { 361 uint8_t c;362 592 int i, end, len; 363 593 … … 369 599 end = udhcp_end_option(packet->options); 370 600 len = 0; 371 for (i = 0; (c = dhcp_optflags[i].code) != 0; i++) { 372 if (( (dhcp_optflags[i].flags & OPTION_REQ) 373 && !client_config.no_default_options 374 ) 375 || (client_config.opt_mask[c >> 3] & (1 << (c & 7))) 376 ) { 377 packet->options[end + OPT_DATA + len] = c; 601 for (i = 1; i < DHCP_END; i++) { 602 if (client_config.opt_mask[i >> 3] & (1 << (i & 7))) { 603 packet->options[end + OPT_DATA + len] = i; 378 604 len++; 379 605 } … … 392 618 udhcp_add_binary_option(packet, client_config.fqdn); 393 619 620 /* Request broadcast replies if we have no IP addr */ 621 if ((option_mask32 & OPT_B) && packet->ciaddr == 0) 622 packet->flags |= htons(BROADCAST_FLAG); 623 394 624 /* Add -x options if any */ 395 625 { … … 404 634 // strncpy((char*)packet->file, client_config.boot_file, sizeof(packet->file) - 1); 405 635 } 636 637 // This will be needed if we remove -V VENDOR_STR in favor of 638 // -x vendor:VENDOR_STR 639 //if (!udhcp_find_option(packet.options, DHCP_VENDOR)) 640 // /* not set, set the default vendor ID */ 641 // ...add (DHCP_VENDOR, "udhcp "BB_VER) opt... 406 642 } 407 643 … … 548 784 /* Broadcast a DHCP decline message */ 549 785 /* NOINLINE: limit stack usage in caller */ 550 static NOINLINE int send_decline( uint32_t xid,uint32_t server, uint32_t requested)786 static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t requested) 551 787 { 552 788 struct dhcp_packet packet; … … 557 793 init_packet(&packet, DHCPDECLINE); 558 794 795 #if 0 559 796 /* RFC 2131 says DHCPDECLINE's xid is randomly selected by client, 560 797 * but in case the server is buggy and wants DHCPDECLINE's xid … … 563 800 */ 564 801 packet.xid = xid; 802 #endif 565 803 /* DHCPDECLINE uses "requested ip", not ciaddr, to store offered IP */ 566 804 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); … … 599 837 struct ip_udp_dhcp_packet packet; 600 838 uint16_t check; 601 602 memset(&packet, 0, sizeof(packet)); 603 bytes = safe_read(fd, &packet, sizeof(packet)); 604 if (bytes < 0) { 605 log1("Packet read error, ignoring"); 606 /* NB: possible down interface, etc. Caller should pause. */ 607 return bytes; /* returns -1 */ 839 unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))]; 840 struct iovec iov; 841 struct msghdr msg; 842 struct cmsghdr *cmsg; 843 844 /* used to use just safe_read(fd, &packet, sizeof(packet)) 845 * but we need to check for TP_STATUS_CSUMNOTREADY :( 846 */ 847 iov.iov_base = &packet; 848 iov.iov_len = sizeof(packet); 849 memset(&msg, 0, sizeof(msg)); 850 msg.msg_iov = &iov; 851 msg.msg_iovlen = 1; 852 msg.msg_control = cmsgbuf; 853 msg.msg_controllen = sizeof(cmsgbuf); 854 for (;;) { 855 bytes = recvmsg(fd, &msg, 0); 856 if (bytes < 0) { 857 if (errno == EINTR) 858 continue; 859 log1("Packet read error, ignoring"); 860 /* NB: possible down interface, etc. Caller should pause. */ 861 return bytes; /* returns -1 */ 862 } 863 break; 608 864 } 609 865 … … 623 879 624 880 /* make sure its the right packet for us, and that it passes sanity checks */ 625 if (packet.ip.protocol != IPPROTO_UDP || packet.ip.version != IPVERSION 881 if (packet.ip.protocol != IPPROTO_UDP 882 || packet.ip.version != IPVERSION 626 883 || packet.ip.ihl != (sizeof(packet.ip) >> 2) 627 884 || packet.udp.dest != htons(CLIENT_PORT) … … 636 893 check = packet.ip.check; 637 894 packet.ip.check = 0; 638 if (check != udhcp_checksum(&packet.ip, sizeof(packet.ip))) {895 if (check != inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip))) { 639 896 log1("Bad IP header checksum, ignoring"); 640 897 return -2; 898 } 899 900 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { 901 if (cmsg->cmsg_level == SOL_PACKET 902 && cmsg->cmsg_type == PACKET_AUXDATA 903 ) { 904 /* some VMs don't checksum UDP and TCP data 905 * they send to the same physical machine, 906 * here we detect this case: 907 */ 908 struct tpacket_auxdata *aux = (void *)CMSG_DATA(cmsg); 909 if (aux->tp_status & TP_STATUS_CSUMNOTREADY) 910 goto skip_udp_sum_check; 911 } 641 912 } 642 913 … … 647 918 check = packet.udp.check; 648 919 packet.udp.check = 0; 649 if (check && check != udhcp_checksum(&packet, bytes)) {920 if (check && check != inet_cksum((uint16_t *)&packet, bytes)) { 650 921 log1("Packet with bad UDP checksum received, ignoring"); 651 922 return -2; 652 923 } 653 654 memcpy(dhcp_pkt, &packet.data, bytes - (sizeof(packet.ip) + sizeof(packet.udp))); 655 656 if (dhcp_pkt->cookie != htonl(DHCP_MAGIC)) { 924 skip_udp_sum_check: 925 926 if (packet.data.cookie != htonl(DHCP_MAGIC)) { 657 927 bb_info_msg("Packet with bad magic, ignoring"); 658 928 return -2; 659 929 } 660 log1("Got valid DHCP packet"); 661 udhcp_dump_packet(dhcp_pkt); 662 return bytes - (sizeof(packet.ip) + sizeof(packet.udp)); 930 931 log1("Received a packet"); 932 udhcp_dump_packet(&packet.data); 933 934 bytes -= sizeof(packet.ip) + sizeof(packet.udp); 935 memcpy(dhcp_pkt, &packet.data, bytes); 936 return bytes; 663 937 } 664 938 … … 715 989 * TODO: make conditional? 716 990 */ 717 #define SERVER_AND_CLIENT_PORTS ((67 << 16) + 68)718 991 static const struct sock_filter filter_instr[] = { 719 /* check for udp*/992 /* load 9th byte (protocol) */ 720 993 BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9), 721 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 2, 0), /* L5, L1, is UDP? */ 722 /* ugly check for arp on ethernet-like and IPv4 */ 723 BPF_STMT(BPF_LD|BPF_W|BPF_ABS, 2), /* L1: */ 724 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x08000604, 3, 4), /* L3, L4 */ 725 /* skip IP header */ 726 BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0), /* L5: */ 727 /* check udp source and destination ports */ 728 BPF_STMT(BPF_LD|BPF_W|BPF_IND, 0), 729 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, SERVER_AND_CLIENT_PORTS, 0, 1), /* L3, L4 */ 730 /* returns */ 731 BPF_STMT(BPF_RET|BPF_K, 0x0fffffff ), /* L3: pass */ 732 BPF_STMT(BPF_RET|BPF_K, 0), /* L4: reject */ 994 /* jump to L1 if it is IPPROTO_UDP, else to L4 */ 995 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6), 996 /* L1: load halfword from offset 6 (flags and frag offset) */ 997 BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6), 998 /* jump to L4 if any bits in frag offset field are set, else to L2 */ 999 BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0), 1000 /* L2: skip IP header (load index reg with header len) */ 1001 BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0), 1002 /* load udp destination port from halfword[header_len + 2] */ 1003 BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2), 1004 /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */ 1005 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1), 1006 /* L3: accept packet */ 1007 BPF_STMT(BPF_RET|BPF_K, 0xffffffff), 1008 /* L4: discard packet */ 1009 BPF_STMT(BPF_RET|BPF_K, 0), 733 1010 }; 734 1011 static const struct sock_fprog filter_prog = { … … 741 1018 742 1019 fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); 743 log1("Got raw socket fd %d", fd); //log2? 744 745 if (SERVER_PORT == 67 && CLIENT_PORT == 68) { 746 /* Use only if standard ports are in use */ 747 /* Ignoring error (kernel may lack support for this) */ 748 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, 749 sizeof(filter_prog)) >= 0) 750 log1("Attached filter to raw socket fd %d", fd); // log? 751 } 1020 log1("Got raw socket fd"); //log2? 752 1021 753 1022 sock.sll_family = AF_PACKET; … … 755 1024 sock.sll_ifindex = ifindex; 756 1025 xbind(fd, (struct sockaddr *) &sock, sizeof(sock)); 1026 1027 if (CLIENT_PORT == 68) { 1028 /* Use only if standard port is in use */ 1029 /* Ignoring error (kernel may lack support for this) */ 1030 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, 1031 sizeof(filter_prog)) >= 0) 1032 log1("Attached filter to raw socket fd"); // log? 1033 } 1034 1035 if (setsockopt(fd, SOL_PACKET, PACKET_AUXDATA, 1036 &const_int_1, sizeof(int)) < 0 1037 ) { 1038 if (errno != ENOPROTOOPT) 1039 log1("Can't set PACKET_AUXDATA on raw socket"); 1040 } 1041 757 1042 log1("Created raw socket"); 758 1043 … … 780 1065 } 781 1066 1067 /* Called only on SIGUSR1 */ 782 1068 static void perform_renew(void) 783 1069 { … … 802 1088 } 803 1089 804 static void perform_release(uint32_t requested_ip, uint32_t server_addr)1090 static void perform_release(uint32_t server_addr, uint32_t requested_ip) 805 1091 { 806 1092 char buffer[sizeof("255.255.255.255")]; … … 850 1136 //usage:#endif 851 1137 //usage:#define udhcpc_trivial_usage 852 //usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"oCR ] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n"853 //usage: " [- H HOSTNAME] [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]")1138 //usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"oCRB] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n" 1139 //usage: " [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]") 854 1140 //usage:#define udhcpc_full_usage "\n" 855 1141 //usage: IF_LONG_OPTS( … … 857 1143 //usage: "\n -p,--pidfile FILE Create pidfile" 858 1144 //usage: "\n -s,--script PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" 1145 //usage: "\n -B,--broadcast Request broadcast replies" 859 1146 //usage: "\n -t,--retries N Send up to N discover packets" 860 1147 //usage: "\n -T,--timeout N Pause between packets (default 3 seconds)" … … 883 1170 //usage: "\n -x 0x3d:0100BEEFC0FFEE - option 61 (client id)" 884 1171 //usage: "\n -F,--fqdn NAME Ask server to update DNS mapping for NAME" 885 //usage: "\n -H,-h,--hostname NAME Send NAME as client hostname (default none)"886 1172 //usage: "\n -V,--vendorclass VENDOR Vendor identifier (default 'udhcp VERSION')" 887 1173 //usage: "\n -C,--clientid-none Don't send MAC as client identifier" … … 894 1180 //usage: "\n -p FILE Create pidfile" 895 1181 //usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" 1182 //usage: "\n -B Request broadcast replies" 896 1183 //usage: "\n -t N Send up to N discover packets" 897 1184 //usage: "\n -T N Pause between packets (default 3 seconds)" … … 920 1207 //usage: "\n -x 0x3d:0100BEEFC0FFEE - option 61 (client id)" 921 1208 //usage: "\n -F NAME Ask server to update DNS mapping for NAME" 922 //usage: "\n -H,-h NAME Send NAME as client hostname (default none)"923 1209 //usage: "\n -V VENDOR Vendor identifier (default 'udhcp VERSION')" 924 1210 //usage: "\n -C Don't send MAC as client identifier" … … 927 1213 //usage: ) 928 1214 //usage: ) 1215 //usage: "\nSignals:" 1216 //usage: "\n USR1 Renew lease" 1217 //usage: "\n USR2 Release lease" 1218 929 1219 930 1220 int udhcpc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; … … 942 1232 uint32_t server_addr = server_addr; /* for compiler */ 943 1233 uint32_t requested_ip = 0; 944 uint32_t xid = 0; 945 uint32_t lease_seconds = 0; /* can be given as 32-bit quantity */ 1234 uint32_t xid = xid; /* for compiler */ 946 1235 int packet_num; 947 1236 int timeout; /* must be signed */ … … 950 1239 int max_fd; 951 1240 int retval; 952 struct timeval tv;953 struct dhcp_packet packet;954 1241 fd_set rfds; 955 956 #if ENABLE_LONG_OPTS957 static const char udhcpc_longopts[] ALIGN1 =958 "clientid-none\0" No_argument "C"959 "vendorclass\0" Required_argument "V"960 "hostname\0" Required_argument "H"961 "fqdn\0" Required_argument "F"962 "interface\0" Required_argument "i"963 "now\0" No_argument "n"964 "pidfile\0" Required_argument "p"965 "quit\0" No_argument "q"966 "release\0" No_argument "R"967 "request\0" Required_argument "r"968 "script\0" Required_argument "s"969 "timeout\0" Required_argument "T"970 "version\0" No_argument "v"971 "retries\0" Required_argument "t"972 "tryagain\0" Required_argument "A"973 "syslog\0" No_argument "S"974 "request-option\0" Required_argument "O"975 "no-default-options\0" No_argument "o"976 "foreground\0" No_argument "f"977 "background\0" No_argument "b"978 IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a")979 IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P")980 ;981 #endif982 enum {983 OPT_C = 1 << 0,984 OPT_V = 1 << 1,985 OPT_H = 1 << 2,986 OPT_h = 1 << 3,987 OPT_F = 1 << 4,988 OPT_i = 1 << 5,989 OPT_n = 1 << 6,990 OPT_p = 1 << 7,991 OPT_q = 1 << 8,992 OPT_R = 1 << 9,993 OPT_r = 1 << 10,994 OPT_s = 1 << 11,995 OPT_T = 1 << 12,996 OPT_t = 1 << 13,997 OPT_S = 1 << 14,998 OPT_A = 1 << 15,999 OPT_O = 1 << 16,1000 OPT_o = 1 << 17,1001 OPT_x = 1 << 18,1002 OPT_f = 1 << 19,1003 /* The rest has variable bit positions, need to be clever */1004 OPTBIT_f = 19,1005 USE_FOR_MMU( OPTBIT_b,)1006 IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,)1007 IF_FEATURE_UDHCP_PORT( OPTBIT_P,)1008 USE_FOR_MMU( OPT_b = 1 << OPTBIT_b,)1009 IF_FEATURE_UDHCPC_ARPING(OPT_a = 1 << OPTBIT_a,)1010 IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,)1011 };1012 1242 1013 1243 /* Default options */ … … 1020 1250 /* Parse command line */ 1021 1251 /* O,x: list; -T,-t,-A take numeric param */ 1022 opt_complementary = "O::x::T+:t+:A+" 1023 #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 1024 ":vv" 1025 #endif 1026 ; 1252 opt_complementary = "O::x::T+:t+:A+" IF_UDHCP_VERBOSE(":vv") ; 1027 1253 IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) 1028 opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:f "1254 opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB" 1029 1255 USE_FOR_MMU("b") 1030 1256 IF_FEATURE_UDHCPC_ARPING("a") … … 1038 1264 , &list_x 1039 1265 IF_FEATURE_UDHCP_PORT(, &str_P) 1040 #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 1041 , &dhcp_verbose1042 #endif 1043 );1044 if (opt & (OPT_h|OPT_H))1266 IF_UDHCP_VERBOSE(, &dhcp_verbose) 1267 ); 1268 if (opt & (OPT_h|OPT_H)) { 1269 //msg added 2011-11 1270 bb_error_msg("option -h NAME is deprecated, use -x hostname:NAME"); 1045 1271 client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0); 1272 } 1046 1273 if (opt & OPT_F) { 1047 1274 /* FQDN option format: [0x51][len][flags][0][0]<fqdn> */ … … 1067 1294 } 1068 1295 #endif 1069 if (opt & OPT_o)1070 client_config.no_default_options = 1;1071 1296 while (list_O) { 1072 1297 char *optstr = llist_pop(&list_O); 1073 unsigned n = udhcp_option_idx(optstr); 1074 n = dhcp_optflags[n].code; 1298 unsigned n = bb_strtou(optstr, NULL, 0); 1299 if (errno || n > 254) { 1300 n = udhcp_option_idx(optstr); 1301 n = dhcp_optflags[n].code; 1302 } 1075 1303 client_config.opt_mask[n >> 3] |= 1 << (n & 7); 1304 } 1305 if (!(opt & OPT_o)) { 1306 unsigned i, n; 1307 for (i = 0; (n = dhcp_optflags[i].code) != 0; i++) { 1308 if (dhcp_optflags[i].flags & OPTION_REQ) { 1309 client_config.opt_mask[n >> 3] |= 1 << (n & 7); 1310 } 1311 } 1076 1312 } 1077 1313 while (list_x) { … … 1101 1337 memcpy(clientid_mac_ptr, client_config.client_mac, 6); 1102 1338 } 1103 if (str_V[0] != '\0') 1339 if (str_V[0] != '\0') { 1340 // can drop -V, str_V, client_config.vendorclass, 1341 // but need to add "vendor" to the list of recognized 1342 // string opts for this to work; 1343 // and need to tweak add_client_options() too... 1344 // ...so the question is, should we? 1345 //bb_error_msg("option -V VENDOR is deprecated, use -x vendor:VENDOR"); 1104 1346 client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0); 1347 } 1348 1105 1349 #if !BB_MMU 1106 1350 /* on NOMMU reexec (i.e., background) early */ … … 1140 1384 */ 1141 1385 for (;;) { 1386 struct timeval tv; 1387 struct dhcp_packet packet; 1142 1388 /* silence "uninitialized!" warning */ 1143 1389 unsigned timestamp_before_wait = timestamp_before_wait; … … 1159 1405 /* If we already timed out, fall through with retval = 0, else... */ 1160 1406 if ((int)tv.tv_sec > 0) { 1407 log1("Waiting on select %u seconds", (int)tv.tv_sec); 1161 1408 timestamp_before_wait = (unsigned)monotonic_sec(); 1162 log1("Waiting on select...");1163 1409 retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); 1164 1410 if (retval < 0) { … … 1187 1433 client_config.client_mac) 1188 1434 ) { 1189 return 1; /* iface is gone? */1435 goto ret0; /* iface is gone? */ 1190 1436 } 1191 1437 if (clientid_mac_ptr) … … 1197 1443 switch (state) { 1198 1444 case INIT_SELECTING: 1199 if ( packet_num < discover_retries) {1445 if (!discover_retries || packet_num < discover_retries) { 1200 1446 if (packet_num == 0) 1201 1447 xid = random_xid(); … … 1226 1472 continue; 1227 1473 case REQUESTING: 1228 if ( packet_num < discover_retries) {1474 if (!discover_retries || packet_num < discover_retries) { 1229 1475 /* send broadcast select packet */ 1230 1476 send_select(xid, server_addr, requested_ip); … … 1243 1489 /* 1/2 lease passed, enter renewing state */ 1244 1490 state = RENEWING; 1491 client_config.first_secs = 0; /* make secs field count from 0 */ 1245 1492 change_listen_mode(LISTEN_KERNEL); 1246 1493 log1("Entering renew state"); … … 1282 1529 udhcp_run_script(NULL, "deconfig"); 1283 1530 state = INIT_SELECTING; 1531 client_config.first_secs = 0; /* make secs field count from 0 */ 1284 1532 /*timeout = 0; - already is */ 1285 1533 packet_num = 0; … … 1298 1546 switch (udhcp_sp_read(&rfds)) { 1299 1547 case SIGUSR1: 1548 client_config.first_secs = 0; /* make secs field count from 0 */ 1549 already_waited_sec = 0; 1300 1550 perform_renew(); 1301 if (state == RENEW_REQUESTED) 1551 if (state == RENEW_REQUESTED) { 1552 /* We might be either on the same network 1553 * (in which case renew might work), 1554 * or we might be on a completely different one 1555 * (in which case renew won't ever succeed). 1556 * For the second case, must make sure timeout 1557 * is not too big, or else we can send 1558 * futile renew requests for hours. 1559 * (Ab)use -A TIMEOUT value (usually 20 sec) 1560 * as a cap on the timeout. 1561 */ 1562 if (timeout > tryagain_timeout) 1563 timeout = tryagain_timeout; 1302 1564 goto case_RENEW_REQUESTED; 1565 } 1303 1566 /* Start things over */ 1304 1567 packet_num = 0; … … 1307 1570 continue; 1308 1571 case SIGUSR2: 1309 perform_release( requested_ip, server_addr);1572 perform_release(server_addr, requested_ip); 1310 1573 timeout = INT_MAX; 1311 1574 continue; 1312 1575 case SIGTERM: 1313 1576 bb_info_msg("Received SIGTERM"); 1314 if (opt & OPT_R) /* release on quit */1315 perform_release(requested_ip, server_addr);1316 1577 goto ret0; 1317 1578 } … … 1366 1627 switch (state) { 1367 1628 case INIT_SELECTING: 1368 /* Must be a DHCPOFFER to one of our xid's*/1629 /* Must be a DHCPOFFER */ 1369 1630 if (*message == DHCPOFFER) { 1370 /* TODO: why we don't just fetch server's IP from IP header? */ 1631 /* What exactly is server's IP? There are several values. 1632 * Example DHCP offer captured with tchdump: 1633 * 1634 * 10.34.25.254:67 > 10.34.25.202:68 // IP header's src 1635 * BOOTP fields: 1636 * Your-IP 10.34.25.202 1637 * Server-IP 10.34.32.125 // "next server" IP 1638 * Gateway-IP 10.34.25.254 // relay's address (if DHCP relays are in use) 1639 * DHCP options: 1640 * DHCP-Message Option 53, length 1: Offer 1641 * Server-ID Option 54, length 4: 10.34.255.7 // "server ID" 1642 * Default-Gateway Option 3, length 4: 10.34.25.254 // router 1643 * 1644 * We think that real server IP (one to use in renew/release) 1645 * is one in Server-ID option. But I am not 100% sure. 1646 * IP header's src and Gateway-IP (same in this example) 1647 * might work too. 1648 * "Next server" and router are definitely wrong ones to use, though... 1649 */ 1371 1650 temp = udhcp_get_option(&packet, DHCP_SERVER_ID); 1372 1651 if (!temp) { … … 1392 1671 case REBINDING: 1393 1672 if (*message == DHCPACK) { 1673 uint32_t lease_seconds; 1674 struct in_addr temp_addr; 1675 1394 1676 temp = udhcp_get_option(&packet, DHCP_LEASE_TIME); 1395 1677 if (!temp) { … … 1400 1682 move_from_unaligned32(lease_seconds, temp); 1401 1683 lease_seconds = ntohl(lease_seconds); 1402 lease_seconds &= 0x0fffffff; /* paranoia: must not be prone to overflows */ 1403 if (lease_seconds < 10) /* and not too small */ 1404 lease_seconds = 10; 1684 /* paranoia: must not be too small and not prone to overflows */ 1685 if (lease_seconds < 0x10) 1686 lease_seconds = 0x10; 1687 if (lease_seconds >= 0x10000000) 1688 lease_seconds = 0x0fffffff; 1405 1689 } 1406 1690 #if ENABLE_FEATURE_UDHCPC_ARPING … … 1423 1707 bb_info_msg("Offered address is in use " 1424 1708 "(got ARP reply), declining"); 1425 send_decline( xid,server_addr, packet.yiaddr);1709 send_decline(/*xid,*/ server_addr, packet.yiaddr); 1426 1710 1427 1711 if (state != REQUESTING) … … 1429 1713 change_listen_mode(LISTEN_RAW); 1430 1714 state = INIT_SELECTING; 1715 client_config.first_secs = 0; /* make secs field count from 0 */ 1431 1716 requested_ip = 0; 1432 1717 timeout = tryagain_timeout; … … 1439 1724 /* enter bound state */ 1440 1725 timeout = lease_seconds / 2; 1441 { 1442 struct in_addr temp_addr; 1443 temp_addr.s_addr = packet.yiaddr; 1444 bb_info_msg("Lease of %s obtained, lease time %u", 1445 inet_ntoa(temp_addr), (unsigned)lease_seconds); 1446 } 1726 temp_addr.s_addr = packet.yiaddr; 1727 bb_info_msg("Lease of %s obtained, lease time %u", 1728 inet_ntoa(temp_addr), (unsigned)lease_seconds); 1447 1729 requested_ip = packet.yiaddr; 1448 1730 udhcp_run_script(&packet, state == REQUESTING ? "bound" : "renew"); … … 1451 1733 change_listen_mode(LISTEN_NONE); 1452 1734 if (opt & OPT_q) { /* quit after lease */ 1453 if (opt & OPT_R) /* release on quit */1454 perform_release(requested_ip, server_addr);1455 1735 goto ret0; 1456 1736 } … … 1464 1744 } 1465 1745 #endif 1746 /* make future renew packets use different xid */ 1747 /* xid = random_xid(); ...but why bother? */ 1466 1748 already_waited_sec = 0; 1467 1749 continue; /* back to main loop */ … … 1476 1758 sleep(3); /* avoid excessive network traffic */ 1477 1759 state = INIT_SELECTING; 1760 client_config.first_secs = 0; /* make secs field count from 0 */ 1478 1761 requested_ip = 0; 1479 1762 timeout = 0; … … 1489 1772 1490 1773 ret0: 1774 if (opt & OPT_R) /* release on quit */ 1775 perform_release(server_addr, requested_ip); 1491 1776 retval = 0; 1492 1777 ret: -
branches/3.2/mindi-busybox/networking/udhcp/dhcpc.h
r2725 r3232 10 10 struct client_config_t { 11 11 uint8_t client_mac[6]; /* Our mac address */ 12 char no_default_options; /* Do not include default options in request */13 12 IF_FEATURE_UDHCP_PORT(uint16_t port;) 14 13 int ifindex; /* Index number of the interface to use */ … … 22 21 uint8_t *hostname; /* Optional hostname to use */ 23 22 uint8_t *fqdn; /* Optional fully qualified domain name to use */ 23 24 uint16_t first_secs; 25 uint16_t last_secs; 24 26 } FIX_ALIASING; 25 27 -
branches/3.2/mindi-busybox/networking/udhcp/dhcpd.c
r2725 r3232 21 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 22 */ 23 24 //usage:#define udhcpd_trivial_usage 25 //usage: "[-fS]" IF_FEATURE_UDHCP_PORT(" [-P N]") " [CONFFILE]" 26 //usage:#define udhcpd_full_usage "\n\n" 27 //usage: "DHCP server\n" 28 //usage: "\n -f Run in foreground" 29 //usage: "\n -S Log to syslog too" 30 //usage: IF_FEATURE_UDHCP_PORT( 31 //usage: "\n -P N Use port N (default 67)" 32 //usage: ) 33 23 34 #include <syslog.h> 24 35 #include "common.h" … … 134 145 /* We got a DHCP DISCOVER. Send an OFFER. */ 135 146 /* NOINLINE: limit stack usage in caller */ 136 static NOINLINE void send_offer(struct dhcp_packet *oldpacket, uint32_t static_lease_nip, struct dyn_lease *lease) 147 static NOINLINE void send_offer(struct dhcp_packet *oldpacket, 148 uint32_t static_lease_nip, 149 struct dyn_lease *lease, 150 uint8_t *requested_ip_opt) 137 151 { 138 152 struct dhcp_packet packet; … … 148 162 /* We have no static lease for client's chaddr */ 149 163 uint32_t req_nip; 150 uint8_t *req_ip_opt;151 164 const char *p_host_name; 152 165 … … 159 172 } 160 173 /* Or: if client has requested an IP */ 161 else if ( (req_ip_opt = udhcp_get_option(oldpacket, DHCP_REQUESTED_IP))!= NULL174 else if (requested_ip_opt != NULL 162 175 /* (read IP) */ 163 && (move_from_unaligned32(req_nip, req _ip_opt), 1)176 && (move_from_unaligned32(req_nip, requested_ip_opt), 1) 164 177 /* and the IP is in the lease range */ 165 178 && ntohl(req_nip) >= server_config.start_ip … … 284 297 int udhcpd_main(int argc UNUSED_PARAM, char **argv) 285 298 { 286 fd_set rfds;287 299 int server_socket = -1, retval, max_sock; 288 struct dhcp_packet packet;289 300 uint8_t *state; 290 uint32_t static_lease_nip;291 301 unsigned timeout_end; 292 302 unsigned num_ips; 293 303 unsigned opt; 294 304 struct option_set *option; 295 struct dyn_lease *lease, fake_lease;296 305 IF_FEATURE_UDHCP_PORT(char *str_P;) 297 306 … … 306 315 opt = getopt32(argv, "fSv" 307 316 IF_FEATURE_UDHCP_PORT("P:", &str_P) 308 #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 309 , &dhcp_verbose 310 #endif 317 IF_UDHCP_VERBOSE(, &dhcp_verbose) 311 318 ); 312 319 if (!(opt & 1)) { /* no -f */ … … 371 378 udhcp_sp_setup(); 372 379 380 continue_with_autotime: 373 381 timeout_end = monotonic_sec() + server_config.auto_time; 374 382 while (1) { /* loop until universe collapses */ 383 fd_set rfds; 384 struct dhcp_packet packet; 375 385 int bytes; 376 386 struct timeval tv; 377 387 uint8_t *server_id_opt; 378 uint8_t *requested_ opt;388 uint8_t *requested_ip_opt; 379 389 uint32_t requested_nip = requested_nip; /* for compiler */ 390 uint32_t static_lease_nip; 391 struct dyn_lease *lease, fake_lease; 380 392 381 393 if (server_socket < 0) { … … 396 408 if (retval == 0) { 397 409 write_leases(); 398 timeout_end = monotonic_sec() + server_config.auto_time; 399 continue; 410 goto continue_with_autotime; 400 411 } 401 412 if (retval < 0 && errno != EINTR) { … … 409 420 write_leases(); 410 421 /* why not just reset the timeout, eh */ 411 timeout_end = monotonic_sec() + server_config.auto_time; 412 continue; 422 goto continue_with_autotime; 413 423 case SIGTERM: 414 424 bb_info_msg("Received SIGTERM"); 425 write_leases(); 415 426 goto ret0; 416 427 case 0: /* no signal: read a packet */ … … 442 453 bb_error_msg("no or bad message type option, ignoring packet"); 443 454 continue; 455 } 456 457 /* Get SERVER_ID if present */ 458 server_id_opt = udhcp_get_option(&packet, DHCP_SERVER_ID); 459 if (server_id_opt) { 460 uint32_t server_id_network_order; 461 move_from_unaligned32(server_id_network_order, server_id_opt); 462 if (server_id_network_order != server_config.server_nip) { 463 /* client talks to somebody else */ 464 log1("server ID doesn't match, ignoring"); 465 continue; 466 } 444 467 } 445 468 … … 456 479 } 457 480 458 /* Get REQUESTED_IP and SERVER_ID if present */ 459 server_id_opt = udhcp_get_option(&packet, DHCP_SERVER_ID); 460 if (server_id_opt) { 461 uint32_t server_id_net; 462 move_from_unaligned32(server_id_net, server_id_opt); 463 if (server_id_net != server_config.server_nip) { 464 /* client talks to somebody else */ 465 log1("server ID doesn't match, ignoring"); 466 continue; 467 } 468 } 469 requested_opt = udhcp_get_option(&packet, DHCP_REQUESTED_IP); 470 if (requested_opt) { 471 move_from_unaligned32(requested_nip, requested_opt); 481 /* Get REQUESTED_IP if present */ 482 requested_ip_opt = udhcp_get_option(&packet, DHCP_REQUESTED_IP); 483 if (requested_ip_opt) { 484 move_from_unaligned32(requested_nip, requested_ip_opt); 472 485 } 473 486 … … 477 490 log1("Received DISCOVER"); 478 491 479 send_offer(&packet, static_lease_nip, lease );492 send_offer(&packet, static_lease_nip, lease, requested_ip_opt); 480 493 break; 481 494 … … 568 581 administrative authority to do so. 569 582 */ 570 if (!requested_ opt) {583 if (!requested_ip_opt) { 571 584 requested_nip = packet.ciaddr; 572 585 if (requested_nip == 0) { … … 581 594 break; 582 595 } 583 if (server_id_opt) { 584 /* client was talking specifically to us. 585 * "No, we don't have this IP for you". */ 596 /* No lease for this MAC, or lease IP != requested IP */ 597 598 if (server_id_opt /* client is in SELECTING state */ 599 || requested_ip_opt /* client is in INIT-REBOOT state */ 600 ) { 601 /* "No, we don't have this IP for you" */ 586 602 send_NAK(&packet); 587 } 603 } /* else: client is in RENEWING or REBINDING, do not answer */ 604 588 605 break; 589 606 … … 604 621 log1("Received DECLINE"); 605 622 if (server_id_opt 606 && requested_ opt623 && requested_ip_opt 607 624 && lease /* chaddr matches this lease */ 608 625 && requested_nip == lease->lease_nip -
branches/3.2/mindi-busybox/networking/udhcp/dhcprelay.c
r2725 r3232 10 10 * Upstream has GPL v2 or later 11 11 */ 12 13 //usage:#define dhcprelay_trivial_usage 14 //usage: "CLIENT_IFACE[,CLIENT_IFACE2]... SERVER_IFACE [SERVER_IP]" 15 //usage:#define dhcprelay_full_usage "\n\n" 16 //usage: "Relay DHCP requests between clients and server" 17 12 18 #include "common.h" 13 19 … … 26 32 struct sockaddr_in ip; 27 33 struct xid_item *next; 28 } ;34 } FIX_ALIASING; 29 35 30 36 #define dhcprelay_xid_list (*(struct xid_item*)&bb_common_bufsiz1) -
branches/3.2/mindi-busybox/networking/udhcp/dumpleases.c
r2725 r3232 3 3 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 4 4 */ 5 6 //usage:#define dumpleases_trivial_usage 7 //usage: "[-r|-a] [-f LEASEFILE]" 8 //usage:#define dumpleases_full_usage "\n\n" 9 //usage: "Display DHCP leases granted by udhcpd\n" 10 //usage: IF_LONG_OPTS( 11 //usage: "\n -f,--file=FILE Lease file" 12 //usage: "\n -r,--remaining Show remaining time" 13 //usage: "\n -a,--absolute Show expiration time" 14 //usage: ) 15 //usage: IF_NOT_LONG_OPTS( 16 //usage: "\n -f FILE Lease file" 17 //usage: "\n -r Show remaining time" 18 //usage: "\n -a Show expiration time" 19 //usage: ) 20 5 21 #include "common.h" 6 22 #include "dhcpd.h" … … 58 74 #if ENABLE_UNICODE_SUPPORT 59 75 { 60 char *uni_name = unicode_conv_to_printable_fixedwidth( NULL,lease.hostname, 19);76 char *uni_name = unicode_conv_to_printable_fixedwidth(/*NULL,*/ lease.hostname, 19); 61 77 printf(" %-16s%s ", inet_ntoa(addr), uni_name); 62 78 free(uni_name); -
branches/3.2/mindi-busybox/networking/udhcp/files.c
r2725 r3232 81 81 {"option" , udhcp_str2optset, &server_config.options , ""}, 82 82 {"opt" , udhcp_str2optset, &server_config.options , ""}, 83 {"notify_file" , read_str , &server_config.notify_file , ""},84 {"sname" , read_str , &server_config.sname , ""},85 {"boot_file" , read_str , &server_config.boot_file , ""},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 86 {"static_lease" , read_staticlease, &server_config.static_leases, ""}, 87 87 }; -
branches/3.2/mindi-busybox/networking/udhcp/leases.c
r2725 r3232 138 138 struct dyn_lease *oldest_lease = NULL; 139 139 140 addr = server_config.start_ip; /* addr is in host order here */ 141 for (; addr <= server_config.end_ip; addr++) { 140 #if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC 141 uint32_t stop; 142 unsigned i, hash; 143 144 /* hash hwaddr: use the SDBM hashing algorithm. Seems to give good 145 * dispersal even with similarly-valued "strings". 146 */ 147 hash = 0; 148 for (i = 0; i < 6; i++) 149 hash += safe_mac[i] + (hash << 6) + (hash << 16) - hash; 150 151 /* pick a seed based on hwaddr then iterate until we find a free address. */ 152 addr = server_config.start_ip 153 + (hash % (1 + server_config.end_ip - server_config.start_ip)); 154 stop = addr; 155 #else 156 addr = server_config.start_ip; 157 #define stop (server_config.end_ip + 1) 158 #endif 159 do { 142 160 uint32_t nip; 143 161 struct dyn_lease *lease; … … 145 163 /* ie, 192.168.55.0 */ 146 164 if ((addr & 0xff) == 0) 147 continue;165 goto next_addr; 148 166 /* ie, 192.168.55.255 */ 149 167 if ((addr & 0xff) == 0xff) 150 continue;168 goto next_addr; 151 169 nip = htonl(addr); 170 /* skip our own address */ 171 if (nip == server_config.server_nip) 172 goto next_addr; 152 173 /* is this a static lease addr? */ 153 174 if (is_nip_reserved(server_config.static_leases, nip)) 154 continue;175 goto next_addr; 155 176 156 177 lease = find_lease_by_nip(nip); … … 163 184 oldest_lease = lease; 164 185 } 165 } 186 187 next_addr: 188 addr++; 189 #if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC 190 if (addr > server_config.end_ip) 191 addr = server_config.start_ip; 192 #endif 193 } while (addr != stop); 166 194 167 195 if (oldest_lease -
branches/3.2/mindi-busybox/networking/udhcp/packet.c
r2725 r3232 7 7 * Licensed under GPLv2, see file LICENSE in this source tree. 8 8 */ 9 #include <netinet/in.h>10 #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined _NEWLIB_VERSION11 # include <netpacket/packet.h>12 # include <net/ethernet.h>13 #else14 # include <asm/types.h>15 # include <linux/if_packet.h>16 # include <linux/if_ether.h>17 #endif18 19 9 #include "common.h" 20 10 #include "dhcpd.h" 11 #include <netinet/in.h> 12 #include <netinet/if_ether.h> 13 #include <netpacket/packet.h> 21 14 22 15 void FAST_FUNC udhcp_init_header(struct dhcp_packet *packet, char type) … … 89 82 { 90 83 int bytes; 91 unsigned char *vendor;92 84 93 85 memset(packet, 0, sizeof(*packet)); … … 98 90 } 99 91 100 if (packet->cookie != htonl(DHCP_MAGIC)) { 92 if (bytes < offsetof(struct dhcp_packet, options) 93 || packet->cookie != htonl(DHCP_MAGIC) 94 ) { 101 95 bb_info_msg("Packet with bad magic, ignoring"); 102 96 return -2; … … 105 99 udhcp_dump_packet(packet); 106 100 107 if (packet->op == BOOTREQUEST) {108 vendor = udhcp_get_option(packet, DHCP_VENDOR);109 if (vendor) {110 #if 0111 static const char broken_vendors[][8] = {112 "MSFT 98",113 ""114 };115 int i;116 for (i = 0; broken_vendors[i][0]; i++) {117 if (vendor[OPT_LEN - OPT_DATA] == (uint8_t)strlen(broken_vendors[i])118 && strncmp((char*)vendor, broken_vendors[i], vendor[OPT_LEN - OPT_DATA]) == 0119 ) {120 log1("Broken client (%s), forcing broadcast replies",121 broken_vendors[i]);122 packet->flags |= htons(BROADCAST_FLAG);123 }124 }125 #else126 if (vendor[OPT_LEN - OPT_DATA] == (uint8_t)(sizeof("MSFT 98")-1)127 && memcmp(vendor, "MSFT 98", sizeof("MSFT 98")-1) == 0128 ) {129 log1("Broken client (%s), forcing broadcast replies", "MSFT 98");130 packet->flags |= htons(BROADCAST_FLAG);131 }132 #endif133 }134 }135 136 101 return bytes; 137 }138 139 uint16_t FAST_FUNC udhcp_checksum(void *addr, int count)140 {141 /* Compute Internet Checksum for "count" bytes142 * beginning at location "addr".143 */144 int32_t sum = 0;145 uint16_t *source = (uint16_t *) addr;146 147 while (count > 1) {148 /* This is the inner loop */149 sum += *source++;150 count -= 2;151 }152 153 /* Add left-over byte, if any */154 if (count > 0) {155 /* Make sure that the left-over byte is added correctly both156 * with little and big endian hosts */157 uint16_t tmp = 0;158 *(uint8_t*)&tmp = *(uint8_t*)source;159 sum += tmp;160 }161 /* Fold 32-bit sum to 16 bits */162 while (sum >> 16)163 sum = (sum & 0xffff) + (sum >> 16);164 165 return ~sum;166 102 } 167 103 … … 220 156 /* for UDP checksumming, ip.len is set to UDP packet len */ 221 157 packet.ip.tot_len = packet.udp.len; 222 packet.udp.check = udhcp_checksum(&packet, IP_UDP_DHCP_SIZE - padding); 158 packet.udp.check = inet_cksum((uint16_t *)&packet, 159 IP_UDP_DHCP_SIZE - padding); 223 160 /* but for sending, it is set to IP packet len */ 224 161 packet.ip.tot_len = htons(IP_UDP_DHCP_SIZE - padding); … … 226 163 packet.ip.version = IPVERSION; 227 164 packet.ip.ttl = IPDEFTTL; 228 packet.ip.check = udhcp_checksum(&packet.ip, sizeof(packet.ip));165 packet.ip.check = inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip)); 229 166 230 167 udhcp_dump_packet(dhcp_pkt); … … 246 183 uint32_t dest_nip, int dest_port) 247 184 { 248 struct sockaddr_in client;185 struct sockaddr_in sa; 249 186 unsigned padding; 250 187 int fd; … … 259 196 setsockopt_reuseaddr(fd); 260 197 261 memset(& client, 0, sizeof(client));262 client.sin_family = AF_INET;263 client.sin_port = htons(source_port);264 client.sin_addr.s_addr = source_nip;265 if (bind(fd, (struct sockaddr *)& client, sizeof(client)) == -1) {198 memset(&sa, 0, sizeof(sa)); 199 sa.sin_family = AF_INET; 200 sa.sin_port = htons(source_port); 201 sa.sin_addr.s_addr = source_nip; 202 if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { 266 203 msg = "bind(%s)"; 267 204 goto ret_close; 268 205 } 269 206 270 memset(& client, 0, sizeof(client));271 client.sin_family = AF_INET;272 client.sin_port = htons(dest_port);273 client.sin_addr.s_addr = dest_nip;274 if (connect(fd, (struct sockaddr *)& client, sizeof(client)) == -1) {207 memset(&sa, 0, sizeof(sa)); 208 sa.sin_family = AF_INET; 209 sa.sin_port = htons(dest_port); 210 sa.sin_addr.s_addr = dest_nip; 211 if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { 275 212 msg = "connect"; 276 213 goto ret_close; … … 278 215 279 216 udhcp_dump_packet(dhcp_pkt); 280 281 217 padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(dhcp_pkt->options); 282 218 result = safe_write(fd, dhcp_pkt, DHCP_SIZE - padding); -
branches/3.2/mindi-busybox/networking/udhcp/socket.c
r2725 r3232 23 23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 24 */ 25 #include "common.h" 25 26 #include <net/if.h> 26 #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined _NEWLIB_VERSION27 # include <netpacket/packet.h>28 # include <net/ethernet.h>29 #else30 # include <asm/types.h>31 # include <linux/if_packet.h>32 # include <linux/if_ether.h>33 #endif34 35 #include "common.h"36 27 37 28 int FAST_FUNC udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac) 38 29 { 30 /* char buffer instead of bona-fide struct avoids aliasing warning */ 31 char ifr_buf[sizeof(struct ifreq)]; 32 struct ifreq *const ifr = (void *)ifr_buf; 33 39 34 int fd; 40 struct ifreq ifr;41 35 struct sockaddr_in *our_ip; 42 36 43 memset( &ifr, 0, sizeof(ifr));37 memset(ifr, 0, sizeof(*ifr)); 44 38 fd = xsocket(AF_INET, SOCK_RAW, IPPROTO_RAW); 45 39 46 ifr .ifr_addr.sa_family = AF_INET;47 strncpy_IFNAMSIZ(ifr .ifr_name, interface);40 ifr->ifr_addr.sa_family = AF_INET; 41 strncpy_IFNAMSIZ(ifr->ifr_name, interface); 48 42 if (nip) { 49 if (ioctl_or_perror(fd, SIOCGIFADDR, &ifr,43 if (ioctl_or_perror(fd, SIOCGIFADDR, ifr, 50 44 "is interface %s up and configured?", interface) 51 45 ) { … … 53 47 return -1; 54 48 } 55 our_ip = (struct sockaddr_in *) &ifr .ifr_addr;49 our_ip = (struct sockaddr_in *) &ifr->ifr_addr; 56 50 *nip = our_ip->sin_addr.s_addr; 57 51 log1("IP %s", inet_ntoa(our_ip->sin_addr)); … … 59 53 60 54 if (ifindex) { 61 if (ioctl_or_warn(fd, SIOCGIFINDEX, &ifr) != 0) {55 if (ioctl_or_warn(fd, SIOCGIFINDEX, ifr) != 0) { 62 56 close(fd); 63 57 return -1; 64 58 } 65 log1("Adapter index %d", ifr .ifr_ifindex);66 *ifindex = ifr .ifr_ifindex;59 log1("Adapter index %d", ifr->ifr_ifindex); 60 *ifindex = ifr->ifr_ifindex; 67 61 } 68 62 69 63 if (mac) { 70 if (ioctl_or_warn(fd, SIOCGIFHWADDR, &ifr) != 0) {64 if (ioctl_or_warn(fd, SIOCGIFHWADDR, ifr) != 0) { 71 65 close(fd); 72 66 return -1; 73 67 } 74 memcpy(mac, ifr .ifr_hwaddr.sa_data, 6);68 memcpy(mac, ifr->ifr_hwaddr.sa_data, 6); 75 69 log1("MAC %02x:%02x:%02x:%02x:%02x:%02x", 76 70 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); … … 87 81 int fd; 88 82 struct sockaddr_in addr; 83 char *colon; 89 84 90 85 log1("Opening listen socket on *:%d %s", port, inf); … … 95 90 bb_perror_msg_and_die("SO_BROADCAST"); 96 91 97 /* NB: bug 1032 says this doesn't work on ethernet aliases (ethN:M) */ 92 /* SO_BINDTODEVICE doesn't work on ethernet aliases (ethN:M) */ 93 colon = strrchr(inf, ':'); 94 if (colon) 95 *colon = '\0'; 96 98 97 if (setsockopt_bindtodevice(fd, inf)) 99 98 xfunc_die(); /* warning is already printed */ 99 100 if (colon) 101 *colon = ':'; 100 102 101 103 memset(&addr, 0, sizeof(addr)); -
branches/3.2/mindi-busybox/networking/vconfig.c
r2725 r3232 9 9 10 10 /* BB_AUDIT SUSv3 N/A */ 11 12 //usage:#define vconfig_trivial_usage 13 //usage: "COMMAND [OPTIONS]" 14 //usage:#define vconfig_full_usage "\n\n" 15 //usage: "Create and remove virtual ethernet devices\n" 16 //usage: "\n add IFACE VLAN_ID" 17 //usage: "\n rem VLAN_NAME" 18 //usage: "\n set_flag IFACE 0|1 VLAN_QOS" 19 //usage: "\n set_egress_map VLAN_NAME SKB_PRIO VLAN_QOS" 20 //usage: "\n set_ingress_map VLAN_NAME SKB_PRIO VLAN_QOS" 21 //usage: "\n set_name_type NAME_TYPE" 11 22 12 23 #include "libbb.h" … … 56 67 static const char *xfind_str(const char *table, const char *str) 57 68 { 58 while (strcasecmp(str, table+1) != 0) { 69 while (strcasecmp(str, table + 1) != 0) { 70 if (!table[0]) 71 bb_show_usage(); 59 72 table += table[0]; 60 if (!*table) {61 bb_show_usage();62 }63 73 } 64 74 return table - 1; … … 67 77 static const char cmds[] ALIGN1 = { 68 78 4, ADD_VLAN_CMD, 7, 69 'a', 'd', 'd',0,79 'a','d','d',0, 70 80 3, DEL_VLAN_CMD, 7, 71 'r', 'e', 'm',0,81 'r','e','m',0, 72 82 3, SET_VLAN_NAME_TYPE_CMD, 17, 73 's', 'e', 't', '_', 74 'n', 'a', 'm', 'e', '_', 75 't', 'y', 'p', 'e', 0, 83 's','e','t','_','n','a','m','e','_','t','y','p','e',0, 76 84 5, SET_VLAN_FLAG_CMD, 12, 77 's', 'e', 't', '_', 78 'f', 'l', 'a', 'g', 0, 85 's','e','t','_','f','l','a','g',0, 79 86 5, SET_VLAN_EGRESS_PRIORITY_CMD, 18, 80 's', 'e', 't', '_', 81 'e', 'g', 'r', 'e', 's', 's', '_', 82 'm', 'a', 'p', 0, 83 5, SET_VLAN_INGRESS_PRIORITY_CMD, 16, 84 's', 'e', 't', '_', 85 'i', 'n', 'g', 'r', 'e', 's', 's', '_', 86 'm', 'a', 'p', 0, 87 's','e','t','_','e','g','r','e','s','s','_','m','a','p',0, 88 5, SET_VLAN_INGRESS_PRIORITY_CMD, 0, 89 's','e','t','_','i','n','g','r','e','s','s','_','m','a','p',0, 87 90 }; 88 91 89 92 static const char name_types[] ALIGN1 = { 90 93 VLAN_NAME_TYPE_PLUS_VID, 16, 91 'V', 'L', 'A', 'N', 92 '_', 'P', 'L', 'U', 'S', '_', 'V', 'I', 'D', 93 0, 94 'V','L','A','N','_','P','L','U','S','_','V','I','D',0, 94 95 VLAN_NAME_TYPE_PLUS_VID_NO_PAD, 22, 95 'V', 'L', 'A', 'N', 96 '_', 'P', 'L', 'U', 'S', '_', 'V', 'I', 'D', 97 '_', 'N', 'O', '_', 'P', 'A', 'D', 0, 96 'V','L','A','N','_','P','L','U','S','_','V','I','D','_','N','O','_','P','A','D',0, 98 97 VLAN_NAME_TYPE_RAW_PLUS_VID, 15, 99 'D', 'E', 'V', 100 '_', 'P', 'L', 'U', 'S', '_', 'V', 'I', 'D', 101 0, 102 VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD, 20, 103 'D', 'E', 'V', 104 '_', 'P', 'L', 'U', 'S', '_', 'V', 'I', 'D', 105 '_', 'N', 'O', '_', 'P', 'A', 'D', 0, 98 'D','E','V','_','P','L','U','S','_','V','I','D',0, 99 VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD, 0, 100 'D','E','V','_','P','L','U','S','_','V','I','D','_','N','O','_','P','A','D',0, 106 101 }; 107 108 static const char conf_file_name[] ALIGN1 = "/proc/net/vlan/config";109 102 110 103 int vconfig_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; … … 115 108 int fd; 116 109 117 if (argc < 3) {118 bb_show_usage();119 }120 121 /* Don't bother closing the filedes. It will be closed on cleanup. */122 /* Will die if 802.1q is not present */123 xopen(conf_file_name, O_RDONLY);124 125 110 memset(&ifr, 0, sizeof(ifr)); 126 111 127 112 ++argv; 128 p = xfind_str(cmds+2, *argv); 113 if (!argv[0]) 114 bb_show_usage(); 115 p = xfind_str(cmds + 2, argv[0]); 129 116 ifr.cmd = *p; 130 if (argc != p[-1]) {117 if (argc != p[-1]) 131 118 bb_show_usage(); 132 }133 119 134 if (ifr.cmd == SET_VLAN_NAME_TYPE_CMD) { /* set_name_type */ 135 ifr.u.name_type = *xfind_str(name_types+1, argv[1]); 120 if (ifr.cmd == SET_VLAN_NAME_TYPE_CMD) { 121 /* set_name_type */ 122 ifr.u.name_type = *xfind_str(name_types + 1, argv[1]); 136 123 } else { 137 124 strncpy_IFNAMSIZ(ifr.device1, argv[1]); … … 142 129 * (unsigned) int members of a unions. But because of the range checking, 143 130 * doing so wouldn't save that much space and would also make maintainence 144 * more of a pain. */ 145 if (ifr.cmd == SET_VLAN_FLAG_CMD) { /* set_flag */ 146 ifr.u.flag = xatoul_range(p, 0, 1); 131 * more of a pain. 132 */ 133 if (ifr.cmd == SET_VLAN_FLAG_CMD) { 134 /* set_flag */ 135 ifr.u.flag = xatou_range(p, 0, 1); 147 136 /* DM: in order to set reorder header, qos must be set */ 148 ifr.vlan_qos = xatoul_range(argv[3], 0, 7); 149 } else if (ifr.cmd == ADD_VLAN_CMD) { /* add */ 150 ifr.u.VID = xatoul_range(p, 0, VLAN_GROUP_ARRAY_LEN-1); 151 } else if (ifr.cmd != DEL_VLAN_CMD) { /* set_{egress|ingress}_map */ 137 ifr.vlan_qos = xatou_range(argv[3], 0, 7); 138 } else if (ifr.cmd == ADD_VLAN_CMD) { 139 /* add */ 140 ifr.u.VID = xatou_range(p, 0, VLAN_GROUP_ARRAY_LEN - 1); 141 } else if (ifr.cmd != DEL_VLAN_CMD) { 142 /* set_{egress|ingress}_map */ 152 143 ifr.u.skb_priority = xatou(p); 153 ifr.vlan_qos = xatou l_range(argv[3], 0, 7);144 ifr.vlan_qos = xatou_range(argv[3], 0, 7); 154 145 } 155 146 } … … 157 148 fd = xsocket(AF_INET, SOCK_STREAM, 0); 158 149 ioctl_or_perror_and_die(fd, SIOCSIFVLAN, &ifr, 159 "ioctl error for %s", *argv);150 "ioctl error for %s", argv[0]); 160 151 161 152 return 0; -
branches/3.2/mindi-busybox/networking/wget.c
r2859 r3232 9 9 * Kuhn's copyrights are licensed GPLv2-or-later. File as a whole remains GPLv2. 10 10 */ 11 12 //usage:#define wget_trivial_usage 13 //usage: IF_FEATURE_WGET_LONG_OPTIONS( 14 //usage: "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" 15 //usage: " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" 16 /* Since we ignore these opts, we don't show them in --help */ 17 /* //usage: " [--no-check-certificate] [--no-cache]" */ 18 //usage: " [-U|--user-agent AGENT]" IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." 19 //usage: ) 20 //usage: IF_NOT_FEATURE_WGET_LONG_OPTIONS( 21 //usage: "[-csq] [-O FILE] [-Y on/off] [-P DIR] [-U AGENT]" 22 //usage: IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." 23 //usage: ) 24 //usage:#define wget_full_usage "\n\n" 25 //usage: "Retrieve files via HTTP or FTP\n" 26 //usage: "\n -s Spider mode - only check file existence" 27 //usage: "\n -c Continue retrieval of aborted transfer" 28 //usage: "\n -q Quiet" 29 //usage: "\n -P DIR Save to DIR (default .)" 30 //usage: IF_FEATURE_WGET_TIMEOUT( 31 //usage: "\n -T SEC Network read timeout is SEC seconds" 32 //usage: ) 33 //usage: "\n -O FILE Save to FILE ('-' for stdout)" 34 //usage: "\n -U STR Use STR for User-Agent header" 35 //usage: "\n -Y Use proxy ('on' or 'off')" 36 11 37 #include "libbb.h" 12 38 39 #if 0 40 # define log_io(...) bb_error_msg(__VA_ARGS__) 41 #else 42 # define log_io(...) ((void)0) 43 #endif 44 45 13 46 struct host_info { 14 // May be used if we ever will want to free() all xstrdup()s... 15 /* char *allocated; */ 47 char *allocated; 16 48 const char *path; 17 49 const char *user; … … 31 63 bb_progress_t pmt; 32 64 #endif 65 char *dir_prefix; 66 #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 */ 33 73 #if ENABLE_FEATURE_WGET_TIMEOUT 34 74 unsigned timeout_seconds; 35 75 #endif 76 int output_fd; 77 int o_flags; 36 78 smallint chunked; /* chunked transfer encoding */ 37 79 smallint got_clen; /* got content-length: from server */ 80 /* Local downloads do benefit from big buffer. 81 * With 512 byte buffer, it was measured to be 82 * an order of magnitude slower than with big one. 83 */ 84 uint64_t just_to_align_next_member; 85 char wget_buf[CONFIG_FEATURE_COPYBUF_KB*1024]; 38 86 } FIX_ALIASING; 39 #define G (*(struct globals*)&bb_common_bufsiz1) 40 struct BUG_G_too_big { 41 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; 42 }; 87 #define G (*ptr_to_globals) 43 88 #define INIT_G() do { \ 89 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 44 90 IF_FEATURE_WGET_TIMEOUT(G.timeout_seconds = 900;) \ 45 91 } while (0) … … 74 120 75 121 if (flag == PROGRESS_START) 76 bb_progress_init(&G.pmt); 77 78 bb_progress_update(&G.pmt, G.curfile, G.beg_range, G.transferred, 79 G.chunked ? 0 : G.beg_range + G.transferred + G.content_len); 122 bb_progress_init(&G.pmt, G.curfile); 123 124 bb_progress_update(&G.pmt, 125 G.beg_range, 126 G.transferred, 127 (G.chunked || !G.got_clen) ? 0 : G.beg_range + G.transferred + G.content_len 128 ); 80 129 81 130 if (flag == PROGRESS_END) { 131 bb_progress_free(&G.pmt); 82 132 bb_putchar_stderr('\n'); 83 133 G.transferred = 0; … … 125 175 } 126 176 127 /* Read NMEMB bytes into PTR from STREAM. Returns the number of bytes read,128 * and a short count if an eof or non-interrupt error is encountered. */129 static size_t safe_fread(void *ptr, size_t nmemb, FILE *stream)130 {131 size_t ret;132 char *p = (char*)ptr;133 134 do {135 clearerr(stream);136 errno = 0;137 ret = fread(p, 1, nmemb, stream);138 p += ret;139 nmemb -= ret;140 } while (nmemb && ferror(stream) && errno == EINTR);141 142 return p - (char*)ptr;143 }144 145 /* Read a line or SIZE-1 bytes into S, whichever is less, from STREAM.146 * Returns S, or NULL if an eof or non-interrupt error is encountered. */147 static char *safe_fgets(char *s, int size, FILE *stream)148 {149 char *ret;150 151 do {152 clearerr(stream);153 errno = 0;154 ret = fgets(s, size, stream);155 } while (ret == NULL && ferror(stream) && errno == EINTR);156 157 return ret;158 }159 160 177 #if ENABLE_FEATURE_WGET_AUTHENTICATION 161 /* Base64-encode character string. buf is assumed to be char buf[512].*/162 static char *base64enc _512(char buf[512],const char *str)178 /* Base64-encode character string. */ 179 static char *base64enc(const char *str) 163 180 { 164 181 unsigned len = strlen(str); 165 if (len > 512/4*3 - 10) /* paranoia */166 len = 512/4*3 - 10;167 bb_uuencode( buf, str, len, bb_uuenc_tbl_base64);168 return buf;182 if (len > sizeof(G.wget_buf)/4*3 - 10) /* paranoia */ 183 len = sizeof(G.wget_buf)/4*3 - 10; 184 bb_uuencode(G.wget_buf, str, len, bb_uuenc_tbl_base64); 185 return G.wget_buf; 169 186 } 170 187 #endif … … 187 204 fp = fdopen(xconnect_stream(lsa), "r+"); 188 205 if (fp == NULL) 189 bb_perror_msg_and_die( "fdopen");206 bb_perror_msg_and_die(bb_msg_memory_exhausted); 190 207 191 208 return fp; 192 209 } 193 210 194 static int ftpcmd(const char *s1, const char *s2, FILE *fp, char *buf) 211 /* Returns '\n' if it was seen, else '\0'. Trims at first '\r' or '\n' */ 212 static char fgets_and_trim(FILE *fp) 213 { 214 char c; 215 char *buf_ptr; 216 217 if (fgets(G.wget_buf, sizeof(G.wget_buf) - 1, fp) == NULL) 218 bb_perror_msg_and_die("error getting response"); 219 220 buf_ptr = strchrnul(G.wget_buf, '\n'); 221 c = *buf_ptr; 222 *buf_ptr = '\0'; 223 buf_ptr = strchrnul(G.wget_buf, '\r'); 224 *buf_ptr = '\0'; 225 226 log_io("< %s", G.wget_buf); 227 228 return c; 229 } 230 231 static int ftpcmd(const char *s1, const char *s2, FILE *fp) 195 232 { 196 233 int result; 197 234 if (s1) { 198 if (!s2) s2 = ""; 235 if (!s2) 236 s2 = ""; 199 237 fprintf(fp, "%s%s\r\n", s1, s2); 200 238 fflush(fp); 239 log_io("> %s%s", s1, s2); 201 240 } 202 241 203 242 do { 204 char *buf_ptr; 205 206 if (fgets(buf, 510, fp) == NULL) { 207 bb_perror_msg_and_die("error getting response"); 208 } 209 buf_ptr = strstr(buf, "\r\n"); 210 if (buf_ptr) { 211 *buf_ptr = '\0'; 212 } 213 } while (!isdigit(buf[0]) || buf[3] != ' '); 214 215 buf[3] = '\0'; 216 result = xatoi_positive(buf); 217 buf[3] = ' '; 243 fgets_and_trim(fp); 244 } while (!isdigit(G.wget_buf[0]) || G.wget_buf[3] != ' '); 245 246 G.wget_buf[3] = '\0'; 247 result = xatoi_positive(G.wget_buf); 248 G.wget_buf[3] = ' '; 218 249 return result; 219 250 } 220 251 221 static void parse_url(c har *src_url, struct host_info *h)252 static void parse_url(const char *src_url, struct host_info *h) 222 253 { 223 254 char *url, *p, *sp; 224 255 225 /* h->allocated = */ url = xstrdup(src_url); 256 free(h->allocated); 257 h->allocated = url = xstrdup(src_url); 226 258 227 259 if (strncmp(url, "http://", 7) == 0) { … … 271 303 sp = strrchr(h->host, '@'); 272 304 if (sp != NULL) { 273 h->user = h->host; 305 // URL-decode "user:password" string before base64-encoding: 306 // wget http://test:my%20pass@example.com should send 307 // Authorization: Basic dGVzdDpteSBwYXNz 308 // which decodes to "test:my pass". 309 // Standard wget and curl do this too. 274 310 *sp = '\0'; 311 h->user = percent_decode_in_place(h->host, /*strict:*/ 0); 275 312 h->host = sp + 1; 276 313 } … … 279 316 } 280 317 281 static char *gethdr( char *buf, size_t bufsiz, FILE *fp /*, int *istrunc*/)318 static char *gethdr(FILE *fp) 282 319 { 283 320 char *s, *hdrval; 284 321 int c; 285 322 286 /* *istrunc = 0; */287 288 323 /* retrieve header line */ 289 if (fgets(buf, bufsiz, fp) == NULL) 324 c = fgets_and_trim(fp); 325 326 /* end of the headers? */ 327 if (G.wget_buf[0] == '\0') 290 328 return NULL; 291 329 292 /* see if we are at the end of the headers */293 for (s = buf; *s == '\r'; ++s)294 continue;295 if (*s == '\n')296 return NULL;297 298 330 /* convert the header name to lower case */ 299 for (s = buf; isalnum(*s) || *s == '-' || *s == '.'; ++s) {331 for (s = G.wget_buf; isalnum(*s) || *s == '-' || *s == '.'; ++s) { 300 332 /* tolower for "A-Z", no-op for "0-9a-z-." */ 301 *s = (*s | 0x20);333 *s |= 0x20; 302 334 } 303 335 304 336 /* verify we are at the end of the header name */ 305 337 if (*s != ':') 306 bb_error_msg_and_die("bad header line: %s", sanitize_string( buf));338 bb_error_msg_and_die("bad header line: %s", sanitize_string(G.wget_buf)); 307 339 308 340 /* locate the start of the header value */ … … 310 342 hdrval = skip_whitespace(s); 311 343 312 /* locate the end of header */ 313 while (*s && *s != '\r' && *s != '\n') 314 ++s; 315 316 /* end of header found */ 317 if (*s) { 318 *s = '\0'; 319 return hdrval; 320 } 321 322 /* Rats! The buffer isn't big enough to hold the entire header value */ 323 while (c = getc(fp), c != EOF && c != '\n') 324 continue; 325 /* *istrunc = 1; */ 344 if (c != '\n') { 345 /* Rats! The buffer isn't big enough to hold the entire header value */ 346 while (c = getc(fp), c != EOF && c != '\n') 347 continue; 348 } 349 326 350 return hdrval; 327 351 } 328 352 329 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 330 static char *URL_escape(const char *str) 331 { 332 /* URL encode, see RFC 2396 */ 333 char *dst; 334 char *res = dst = xmalloc(strlen(str) * 3 + 1); 335 unsigned char c; 336 337 while (1) { 338 c = *str++; 339 if (c == '\0' 340 /* || strchr("!&'()*-.=_~", c) - more code */ 341 || c == '!' 342 || c == '&' 343 || c == '\'' 344 || c == '(' 345 || c == ')' 346 || c == '*' 347 || c == '-' 348 || c == '.' 349 || c == '=' 350 || c == '_' 351 || c == '~' 352 || (c >= '0' && c <= '9') 353 || ((c|0x20) >= 'a' && (c|0x20) <= 'z') 354 ) { 355 *dst++ = c; 356 if (c == '\0') 357 return res; 358 } else { 359 *dst++ = '%'; 360 *dst++ = bb_hexdigits_upcase[c >> 4]; 361 *dst++ = bb_hexdigits_upcase[c & 0xf]; 362 } 363 } 364 } 365 #endif 353 static void reset_beg_range_to_zero(void) 354 { 355 bb_error_msg("restart failed"); 356 G.beg_range = 0; 357 xlseek(G.output_fd, 0, SEEK_SET); 358 /* Done at the end instead: */ 359 /* ftruncate(G.output_fd, 0); */ 360 } 366 361 367 362 static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_sockaddr *lsa) 368 363 { 369 char buf[512];370 364 FILE *sfp; 371 365 char *str; … … 376 370 377 371 sfp = open_socket(lsa); 378 if (ftpcmd(NULL, NULL, sfp , buf) != 220)379 bb_error_msg_and_die("%s", sanitize_string( buf+4));372 if (ftpcmd(NULL, NULL, sfp) != 220) 373 bb_error_msg_and_die("%s", sanitize_string(G.wget_buf + 4)); 380 374 381 375 /* … … 386 380 if (str) 387 381 *str++ = '\0'; 388 switch (ftpcmd("USER ", target->user, sfp , buf)) {382 switch (ftpcmd("USER ", target->user, sfp)) { 389 383 case 230: 390 384 break; 391 385 case 331: 392 if (ftpcmd("PASS ", str, sfp , buf) == 230)386 if (ftpcmd("PASS ", str, sfp) == 230) 393 387 break; 394 388 /* fall through (failed login) */ 395 389 default: 396 bb_error_msg_and_die("ftp login: %s", sanitize_string( buf+4));397 } 398 399 ftpcmd("TYPE I", NULL, sfp , buf);390 bb_error_msg_and_die("ftp login: %s", sanitize_string(G.wget_buf + 4)); 391 } 392 393 ftpcmd("TYPE I", NULL, sfp); 400 394 401 395 /* 402 396 * Querying file size 403 397 */ 404 if (ftpcmd("SIZE ", target->path, sfp , buf) == 213) {405 G.content_len = BB_STRTOOFF( buf+4, NULL, 10);398 if (ftpcmd("SIZE ", target->path, sfp) == 213) { 399 G.content_len = BB_STRTOOFF(G.wget_buf + 4, NULL, 10); 406 400 if (G.content_len < 0 || errno) { 407 401 bb_error_msg_and_die("SIZE value is garbage"); … … 413 407 * Entering passive mode 414 408 */ 415 if (ftpcmd("PASV", NULL, sfp , buf) != 227) {409 if (ftpcmd("PASV", NULL, sfp) != 227) { 416 410 pasv_error: 417 bb_error_msg_and_die("bad response to %s: %s", "PASV", sanitize_string( buf));411 bb_error_msg_and_die("bad response to %s: %s", "PASV", sanitize_string(G.wget_buf)); 418 412 } 419 413 // Response is "227 garbageN1,N2,N3,N4,P1,P2[)garbage] 420 414 // Server's IP is N1.N2.N3.N4 (we ignore it) 421 415 // Server's port for data connection is P1*256+P2 422 str = strrchr( buf, ')');416 str = strrchr(G.wget_buf, ')'); 423 417 if (str) str[0] = '\0'; 424 str = strrchr( buf, ',');418 str = strrchr(G.wget_buf, ','); 425 419 if (!str) goto pasv_error; 426 420 port = xatou_range(str+1, 0, 255); 427 421 *str = '\0'; 428 str = strrchr( buf, ',');422 str = strrchr(G.wget_buf, ','); 429 423 if (!str) goto pasv_error; 430 424 port += xatou_range(str+1, 0, 255) * 256; 431 set_nport( lsa, htons(port));425 set_nport(&lsa->u.sa, htons(port)); 432 426 433 427 *dfpp = open_socket(lsa); 434 428 435 if (G.beg_range ) {436 sprintf( buf, "REST %"OFF_FMT"u", G.beg_range);437 if (ftpcmd( buf, NULL, sfp, buf) == 350)429 if (G.beg_range != 0) { 430 sprintf(G.wget_buf, "REST %"OFF_FMT"u", G.beg_range); 431 if (ftpcmd(G.wget_buf, NULL, sfp) == 350) 438 432 G.content_len -= G.beg_range; 439 } 440 441 if (ftpcmd("RETR ", target->path, sfp, buf) > 150) 442 bb_error_msg_and_die("bad response to %s: %s", "RETR", sanitize_string(buf)); 433 else 434 reset_beg_range_to_zero(); 435 } 436 437 if (ftpcmd("RETR ", target->path, sfp) > 150) 438 bb_error_msg_and_die("bad response to %s: %s", "RETR", sanitize_string(G.wget_buf)); 443 439 444 440 return sfp; 445 441 } 446 442 447 static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd) 448 { 449 char buf[4*1024]; /* made bigger to speed up local xfers */ 443 static void NOINLINE retrieve_file_data(FILE *dfp) 444 { 450 445 #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT 451 446 # if ENABLE_FEATURE_WGET_TIMEOUT 452 unsigned second_cnt ;447 unsigned second_cnt = G.timeout_seconds; 453 448 # endif 454 449 struct pollfd polldata; … … 466 461 467 462 #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT 463 /* Must use nonblocking I/O, otherwise fread will loop 464 * and *block* until it reads full buffer, 465 * which messes up progress bar and/or timeout logic. 466 * Because of nonblocking I/O, we need to dance 467 * very carefully around EAGAIN. See explanation at 468 * clearerr() calls. 469 */ 468 470 ndelay_on(polldata.fd); 469 471 #endif … … 472 474 unsigned rdsz; 473 475 474 rdsz = sizeof(buf);475 if (G.got_clen) {476 if (G.content_len < (off_t)sizeof(buf)) {477 if ((int)G.content_len <= 0)478 break;479 rdsz = (unsigned)G.content_len;480 }481 }482 476 #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT 483 # if ENABLE_FEATURE_WGET_TIMEOUT484 second_cnt = G.timeout_seconds;485 # endif486 while (1) {487 if (safe_poll(&polldata, 1, 1000) != 0)488 break; /* error, EOF, or data is available */489 # if ENABLE_FEATURE_WGET_TIMEOUT490 if (second_cnt != 0 && --second_cnt == 0) {491 progress_meter(PROGRESS_END);492 bb_perror_msg_and_die("download timed out");493 }494 # endif495 /* Needed for "stalled" indicator */496 progress_meter(PROGRESS_BUMP);497 }498 #endif499 477 /* fread internally uses read loop, which in our case 500 478 * is usually exited when we get EAGAIN. … … 506 484 */ 507 485 clearerr(dfp); 486 #endif 508 487 errno = 0; 509 n = safe_fread(buf, rdsz, dfp); 510 /* man fread: 488 rdsz = sizeof(G.wget_buf); 489 if (G.got_clen) { 490 if (G.content_len < (off_t)sizeof(G.wget_buf)) { 491 if ((int)G.content_len <= 0) 492 break; 493 rdsz = (unsigned)G.content_len; 494 } 495 } 496 n = fread(G.wget_buf, 1, rdsz, dfp); 497 498 if (n > 0) { 499 xwrite(G.output_fd, G.wget_buf, n); 500 #if ENABLE_FEATURE_WGET_STATUSBAR 501 G.transferred += n; 502 #endif 503 if (G.got_clen) { 504 G.content_len -= n; 505 if (G.content_len == 0) 506 break; 507 } 508 #if ENABLE_FEATURE_WGET_TIMEOUT 509 second_cnt = G.timeout_seconds; 510 #endif 511 continue; 512 } 513 514 /* n <= 0. 515 * man fread: 511 516 * If error occurs, or EOF is reached, the return value 512 517 * is a short item count (or zero). 513 518 * fread does not distinguish between EOF and error. 514 519 */ 515 if (n <= 0) { 516 #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT 517 if (errno == EAGAIN) /* poll lied, there is no data? */ 518 continue; /* yes */ 519 #endif 520 if (ferror(dfp)) 520 if (errno != EAGAIN) { 521 if (ferror(dfp)) { 522 progress_meter(PROGRESS_END); 521 523 bb_perror_msg_and_die(bb_msg_read_error); 524 } 522 525 break; /* EOF, not error */ 523 526 } 524 527 525 xwrite(output_fd, buf, n); 526 #if ENABLE_FEATURE_WGET_STATUSBAR 527 G.transferred += n; 528 #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT 529 /* It was EAGAIN. There is no data. Wait up to one second 530 * then abort if timed out, or update the bar and try reading again. 531 */ 532 if (safe_poll(&polldata, 1, 1000) == 0) { 533 # if ENABLE_FEATURE_WGET_TIMEOUT 534 if (second_cnt != 0 && --second_cnt == 0) { 535 progress_meter(PROGRESS_END); 536 bb_error_msg_and_die("download timed out"); 537 } 538 # endif 539 /* We used to loop back to poll here, 540 * but there is no great harm in letting fread 541 * to try reading anyway. 542 */ 543 } 544 /* Need to do it _every_ second for "stalled" indicator 545 * to be shown properly. 546 */ 528 547 progress_meter(PROGRESS_BUMP); 529 548 #endif 530 if (G.got_clen) { 531 G.content_len -= n; 532 if (G.content_len == 0) 533 break; 534 } 535 } 549 } /* while (reading data) */ 550 536 551 #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT 537 ndelay_off(polldata.fd);538 #endif 539 552 clearerr(dfp); 553 ndelay_off(polldata.fd); /* else fgets can get very unhappy */ 554 #endif 540 555 if (!G.chunked) 541 556 break; 542 557 543 safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */558 fgets_and_trim(dfp); /* Eat empty line */ 544 559 get_clen: 545 safe_fgets(buf, sizeof(buf),dfp);546 G.content_len = STRTOOFF( buf, NULL, 16);560 fgets_and_trim(dfp); 561 G.content_len = STRTOOFF(G.wget_buf, NULL, 16); 547 562 /* FIXME: error check? */ 548 563 if (G.content_len == 0) 549 564 break; /* all done! */ 550 565 G.got_clen = 1; 551 } 552 566 /* 567 * Note that fgets may result in some data being buffered in dfp. 568 * We loop back to fread, which will retrieve this data. 569 * Also note that code has to be arranged so that fread 570 * is done _before_ one-second poll wait - poll doesn't know 571 * about stdio buffering and can result in spurious one second waits! 572 */ 573 } 574 575 /* If -c failed, we restart from the beginning, 576 * but we do not truncate file then, we do it only now, at the end. 577 * This lets user to ^C if his 99% complete 10 GB file download 578 * failed to restart *without* losing the almost complete file. 579 */ 580 { 581 off_t pos = lseek(G.output_fd, 0, SEEK_CUR); 582 if (pos != (off_t)-1) 583 ftruncate(G.output_fd, pos); 584 } 585 586 /* Draw full bar and free its resources */ 587 G.chunked = 0; /* makes it show 100% even for chunked download */ 588 G.got_clen = 1; /* makes it show 100% even for download of (formerly) unknown size */ 553 589 progress_meter(PROGRESS_END); 554 590 } 555 591 556 int wget_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 557 int wget_main(int argc UNUSED_PARAM, char **argv) 558 { 559 char buf[512]; 560 struct host_info server, target; 592 static void download_one_url(const char *url) 593 { 594 bool use_proxy; /* Use proxies if env vars are set */ 595 int redir_limit; 561 596 len_and_sockaddr *lsa; 562 unsigned opt;563 int redir_limit;564 char *proxy = NULL;565 char *dir_prefix = NULL;566 #if ENABLE_FEATURE_WGET_LONG_OPTIONS567 char *post_data;568 char *extra_headers = NULL;569 llist_t *headers_llist = NULL;570 #endif571 597 FILE *sfp; /* socket to web/ftp server */ 572 598 FILE *dfp; /* socket to ftp server (data) */ 573 char *fname_out; /* where to direct output (-O) */ 574 int output_fd = -1; 575 bool use_proxy; /* Use proxies if env vars are set */ 576 const char *proxy_flag = "on"; /* Use proxies if env vars are set */ 577 const char *user_agent = "Wget";/* "User-Agent" header field */ 578 579 static const char keywords[] ALIGN1 = 580 "content-length\0""transfer-encoding\0""chunked\0""location\0"; 581 enum { 582 KEY_content_length = 1, KEY_transfer_encoding, KEY_chunked, KEY_location 583 }; 584 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 585 static const char wget_longopts[] ALIGN1 = 586 /* name, has_arg, val */ 587 "continue\0" No_argument "c" 588 "spider\0" No_argument "s" 589 "quiet\0" No_argument "q" 590 "output-document\0" Required_argument "O" 591 "directory-prefix\0" Required_argument "P" 592 "proxy\0" Required_argument "Y" 593 "user-agent\0" Required_argument "U" 594 #if ENABLE_FEATURE_WGET_TIMEOUT 595 "timeout\0" Required_argument "T" 596 #endif 597 /* Ignored: */ 598 // "tries\0" Required_argument "t" 599 /* Ignored (we always use PASV): */ 600 "passive-ftp\0" No_argument "\xff" 601 "header\0" Required_argument "\xfe" 602 "post-data\0" Required_argument "\xfd" 603 /* Ignored (we don't do ssl) */ 604 "no-check-certificate\0" No_argument "\xfc" 605 ; 606 #endif 607 608 INIT_G(); 609 610 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 611 applet_long_options = wget_longopts; 612 #endif 613 /* server.allocated = target.allocated = NULL; */ 614 opt_complementary = "-1" IF_FEATURE_WGET_TIMEOUT(":T+") IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); 615 opt = getopt32(argv, "csqO:P:Y:U:T:" /*ignored:*/ "t:", 616 &fname_out, &dir_prefix, 617 &proxy_flag, &user_agent, 618 IF_FEATURE_WGET_TIMEOUT(&G.timeout_seconds) IF_NOT_FEATURE_WGET_TIMEOUT(NULL), 619 NULL /* -t RETRIES */ 620 IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) 621 IF_FEATURE_WGET_LONG_OPTIONS(, &post_data) 622 ); 623 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 624 if (headers_llist) { 625 int size = 1; 626 char *cp; 627 llist_t *ll = headers_llist; 628 while (ll) { 629 size += strlen(ll->data) + 2; 630 ll = ll->link; 631 } 632 extra_headers = cp = xmalloc(size); 633 while (headers_llist) { 634 cp += sprintf(cp, "%s\r\n", (char*)llist_pop(&headers_llist)); 635 } 636 } 637 #endif 638 639 /* TODO: compat issue: should handle "wget URL1 URL2..." */ 640 599 char *proxy = NULL; 600 char *fname_out_alloc; 601 char *redirected_path = NULL; 602 struct host_info server; 603 struct host_info target; 604 605 server.allocated = NULL; 606 target.allocated = NULL; 607 server.user = NULL; 641 608 target.user = NULL; 642 parse_url(argv[optind], &target); 609 610 parse_url(url, &target); 643 611 644 612 /* Use the proxy if necessary */ 645 use_proxy = (strcmp( proxy_flag, "off") != 0);613 use_proxy = (strcmp(G.proxy_flag, "off") != 0); 646 614 if (use_proxy) { 647 615 proxy = getenv(target.is_ftp ? "ftp_proxy" : "http_proxy"); 648 if (proxy && proxy[0]) {649 server.user = NULL;616 use_proxy = (proxy && proxy[0]); 617 if (use_proxy) 650 618 parse_url(proxy, &server); 651 } else {652 use_proxy = 0;653 }654 619 } 655 620 if (!use_proxy) { 656 621 server.port = target.port; 657 622 if (ENABLE_FEATURE_IPV6) { 658 server.host = xstrdup(target.host); 623 //free(server.allocated); - can't be non-NULL 624 server.host = server.allocated = xstrdup(target.host); 659 625 } else { 660 626 server.host = target.host; … … 665 631 strip_ipv6_scope_id(target.host); 666 632 667 /* Guess an output filename, if there was no -O FILE */ 668 if (!(opt & WGET_OPT_OUTNAME)) { 669 fname_out = bb_get_last_path_component_nostrip(target.path); 633 /* If there was no -O FILE, guess output filename */ 634 fname_out_alloc = NULL; 635 if (!(option_mask32 & WGET_OPT_OUTNAME)) { 636 G.fname_out = bb_get_last_path_component_nostrip(target.path); 670 637 /* handle "wget http://kernel.org//" */ 671 if ( fname_out[0] == '/' || !fname_out[0])672 fname_out = (char*)"index.html";638 if (G.fname_out[0] == '/' || !G.fname_out[0]) 639 G.fname_out = (char*)"index.html"; 673 640 /* -P DIR is considered only if there was no -O FILE */ 674 if (dir_prefix) 675 fname_out = concat_path_file(dir_prefix, fname_out); 676 } else { 677 if (LONE_DASH(fname_out)) { 678 /* -O - */ 679 output_fd = 1; 680 opt &= ~WGET_OPT_CONTINUE; 641 if (G.dir_prefix) 642 G.fname_out = fname_out_alloc = concat_path_file(G.dir_prefix, G.fname_out); 643 else { 644 /* redirects may free target.path later, need to make a copy */ 645 G.fname_out = fname_out_alloc = xstrdup(G.fname_out); 681 646 } 682 647 } 683 648 #if ENABLE_FEATURE_WGET_STATUSBAR 684 G.curfile = bb_get_last_path_component_nostrip(fname_out); 685 #endif 686 687 /* Impossible? 688 if ((opt & WGET_OPT_CONTINUE) && !fname_out) 689 bb_error_msg_and_die("can't specify continue (-c) without a filename (-O)"); 690 */ 649 G.curfile = bb_get_last_path_component_nostrip(G.fname_out); 650 #endif 691 651 692 652 /* Determine where to start transfer */ 693 if (opt & WGET_OPT_CONTINUE) { 694 output_fd = open(fname_out, O_WRONLY); 695 if (output_fd >= 0) { 696 G.beg_range = xlseek(output_fd, 0, SEEK_END); 653 G.beg_range = 0; 654 if (option_mask32 & WGET_OPT_CONTINUE) { 655 G.output_fd = open(G.fname_out, O_WRONLY); 656 if (G.output_fd >= 0) { 657 G.beg_range = xlseek(G.output_fd, 0, SEEK_END); 697 658 } 698 659 /* File doesn't exist. We do not create file here yet. 699 * We are not sure it exists on remo ve side */660 * We are not sure it exists on remote side */ 700 661 } 701 662 … … 703 664 resolve_lsa: 704 665 lsa = xhost2sockaddr(server.host, server.port); 705 if (!(opt & WGET_OPT_QUIET)) {666 if (!(option_mask32 & WGET_OPT_QUIET)) { 706 667 char *s = xmalloc_sockaddr2dotted(&lsa->u.sa); 707 668 fprintf(stderr, "Connecting to %s (%s)\n", server.host, s); … … 709 670 } 710 671 establish_session: 672 /*G.content_len = 0; - redundant, got_clen = 0 is enough */ 673 G.got_clen = 0; 674 G.chunked = 0; 711 675 if (use_proxy || !target.is_ftp) { 712 676 /* … … 716 680 int status; 717 681 682 718 683 /* Open socket to http server */ 719 684 sfp = open_socket(lsa); … … 725 690 target.path); 726 691 } else { 727 if (opt & WGET_OPT_POST_DATA)692 if (option_mask32 & WGET_OPT_POST_DATA) 728 693 fprintf(sfp, "POST /%s HTTP/1.1\r\n", target.path); 729 694 else … … 732 697 733 698 fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n", 734 target.host, user_agent);699 target.host, G.user_agent); 735 700 736 701 /* Ask server to close the connection as soon as we are done … … 742 707 if (target.user) { 743 708 fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6, 744 base64enc _512(buf,target.user));709 base64enc(target.user)); 745 710 } 746 711 if (use_proxy && server.user) { 747 712 fprintf(sfp, "Proxy-Authorization: Basic %s\r\n", 748 base64enc _512(buf,server.user));749 } 750 #endif 751 752 if (G.beg_range )713 base64enc(server.user)); 714 } 715 #endif 716 717 if (G.beg_range != 0) 753 718 fprintf(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range); 754 719 755 720 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 756 if (extra_headers) 757 fputs(extra_headers, sfp); 758 759 if (opt & WGET_OPT_POST_DATA) { 760 char *estr = URL_escape(post_data); 721 if (G.extra_headers) 722 fputs(G.extra_headers, sfp); 723 724 if (option_mask32 & WGET_OPT_POST_DATA) { 761 725 fprintf(sfp, 762 726 "Content-Type: application/x-www-form-urlencoded\r\n" … … 764 728 "\r\n" 765 729 "%s", 766 (int) strlen( estr), estr730 (int) strlen(G.post_data), G.post_data 767 731 ); 768 free(estr);769 732 } else 770 733 #endif … … 779 742 */ 780 743 read_response: 781 if (fgets(buf, sizeof(buf), sfp) == NULL) 782 bb_error_msg_and_die("no response from server"); 783 784 str = buf; 744 fgets_and_trim(sfp); 745 746 str = G.wget_buf; 785 747 str = skip_non_whitespace(str); 786 748 str = skip_whitespace(str); … … 791 753 case 0: 792 754 case 100: 793 while (gethdr( buf, sizeof(buf), sfp /*, &n*/) != NULL)755 while (gethdr(sfp) != NULL) 794 756 /* eat all remaining headers */; 795 757 goto read_response; … … 820 782 */ 821 783 case 204: 784 if (G.beg_range != 0) { 785 /* "Range:..." was not honored by the server. 786 * Restart download from the beginning. 787 */ 788 reset_beg_range_to_zero(); 789 } 822 790 break; 823 791 case 300: /* redirection */ … … 826 794 case 303: 827 795 break; 828 case 206: 829 if (G.beg_range) 796 case 206: /* Partial Content */ 797 if (G.beg_range != 0) 798 /* "Range:..." worked. Good. */ 830 799 break; 800 /* Partial Content even though we did not ask for it??? */ 831 801 /* fall through */ 832 802 default: 833 bb_error_msg_and_die("server returned error: %s", sanitize_string( buf));803 bb_error_msg_and_die("server returned error: %s", sanitize_string(G.wget_buf)); 834 804 } 835 805 … … 837 807 * Retrieve HTTP headers. 838 808 */ 839 while ((str = gethdr(buf, sizeof(buf), sfp /*, &n*/)) != NULL) { 809 while ((str = gethdr(sfp)) != NULL) { 810 static const char keywords[] ALIGN1 = 811 "content-length\0""transfer-encoding\0""location\0"; 812 enum { 813 KEY_content_length = 1, KEY_transfer_encoding, KEY_location 814 }; 815 smalluint key; 816 840 817 /* gethdr converted "FOO:" string to lowercase */ 841 smalluint key; 818 842 819 /* strip trailing whitespace */ 843 820 char *s = strchrnul(str, '\0') - 1; … … 846 823 s--; 847 824 } 848 key = index_in_strings(keywords, buf) + 1;825 key = index_in_strings(keywords, G.wget_buf) + 1; 849 826 if (key == KEY_content_length) { 850 827 G.content_len = BB_STRTOOFF(str, NULL, 10); … … 856 833 } 857 834 if (key == KEY_transfer_encoding) { 858 if ( index_in_strings(keywords, str_tolower(str)) + 1 != KEY_chunked)835 if (strcmp(str_tolower(str), "chunked") != 0) 859 836 bb_error_msg_and_die("transfer encoding '%s' is not supported", sanitize_string(str)); 860 G.chunked = G.got_clen =1;837 G.chunked = 1; 861 838 } 862 839 if (key == KEY_location && status >= 300) { … … 864 841 bb_error_msg_and_die("too many redirections"); 865 842 fclose(sfp); 866 G.got_clen = 0; 867 G.chunked = 0; 868 if (str[0] == '/') 869 /* free(target.allocated); */ 870 target.path = /* target.allocated = */ xstrdup(str+1); 843 if (str[0] == '/') { 844 free(redirected_path); 845 target.path = redirected_path = xstrdup(str+1); 871 846 /* lsa stays the same: it's on the same server */ 872 else {847 } else { 873 848 parse_url(str, &target); 874 849 if (!use_proxy) { 850 free(server.allocated); 851 server.allocated = NULL; 875 852 server.host = target.host; 876 853 /* strip_ipv6_scope_id(target.host); - no! */ … … 897 874 } 898 875 899 if (opt & WGET_OPT_SPIDER) { 900 if (ENABLE_FEATURE_CLEAN_UP) 901 fclose(sfp); 902 return EXIT_SUCCESS; 903 } 904 905 if (output_fd < 0) { 906 int o_flags = O_WRONLY | O_CREAT | O_TRUNC | O_EXCL; 876 free(lsa); 877 878 if (!(option_mask32 & WGET_OPT_SPIDER)) { 879 if (G.output_fd < 0) 880 G.output_fd = xopen(G.fname_out, G.o_flags); 881 retrieve_file_data(dfp); 882 if (!(option_mask32 & WGET_OPT_OUTNAME)) { 883 xclose(G.output_fd); 884 G.output_fd = -1; 885 } 886 } 887 888 if (dfp != sfp) { 889 /* It's ftp. Close data connection properly */ 890 fclose(dfp); 891 if (ftpcmd(NULL, NULL, sfp) != 226) 892 bb_error_msg_and_die("ftp error: %s", sanitize_string(G.wget_buf + 4)); 893 /* ftpcmd("QUIT", NULL, sfp); - why bother? */ 894 } 895 fclose(sfp); 896 897 free(server.allocated); 898 free(target.allocated); 899 free(fname_out_alloc); 900 free(redirected_path); 901 } 902 903 int wget_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 904 int wget_main(int argc UNUSED_PARAM, char **argv) 905 { 906 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 907 static const char wget_longopts[] ALIGN1 = 908 /* name, has_arg, val */ 909 "continue\0" No_argument "c" 910 //FIXME: -s isn't --spider, it's --save-headers! 911 "spider\0" No_argument "s" 912 "quiet\0" No_argument "q" 913 "output-document\0" Required_argument "O" 914 "directory-prefix\0" Required_argument "P" 915 "proxy\0" Required_argument "Y" 916 "user-agent\0" Required_argument "U" 917 #if ENABLE_FEATURE_WGET_TIMEOUT 918 "timeout\0" Required_argument "T" 919 #endif 920 /* Ignored: */ 921 // "tries\0" Required_argument "t" 922 /* 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" 926 /* Ignored (we don't do ssl) */ 927 "no-check-certificate\0" No_argument "\xfc" 928 /* Ignored (we don't support caching) */ 929 "no-cache\0" No_argument "\xfb" 930 ; 931 #endif 932 933 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 934 llist_t *headers_llist = NULL; 935 #endif 936 937 INIT_G(); 938 939 IF_FEATURE_WGET_TIMEOUT(G.timeout_seconds = 900;) 940 G.proxy_flag = "on"; /* use proxies if env vars are set */ 941 G.user_agent = "Wget"; /* "User-Agent" header field */ 942 943 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 944 applet_long_options = wget_longopts; 945 #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, 949 &G.proxy_flag, &G.user_agent, 950 IF_FEATURE_WGET_TIMEOUT(&G.timeout_seconds) IF_NOT_FEATURE_WGET_TIMEOUT(NULL), 951 NULL /* -t RETRIES */ 952 IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) 953 IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data) 954 ); 955 argv += optind; 956 957 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 958 if (headers_llist) { 959 int size = 1; 960 char *cp; 961 llist_t *ll = headers_llist; 962 while (ll) { 963 size += strlen(ll->data) + 2; 964 ll = ll->link; 965 } 966 G.extra_headers = cp = xmalloc(size); 967 while (headers_llist) { 968 cp += sprintf(cp, "%s\r\n", (char*)llist_pop(&headers_llist)); 969 } 970 } 971 #endif 972 973 G.output_fd = -1; 974 G.o_flags = O_WRONLY | O_CREAT | O_TRUNC | O_EXCL; 975 if (G.fname_out) { /* -O FILE ? */ 976 if (LONE_DASH(G.fname_out)) { /* -O - ? */ 977 G.output_fd = 1; 978 option_mask32 &= ~WGET_OPT_CONTINUE; 979 } 907 980 /* compat with wget: -O FILE can overwrite */ 908 if (opt & WGET_OPT_OUTNAME) 909 o_flags = O_WRONLY | O_CREAT | O_TRUNC; 910 output_fd = xopen(fname_out, o_flags); 911 } 912 913 retrieve_file_data(dfp, output_fd); 914 xclose(output_fd); 915 916 if (dfp != sfp) { 917 /* It's ftp. Close it properly */ 918 fclose(dfp); 919 if (ftpcmd(NULL, NULL, sfp, buf) != 226) 920 bb_error_msg_and_die("ftp error: %s", sanitize_string(buf+4)); 921 /* ftpcmd("QUIT", NULL, sfp, buf); - why bother? */ 922 } 981 G.o_flags = O_WRONLY | O_CREAT | O_TRUNC; 982 } 983 984 while (*argv) 985 download_one_url(*argv++); 986 987 if (G.output_fd >= 0) 988 xclose(G.output_fd); 923 989 924 990 return EXIT_SUCCESS; -
branches/3.2/mindi-busybox/networking/zcip.c
r2725 r3232 24 24 // - link status monitoring (restart on link-up; stop on link-down) 25 25 26 //usage:#define zcip_trivial_usage 27 //usage: "[OPTIONS] IFACE SCRIPT" 28 //usage:#define zcip_full_usage "\n\n" 29 //usage: "Manage a ZeroConf IPv4 link-local address\n" 30 //usage: "\n -f Run in foreground" 31 //usage: "\n -q Quit after obtaining address" 32 //usage: "\n -r 169.254.x.x Request this address first" 33 //usage: "\n -v Verbose" 34 //usage: "\n" 35 //usage: "\nWith no -q, runs continuously monitoring for ARP conflicts," 36 //usage: "\nexits only on I/O errors (link down etc)" 37 38 #include "libbb.h" 26 39 #include <netinet/ether.h> 27 #include <net/ethernet.h>28 40 #include <net/if.h> 29 41 #include <net/if_arp.h> 30 #include <linux/if_packet.h>31 42 #include <linux/sockios.h> 32 43 33 #include "libbb.h"34 44 #include <syslog.h> 35 45 … … 82 92 #define saddr (G.saddr ) 83 93 #define eth_addr (G.eth_addr) 94 #define INIT_G() do { } while (0) 84 95 85 96 … … 214 225 215 226 memset(&L, 0, sizeof(L)); 227 INIT_G(); 216 228 217 229 #define FOREGROUND (opts & 1)
Note:
See TracChangeset
for help on using the changeset viewer.