Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/networking/udhcp
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (8 years ago)
- Location:
- branches/3.3
- Files:
-
- 4 added
- 6 deleted
- 16 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/networking/udhcp/Config.src
r3232 r3621 85 85 and restart the discover process. 86 86 87 config FEATURE_UDHCPC_SANITIZEOPT 88 bool "Do not pass malformed host and domain names" 89 default y 90 depends on UDHCPC 91 help 92 If selected, udhcpc will check some options (such as option 12 - 93 hostname) and if they don't look like valid hostnames 94 (for example, if they start with dash or contain spaces), 95 they will be replaced with string "bad" when exporting 96 to the environment. 97 87 98 config FEATURE_UDHCP_PORT 88 99 bool "Enable '-P port' option for udhcpd and udhcpc" -
branches/3.3/mindi-busybox/networking/udhcp/arpping.c
r3232 r3621 40 40 uint32_t from_ip, 41 41 uint8_t *from_mac, 42 const char *interface) 42 const char *interface, 43 unsigned timeo) 43 44 { 44 45 int timeout_ms; … … 48 49 struct sockaddr addr; /* for interface name */ 49 50 struct arpMsg arp; 51 52 if (!timeo) 53 return 1; 50 54 51 55 s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)); … … 84 88 85 89 /* wait for arp reply, and check it */ 86 timeout_ms = 2000;90 timeout_ms = (int)timeo; 87 91 do { 88 92 typedef uint32_t aliased_uint32_t FIX_ALIASING; … … 125 129 * (people did see overflows here when system time jumps): 126 130 */ 127 } while ((unsigned)timeout_ms <= 2000);131 } while ((unsigned)timeout_ms <= timeo); 128 132 129 133 ret: 130 134 close(s); 131 log1("%srp reply received for this address", rv ? " No a" : "A");135 log1("%srp reply received for this address", rv ? "no a" : "A"); 132 136 return rv; 133 137 } -
branches/3.3/mindi-busybox/networking/udhcp/common.c
r3232 r3621 63 63 { OPTION_U8 , 0x85 }, /* DHCP_VLAN_PRIORITY */ 64 64 #endif 65 { OPTION_STRING , 0xd1 }, /* DHCP_PXE_CONF_FILE */ 66 { OPTION_STRING , 0xd2 }, /* DHCP_PXE_PATH_PREFIX */ 65 67 { OPTION_6RD , 0xd4 }, /* DHCP_6RD */ 66 68 { OPTION_STATIC_ROUTES | OPTION_LIST , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ … … 129 131 "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY */ 130 132 #endif 133 "pxeconffile" "\0" /* DHCP_PXE_CONF_FILE */ 134 "pxepathprefix" "\0" /* DHCP_PXE_PATH_PREFIX */ 131 135 "ip6rd" "\0" /* DHCP_6RD */ 132 136 "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ … … 139 143 * xmalloc_optname_optval: to estimate string length 140 144 * from binary option length: (option[LEN] / dhcp_option_lengths[opt_type]) 141 * is the number of elements, multiply i nby one element's string width145 * is the number of elements, multiply it by one element's string width 142 146 * (len_of_option_as_string[opt_type]) and you know how wide string you need. 143 147 */ … … 159 163 /* Just like OPTION_STRING, we use minimum length here */ 160 164 [OPTION_STATIC_ROUTES] = 5, 161 [OPTION_6RD] = 22, /* ignored by udhcp_str2optset */ 165 [OPTION_6RD] = 12, /* ignored by udhcp_str2optset */ 166 /* The above value was chosen as follows: 167 * len_of_option_as_string[] for this option is >60: it's a string of the form 168 * "32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 ". 169 * Each additional ipv4 address takes 4 bytes in binary option and appends 170 * another "255.255.255.255 " 16-byte string. We can set [OPTION_6RD] = 4 171 * but this severely overestimates string length: instead of 16 bytes, 172 * it adds >60 for every 4 bytes in binary option. 173 * We cheat and declare here that option is in units of 12 bytes. 174 * This adds more than 60 bytes for every three ipv4 addresses - more than enough. 175 * (Even 16 instead of 12 should work, but let's be paranoid). 176 */ 162 177 }; 163 178 … … 169 184 char buf[256 * 2 + 2]; 170 185 *bin2hex(buf, (void*) (opt + OPT_DATA), opt[OPT_LEN]) = '\0'; 171 bb_ info_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf);186 bb_error_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf); 172 187 } 173 188 } … … 243 258 244 259 if (optionptr[OPT_CODE] == code) { 245 log_option(" Option found", optionptr);260 log_option("option found", optionptr); 246 261 return optionptr + OPT_DATA; 247 262 } … … 255 270 256 271 /* log3 because udhcpc uses it a lot - very noisy */ 257 log3(" Option 0x%02x not found", code);272 log3("option 0x%02x not found", code); 258 273 return NULL; 259 274 } … … 289 304 return; 290 305 } 291 log_option(" Adding option", addopt);306 log_option("adding option", addopt); 292 307 memcpy(optionptr + end, addopt, len); 293 308 optionptr[end + len] = DHCP_END; … … 372 387 int length) 373 388 { 374 struct option_set *existing, *new, **curr; 375 char *allocated = NULL; 389 struct option_set *existing; 390 char *allocated; 391 392 allocated = allocate_tempopt_if_needed(optflag, buffer, &length); 393 #if ENABLE_FEATURE_UDHCP_RFC3397 394 if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_DNS_STRING) { 395 /* reuse buffer and length for RFC1035-formatted string */ 396 allocated = buffer = (char *)dname_enc(NULL, 0, buffer, &length); 397 } 398 #endif 376 399 377 400 existing = udhcp_find_option(*opt_list, optflag->code); 378 401 if (!existing) { 379 log2("Attaching option %02x to list", optflag->code); 380 allocated = allocate_tempopt_if_needed(optflag, buffer, &length); 381 #if ENABLE_FEATURE_UDHCP_RFC3397 382 if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_DNS_STRING) { 383 /* reuse buffer and length for RFC1035-formatted string */ 384 allocated = buffer = (char *)dname_enc(NULL, 0, buffer, &length); 385 } 386 #endif 402 struct option_set *new, **curr; 403 387 404 /* make a new option */ 405 log2("attaching option %02x to list", optflag->code); 388 406 new = xmalloc(sizeof(*new)); 389 407 new->data = xmalloc(length + OPT_DATA); … … 405 423 406 424 /* add it to an existing option */ 407 log2("Attaching option %02x to existing member of list", optflag->code); 408 allocated = allocate_tempopt_if_needed(optflag, buffer, &length); 425 log2("attaching option %02x to existing member of list", optflag->code); 409 426 old_len = existing->data[OPT_LEN]; 410 #if ENABLE_FEATURE_UDHCP_RFC3397411 if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_DNS_STRING) {412 /* reuse buffer and length for RFC1035-formatted string */413 allocated = buffer = (char *)dname_enc(existing->data + OPT_DATA, old_len, buffer, &length);414 }415 #endif416 427 if (old_len + length < 255) { 417 428 /* actually 255 is ok too, but adding a space can overlow it */ … … 425 436 old_len++; 426 437 } 427 memcpy(existing->data + OPT_DATA + old_len, buffer, length);438 memcpy(existing->data + OPT_DATA + old_len, (allocated ? allocated : buffer), length); 428 439 existing->data[OPT_LEN] = old_len + length; 429 440 } /* else, ignore the data, we could put this in a second option in the future */ -
branches/3.3/mindi-busybox/networking/udhcp/common.h
r3232 r3621 10 10 11 11 #include "libbb.h" 12 #include "common_bufsiz.h" 12 13 #include <netinet/udp.h> 13 14 #include <netinet/ip.h> … … 150 151 //#define DHCP_SIP_SERVERS 0x78 /* RFC 3361. flag byte, then: 0: domain names, 1: IP addrs */ 151 152 //#define DHCP_STATIC_ROUTES 0x79 /* RFC 3442. (mask,ip,router) tuples */ 152 #define DHCP_VLAN_ID 0x84 /* 802.1P VLAN ID */ 153 #define DHCP_VLAN_PRIORITY 0x85 /* 802.1Q VLAN priority */ 153 //#define DHCP_VLAN_ID 0x84 /* 802.1P VLAN ID */ 154 //#define DHCP_VLAN_PRIORITY 0x85 /* 802.1Q VLAN priority */ 155 //#define DHCP_PXE_CONF_FILE 0xd1 /* RFC 5071 Configuration File */ 156 //#define DHCP_PXE_PATH_PREFIX 0xd2 /* RFC 5071 Configuration File */ 154 157 //#define DHCP_MS_STATIC_ROUTES 0xf9 /* Microsoft's pre-RFC 3442 code for 0x79? */ 155 158 //#define DHCP_WPAD 0xfc /* MSIE's Web Proxy Autodiscovery Protocol */ … … 255 258 # define IF_UDHCP_VERBOSE(...) __VA_ARGS__ 256 259 extern unsigned dhcp_verbose; 257 # define log1(...) do { if (dhcp_verbose >= 1) bb_ info_msg(__VA_ARGS__); } while (0)260 # define log1(...) do { if (dhcp_verbose >= 1) bb_error_msg(__VA_ARGS__); } while (0) 258 261 # if CONFIG_UDHCP_DEBUG >= 2 259 262 void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC; 260 # define log2(...) do { if (dhcp_verbose >= 2) bb_ info_msg(__VA_ARGS__); } while (0)263 # define log2(...) do { if (dhcp_verbose >= 2) bb_error_msg(__VA_ARGS__); } while (0) 261 264 # else 262 265 # define udhcp_dump_packet(...) ((void)0) … … 264 267 # endif 265 268 # if CONFIG_UDHCP_DEBUG >= 3 266 # define log3(...) do { if (dhcp_verbose >= 3) bb_ info_msg(__VA_ARGS__); } while (0)269 # define log3(...) do { if (dhcp_verbose >= 3) bb_error_msg(__VA_ARGS__); } while (0) 267 270 # else 268 271 # define log3(...) ((void)0) … … 310 313 uint32_t from_ip, 311 314 uint8_t *from_mac, 312 const char *interface) FAST_FUNC; 315 const char *interface, 316 unsigned timeo) FAST_FUNC; 313 317 314 318 /* note: ip is a pointer to an IPv6 in network order, possibly misaliged */ -
branches/3.3/mindi-busybox/networking/udhcp/dhcpc.c
r3306 r3621 26 26 #include "dhcpc.h" 27 27 28 #include <asm/types.h> 29 #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined(_NEWLIB_VERSION) 30 # include <netpacket/packet.h> 31 # include <net/ethernet.h> 32 #else 33 # include <linux/if_packet.h> 34 # include <linux/if_ether.h> 28 #include <netinet/if_ether.h> 29 #include <linux/filter.h> 30 #include <linux/if_packet.h> 31 32 #ifndef PACKET_AUXDATA 33 # define PACKET_AUXDATA 8 34 struct tpacket_auxdata { 35 uint32_t tp_status; 36 uint32_t tp_len; 37 uint32_t tp_snaplen; 38 uint16_t tp_mac; 39 uint16_t tp_net; 40 uint16_t tp_vlan_tci; 41 uint16_t tp_padding; 42 }; 35 43 #endif 36 #include <linux/filter.h> 44 37 45 38 46 /* "struct client_config_t client_config" is in bb_common_bufsiz1 */ … … 61 69 "background\0" No_argument "b" 62 70 "broadcast\0" No_argument "B" 63 IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument"a")71 IF_FEATURE_UDHCPC_ARPING("arping\0" Optional_argument "a") 64 72 IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P") 65 73 ; … … 102 110 103 111 /* get a rough idea of how long an option will be (rounding up...) */ 104 static const uint8_t len_of_option_as_string[] = {112 static const uint8_t len_of_option_as_string[] ALIGN1 = { 105 113 [OPTION_IP ] = sizeof("255.255.255.255 "), 106 114 [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2, 107 115 [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "), 108 [OPTION_6RD ] = sizeof(" 32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "),116 [OPTION_6RD ] = sizeof("132 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "), 109 117 [OPTION_STRING ] = 1, 110 118 [OPTION_STRING_HOST ] = 1, … … 143 151 } 144 152 153 #if ENABLE_FEATURE_UDHCPC_SANITIZEOPT 145 154 /* Check if a given label represents a valid DNS label 146 155 * Return pointer to the first character after the label upon success, … … 162 171 ch = *label; 163 172 if ((ch|0x20) < 'a' || (ch|0x20) > 'z') { 164 if (pos == 0) {165 /* label must begin with letter */166 return NULL;167 }168 173 if (ch < '0' || ch > '9') { 169 174 if (ch == '\0' || ch == '.') … … 197 202 //return ((name - start) < 1025); /* NS_MAXDNAME */ 198 203 name++; 199 } 200 } 204 if (*name == '\0') 205 return 1; // We allow trailing dot too 206 } 207 } 208 #else 209 # define good_hostname(name) 1 210 #endif 201 211 202 212 /* Create "opt_name=opt_value" string */ … … 213 223 optlen = dhcp_option_lengths[type]; 214 224 upper_length = len_of_option_as_string[type] 215 * ((unsigned)(len + optlen - 1) / (unsigned)optlen);225 * ((unsigned)(len + optlen) / (unsigned)optlen); 216 226 217 227 dest = ret = xmalloc(upper_length + strlen(opt_name) + 2); … … 552 562 553 563 /* call script */ 554 log1(" Executing %s %s", client_config.script, name);564 log1("executing %s %s", client_config.script, name); 555 565 argv[0] = (char*) client_config.script; 556 566 argv[1] = (char*) name; … … 666 676 */ 667 677 668 static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet )678 static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet, uint32_t src_nip) 669 679 { 670 680 return udhcp_send_raw_packet(packet, 671 /*src*/ INADDR_ANY, CLIENT_PORT,681 /*src*/ src_nip, CLIENT_PORT, 672 682 /*dst*/ INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR, 673 683 client_config.ifindex); 684 } 685 686 static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server) 687 { 688 if (server) 689 return udhcp_send_kernel_packet(packet, 690 ciaddr, CLIENT_PORT, 691 server, SERVER_PORT); 692 return raw_bcast_from_client_config_ifindex(packet, ciaddr); 674 693 } 675 694 … … 696 715 add_client_options(&packet); 697 716 698 bb_ info_msg("Sending discover...");699 return raw_bcast_from_client_config_ifindex(&packet );717 bb_error_msg("sending %s", "discover"); 718 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); 700 719 } 701 720 … … 740 759 741 760 addr.s_addr = requested; 742 bb_ info_msg("Sending select for %s...", inet_ntoa(addr));743 return raw_bcast_from_client_config_ifindex(&packet );761 bb_error_msg("sending select for %s", inet_ntoa(addr)); 762 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); 744 763 } 745 764 … … 779 798 add_client_options(&packet); 780 799 781 bb_info_msg("Sending renew..."); 782 if (server) 783 return udhcp_send_kernel_packet(&packet, 784 ciaddr, CLIENT_PORT, 785 server, SERVER_PORT); 786 return raw_bcast_from_client_config_ifindex(&packet); 800 bb_error_msg("sending %s", "renew"); 801 return bcast_or_ucast(&packet, ciaddr, server); 787 802 } 788 803 … … 812 827 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); 813 828 814 bb_ info_msg("Sending decline...");815 return raw_bcast_from_client_config_ifindex(&packet );829 bb_error_msg("sending %s", "decline"); 830 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); 816 831 } 817 832 #endif … … 832 847 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); 833 848 834 bb_info_msg("Sending release..."); 835 return udhcp_send_kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT); 849 bb_error_msg("sending %s", "release"); 850 /* Note: normally we unicast here since "server" is not zero. 851 * However, there _are_ people who run "address-less" DHCP servers, 852 * and reportedly ISC dhcp client and Windows allow that. 853 */ 854 return bcast_or_ucast(&packet, ciaddr, server); 836 855 } 837 856 … … 843 862 struct ip_udp_dhcp_packet packet; 844 863 uint16_t check; 845 #ifdef PACKET_AUXDATA846 864 unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))]; 847 struct cmsghdr *cmsg;848 #endif849 865 struct iovec iov; 850 866 struct msghdr msg; 851 852 #ifdef PACKET_AUXDATA 867 struct cmsghdr *cmsg; 868 853 869 /* used to use just safe_read(fd, &packet, sizeof(packet)) 854 870 * but we need to check for TP_STATUS_CSUMNOTREADY :( … … 866 882 if (errno == EINTR) 867 883 continue; 868 log1(" Packet read error, ignoring");884 log1("packet read error, ignoring"); 869 885 /* NB: possible down interface, etc. Caller should pause. */ 870 886 return bytes; /* returns -1 */ … … 872 888 break; 873 889 } 874 #else875 memset(&packet, 0, sizeof(packet));876 bytes = safe_read(fd, &packet, sizeof(packet));877 if (bytes < 0) {878 log1("Packet read error, ignoring");879 /* NB: possible down interface, etc. Caller should pause. */880 return bytes; /* returns -1 */881 }882 #endif883 890 884 891 if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) { 885 log1(" Packet is too short, ignoring");892 log1("packet is too short, ignoring"); 886 893 return -2; 887 894 } … … 889 896 if (bytes < ntohs(packet.ip.tot_len)) { 890 897 /* packet is bigger than sizeof(packet), we did partial read */ 891 log1(" Oversized packet, ignoring");898 log1("oversized packet, ignoring"); 892 899 return -2; 893 900 } … … 904 911 || ntohs(packet.udp.len) != (uint16_t)(bytes - sizeof(packet.ip)) 905 912 ) { 906 log1(" Unrelated/bogus packet, ignoring");913 log1("unrelated/bogus packet, ignoring"); 907 914 return -2; 908 915 } … … 912 919 packet.ip.check = 0; 913 920 if (check != inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip))) { 914 log1(" Bad IP header checksum, ignoring");921 log1("bad IP header checksum, ignoring"); 915 922 return -2; 916 923 } 917 924 918 #ifdef PACKET_AUXDATA919 925 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { 920 926 if (cmsg->cmsg_level == SOL_PACKET … … 930 936 } 931 937 } 932 #endif933 938 934 939 /* verify UDP checksum. IP header has to be modified for this */ … … 939 944 packet.udp.check = 0; 940 945 if (check && check != inet_cksum((uint16_t *)&packet, bytes)) { 941 log1(" Packet with bad UDP checksum received, ignoring");946 log1("packet with bad UDP checksum received, ignoring"); 942 947 return -2; 943 948 } 944 #ifdef PACKET_AUXDATA945 949 skip_udp_sum_check: 946 #endif947 950 948 951 if (packet.data.cookie != htonl(DHCP_MAGIC)) { 949 bb_ info_msg("Packet with bad magic, ignoring");952 bb_error_msg("packet with bad magic, ignoring"); 950 953 return -2; 951 954 } 952 955 953 log1(" Receiveda packet");956 log1("received %s", "a packet"); 954 957 udhcp_dump_packet(&packet.data); 955 958 … … 990 993 struct sockaddr_ll sock; 991 994 992 /* 993 * Comment: 994 * 995 * I've selected not to see LL header, so BPF doesn't see it, too. 996 * The filter may also pass non-IP and non-ARP packets, but we do 997 * a more complete check when receiving the message in userspace. 998 * 999 * and filter shamelessly stolen from: 1000 * 1001 * http://www.flamewarmaster.de/software/dhcpclient/ 1002 * 1003 * There are a few other interesting ideas on that page (look under 1004 * "Motivation"). Use of netlink events is most interesting. Think 1005 * of various network servers listening for events and reconfiguring. 1006 * That would obsolete sending HUP signals and/or make use of restarts. 1007 * 1008 * Copyright: 2006, 2007 Stefan Rompf <sux@loplof.de>. 1009 * License: GPL v2. 1010 * 1011 * TODO: make conditional? 995 log1("opening raw socket on ifindex %d", ifindex); //log2? 996 997 fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); 998 /* ^^^^^ 999 * SOCK_DGRAM: remove link-layer headers on input (SOCK_RAW keeps them) 1000 * ETH_P_IP: want to receive only packets with IPv4 eth type 1012 1001 */ 1013 static const struct sock_filter filter_instr[] = { 1014 /* load 9th byte (protocol) */ 1015 BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9), 1016 /* jump to L1 if it is IPPROTO_UDP, else to L4 */ 1017 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6), 1018 /* L1: load halfword from offset 6 (flags and frag offset) */ 1019 BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6), 1020 /* jump to L4 if any bits in frag offset field are set, else to L2 */ 1021 BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0), 1022 /* L2: skip IP header (load index reg with header len) */ 1023 BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0), 1024 /* load udp destination port from halfword[header_len + 2] */ 1025 BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2), 1026 /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */ 1027 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1), 1028 /* L3: accept packet */ 1029 BPF_STMT(BPF_RET|BPF_K, 0xffffffff), 1030 /* L4: discard packet */ 1031 BPF_STMT(BPF_RET|BPF_K, 0), 1032 }; 1033 static const struct sock_fprog filter_prog = { 1034 .len = sizeof(filter_instr) / sizeof(filter_instr[0]), 1035 /* casting const away: */ 1036 .filter = (struct sock_filter *) filter_instr, 1037 }; 1038 1039 log1("Opening raw socket on ifindex %d", ifindex); //log2? 1040 1041 fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); 1042 log1("Got raw socket fd"); //log2? 1002 log1("got raw socket fd"); //log2? 1043 1003 1044 1004 sock.sll_family = AF_PACKET; … … 1047 1007 xbind(fd, (struct sockaddr *) &sock, sizeof(sock)); 1048 1008 1009 #if 0 /* Several users reported breakage when BPF filter is used */ 1049 1010 if (CLIENT_PORT == 68) { 1050 1011 /* Use only if standard port is in use */ 1012 /* 1013 * I've selected not to see LL header, so BPF doesn't see it, too. 1014 * The filter may also pass non-IP and non-ARP packets, but we do 1015 * a more complete check when receiving the message in userspace. 1016 * 1017 * and filter shamelessly stolen from: 1018 * 1019 * http://www.flamewarmaster.de/software/dhcpclient/ 1020 * 1021 * There are a few other interesting ideas on that page (look under 1022 * "Motivation"). Use of netlink events is most interesting. Think 1023 * of various network servers listening for events and reconfiguring. 1024 * That would obsolete sending HUP signals and/or make use of restarts. 1025 * 1026 * Copyright: 2006, 2007 Stefan Rompf <sux@loplof.de>. 1027 * License: GPL v2. 1028 */ 1029 static const struct sock_filter filter_instr[] = { 1030 /* load 9th byte (protocol) */ 1031 BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9), 1032 /* jump to L1 if it is IPPROTO_UDP, else to L4 */ 1033 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6), 1034 /* L1: load halfword from offset 6 (flags and frag offset) */ 1035 BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6), 1036 /* jump to L4 if any bits in frag offset field are set, else to L2 */ 1037 BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0), 1038 /* L2: skip IP header (load index reg with header len) */ 1039 BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0), 1040 /* load udp destination port from halfword[header_len + 2] */ 1041 BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2), 1042 /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */ 1043 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1), 1044 /* L3: accept packet ("accept 0x7fffffff bytes") */ 1045 /* Accepting 0xffffffff works too but kernel 2.6.19 is buggy */ 1046 BPF_STMT(BPF_RET|BPF_K, 0x7fffffff), 1047 /* L4: discard packet ("accept zero bytes") */ 1048 BPF_STMT(BPF_RET|BPF_K, 0), 1049 }; 1050 static const struct sock_fprog filter_prog = { 1051 .len = sizeof(filter_instr) / sizeof(filter_instr[0]), 1052 /* casting const away: */ 1053 .filter = (struct sock_filter *) filter_instr, 1054 }; 1051 1055 /* Ignoring error (kernel may lack support for this) */ 1052 1056 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, 1053 1057 sizeof(filter_prog)) >= 0) 1054 log1("Attached filter to raw socket fd"); // log? 1055 } 1056 1057 #ifdef PACKET_AUXDATA 1058 if (setsockopt(fd, SOL_PACKET, PACKET_AUXDATA, 1059 &const_int_1, sizeof(int)) < 0 1060 ) { 1058 log1("attached filter to raw socket fd"); // log? 1059 } 1060 #endif 1061 1062 if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) { 1061 1063 if (errno != ENOPROTOOPT) 1062 log1("Can't set PACKET_AUXDATA on raw socket"); 1063 } 1064 #else 1065 sock.sll_family = AF_PACKET; 1066 sock.sll_protocol = htons(ETH_P_IP); 1067 sock.sll_ifindex = ifindex; 1068 xbind(fd, (struct sockaddr *) &sock, sizeof(sock)); 1069 #endif 1070 1071 log1("Created raw socket"); 1064 log1("can't set PACKET_AUXDATA on raw socket"); 1065 } 1066 1067 log1("created raw socket"); 1072 1068 1073 1069 return fd; … … 1076 1072 static void change_listen_mode(int new_mode) 1077 1073 { 1078 log1(" Entering listen mode: %s",1074 log1("entering listen mode: %s", 1079 1075 new_mode != LISTEN_NONE 1080 1076 ? (new_mode == LISTEN_KERNEL ? "kernel" : "raw") … … 1097 1093 static void perform_renew(void) 1098 1094 { 1099 bb_ info_msg("Performing aDHCP renew");1095 bb_error_msg("performing DHCP renew"); 1100 1096 switch (state) { 1101 1097 case BOUND: … … 1127 1123 strcpy(buffer, inet_ntoa(temp_addr)); 1128 1124 temp_addr.s_addr = requested_ip; 1129 bb_ info_msg("Unicasting a release of %s to %s",1125 bb_error_msg("unicasting a release of %s to %s", 1130 1126 inet_ntoa(temp_addr), buffer); 1131 1127 send_release(server_addr, requested_ip); /* unicast */ 1132 1128 udhcp_run_script(NULL, "deconfig"); 1133 1129 } 1134 bb_ info_msg("Entering released state");1130 bb_error_msg("entering released state"); 1135 1131 1136 1132 change_listen_mode(LISTEN_NONE); … … 1165 1161 //usage:#endif 1166 1162 //usage:#define udhcpc_trivial_usage 1167 //usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"oCRB] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n" 1168 //usage: " [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]") 1163 //usage: "[-fbq"IF_UDHCP_VERBOSE("v")"RB]"IF_FEATURE_UDHCPC_ARPING(" [-a[MSEC]]")" [-t N] [-T SEC] [-A SEC/-n]\n" 1164 //usage: " [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-s PROG] [-p PIDFILE]\n" 1165 //usage: " [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]..." 1169 1166 //usage:#define udhcpc_full_usage "\n" 1170 1167 //usage: IF_LONG_OPTS( 1171 1168 //usage: "\n -i,--interface IFACE Interface to use (default eth0)" 1169 //usage: IF_FEATURE_UDHCP_PORT( 1170 //usage: "\n -P,--client-port PORT Use PORT (default 68)" 1171 //usage: ) 1172 //usage: "\n -s,--script PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" 1172 1173 //usage: "\n -p,--pidfile FILE Create pidfile" 1173 //usage: "\n -s,--script PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"1174 1174 //usage: "\n -B,--broadcast Request broadcast replies" 1175 //usage: "\n -t,--retries N Send up to N discover packets" 1176 //usage: "\n -T,--timeout N Pause between packets (default 3 seconds)" 1177 //usage: "\n -A,--tryagain N Wait N seconds after failure (default 20)" 1175 //usage: "\n -t,--retries N Send up to N discover packets (default 3)" 1176 //usage: "\n -T,--timeout SEC Pause between packets (default 3)" 1177 //usage: "\n -A,--tryagain SEC Wait if lease is not obtained (default 20)" 1178 //usage: "\n -n,--now Exit if lease is not obtained" 1179 //usage: "\n -q,--quit Exit after obtaining lease" 1180 //usage: "\n -R,--release Release IP on exit" 1178 1181 //usage: "\n -f,--foreground Run in foreground" 1179 1182 //usage: USE_FOR_MMU( 1180 1183 //usage: "\n -b,--background Background if lease is not obtained" 1181 1184 //usage: ) 1182 //usage: "\n -n,--now Exit if lease is not obtained"1183 //usage: "\n -q,--quit Exit after obtaining lease"1184 //usage: "\n -R,--release Release IP on exit"1185 1185 //usage: "\n -S,--syslog Log to syslog too" 1186 //usage: IF_FEATURE_UDHCP _PORT(1187 //usage: "\n - P,--client-port N Use port N (default 68)"1186 //usage: IF_FEATURE_UDHCPC_ARPING( 1187 //usage: "\n -a[MSEC],--arping[=MSEC] Validate offered address with ARP ping" 1188 1188 //usage: ) 1189 //usage: IF_FEATURE_UDHCPC_ARPING( 1190 //usage: "\n -a,--arping Use arping to validate offered address" 1191 //usage: ) 1189 //usage: "\n -r,--request IP Request this IP address" 1190 //usage: "\n -o,--no-default-options Don't request any options (unless -O is given)" 1192 1191 //usage: "\n -O,--request-option OPT Request option OPT from server (cumulative)" 1193 //usage: "\n -o,--no-default-options Don't request any options (unless -O is given)"1194 //usage: "\n -r,--request IP Request this IP address"1195 1192 //usage: "\n -x OPT:VAL Include option OPT in sent packets (cumulative)" 1196 1193 //usage: "\n Examples of string, numeric, and hex byte opts:" … … 1207 1204 //usage: IF_NOT_LONG_OPTS( 1208 1205 //usage: "\n -i IFACE Interface to use (default eth0)" 1206 //usage: IF_FEATURE_UDHCP_PORT( 1207 //usage: "\n -P PORT Use PORT (default 68)" 1208 //usage: ) 1209 //usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" 1209 1210 //usage: "\n -p FILE Create pidfile" 1210 //usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"1211 1211 //usage: "\n -B Request broadcast replies" 1212 //usage: "\n -t N Send up to N discover packets" 1213 //usage: "\n -T N Pause between packets (default 3 seconds)" 1214 //usage: "\n -A N Wait N seconds (default 20) after failure" 1212 //usage: "\n -t N Send up to N discover packets (default 3)" 1213 //usage: "\n -T SEC Pause between packets (default 3)" 1214 //usage: "\n -A SEC Wait if lease is not obtained (default 20)" 1215 //usage: "\n -n Exit if lease is not obtained" 1216 //usage: "\n -q Exit after obtaining lease" 1217 //usage: "\n -R Release IP on exit" 1215 1218 //usage: "\n -f Run in foreground" 1216 1219 //usage: USE_FOR_MMU( 1217 1220 //usage: "\n -b Background if lease is not obtained" 1218 1221 //usage: ) 1219 //usage: "\n -n Exit if lease is not obtained"1220 //usage: "\n -q Exit after obtaining lease"1221 //usage: "\n -R Release IP on exit"1222 1222 //usage: "\n -S Log to syslog too" 1223 //usage: IF_FEATURE_UDHCP _PORT(1224 //usage: "\n - P N Use port N (default 68)"1223 //usage: IF_FEATURE_UDHCPC_ARPING( 1224 //usage: "\n -a[MSEC] Validate offered address with ARP ping" 1225 1225 //usage: ) 1226 //usage: IF_FEATURE_UDHCPC_ARPING( 1227 //usage: "\n -a Use arping to validate offered address" 1228 //usage: ) 1226 //usage: "\n -r IP Request this IP address" 1227 //usage: "\n -o Don't request any options (unless -O is given)" 1229 1228 //usage: "\n -O OPT Request option OPT from server (cumulative)" 1230 //usage: "\n -o Don't request any options (unless -O is given)"1231 //usage: "\n -r IP Request this IP address"1232 1229 //usage: "\n -x OPT:VAL Include option OPT in sent packets (cumulative)" 1233 1230 //usage: "\n Examples of string, numeric, and hex byte opts:" … … 1250 1247 int udhcpc_main(int argc UNUSED_PARAM, char **argv) 1251 1248 { 1252 uint8_t * temp, *message;1249 uint8_t *message; 1253 1250 const char *str_V, *str_h, *str_F, *str_r; 1251 IF_FEATURE_UDHCPC_ARPING(const char *str_a = "2000";) 1254 1252 IF_FEATURE_UDHCP_PORT(char *str_P;) 1255 1253 void *clientid_mac_ptr; … … 1266 1264 unsigned already_waited_sec; 1267 1265 unsigned opt; 1266 IF_FEATURE_UDHCPC_ARPING(unsigned arpping_ms;) 1268 1267 int max_fd; 1269 1268 int retval; 1270 1269 fd_set rfds; 1270 1271 setup_common_bufsiz(); 1271 1272 1272 1273 /* Default options */ … … 1283 1284 opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB" 1284 1285 USE_FOR_MMU("b") 1285 IF_FEATURE_UDHCPC_ARPING("a ")1286 IF_FEATURE_UDHCPC_ARPING("a::") 1286 1287 IF_FEATURE_UDHCP_PORT("P:") 1287 1288 "v" … … 1292 1293 , &list_O 1293 1294 , &list_x 1295 IF_FEATURE_UDHCPC_ARPING(, &str_a) 1294 1296 IF_FEATURE_UDHCP_PORT(, &str_P) 1295 1297 IF_UDHCP_VERBOSE(, &dhcp_verbose) … … 1323 1325 } 1324 1326 #endif 1327 IF_FEATURE_UDHCPC_ARPING(arpping_ms = xatou(str_a);) 1325 1328 while (list_O) { 1326 1329 char *optstr = llist_pop(&list_O); … … 1395 1398 write_pidfile(client_config.pidfile); 1396 1399 /* Goes to stdout (unless NOMMU) and possibly syslog */ 1397 bb_ info_msg("%s (v"BB_VER") started", applet_name);1400 bb_error_msg("started, v"BB_VER); 1398 1401 /* Set up the signal pipe */ 1399 1402 udhcp_sp_setup(); … … 1434 1437 /* If we already timed out, fall through with retval = 0, else... */ 1435 1438 if ((int)tv.tv_sec > 0) { 1436 log1(" Waiting on select %u seconds", (int)tv.tv_sec);1439 log1("waiting on select %u seconds", (int)tv.tv_sec); 1437 1440 timestamp_before_wait = (unsigned)monotonic_sec(); 1438 1441 retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); … … 1485 1488 #if BB_MMU /* -b is not supported on NOMMU */ 1486 1489 if (opt & OPT_b) { /* background if no lease */ 1487 bb_ info_msg("No lease, forking to background");1490 bb_error_msg("no lease, forking to background"); 1488 1491 client_background(); 1489 1492 /* do not background again! */ … … 1492 1495 #endif 1493 1496 if (opt & OPT_n) { /* abort if no lease */ 1494 bb_ info_msg("No lease, failing");1497 bb_error_msg("no lease, failing"); 1495 1498 retval = 1; 1496 1499 goto ret; … … 1501 1504 continue; 1502 1505 case REQUESTING: 1503 if ( !discover_retries || packet_num < discover_retries) {1506 if (packet_num < 3) { 1504 1507 /* send broadcast select packet */ 1505 1508 send_select(xid, server_addr, requested_ip); … … 1520 1523 client_config.first_secs = 0; /* make secs field count from 0 */ 1521 1524 change_listen_mode(LISTEN_KERNEL); 1522 log1(" Entering renew state");1525 log1("entering renew state"); 1523 1526 /* fall right through */ 1524 1527 case RENEW_REQUESTED: /* manual (SIGUSR1) renew */ … … 1540 1543 } 1541 1544 /* Timed out, enter rebinding state */ 1542 log1(" Entering rebinding state");1545 log1("entering rebinding state"); 1543 1546 state = REBINDING; 1544 1547 /* fall right through */ … … 1555 1558 } 1556 1559 /* Timed out, enter init state */ 1557 bb_ info_msg("Lease lost, entering init state");1560 bb_error_msg("lease lost, entering init state"); 1558 1561 udhcp_run_script(NULL, "deconfig"); 1559 1562 state = INIT_SELECTING; … … 1603 1606 continue; 1604 1607 case SIGTERM: 1605 bb_ info_msg("ReceivedSIGTERM");1608 bb_error_msg("received %s", "SIGTERM"); 1606 1609 goto ret0; 1607 1610 } … … 1621 1624 if (len == -1) { 1622 1625 /* Error is severe, reopen socket */ 1623 bb_ info_msg("Read error: %s, reopening socket", strerror(errno));1626 bb_error_msg("read error: %s, reopening socket", strerror(errno)); 1624 1627 sleep(discover_timeout); /* 3 seconds by default */ 1625 1628 change_listen_mode(listen_mode); /* just close and reopen */ … … 1658 1661 /* Must be a DHCPOFFER */ 1659 1662 if (*message == DHCPOFFER) { 1663 uint8_t *temp; 1664 1660 1665 /* What exactly is server's IP? There are several values. 1661 1666 * Example DHCP offer captured with tchdump: … … 1677 1682 * "Next server" and router are definitely wrong ones to use, though... 1678 1683 */ 1684 /* We used to ignore pcakets without DHCP_SERVER_ID. 1685 * I've got user reports from people who run "address-less" servers. 1686 * They either supply DHCP_SERVER_ID of 0.0.0.0 or don't supply it at all. 1687 * They say ISC DHCP client supports this case. 1688 */ 1689 server_addr = 0; 1679 1690 temp = udhcp_get_option(&packet, DHCP_SERVER_ID); 1680 1691 if (!temp) { 1681 bb_error_msg("no server ID, ignoring packet"); 1682 continue; 1683 /* still selecting - this server looks bad */ 1692 bb_error_msg("no server ID, using 0.0.0.0"); 1693 } else { 1694 /* it IS unaligned sometimes, don't "optimize" */ 1695 move_from_unaligned32(server_addr, temp); 1684 1696 } 1685 /* it IS unaligned sometimes, don't "optimize" */1686 move_from_unaligned32(server_addr, temp);1687 1697 /*xid = packet.xid; - already is */ 1688 1698 requested_ip = packet.yiaddr; … … 1700 1710 case REBINDING: 1701 1711 if (*message == DHCPACK) { 1712 unsigned start; 1702 1713 uint32_t lease_seconds; 1703 1714 struct in_addr temp_addr; 1715 uint8_t *temp; 1704 1716 1705 1717 temp = udhcp_get_option(&packet, DHCP_LEASE_TIME); … … 1732 1744 (uint32_t) 0, 1733 1745 client_config.client_mac, 1734 client_config.interface) 1746 client_config.interface, 1747 arpping_ms) 1735 1748 ) { 1736 bb_ info_msg("Offered address is in use "1749 bb_error_msg("offered address is in use " 1737 1750 "(got ARP reply), declining"); 1738 1751 send_decline(/*xid,*/ server_addr, packet.yiaddr); … … 1752 1765 #endif 1753 1766 /* enter bound state */ 1754 timeout = lease_seconds / 2;1755 1767 temp_addr.s_addr = packet.yiaddr; 1756 bb_ info_msg("Lease of %s obtained, lease time %u",1768 bb_error_msg("lease of %s obtained, lease time %u", 1757 1769 inet_ntoa(temp_addr), (unsigned)lease_seconds); 1758 1770 requested_ip = packet.yiaddr; 1771 1772 start = monotonic_sec(); 1759 1773 udhcp_run_script(&packet, state == REQUESTING ? "bound" : "renew"); 1774 already_waited_sec = (unsigned)monotonic_sec() - start; 1775 timeout = lease_seconds / 2; 1776 if ((unsigned)timeout < already_waited_sec) { 1777 /* Something went wrong. Back to discover state */ 1778 timeout = already_waited_sec = 0; 1779 } 1760 1780 1761 1781 state = BOUND; … … 1775 1795 /* make future renew packets use different xid */ 1776 1796 /* xid = random_xid(); ...but why bother? */ 1777 already_waited_sec = 0; 1797 1778 1798 continue; /* back to main loop */ 1779 1799 } 1780 1800 if (*message == DHCPNAK) { 1801 /* If network has more than one DHCP server, 1802 * "wrong" server can reply first, with a NAK. 1803 * Do not interpret it as a NAK from "our" server. 1804 */ 1805 if (server_addr != 0) { 1806 uint32_t svid; 1807 uint8_t *temp; 1808 1809 temp = udhcp_get_option(&packet, DHCP_SERVER_ID); 1810 if (!temp) { 1811 non_matching_svid: 1812 log1("%s with wrong server ID, ignoring packet", 1813 "Received DHCP NAK" 1814 ); 1815 continue; 1816 } 1817 move_from_unaligned32(svid, temp); 1818 if (svid != server_addr) 1819 goto non_matching_svid; 1820 } 1781 1821 /* return to init state */ 1782 bb_ info_msg("ReceivedDHCP NAK");1822 bb_error_msg("received %s", "DHCP NAK"); 1783 1823 udhcp_run_script(&packet, "nak"); 1784 1824 if (state != REQUESTING) -
branches/3.3/mindi-busybox/networking/udhcp/dhcpc.h
r3232 r3621 30 30 31 31 #if ENABLE_FEATURE_UDHCP_PORT 32 #define CLIENT_PORT (client_config.port) 32 #define CLIENT_PORT (client_config.port) 33 #define CLIENT_PORT6 (client_config.port) 33 34 #else 34 #define CLIENT_PORT 68 35 #define CLIENT_PORT 68 36 #define CLIENT_PORT6 546 35 37 #endif 36 38 -
branches/3.3/mindi-busybox/networking/udhcp/dhcpd.c
r3232 r3621 23 23 24 24 //usage:#define udhcpd_trivial_usage 25 //usage: "[-fS] " IF_FEATURE_UDHCP_PORT(" [-P N]") " [CONFFILE]"25 //usage: "[-fS] [-I ADDR]" IF_FEATURE_UDHCP_PORT(" [-P N]") " [CONFFILE]" 26 26 //usage:#define udhcpd_full_usage "\n\n" 27 27 //usage: "DHCP server\n" 28 28 //usage: "\n -f Run in foreground" 29 29 //usage: "\n -S Log to syslog too" 30 //usage: "\n -I ADDR Local address" 31 //usage: "\n -a MSEC Timeout for ARP ping (default 2000)" 30 32 //usage: IF_FEATURE_UDHCP_PORT( 31 33 //usage: "\n -P N Use port N (default 67)" … … 60 62 || dhcp_pkt->ciaddr == 0 61 63 ) { 62 log1(" Broadcasting packet to client");64 log1("broadcasting packet to client"); 63 65 ciaddr = INADDR_BROADCAST; 64 66 chaddr = MAC_BCAST_ADDR; 65 67 } else { 66 log1(" Unicasting packet to client ciaddr");68 log1("unicasting packet to client ciaddr"); 67 69 ciaddr = dhcp_pkt->ciaddr; 68 70 chaddr = dhcp_pkt->chaddr; … … 78 80 static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt) 79 81 { 80 log1(" Forwarding packet to relay");82 log1("forwarding packet to relay"); 81 83 82 84 udhcp_send_kernel_packet(dhcp_pkt, … … 148 150 uint32_t static_lease_nip, 149 151 struct dyn_lease *lease, 150 uint8_t *requested_ip_opt) 152 uint8_t *requested_ip_opt, 153 unsigned arpping_ms) 151 154 { 152 155 struct dhcp_packet packet; … … 187 190 else { 188 191 /* Otherwise, find a free IP */ 189 packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr );192 packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr, arpping_ms); 190 193 } 191 194 … … 212 215 213 216 addr.s_addr = packet.yiaddr; 214 bb_ info_msg("Sending OFFER of %s", inet_ntoa(addr));217 bb_error_msg("sending OFFER of %s", inet_ntoa(addr)); 215 218 /* send_packet emits error message itself if it detects failure */ 216 219 send_packet(&packet, /*force_bcast:*/ 0); … … 224 227 init_packet(&packet, oldpacket, DHCPNAK); 225 228 226 log1(" SendingNAK");229 log1("sending %s", "NAK"); 227 230 send_packet(&packet, /*force_bcast:*/ 1); 228 231 } … … 245 248 246 249 addr.s_addr = yiaddr; 247 bb_ info_msg("Sending ACK to %s", inet_ntoa(addr));250 bb_error_msg("sending ACK to %s", inet_ntoa(addr)); 248 251 send_packet(&packet, /*force_bcast:*/ 0); 249 252 … … 303 306 unsigned opt; 304 307 struct option_set *option; 308 char *str_I = str_I; 309 const char *str_a = "2000"; 310 unsigned arpping_ms; 305 311 IF_FEATURE_UDHCP_PORT(char *str_P;) 306 312 307 #if ENABLE_FEATURE_UDHCP_PORT 308 SERVER_PORT = 67; 309 CLIENT_PORT = 68;310 #endif 313 setup_common_bufsiz(); 314 315 IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) 316 IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) 311 317 312 318 #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 313 319 opt_complementary = "vv"; 314 320 #endif 315 opt = getopt32(argv, "fSv" 316 IF_FEATURE_UDHCP_PORT("P:", &str_P) 321 opt = getopt32(argv, "fSI:va:" 322 IF_FEATURE_UDHCP_PORT("P:") 323 , &str_I 324 , &str_a 325 IF_FEATURE_UDHCP_PORT(, &str_P) 317 326 IF_UDHCP_VERBOSE(, &dhcp_verbose) 318 327 ); … … 327 336 logmode |= LOGMODE_SYSLOG; 328 337 } 338 if (opt & 4) { /* -I */ 339 len_and_sockaddr *lsa = xhost_and_af2sockaddr(str_I, 0, AF_INET); 340 server_config.server_nip = lsa->u.sin.sin_addr.s_addr; 341 free(lsa); 342 } 329 343 #if ENABLE_FEATURE_UDHCP_PORT 330 if (opt & 8) { /* -P */344 if (opt & 32) { /* -P */ 331 345 SERVER_PORT = xatou16(str_P); 332 346 CLIENT_PORT = SERVER_PORT + 1; 333 347 } 334 348 #endif 349 arpping_ms = xatou(str_a); 350 335 351 /* Would rather not do read_config before daemonization - 336 352 * otherwise NOMMU machines will parse config twice */ … … 346 362 /* if (!..) bb_perror_msg("can't create pidfile %s", pidfile); */ 347 363 348 bb_ info_msg("%s (v"BB_VER") started", applet_name);364 bb_error_msg("started, v"BB_VER); 349 365 350 366 option = udhcp_find_option(server_config.options, DHCP_LEASE_TIME); … … 368 384 if (udhcp_read_interface(server_config.interface, 369 385 &server_config.ifindex, 370 &server_config.server_nip,386 (server_config.server_nip == 0 ? &server_config.server_nip : NULL), 371 387 server_config.server_mac) 372 388 ) { … … 398 414 max_sock = udhcp_sp_fd_set(&rfds, server_socket); 399 415 if (server_config.auto_time) { 400 tv.tv_sec = timeout_end - monotonic_sec(); 416 /* cast to signed is essential if tv_sec is wider than int */ 417 tv.tv_sec = (int)(timeout_end - monotonic_sec()); 401 418 tv.tv_usec = 0; 402 419 } … … 411 428 } 412 429 if (retval < 0 && errno != EINTR) { 413 log1(" Error on select");430 log1("error on select"); 414 431 continue; 415 432 } … … 417 434 switch (udhcp_sp_read(&rfds)) { 418 435 case SIGUSR1: 419 bb_ info_msg("ReceivedSIGUSR1");436 bb_error_msg("received %s", "SIGUSR1"); 420 437 write_leases(); 421 438 /* why not just reset the timeout, eh */ 422 439 goto continue_with_autotime; 423 440 case SIGTERM: 424 bb_ info_msg("ReceivedSIGTERM");441 bb_error_msg("received %s", "SIGTERM"); 425 442 write_leases(); 426 443 goto ret0; … … 435 452 /* bytes can also be -2 ("bad packet data") */ 436 453 if (bytes == -1 && errno != EINTR) { 437 log1(" Read error: %s, reopening socket", strerror(errno));454 log1("read error: %s, reopening socket", strerror(errno)); 438 455 close(server_socket); 439 456 server_socket = -1; … … 470 487 static_lease_nip = get_static_nip_by_mac(server_config.static_leases, &packet.chaddr); 471 488 if (static_lease_nip) { 472 bb_ info_msg("Found static lease: %x", static_lease_nip);489 bb_error_msg("found static lease: %x", static_lease_nip); 473 490 memcpy(&fake_lease.lease_mac, &packet.chaddr, 6); 474 491 fake_lease.lease_nip = static_lease_nip; … … 488 505 489 506 case DHCPDISCOVER: 490 log1(" ReceivedDISCOVER");491 492 send_offer(&packet, static_lease_nip, lease, requested_ip_opt );507 log1("received %s", "DISCOVER"); 508 509 send_offer(&packet, static_lease_nip, lease, requested_ip_opt, arpping_ms); 493 510 break; 494 511 495 512 case DHCPREQUEST: 496 log1(" ReceivedREQUEST");513 log1("received %s", "REQUEST"); 497 514 /* RFC 2131: 498 515 … … 619 636 * ciaddr must be 0 (we do not check this) 620 637 */ 621 log1(" ReceivedDECLINE");638 log1("received %s", "DECLINE"); 622 639 if (server_id_opt 623 640 && requested_ip_opt … … 639 656 * ciaddr must be filled in 640 657 */ 641 log1(" ReceivedRELEASE");658 log1("received %s", "RELEASE"); 642 659 if (server_id_opt 643 660 && lease /* chaddr matches this lease */ … … 649 666 650 667 case DHCPINFORM: 651 log1(" ReceivedINFORM");668 log1("received %s", "INFORM"); 652 669 send_inform(&packet); 653 670 break; -
branches/3.3/mindi-busybox/networking/udhcp/dhcpd.h
r2725 r3621 58 58 } FIX_ALIASING; 59 59 60 #define server_config (*(struct server_config_t*) &bb_common_bufsiz1)60 #define server_config (*(struct server_config_t*)bb_common_bufsiz1) 61 61 /* client_config sits in 2nd half of bb_common_bufsiz1 */ 62 62 63 63 #if ENABLE_FEATURE_UDHCP_PORT 64 #define SERVER_PORT (server_config.port) 64 #define SERVER_PORT (server_config.port) 65 #define SERVER_PORT6 (server_config.port) 65 66 #else 66 #define SERVER_PORT 67 67 #define SERVER_PORT 67 68 #define SERVER_PORT6 547 67 69 #endif 68 70 … … 99 101 struct dyn_lease *find_lease_by_mac(const uint8_t *mac) FAST_FUNC; 100 102 struct dyn_lease *find_lease_by_nip(uint32_t nip) FAST_FUNC; 101 uint32_t find_free_or_expired_nip(const uint8_t *safe_mac ) FAST_FUNC;103 uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arpping_ms) FAST_FUNC; 102 104 103 105 -
branches/3.3/mindi-busybox/networking/udhcp/dhcprelay.c
r3232 r3621 34 34 } FIX_ALIASING; 35 35 36 #define dhcprelay_xid_list (*(struct xid_item*)&bb_common_bufsiz1) 36 #define dhcprelay_xid_list (*(struct xid_item*)bb_common_bufsiz1) 37 #define INIT_G() do { setup_common_bufsiz(); } while (0) 37 38 38 39 static struct xid_item *xid_add(uint32_t xid, struct sockaddr_in *ip, int client) … … 257 258 int num_sockets, max_socket; 258 259 uint32_t our_nip; 260 261 INIT_G(); 259 262 260 263 server_addr.sin_family = AF_INET; -
branches/3.3/mindi-busybox/networking/udhcp/domain_codec.c
r2725 r3621 8 8 */ 9 9 #ifdef DNS_COMPR_TESTING 10 # define _GNU_SOURCE 10 11 # define FAST_FUNC /* nothing */ 11 12 # define xmalloc malloc … … 43 44 while (1) { 44 45 /* note: "return NULL" below are leak-safe since 45 * dst isn't yet allocated*/46 * dst isn't allocated yet */ 46 47 const uint8_t *c; 47 48 unsigned crtpos, retpos, depth, len; … … 64 65 return NULL; 65 66 if (dst) 66 memcpy(dst + len, c + 1, *c); 67 /* \3com ---> "com." */ 68 ((char*)mempcpy(dst + len, c + 1, *c))[0] = '.'; 67 69 len += *c + 1; 68 70 crtpos += *c + 1; 69 if (dst)70 dst[len - 1] = '.';71 71 } else { 72 72 /* NUL: end of current domain name */ … … 79 79 retpos = depth = 0; 80 80 } 81 if (dst) 81 if (dst && len != 0) 82 /* \4host\3com\0\4host and we are at \0: 83 * \3com was converted to "com.", change dot to space. 84 */ 82 85 dst[len - 1] = ' '; 83 86 } … … 96 99 /* allocate dst buffer and copy pre */ 97 100 unsigned plen = strlen(pre); 98 ret = dst = xmalloc(plen + len); 99 memcpy(dst, pre, plen); 100 dst += plen; 101 ret = xmalloc(plen + len); 102 dst = stpcpy(ret, pre); 101 103 } else { 102 104 dst[len - 1] = '\0'; … … 229 231 uint8_t *encoded; 230 232 233 uint8_t str[6] = { 0x00, 0x00, 0x02, 0x65, 0x65, 0x00 }; 234 printf("NUL:'%s'\n", dname_dec(str, 6, "")); 235 231 236 #define DNAME_DEC(encoded,pre) dname_dec((uint8_t*)(encoded), sizeof(encoded), (pre)) 232 237 printf("'%s'\n", DNAME_DEC("\4host\3com\0", "test1:")); -
branches/3.3/mindi-busybox/networking/udhcp/dumpleases.c
r3232 r3621 5 5 6 6 //usage:#define dumpleases_trivial_usage 7 //usage: "[-r|-a] [- f LEASEFILE]"7 //usage: "[-r|-a] [-d] [-f LEASEFILE]" 8 8 //usage:#define dumpleases_full_usage "\n\n" 9 9 //usage: "Display DHCP leases granted by udhcpd\n" … … 12 12 //usage: "\n -r,--remaining Show remaining time" 13 13 //usage: "\n -a,--absolute Show expiration time" 14 //usage: "\n -d,--decimal Show time in seconds" 14 15 //usage: ) 15 16 //usage: IF_NOT_LONG_OPTS( … … 17 18 //usage: "\n -r Show remaining time" 18 19 //usage: "\n -a Show expiration time" 20 //usage: "\n -d Show time in seconds" 19 21 //usage: ) 20 22 … … 29 31 int i; 30 32 unsigned opt; 31 int64_t written_at, curr , expires_abs;33 int64_t written_at, curr; 32 34 const char *file = LEASES_FILE; 33 35 struct dyn_lease lease; 34 struct in_addr addr;35 36 36 37 enum { … … 38 39 OPT_r = 0x2, // -r 39 40 OPT_f = 0x4, // -f 41 OPT_d = 0x8, // -d 40 42 }; 41 43 #if ENABLE_LONG_OPTS … … 44 46 "remaining\0" No_argument "r" 45 47 "file\0" Required_argument "f" 48 "decimal\0" No_argument "d" 46 49 ; 47 50 … … 51 54 52 55 opt_complementary = "=0:a--r:r--a"; 53 opt = getopt32(argv, "arf: ", &file);56 opt = getopt32(argv, "arf:d", &file); 54 57 55 58 fd = xopen(file, O_RDONLY); 56 59 57 printf("Mac Address IP Address Host Name Expires %s\n", (opt & OPT_a) ? "at" : "in");60 /* "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 */ 58 61 /* "00:00:00:00:00:00 255.255.255.255 ABCDEFGHIJKLMNOPQRS Wed Jun 30 21:49:08 1993" */ 59 /* "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 */ 62 printf("Mac %-14s" "IP %-13s" "Host %-15s" "Expires %s\n", 63 "Address", "Address", "Name", 64 (opt & OPT_a) ? "at" : "in" 65 ); 60 66 61 67 xread(fd, &written_at, sizeof(written_at)); … … 66 72 67 73 while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { 74 struct in_addr addr; 75 int64_t expires_abs; 76 68 77 const char *fmt = ":%02x" + 1; 69 78 for (i = 0; i < 6; i++) { … … 88 97 continue; 89 98 } 99 if (opt & OPT_d) { 100 /* -d: decimal time */ 101 if (!(opt & OPT_a)) 102 expires_abs -= curr; 103 printf("%llu\n", (unsigned long long) expires_abs); 104 continue; 105 } 90 106 if (!(opt & OPT_a)) { /* no -a */ 91 107 unsigned d, h, m; -
branches/3.3/mindi-busybox/networking/udhcp/files.c
r3232 r3621 58 58 const char *keyword; 59 59 int (*handler)(const char *line, void *var) FAST_FUNC; 60 void *var;60 unsigned ofs; 61 61 const char *def; 62 62 }; 63 63 64 #define OFS(field) offsetof(struct server_config_t, field) 65 64 66 static const struct config_keyword keywords[] = { 65 67 /* keyword handler variable address default */ 66 {"start" , udhcp_str2nip , &server_config.start_ip, "192.168.0.20"},67 {"end" , udhcp_str2nip , &server_config.end_ip, "192.168.0.254"},68 {"interface" , read_str , &server_config.interface, "eth0"},68 {"start" , udhcp_str2nip , OFS(start_ip ), "192.168.0.20"}, 69 {"end" , udhcp_str2nip , OFS(end_ip ), "192.168.0.254"}, 70 {"interface" , read_str , OFS(interface ), "eth0"}, 69 71 /* Avoid "max_leases value not sane" warning by setting default 70 72 * to default_end_ip - default_start_ip + 1: */ 71 {"max_leases" , read_u32 , &server_config.max_leases, "235"},72 {"auto_time" , read_u32 , &server_config.auto_time, "7200"},73 {"decline_time" , read_u32 , &server_config.decline_time, "3600"},74 {"conflict_time", read_u32 , &server_config.conflict_time, "3600"},75 {"offer_time" , read_u32 , &server_config.offer_time, "60"},76 {"min_lease" , read_u32 , &server_config.min_lease_sec, "60"},77 {"lease_file" , read_str , &server_config.lease_file, LEASES_FILE},78 {"pidfile" , read_str , &server_config.pidfile, "/var/run/udhcpd.pid"},79 {"siaddr" , udhcp_str2nip , &server_config.siaddr_nip, "0.0.0.0"},73 {"max_leases" , read_u32 , OFS(max_leases ), "235"}, 74 {"auto_time" , read_u32 , OFS(auto_time ), "7200"}, 75 {"decline_time" , read_u32 , OFS(decline_time ), "3600"}, 76 {"conflict_time", read_u32 , OFS(conflict_time), "3600"}, 77 {"offer_time" , read_u32 , OFS(offer_time ), "60"}, 78 {"min_lease" , read_u32 , OFS(min_lease_sec), "60"}, 79 {"lease_file" , read_str , OFS(lease_file ), LEASES_FILE}, 80 {"pidfile" , read_str , OFS(pidfile ), "/var/run/udhcpd.pid"}, 81 {"siaddr" , udhcp_str2nip , OFS(siaddr_nip ), "0.0.0.0"}, 80 82 /* keywords with no defaults must be last! */ 81 {"option" , udhcp_str2optset, &server_config.options, ""},82 {"opt" , udhcp_str2optset, &server_config.options, ""},83 {"notify_file" , read_str , &server_config.notify_file, NULL},84 {"sname" , read_str , &server_config.sname, NULL},85 {"boot_file" , read_str , &server_config.boot_file, NULL},86 {"static_lease" , read_staticlease, &server_config.static_leases, ""},83 {"option" , udhcp_str2optset, OFS(options ), ""}, 84 {"opt" , udhcp_str2optset, OFS(options ), ""}, 85 {"notify_file" , read_str , OFS(notify_file ), NULL}, 86 {"sname" , read_str , OFS(sname ), NULL}, 87 {"boot_file" , read_str , OFS(boot_file ), NULL}, 88 {"static_lease" , read_staticlease, OFS(static_leases), ""}, 87 89 }; 88 90 enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 }; … … 96 98 97 99 for (i = 0; i < KWS_WITH_DEFAULTS; i++) 98 keywords[i].handler(keywords[i].def, keywords[i].var);100 keywords[i].handler(keywords[i].def, (char*)&server_config + keywords[i].ofs); 99 101 100 102 parser = config_open(file); … … 102 104 for (k = keywords, i = 0; i < ARRAY_SIZE(keywords); k++, i++) { 103 105 if (strcasecmp(token[0], k->keyword) == 0) { 104 if (!k->handler(token[1], k->var)) {106 if (!k->handler(token[1], (char*)&server_config + k->ofs)) { 105 107 bb_error_msg("can't parse line %u in %s", 106 108 parser->lineno, file); 107 109 /* reset back to the default value */ 108 k->handler(k->def, k->var);110 k->handler(k->def, (char*)&server_config + k->ofs); 109 111 } 110 112 break; … … 190 192 191 193 while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { 192 //FIXME: what if it matches some static lease?193 194 uint32_t y = ntohl(lease.lease_nip); 194 195 if (y >= server_config.start_ip && y <= server_config.end_ip) { 195 196 signed_leasetime_t expires = ntohl(lease.expires) - (signed_leasetime_t)time_passed; 197 uint32_t static_nip; 198 196 199 if (expires <= 0) 200 /* We keep expired leases: add_lease() will add 201 * a lease with 0 seconds remaining. 202 * Fewer IP address changes this way for mass reboot scenario. 203 */ 204 expires = 0; 205 206 /* Check if there is a different static lease for this IP or MAC */ 207 static_nip = get_static_nip_by_mac(server_config.static_leases, lease.lease_mac); 208 if (static_nip) { 209 /* NB: we do not add lease even if static_nip == lease.lease_nip. 210 */ 197 211 continue; 212 } 213 if (is_nip_reserved(server_config.static_leases, lease.lease_nip)) 214 continue; 215 198 216 /* NB: add_lease takes "relative time", IOW, 199 217 * lease duration, not lease deadline. */ … … 211 229 } 212 230 } 213 log1(" Read %d leases", i);231 log1("read %d leases", i); 214 232 ret: 215 233 close(fd); -
branches/3.3/mindi-busybox/networking/udhcp/leases.c
r3232 r3621 18 18 * and therefore can't ever match */ 19 19 for (i = 0; i < server_config.max_leases; i++) { 20 if (g_leases[i].expires < oldest_time) { 20 if (g_leases[i].expires == 0 /* empty entry */ 21 || g_leases[i].expires < oldest_time 22 ) { 21 23 oldest_time = g_leases[i].expires; 22 24 oldest_lease = &g_leases[i]; … … 66 68 hostname_len = sizeof(oldest->hostname); 67 69 p = safe_strncpy(oldest->hostname, hostname, hostname_len); 68 /* sanitization (s/non-ASCII/^/g) */ 70 /* 71 * Sanitization (s/bad_char/./g). 72 * The intent is not to allow only "DNS-valid" hostnames, 73 * but merely make dumpleases output safe for shells to use. 74 * We accept "0-9A-Za-z._-", all other chars turn to dots. 75 */ 69 76 while (*p) { 70 if ( *p < ' ' || *p > 126)71 *p = ' ^';77 if (!isalnum(*p) && *p != '-' && *p != '_') 78 *p = '.'; 72 79 p++; 73 80 } … … 113 120 114 121 /* Check if the IP is taken; if it is, add it to the lease table */ 115 static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac )122 static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac, unsigned arpping_ms) 116 123 { 117 124 struct in_addr temp; … … 121 128 server_config.server_nip, 122 129 server_config.server_mac, 123 server_config.interface); 130 server_config.interface, 131 arpping_ms); 124 132 if (r) 125 133 return r; 126 134 127 135 temp.s_addr = nip; 128 bb_ info_msg("%s belongs to someone, reserving it for %u seconds",136 bb_error_msg("%s belongs to someone, reserving it for %u seconds", 129 137 inet_ntoa(temp), (unsigned)server_config.conflict_time); 130 138 add_lease(NULL, nip, server_config.conflict_time, NULL, 0); … … 133 141 134 142 /* Find a new usable (we think) address */ 135 uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac )143 uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arpping_ms) 136 144 { 137 145 uint32_t addr; … … 178 186 if (!lease) { 179 187 //TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping! 180 if (nobody_responds_to_arp(nip, safe_mac ))188 if (nobody_responds_to_arp(nip, safe_mac, arpping_ms)) 181 189 return nip; 182 190 } else { … … 195 203 if (oldest_lease 196 204 && is_expired_lease(oldest_lease) 197 && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac )205 && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac, arpping_ms) 198 206 ) { 199 207 return oldest_lease->lease_nip; -
branches/3.3/mindi-busybox/networking/udhcp/packet.c
r3232 r3621 39 39 return; 40 40 41 bb_ info_msg(42 //" 41 bb_error_msg( 42 //"op %x" 43 43 //" htype %x" 44 44 " hlen %x" … … 74 74 ); 75 75 *bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0'; 76 bb_ info_msg("chaddr %s", buf);76 bb_error_msg("chaddr %s", buf); 77 77 } 78 78 #endif … … 86 86 bytes = safe_read(fd, packet, sizeof(*packet)); 87 87 if (bytes < 0) { 88 log1(" Packet read error, ignoring");88 log1("packet read error, ignoring"); 89 89 return bytes; /* returns -1 */ 90 90 } … … 93 93 || packet->cookie != htonl(DHCP_MAGIC) 94 94 ) { 95 bb_ info_msg("Packet with bad magic, ignoring");95 bb_error_msg("packet with bad magic, ignoring"); 96 96 return -2; 97 97 } 98 log1(" Receiveda packet");98 log1("received %s", "a packet"); 99 99 udhcp_dump_packet(packet); 100 100 … … 144 144 * In order to work with those buggy servers, 145 145 * we truncate packets after end option byte. 146 * 147 * However, RFC 1542 says "The IP Total Length and UDP Length 148 * must be large enough to contain the minimal BOOTP header of 300 octets". 149 * Thus, we retain enough padding to not go below 300 BOOTP bytes. 150 * Some devices have filters which drop DHCP packets shorter than that. 146 151 */ 147 152 padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(packet.data.options); 153 if (padding > DHCP_SIZE - 300) 154 padding = DHCP_SIZE - 300; 148 155 149 156 packet.ip.protocol = IPPROTO_UDP; … … 216 223 udhcp_dump_packet(dhcp_pkt); 217 224 padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(dhcp_pkt->options); 225 if (padding > DHCP_SIZE - 300) 226 padding = DHCP_SIZE - 300; 218 227 result = safe_write(fd, dhcp_pkt, DHCP_SIZE - padding); 219 228 msg = "write"; -
branches/3.3/mindi-busybox/networking/udhcp/socket.c
r3232 r3621 57 57 return -1; 58 58 } 59 log1(" Adapter index %d", ifr->ifr_ifindex);59 log1("adapter index %d", ifr->ifr_ifindex); 60 60 *ifindex = ifr->ifr_ifindex; 61 61 } … … 83 83 char *colon; 84 84 85 log1(" Opening listen socket on *:%d %s", port, inf);85 log1("opening listen socket on *:%d %s", port, inf); 86 86 fd = xsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 87 87 -
branches/3.3/mindi-busybox/networking/udhcp/static_leases.c
r2725 r3621 67 67 cur = *st_lease_pp; 68 68 while (cur) { 69 bb_ info_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x",69 bb_error_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x", 70 70 cur->mac[0], cur->mac[1], cur->mac[2], 71 71 cur->mac[3], cur->mac[4], cur->mac[5],
Note:
See TracChangeset
for help on using the changeset viewer.