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