1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <syslog.h>
28
29#define WANT_PIDFILE 1
30#include "common.h"
31#include "dhcpd.h"
32#include "dhcpc.h"
33
34#include <netinet/if_ether.h>
35#include <linux/filter.h>
36#include <linux/if_packet.h>
37
38#ifndef PACKET_AUXDATA
39# define PACKET_AUXDATA 8
40struct tpacket_auxdata {
41 uint32_t tp_status;
42 uint32_t tp_len;
43 uint32_t tp_snaplen;
44 uint16_t tp_mac;
45 uint16_t tp_net;
46 uint16_t tp_vlan_tci;
47 uint16_t tp_padding;
48};
49#endif
50
51
52
53
54
55#if ENABLE_LONG_OPTS
56static const char udhcpc_longopts[] ALIGN1 =
57 "clientid-none\0" No_argument "C"
58 "vendorclass\0" Required_argument "V"
59 "hostname\0" Required_argument "H"
60 "fqdn\0" Required_argument "F"
61 "interface\0" Required_argument "i"
62 "now\0" No_argument "n"
63 "pidfile\0" Required_argument "p"
64 "quit\0" No_argument "q"
65 "release\0" No_argument "R"
66 "request\0" Required_argument "r"
67 "script\0" Required_argument "s"
68 "timeout\0" Required_argument "T"
69 "retries\0" Required_argument "t"
70 "tryagain\0" Required_argument "A"
71 "syslog\0" No_argument "S"
72 "request-option\0" Required_argument "O"
73 "no-default-options\0" No_argument "o"
74 "foreground\0" No_argument "f"
75 USE_FOR_MMU(
76 "background\0" No_argument "b"
77 )
78 "broadcast\0" No_argument "B"
79 IF_FEATURE_UDHCPC_ARPING("arping\0" Optional_argument "a")
80 IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P")
81 ;
82#endif
83
84enum {
85 OPT_C = 1 << 0,
86 OPT_V = 1 << 1,
87 OPT_H = 1 << 2,
88 OPT_h = 1 << 3,
89 OPT_F = 1 << 4,
90 OPT_i = 1 << 5,
91 OPT_n = 1 << 6,
92 OPT_p = 1 << 7,
93 OPT_q = 1 << 8,
94 OPT_R = 1 << 9,
95 OPT_r = 1 << 10,
96 OPT_s = 1 << 11,
97 OPT_T = 1 << 12,
98 OPT_t = 1 << 13,
99 OPT_S = 1 << 14,
100 OPT_A = 1 << 15,
101 OPT_O = 1 << 16,
102 OPT_o = 1 << 17,
103 OPT_x = 1 << 18,
104 OPT_f = 1 << 19,
105 OPT_B = 1 << 20,
106
107 OPTBIT_B = 20,
108 USE_FOR_MMU( OPTBIT_b,)
109 IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,)
110 IF_FEATURE_UDHCP_PORT( OPTBIT_P,)
111 USE_FOR_MMU( OPT_b = 1 << OPTBIT_b,)
112 IF_FEATURE_UDHCPC_ARPING(OPT_a = 1 << OPTBIT_a,)
113 IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,)
114};
115
116
117
118
119
120static const uint8_t len_of_option_as_string[] ALIGN1 = {
121 [OPTION_IP ] = sizeof("255.255.255.255 "),
122 [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2,
123 [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "),
124 [OPTION_6RD ] = sizeof("132 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "),
125 [OPTION_STRING ] = 1,
126 [OPTION_STRING_HOST ] = 1,
127#if ENABLE_FEATURE_UDHCP_RFC3397
128 [OPTION_DNS_STRING ] = 1,
129
130
131
132
133 [OPTION_SIP_SERVERS ] = sizeof("255.255.255.255 "),
134#endif
135
136 [OPTION_U8 ] = sizeof("255 "),
137 [OPTION_U16 ] = sizeof("65535 "),
138
139 [OPTION_U32 ] = sizeof("4294967295 "),
140 [OPTION_S32 ] = sizeof("-2147483684 "),
141};
142
143
144static int sprint_nip(char *dest, const char *pre, const uint8_t *ip)
145{
146 return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]);
147}
148
149
150static int mton(uint32_t mask)
151{
152 int i = 0;
153 mask = ntohl(mask);
154 while (mask) {
155 i++;
156 mask <<= 1;
157 }
158 return i;
159}
160
161#if ENABLE_FEATURE_UDHCPC_SANITIZEOPT
162
163
164
165
166
167
168
169
170
171
172
173static const char *valid_domain_label(const char *label)
174{
175 unsigned char ch;
176 unsigned pos = 0;
177
178 for (;;) {
179 ch = *label;
180 if ((ch|0x20) < 'a' || (ch|0x20) > 'z') {
181 if (ch < '0' || ch > '9') {
182 if (ch == '\0' || ch == '.')
183 return label;
184
185 if (ch != '-' && ch != '_')
186 return NULL;
187 }
188 }
189 label++;
190 pos++;
191
192
193
194 }
195}
196
197
198
199static int good_hostname(const char *name)
200{
201
202
203 for (;;) {
204 name = valid_domain_label(name);
205 if (!name)
206 return 0;
207 if (!name[0])
208 return 1;
209
210
211 name++;
212 if (*name == '\0')
213 return 1;
214 }
215}
216#else
217# define good_hostname(name) 1
218#endif
219
220
221static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_optflag *optflag, const char *opt_name)
222{
223 unsigned upper_length;
224 int len, type, optlen;
225 char *dest, *ret;
226
227
228 len = option[-OPT_DATA + OPT_LEN];
229
230 type = optflag->flags & OPTION_TYPE_MASK;
231 optlen = dhcp_option_lengths[type];
232 upper_length = len_of_option_as_string[type]
233 * ((unsigned)(len + optlen) / (unsigned)optlen);
234
235 dest = ret = xmalloc(upper_length + strlen(opt_name) + 2);
236 dest += sprintf(ret, "%s=", opt_name);
237
238 while (len >= optlen) {
239 switch (type) {
240 case OPTION_IP:
241 case OPTION_IP_PAIR:
242 dest += sprint_nip(dest, "", option);
243 if (type == OPTION_IP)
244 break;
245 dest += sprint_nip(dest, "/", option + 4);
246 break;
247
248
249
250 case OPTION_U8:
251 dest += sprintf(dest, "%u", *option);
252 break;
253
254 case OPTION_U16: {
255 uint16_t val_u16;
256 move_from_unaligned16(val_u16, option);
257 dest += sprintf(dest, "%u", ntohs(val_u16));
258 break;
259 }
260 case OPTION_S32:
261 case OPTION_U32: {
262 uint32_t val_u32;
263 move_from_unaligned32(val_u32, option);
264 dest += sprintf(dest, type == OPTION_U32 ? "%lu" : "%ld", (unsigned long) ntohl(val_u32));
265 break;
266 }
267
268
269
270
271 case OPTION_STRING:
272 case OPTION_STRING_HOST:
273 memcpy(dest, option, len);
274 dest[len] = '\0';
275 if (type == OPTION_STRING_HOST && !good_hostname(dest))
276 safe_strncpy(dest, "bad", len);
277 return ret;
278 case OPTION_STATIC_ROUTES: {
279
280
281
282
283
284
285
286
287 const char *pfx = "";
288
289 while (len >= 1 + 4) {
290 uint32_t nip;
291 uint8_t *p;
292 unsigned mask;
293 int bytes;
294
295 mask = *option++;
296 if (mask > 32)
297 break;
298 len--;
299
300 nip = 0;
301 p = (void*) &nip;
302 bytes = (mask + 7) / 8;
303 while (--bytes >= 0) {
304 *p++ = *option++;
305 len--;
306 }
307 if (len < 4)
308 break;
309
310
311 dest += sprint_nip(dest, pfx, (void*) &nip);
312 pfx = " ";
313 dest += sprintf(dest, "/%u ", mask);
314
315 dest += sprint_nip(dest, "", option);
316 option += 4;
317 len -= 4;
318 }
319
320 return ret;
321 }
322 case OPTION_6RD:
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344 if (len >= (1 + 1 + 16 + 4)
345 && option[0] <= 32
346 && (option[1] + 32 - option[0]) <= 128
347 ) {
348
349 dest += sprintf(dest, "%u ", *option++);
350
351 dest += sprintf(dest, "%u ", *option++);
352
353 dest += sprint_nip6(dest, option);
354 option += 16;
355 len -= 1 + 1 + 16 + 4;
356
357
358 while (1) {
359
360 dest += sprint_nip(dest, " ", option);
361 option += 4;
362 len -= 4;
363 if (len < 0)
364 break;
365 }
366 }
367
368 return ret;
369#if ENABLE_FEATURE_UDHCP_RFC3397
370 case OPTION_DNS_STRING:
371
372 dest = dname_dec(option, len, ret);
373 if (dest) {
374 free(ret);
375 return dest;
376 }
377
378 return ret;
379 case OPTION_SIP_SERVERS:
380
381
382
383
384
385 option++;
386 len--;
387 if (option[-1] == 0) {
388 dest = dname_dec(option, len, ret);
389 if (dest) {
390 free(ret);
391 return dest;
392 }
393 } else
394 if (option[-1] == 1) {
395 const char *pfx = "";
396 while (1) {
397 len -= 4;
398 if (len < 0)
399 break;
400 dest += sprint_nip(dest, pfx, option);
401 pfx = " ";
402 option += 4;
403 }
404 }
405 return ret;
406#endif
407 }
408
409
410
411
412 option += optlen;
413 len -= optlen;
414
415
416
417 if (len < optlen )
418 break;
419 *dest++ = ' ';
420 *dest = '\0';
421 }
422
423 return ret;
424}
425
426
427static char **fill_envp(struct dhcp_packet *packet)
428{
429 int envc;
430 int i;
431 char **envp, **curr;
432 const char *opt_name;
433 uint8_t *temp;
434 uint8_t overload = 0;
435
436#define BITMAP unsigned
437#define BBITS (sizeof(BITMAP) * 8)
438#define BMASK(i) (1 << (i & (sizeof(BITMAP) * 8 - 1)))
439#define FOUND_OPTS(i) (found_opts[(unsigned)i / BBITS])
440 BITMAP found_opts[256 / BBITS];
441
442 memset(found_opts, 0, sizeof(found_opts));
443
444
445
446
447
448
449
450
451
452 envc = 6;
453
454 if (packet) {
455
456
457 for (i = 1; i < 255; i++) {
458 temp = udhcp_get_option(packet, i);
459 if (temp) {
460 if (i == DHCP_OPTION_OVERLOAD)
461 overload |= *temp;
462 else if (i == DHCP_SUBNET)
463 envc++;
464 envc++;
465
466 FOUND_OPTS(i) |= BMASK(i);
467 }
468 }
469 }
470 curr = envp = xzalloc(sizeof(envp[0]) * envc);
471
472 *curr = xasprintf("interface=%s", client_config.interface);
473 putenv(*curr++);
474
475 if (!packet)
476 return envp;
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493 *curr = xmalloc(sizeof("ip=255.255.255.255"));
494 sprint_nip(*curr, "ip=", (uint8_t *) &packet->yiaddr);
495 putenv(*curr++);
496 if (packet->siaddr_nip) {
497
498 *curr = xmalloc(sizeof("siaddr=255.255.255.255"));
499 sprint_nip(*curr, "siaddr=", (uint8_t *) &packet->siaddr_nip);
500 putenv(*curr++);
501 }
502 if (!(overload & FILE_FIELD) && packet->file[0]) {
503
504 *curr = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file);
505 putenv(*curr++);
506 }
507 if (!(overload & SNAME_FIELD) && packet->sname[0]) {
508
509 *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname);
510 putenv(*curr++);
511 }
512
513
514 opt_name = dhcp_option_strings;
515 i = 0;
516 while (*opt_name) {
517 uint8_t code = dhcp_optflags[i].code;
518 BITMAP *found_ptr = &FOUND_OPTS(code);
519 BITMAP found_mask = BMASK(code);
520 if (!(*found_ptr & found_mask))
521 goto next;
522 *found_ptr &= ~found_mask;
523 temp = udhcp_get_option(packet, code);
524 *curr = xmalloc_optname_optval(temp, &dhcp_optflags[i], opt_name);
525 putenv(*curr++);
526 if (code == DHCP_SUBNET) {
527
528 uint32_t subnet;
529 move_from_unaligned32(subnet, temp);
530 *curr = xasprintf("mask=%u", mton(subnet));
531 putenv(*curr++);
532 }
533 next:
534 opt_name += strlen(opt_name) + 1;
535 i++;
536 }
537
538 for (i = 0; i < 256;) {
539 BITMAP bitmap = FOUND_OPTS(i);
540 if (!bitmap) {
541 i += BBITS;
542 continue;
543 }
544 if (bitmap & BMASK(i)) {
545 unsigned len, ofs;
546
547 temp = udhcp_get_option(packet, i);
548
549
550
551 len = temp[-OPT_DATA + OPT_LEN];
552 *curr = xmalloc(sizeof("optNNN=") + 1 + len*2);
553 ofs = sprintf(*curr, "opt%u=", i);
554 *bin2hex(*curr + ofs, (void*) temp, len) = '\0';
555 putenv(*curr++);
556 }
557 i++;
558 }
559
560 return envp;
561}
562
563
564static void udhcp_run_script(struct dhcp_packet *packet, const char *name)
565{
566 char **envp, **curr;
567 char *argv[3];
568
569 envp = fill_envp(packet);
570
571
572 log1("executing %s %s", client_config.script, name);
573 argv[0] = (char*) client_config.script;
574 argv[1] = (char*) name;
575 argv[2] = NULL;
576 spawn_and_wait(argv);
577
578 for (curr = envp; *curr; curr++) {
579 log2(" %s", *curr);
580 bb_unsetenv_and_free(*curr);
581 }
582 free(envp);
583}
584
585
586
587
588static ALWAYS_INLINE uint32_t random_xid(void)
589{
590 return rand();
591}
592
593
594static void init_packet(struct dhcp_packet *packet, char type)
595{
596 uint16_t secs;
597
598
599 udhcp_init_header(packet, type);
600
601 packet->xid = random_xid();
602
603 client_config.last_secs = monotonic_sec();
604 if (client_config.first_secs == 0)
605 client_config.first_secs = client_config.last_secs;
606 secs = client_config.last_secs - client_config.first_secs;
607 packet->secs = htons(secs);
608
609 memcpy(packet->chaddr, client_config.client_mac, 6);
610 if (client_config.clientid)
611 udhcp_add_binary_option(packet, client_config.clientid);
612}
613
614static void add_client_options(struct dhcp_packet *packet)
615{
616 int i, end, len;
617
618 udhcp_add_simple_option(packet, DHCP_MAX_SIZE, htons(IP_UDP_DHCP_SIZE));
619
620
621
622
623 end = udhcp_end_option(packet->options);
624 len = 0;
625 for (i = 1; i < DHCP_END; i++) {
626 if (client_config.opt_mask[i >> 3] & (1 << (i & 7))) {
627 packet->options[end + OPT_DATA + len] = i;
628 len++;
629 }
630 }
631 if (len) {
632 packet->options[end + OPT_CODE] = DHCP_PARAM_REQ;
633 packet->options[end + OPT_LEN] = len;
634 packet->options[end + OPT_DATA + len] = DHCP_END;
635 }
636
637 if (client_config.vendorclass)
638 udhcp_add_binary_option(packet, client_config.vendorclass);
639 if (client_config.hostname)
640 udhcp_add_binary_option(packet, client_config.hostname);
641 if (client_config.fqdn)
642 udhcp_add_binary_option(packet, client_config.fqdn);
643
644
645 if ((option_mask32 & OPT_B) && packet->ciaddr == 0)
646 packet->flags |= htons(BROADCAST_FLAG);
647
648
649 {
650 struct option_set *curr = client_config.options;
651 while (curr) {
652 udhcp_add_binary_option(packet, curr->data);
653 curr = curr->next;
654 }
655
656
657
658
659 }
660
661
662
663
664
665
666}
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet, uint32_t src_nip)
687{
688 return udhcp_send_raw_packet(packet,
689 src_nip, CLIENT_PORT,
690 INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR,
691 client_config.ifindex);
692}
693
694static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server)
695{
696 if (server)
697 return udhcp_send_kernel_packet(packet,
698 ciaddr, CLIENT_PORT,
699 server, SERVER_PORT);
700 return raw_bcast_from_client_config_ifindex(packet, ciaddr);
701}
702
703
704
705static NOINLINE int send_discover(uint32_t xid, uint32_t requested)
706{
707 struct dhcp_packet packet;
708
709
710
711
712
713 init_packet(&packet, DHCPDISCOVER);
714
715 packet.xid = xid;
716 if (requested)
717 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
718
719
720
721
722
723 add_client_options(&packet);
724
725 bb_error_msg("sending %s", "discover");
726 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY);
727}
728
729
730
731
732
733
734static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requested)
735{
736 struct dhcp_packet packet;
737 struct in_addr temp_addr;
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755 init_packet(&packet, DHCPREQUEST);
756
757 packet.xid = xid;
758 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
759
760 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
761
762
763
764
765
766 add_client_options(&packet);
767
768 temp_addr.s_addr = requested;
769 bb_error_msg("sending select for %s", inet_ntoa(temp_addr));
770 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY);
771}
772
773
774
775static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
776{
777 struct dhcp_packet packet;
778 struct in_addr temp_addr;
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798 init_packet(&packet, DHCPREQUEST);
799
800 packet.xid = xid;
801 packet.ciaddr = ciaddr;
802
803
804
805
806
807 add_client_options(&packet);
808
809 temp_addr.s_addr = server;
810 bb_error_msg("sending renew to %s", inet_ntoa(temp_addr));
811 return bcast_or_ucast(&packet, ciaddr, server);
812}
813
814#if ENABLE_FEATURE_UDHCPC_ARPING
815
816
817static NOINLINE int send_decline( uint32_t server, uint32_t requested)
818{
819 struct dhcp_packet packet;
820
821
822
823
824 init_packet(&packet, DHCPDECLINE);
825
826#if 0
827
828
829
830
831
832 packet.xid = xid;
833#endif
834
835 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
836
837 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
838
839 bb_error_msg("sending %s", "decline");
840 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY);
841}
842#endif
843
844
845static int send_release(uint32_t server, uint32_t ciaddr)
846{
847 struct dhcp_packet packet;
848
849
850
851
852 init_packet(&packet, DHCPRELEASE);
853
854
855 packet.ciaddr = ciaddr;
856
857 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
858
859 bb_error_msg("sending %s", "release");
860
861
862
863
864 return bcast_or_ucast(&packet, ciaddr, server);
865}
866
867
868
869static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd)
870{
871 int bytes;
872 struct ip_udp_dhcp_packet packet;
873 uint16_t check;
874 unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
875 struct iovec iov;
876 struct msghdr msg;
877 struct cmsghdr *cmsg;
878
879
880
881
882 iov.iov_base = &packet;
883 iov.iov_len = sizeof(packet);
884 memset(&msg, 0, sizeof(msg));
885 msg.msg_iov = &iov;
886 msg.msg_iovlen = 1;
887 msg.msg_control = cmsgbuf;
888 msg.msg_controllen = sizeof(cmsgbuf);
889 for (;;) {
890 bytes = recvmsg(fd, &msg, 0);
891 if (bytes < 0) {
892 if (errno == EINTR)
893 continue;
894 log1("packet read error, ignoring");
895
896 return bytes;
897 }
898 break;
899 }
900
901 if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) {
902 log1("packet is too short, ignoring");
903 return -2;
904 }
905
906 if (bytes < ntohs(packet.ip.tot_len)) {
907
908 log1("oversized packet, ignoring");
909 return -2;
910 }
911
912
913 bytes = ntohs(packet.ip.tot_len);
914
915
916 if (packet.ip.protocol != IPPROTO_UDP
917 || packet.ip.version != IPVERSION
918 || packet.ip.ihl != (sizeof(packet.ip) >> 2)
919 || packet.udp.dest != htons(CLIENT_PORT)
920
921 || ntohs(packet.udp.len) != (uint16_t)(bytes - sizeof(packet.ip))
922 ) {
923 log1("unrelated/bogus packet, ignoring");
924 return -2;
925 }
926
927
928 check = packet.ip.check;
929 packet.ip.check = 0;
930 if (check != inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip))) {
931 log1("bad IP header checksum, ignoring");
932 return -2;
933 }
934
935 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
936 if (cmsg->cmsg_level == SOL_PACKET
937 && cmsg->cmsg_type == PACKET_AUXDATA
938 ) {
939
940
941
942
943 struct tpacket_auxdata *aux = (void *)CMSG_DATA(cmsg);
944 if (aux->tp_status & TP_STATUS_CSUMNOTREADY)
945 goto skip_udp_sum_check;
946 }
947 }
948
949
950 memset(&packet.ip, 0, offsetof(struct iphdr, protocol));
951
952 packet.ip.tot_len = packet.udp.len;
953 check = packet.udp.check;
954 packet.udp.check = 0;
955 if (check && check != inet_cksum((uint16_t *)&packet, bytes)) {
956 log1("packet with bad UDP checksum received, ignoring");
957 return -2;
958 }
959 skip_udp_sum_check:
960
961 if (packet.data.cookie != htonl(DHCP_MAGIC)) {
962 bb_error_msg("packet with bad magic, ignoring");
963 return -2;
964 }
965
966 log1("received %s", "a packet");
967 udhcp_dump_packet(&packet.data);
968
969 bytes -= sizeof(packet.ip) + sizeof(packet.udp);
970 memcpy(dhcp_pkt, &packet.data, bytes);
971 return bytes;
972}
973
974
975
976
977static int sockfd = -1;
978
979#define LISTEN_NONE 0
980#define LISTEN_KERNEL 1
981#define LISTEN_RAW 2
982static smallint listen_mode;
983
984
985#define INIT_SELECTING 0
986
987#define REQUESTING 1
988
989#define BOUND 2
990
991#define RENEWING 3
992
993#define REBINDING 4
994
995#define RENEW_REQUESTED 5
996
997#define RELEASED 6
998static smallint state;
999
1000static int udhcp_raw_socket(int ifindex)
1001{
1002 int fd;
1003 struct sockaddr_ll sock;
1004
1005 log2("opening raw socket on ifindex %d", ifindex);
1006
1007 fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
1008
1009
1010
1011
1012 log2("got raw socket fd");
1013
1014 memset(&sock, 0, sizeof(sock));
1015 sock.sll_family = AF_PACKET;
1016 sock.sll_protocol = htons(ETH_P_IP);
1017 sock.sll_ifindex = ifindex;
1018
1019
1020
1021
1022 xbind(fd, (struct sockaddr *) &sock, sizeof(sock));
1023
1024#if 0
1025 if (CLIENT_PORT == 68) {
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044 static const struct sock_filter filter_instr[] = {
1045
1046 BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9),
1047
1048 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6),
1049
1050 BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6),
1051
1052 BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0),
1053
1054 BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0),
1055
1056 BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2),
1057
1058 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1),
1059
1060
1061 BPF_STMT(BPF_RET|BPF_K, 0x7fffffff),
1062
1063 BPF_STMT(BPF_RET|BPF_K, 0),
1064 };
1065 static const struct sock_fprog filter_prog = {
1066 .len = sizeof(filter_instr) / sizeof(filter_instr[0]),
1067
1068 .filter = (struct sock_filter *) filter_instr,
1069 };
1070
1071 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog,
1072 sizeof(filter_prog)) >= 0)
1073 log1("attached filter to raw socket fd");
1074 }
1075#endif
1076
1077 if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) {
1078 if (errno != ENOPROTOOPT)
1079 log1("can't set PACKET_AUXDATA on raw socket");
1080 }
1081
1082 log1("created raw socket");
1083
1084 return fd;
1085}
1086
1087static void change_listen_mode(int new_mode)
1088{
1089 log1("entering listen mode: %s",
1090 new_mode != LISTEN_NONE
1091 ? (new_mode == LISTEN_KERNEL ? "kernel" : "raw")
1092 : "none"
1093 );
1094
1095 listen_mode = new_mode;
1096 if (sockfd >= 0) {
1097 close(sockfd);
1098 sockfd = -1;
1099 }
1100 if (new_mode == LISTEN_KERNEL)
1101 sockfd = udhcp_listen_socket( CLIENT_PORT, client_config.interface);
1102 else if (new_mode != LISTEN_NONE)
1103 sockfd = udhcp_raw_socket(client_config.ifindex);
1104
1105}
1106
1107
1108static void perform_renew(void)
1109{
1110 bb_error_msg("performing DHCP renew");
1111 switch (state) {
1112 case BOUND:
1113 change_listen_mode(LISTEN_KERNEL);
1114 case RENEWING:
1115 case REBINDING:
1116 state = RENEW_REQUESTED;
1117 break;
1118 case RENEW_REQUESTED:
1119 udhcp_run_script(NULL, "deconfig");
1120 case REQUESTING:
1121 case RELEASED:
1122 change_listen_mode(LISTEN_RAW);
1123 state = INIT_SELECTING;
1124 break;
1125 case INIT_SELECTING:
1126 break;
1127 }
1128}
1129
1130static void perform_release(uint32_t server_addr, uint32_t requested_ip)
1131{
1132 char buffer[sizeof("255.255.255.255")];
1133 struct in_addr temp_addr;
1134
1135
1136 if (state == BOUND
1137 || state == RENEWING
1138 || state == REBINDING
1139 || state == RENEW_REQUESTED
1140 ) {
1141 temp_addr.s_addr = server_addr;
1142 strcpy(buffer, inet_ntoa(temp_addr));
1143 temp_addr.s_addr = requested_ip;
1144 bb_error_msg("unicasting a release of %s to %s",
1145 inet_ntoa(temp_addr), buffer);
1146 send_release(server_addr, requested_ip);
1147 }
1148 bb_error_msg("entering released state");
1149
1150
1151
1152
1153
1154
1155 udhcp_run_script(NULL, "deconfig");
1156
1157 change_listen_mode(LISTEN_NONE);
1158 state = RELEASED;
1159}
1160
1161static uint8_t* alloc_dhcp_option(int code, const char *str, int extra)
1162{
1163 uint8_t *storage;
1164 int len = strnlen(str, 255);
1165 storage = xzalloc(len + extra + OPT_DATA);
1166 storage[OPT_CODE] = code;
1167 storage[OPT_LEN] = len + extra;
1168 memcpy(storage + extra + OPT_DATA, str, len);
1169 return storage;
1170}
1171
1172#if BB_MMU
1173static void client_background(void)
1174{
1175 bb_daemonize(0);
1176 logmode &= ~LOGMODE_STDIO;
1177
1178 write_pidfile(client_config.pidfile);
1179}
1180#endif
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233int udhcpc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1234int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1235{
1236 uint8_t *message;
1237 const char *str_V, *str_h, *str_F, *str_r;
1238 IF_FEATURE_UDHCPC_ARPING(const char *str_a = "2000";)
1239 IF_FEATURE_UDHCP_PORT(char *str_P;)
1240 void *clientid_mac_ptr;
1241 llist_t *list_O = NULL;
1242 llist_t *list_x = NULL;
1243 int tryagain_timeout = 20;
1244 int discover_timeout = 3;
1245 int discover_retries = 3;
1246 uint32_t server_addr = server_addr;
1247 uint32_t requested_ip = 0;
1248 uint32_t xid = xid;
1249 int packet_num;
1250 int timeout;
1251 unsigned already_waited_sec;
1252 unsigned opt;
1253 IF_FEATURE_UDHCPC_ARPING(unsigned arpping_ms;)
1254 int retval;
1255
1256 setup_common_bufsiz();
1257
1258
1259 IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;)
1260 IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;)
1261 client_config.interface = "eth0";
1262 client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT;
1263 str_V = "udhcp "BB_VER;
1264
1265
1266 opt = getopt32long(argv, "^"
1267
1268 "CV:H:h:F:i:np:qRr:s:T:+t:+SA:+O:*ox:*fB"
1269 USE_FOR_MMU("b")
1270 IF_FEATURE_UDHCPC_ARPING("a::")
1271 IF_FEATURE_UDHCP_PORT("P:")
1272 "v"
1273 "\0" IF_UDHCP_VERBOSE("vv")
1274 , udhcpc_longopts
1275 , &str_V, &str_h, &str_h, &str_F
1276 , &client_config.interface, &client_config.pidfile
1277 , &str_r
1278 , &client_config.script
1279 , &discover_timeout, &discover_retries, &tryagain_timeout
1280 , &list_O
1281 , &list_x
1282 IF_FEATURE_UDHCPC_ARPING(, &str_a)
1283 IF_FEATURE_UDHCP_PORT(, &str_P)
1284 IF_UDHCP_VERBOSE(, &dhcp_verbose)
1285 );
1286 if (opt & (OPT_h|OPT_H)) {
1287
1288 bb_error_msg("option -h NAME is deprecated, use -x hostname:NAME");
1289 client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0);
1290 }
1291 if (opt & OPT_F) {
1292
1293 client_config.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3);
1294
1295
1296
1297
1298
1299
1300
1301
1302 client_config.fqdn[OPT_DATA + 0] = 0x1;
1303
1304
1305 }
1306 if (opt & OPT_r)
1307 requested_ip = inet_addr(str_r);
1308#if ENABLE_FEATURE_UDHCP_PORT
1309 if (opt & OPT_P) {
1310 CLIENT_PORT = xatou16(str_P);
1311 SERVER_PORT = CLIENT_PORT - 1;
1312 }
1313#endif
1314 IF_FEATURE_UDHCPC_ARPING(arpping_ms = xatou(str_a);)
1315 while (list_O) {
1316 char *optstr = llist_pop(&list_O);
1317 unsigned n = bb_strtou(optstr, NULL, 0);
1318 if (errno || n > 254) {
1319 n = udhcp_option_idx(optstr, dhcp_option_strings);
1320 n = dhcp_optflags[n].code;
1321 }
1322 client_config.opt_mask[n >> 3] |= 1 << (n & 7);
1323 }
1324 if (!(opt & OPT_o)) {
1325 unsigned i, n;
1326 for (i = 0; (n = dhcp_optflags[i].code) != 0; i++) {
1327 if (dhcp_optflags[i].flags & OPTION_REQ) {
1328 client_config.opt_mask[n >> 3] |= 1 << (n & 7);
1329 }
1330 }
1331 }
1332 while (list_x) {
1333 char *optstr = xstrdup(llist_pop(&list_x));
1334 udhcp_str2optset(optstr, &client_config.options,
1335 dhcp_optflags, dhcp_option_strings,
1336 0
1337 );
1338 free(optstr);
1339 }
1340
1341 if (udhcp_read_interface(client_config.interface,
1342 &client_config.ifindex,
1343 NULL,
1344 client_config.client_mac)
1345 ) {
1346 return 1;
1347 }
1348
1349 clientid_mac_ptr = NULL;
1350 if (!(opt & OPT_C) && !udhcp_find_option(client_config.options, DHCP_CLIENT_ID)) {
1351
1352 client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7);
1353 client_config.clientid[OPT_DATA] = 1;
1354 clientid_mac_ptr = client_config.clientid + OPT_DATA+1;
1355 memcpy(clientid_mac_ptr, client_config.client_mac, 6);
1356 }
1357 if (str_V[0] != '\0') {
1358
1359
1360
1361
1362
1363
1364 client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0);
1365 }
1366
1367#if !BB_MMU
1368
1369 if (!(opt & OPT_f)) {
1370 bb_daemonize_or_rexec(0 , argv);
1371 logmode = LOGMODE_NONE;
1372 }
1373#endif
1374 if (opt & OPT_S) {
1375 openlog(applet_name, LOG_PID, LOG_DAEMON);
1376 logmode |= LOGMODE_SYSLOG;
1377 }
1378
1379
1380 bb_sanitize_stdio();
1381
1382 write_pidfile(client_config.pidfile);
1383
1384 bb_error_msg("started, v"BB_VER);
1385
1386 udhcp_sp_setup();
1387
1388 srand(monotonic_us());
1389
1390 state = INIT_SELECTING;
1391 udhcp_run_script(NULL, "deconfig");
1392 change_listen_mode(LISTEN_RAW);
1393 packet_num = 0;
1394 timeout = 0;
1395 already_waited_sec = 0;
1396
1397
1398
1399
1400
1401 for (;;) {
1402 int tv;
1403 struct pollfd pfds[2];
1404 struct dhcp_packet packet;
1405
1406 unsigned timestamp_before_wait = timestamp_before_wait;
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417 udhcp_sp_fd_set(pfds, sockfd);
1418
1419 tv = timeout - already_waited_sec;
1420 retval = 0;
1421
1422 if (tv > 0) {
1423 log1("waiting %u seconds", tv);
1424 timestamp_before_wait = (unsigned)monotonic_sec();
1425 retval = poll(pfds, 2, tv < INT_MAX/1000 ? tv * 1000 : INT_MAX);
1426 if (retval < 0) {
1427
1428 if (errno == EINTR) {
1429 already_waited_sec += (unsigned)monotonic_sec() - timestamp_before_wait;
1430 continue;
1431 }
1432
1433 bb_perror_msg_and_die("poll");
1434 }
1435 }
1436
1437
1438
1439
1440 if (retval == 0) {
1441
1442
1443
1444
1445
1446 if (udhcp_read_interface(client_config.interface,
1447 &client_config.ifindex,
1448 NULL,
1449 client_config.client_mac)
1450 ) {
1451 goto ret0;
1452 }
1453 if (clientid_mac_ptr)
1454 memcpy(clientid_mac_ptr, client_config.client_mac, 6);
1455
1456
1457 already_waited_sec = 0;
1458
1459 switch (state) {
1460 case INIT_SELECTING:
1461 if (!discover_retries || packet_num < discover_retries) {
1462 if (packet_num == 0)
1463 xid = random_xid();
1464
1465 send_discover(xid, requested_ip);
1466 timeout = discover_timeout;
1467 packet_num++;
1468 continue;
1469 }
1470 leasefail:
1471 udhcp_run_script(NULL, "leasefail");
1472#if BB_MMU
1473 if (opt & OPT_b) {
1474 bb_error_msg("no lease, forking to background");
1475 client_background();
1476
1477 opt = ((opt & ~OPT_b) | OPT_f);
1478 } else
1479#endif
1480 if (opt & OPT_n) {
1481 bb_error_msg("no lease, failing");
1482 retval = 1;
1483 goto ret;
1484 }
1485
1486 timeout = tryagain_timeout;
1487 packet_num = 0;
1488 continue;
1489 case REQUESTING:
1490 if (packet_num < 3) {
1491
1492 send_select(xid, server_addr, requested_ip);
1493 timeout = discover_timeout;
1494 packet_num++;
1495 continue;
1496 }
1497
1498
1499
1500
1501 change_listen_mode(LISTEN_RAW);
1502 state = INIT_SELECTING;
1503 goto leasefail;
1504 case BOUND:
1505
1506 state = RENEWING;
1507 client_config.first_secs = 0;
1508 change_listen_mode(LISTEN_KERNEL);
1509 log1("entering renew state");
1510
1511 case RENEW_REQUESTED:
1512 case_RENEW_REQUESTED:
1513 case RENEWING:
1514 if (timeout > 60) {
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524 if (send_renew(xid, server_addr, requested_ip) >= 0) {
1525 timeout >>= 1;
1526
1527
1528
1529
1530
1531
1532
1533 continue;
1534 }
1535
1536
1537
1538
1539
1540 }
1541
1542 log1("entering rebinding state");
1543 state = REBINDING;
1544
1545 case REBINDING:
1546
1547 change_listen_mode(LISTEN_RAW);
1548
1549
1550 if (timeout > 0) {
1551
1552 send_renew(xid, 0 , requested_ip);
1553 timeout >>= 1;
1554 continue;
1555 }
1556
1557 bb_error_msg("lease lost, entering init state");
1558 udhcp_run_script(NULL, "deconfig");
1559 state = INIT_SELECTING;
1560 client_config.first_secs = 0;
1561
1562 packet_num = 0;
1563 continue;
1564
1565 }
1566
1567 timeout = INT_MAX;
1568 continue;
1569 }
1570
1571
1572
1573
1574 switch (udhcp_sp_read()) {
1575 case SIGUSR1:
1576 client_config.first_secs = 0;
1577 already_waited_sec = 0;
1578 perform_renew();
1579 if (state == RENEW_REQUESTED) {
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590 if (timeout > tryagain_timeout)
1591 timeout = tryagain_timeout;
1592 goto case_RENEW_REQUESTED;
1593 }
1594
1595 packet_num = 0;
1596
1597 timeout = 0;
1598 continue;
1599 case SIGUSR2:
1600 perform_release(server_addr, requested_ip);
1601 timeout = INT_MAX;
1602 continue;
1603 case SIGTERM:
1604 bb_error_msg("received %s", "SIGTERM");
1605 goto ret0;
1606 }
1607
1608
1609 if (!pfds[1].revents)
1610 continue;
1611
1612 {
1613 int len;
1614
1615
1616 if (listen_mode == LISTEN_KERNEL)
1617 len = udhcp_recv_kernel_packet(&packet, sockfd);
1618 else
1619 len = udhcp_recv_raw_packet(&packet, sockfd);
1620 if (len == -1) {
1621
1622 bb_error_msg("read error: "STRERROR_FMT", reopening socket" STRERROR_ERRNO);
1623 sleep(discover_timeout);
1624 change_listen_mode(listen_mode);
1625 }
1626
1627
1628
1629 already_waited_sec += (unsigned)monotonic_sec() - timestamp_before_wait;
1630 if (len < 0)
1631 continue;
1632 }
1633
1634 if (packet.xid != xid) {
1635 log1("xid %x (our is %x), ignoring packet",
1636 (unsigned)packet.xid, (unsigned)xid);
1637 continue;
1638 }
1639
1640
1641 if (packet.hlen != 6
1642 || memcmp(packet.chaddr, client_config.client_mac, 6) != 0
1643 ) {
1644
1645 log1("chaddr does not match, ignoring packet");
1646 continue;
1647 }
1648
1649 message = udhcp_get_option(&packet, DHCP_MESSAGE_TYPE);
1650 if (message == NULL) {
1651 bb_error_msg("no message type option, ignoring packet");
1652 continue;
1653 }
1654
1655 switch (state) {
1656 case INIT_SELECTING:
1657
1658 if (*message == DHCPOFFER) {
1659 uint8_t *temp;
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685 server_addr = 0;
1686 temp = udhcp_get_option(&packet, DHCP_SERVER_ID);
1687 if (!temp) {
1688 bb_error_msg("no server ID, using 0.0.0.0");
1689 } else {
1690
1691 move_from_unaligned32(server_addr, temp);
1692 }
1693
1694 requested_ip = packet.yiaddr;
1695
1696
1697 state = REQUESTING;
1698 timeout = 0;
1699 packet_num = 0;
1700 already_waited_sec = 0;
1701 }
1702 continue;
1703 case REQUESTING:
1704 case RENEWING:
1705 case RENEW_REQUESTED:
1706 case REBINDING:
1707 if (*message == DHCPACK) {
1708 unsigned start;
1709 uint32_t lease_seconds;
1710 struct in_addr temp_addr;
1711 uint8_t *temp;
1712
1713 temp = udhcp_get_option(&packet, DHCP_LEASE_TIME);
1714 if (!temp) {
1715 bb_error_msg("no lease time with ACK, using 1 hour lease");
1716 lease_seconds = 60 * 60;
1717 } else {
1718
1719 move_from_unaligned32(lease_seconds, temp);
1720 lease_seconds = ntohl(lease_seconds);
1721
1722 if (lease_seconds < 0x10)
1723 lease_seconds = 0x10;
1724
1725
1726
1727
1728 }
1729#if ENABLE_FEATURE_UDHCPC_ARPING
1730 if (opt & OPT_a) {
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740 if (!arpping(packet.yiaddr,
1741 NULL,
1742 (uint32_t) 0,
1743 client_config.client_mac,
1744 client_config.interface,
1745 arpping_ms)
1746 ) {
1747 bb_error_msg("offered address is in use "
1748 "(got ARP reply), declining");
1749 send_decline( server_addr, packet.yiaddr);
1750
1751 if (state != REQUESTING)
1752 udhcp_run_script(NULL, "deconfig");
1753 change_listen_mode(LISTEN_RAW);
1754 state = INIT_SELECTING;
1755 client_config.first_secs = 0;
1756 requested_ip = 0;
1757 timeout = tryagain_timeout;
1758 packet_num = 0;
1759 already_waited_sec = 0;
1760 continue;
1761 }
1762 }
1763#endif
1764
1765 temp_addr.s_addr = packet.yiaddr;
1766 bb_error_msg("lease of %s obtained, lease time %u",
1767 inet_ntoa(temp_addr), (unsigned)lease_seconds);
1768 requested_ip = packet.yiaddr;
1769
1770 start = monotonic_sec();
1771 udhcp_run_script(&packet, state == REQUESTING ? "bound" : "renew");
1772 already_waited_sec = (unsigned)monotonic_sec() - start;
1773 timeout = lease_seconds / 2;
1774 if ((unsigned)timeout < already_waited_sec) {
1775
1776 timeout = already_waited_sec = 0;
1777 }
1778
1779 state = BOUND;
1780 change_listen_mode(LISTEN_NONE);
1781 if (opt & OPT_q) {
1782 goto ret0;
1783 }
1784
1785 opt &= ~OPT_n;
1786#if BB_MMU
1787 if (!(opt & OPT_f)) {
1788 client_background();
1789
1790 opt = ((opt & ~OPT_b) | OPT_f);
1791 }
1792#endif
1793
1794
1795
1796 continue;
1797 }
1798 if (*message == DHCPNAK) {
1799
1800
1801
1802
1803 if (server_addr != 0) {
1804 uint32_t svid;
1805 uint8_t *temp;
1806
1807 temp = udhcp_get_option(&packet, DHCP_SERVER_ID);
1808 if (!temp) {
1809 non_matching_svid:
1810 log1("received DHCP NAK with wrong"
1811 " server ID, ignoring packet");
1812 continue;
1813 }
1814 move_from_unaligned32(svid, temp);
1815 if (svid != server_addr)
1816 goto non_matching_svid;
1817 }
1818
1819 bb_error_msg("received %s", "DHCP NAK");
1820 udhcp_run_script(&packet, "nak");
1821 if (state != REQUESTING)
1822 udhcp_run_script(NULL, "deconfig");
1823 change_listen_mode(LISTEN_RAW);
1824 sleep(3);
1825 state = INIT_SELECTING;
1826 client_config.first_secs = 0;
1827 requested_ip = 0;
1828 timeout = 0;
1829 packet_num = 0;
1830 already_waited_sec = 0;
1831 }
1832 continue;
1833
1834
1835 }
1836
1837 }
1838
1839 ret0:
1840 if (opt & OPT_R)
1841 perform_release(server_addr, requested_ip);
1842 retval = 0;
1843 ret:
1844
1845 remove_pidfile(client_config.pidfile);
1846 return retval;
1847}
1848