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