dhcpc.c 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * udhcp client
  4. *
  5. * Russ Dill <Russ.Dill@asu.edu> July 2001
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include <syslog.h>
  22. /* Override ENABLE_FEATURE_PIDFILE - ifupdown needs our pidfile to always exist */
  23. #define WANT_PIDFILE 1
  24. #include "common.h"
  25. #include "dhcpd.h"
  26. #include "dhcpc.h"
  27. #include <netinet/if_ether.h>
  28. #include <netpacket/packet.h>
  29. #include <linux/filter.h>
  30. /* struct client_config_t client_config is in bb_common_bufsiz1 */
  31. #if ENABLE_LONG_OPTS
  32. static const char udhcpc_longopts[] ALIGN1 =
  33. "clientid-none\0" No_argument "C"
  34. "vendorclass\0" Required_argument "V"
  35. "hostname\0" Required_argument "H"
  36. "fqdn\0" Required_argument "F"
  37. "interface\0" Required_argument "i"
  38. "now\0" No_argument "n"
  39. "pidfile\0" Required_argument "p"
  40. "quit\0" No_argument "q"
  41. "release\0" No_argument "R"
  42. "request\0" Required_argument "r"
  43. "script\0" Required_argument "s"
  44. "timeout\0" Required_argument "T"
  45. "version\0" No_argument "v"
  46. "retries\0" Required_argument "t"
  47. "tryagain\0" Required_argument "A"
  48. "syslog\0" No_argument "S"
  49. "request-option\0" Required_argument "O"
  50. "no-default-options\0" No_argument "o"
  51. "foreground\0" No_argument "f"
  52. "background\0" No_argument "b"
  53. "broadcast\0" No_argument "B"
  54. IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a")
  55. IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P")
  56. ;
  57. #endif
  58. /* Must match getopt32 option string order */
  59. enum {
  60. OPT_C = 1 << 0,
  61. OPT_V = 1 << 1,
  62. OPT_H = 1 << 2,
  63. OPT_h = 1 << 3,
  64. OPT_F = 1 << 4,
  65. OPT_i = 1 << 5,
  66. OPT_n = 1 << 6,
  67. OPT_p = 1 << 7,
  68. OPT_q = 1 << 8,
  69. OPT_R = 1 << 9,
  70. OPT_r = 1 << 10,
  71. OPT_s = 1 << 11,
  72. OPT_T = 1 << 12,
  73. OPT_t = 1 << 13,
  74. OPT_S = 1 << 14,
  75. OPT_A = 1 << 15,
  76. OPT_O = 1 << 16,
  77. OPT_o = 1 << 17,
  78. OPT_x = 1 << 18,
  79. OPT_f = 1 << 19,
  80. OPT_B = 1 << 20,
  81. /* The rest has variable bit positions, need to be clever */
  82. OPTBIT_B = 20,
  83. USE_FOR_MMU( OPTBIT_b,)
  84. IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,)
  85. IF_FEATURE_UDHCP_PORT( OPTBIT_P,)
  86. USE_FOR_MMU( OPT_b = 1 << OPTBIT_b,)
  87. IF_FEATURE_UDHCPC_ARPING(OPT_a = 1 << OPTBIT_a,)
  88. IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,)
  89. };
  90. /*** Script execution code ***/
  91. /* get a rough idea of how long an option will be (rounding up...) */
  92. static const uint8_t len_of_option_as_string[] = {
  93. [OPTION_IP ] = sizeof("255.255.255.255 "),
  94. [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2,
  95. [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "),
  96. [OPTION_STRING ] = 1,
  97. #if ENABLE_FEATURE_UDHCP_RFC3397
  98. [OPTION_DNS_STRING ] = 1, /* unused */
  99. /* Hmmm, this severely overestimates size if SIP_SERVERS option
  100. * is in domain name form: N-byte option in binary form
  101. * mallocs ~16*N bytes. But it is freed almost at once.
  102. */
  103. [OPTION_SIP_SERVERS ] = sizeof("255.255.255.255 "),
  104. #endif
  105. // [OPTION_BOOLEAN ] = sizeof("yes "),
  106. [OPTION_U8 ] = sizeof("255 "),
  107. [OPTION_U16 ] = sizeof("65535 "),
  108. // [OPTION_S16 ] = sizeof("-32768 "),
  109. [OPTION_U32 ] = sizeof("4294967295 "),
  110. [OPTION_S32 ] = sizeof("-2147483684 "),
  111. };
  112. /* note: ip is a pointer to an IP in network order, possibly misaliged */
  113. static int sprint_nip(char *dest, const char *pre, const uint8_t *ip)
  114. {
  115. return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]);
  116. }
  117. /* really simple implementation, just count the bits */
  118. static int mton(uint32_t mask)
  119. {
  120. int i = 0;
  121. mask = ntohl(mask); /* 111110000-like bit pattern */
  122. while (mask) {
  123. i++;
  124. mask <<= 1;
  125. }
  126. return i;
  127. }
  128. /* Create "opt_name=opt_value" string */
  129. static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_optflag *optflag, const char *opt_name)
  130. {
  131. unsigned upper_length;
  132. int len, type, optlen;
  133. char *dest, *ret;
  134. /* option points to OPT_DATA, need to go back and get OPT_LEN */
  135. len = option[OPT_LEN - OPT_DATA];
  136. type = optflag->flags & OPTION_TYPE_MASK;
  137. optlen = dhcp_option_lengths[type];
  138. upper_length = len_of_option_as_string[type] * ((unsigned)len / (unsigned)optlen);
  139. dest = ret = xmalloc(upper_length + strlen(opt_name) + 2);
  140. dest += sprintf(ret, "%s=", opt_name);
  141. while (len >= optlen) {
  142. unsigned ip_ofs = 0;
  143. switch (type) {
  144. case OPTION_IP_PAIR:
  145. dest += sprint_nip(dest, "", option);
  146. *dest++ = '/';
  147. ip_ofs = 4;
  148. /* fall through */
  149. case OPTION_IP:
  150. dest += sprint_nip(dest, "", option + ip_ofs);
  151. break;
  152. // case OPTION_BOOLEAN:
  153. // dest += sprintf(dest, *option ? "yes" : "no");
  154. // break;
  155. case OPTION_U8:
  156. dest += sprintf(dest, "%u", *option);
  157. break;
  158. // case OPTION_S16:
  159. case OPTION_U16: {
  160. uint16_t val_u16;
  161. move_from_unaligned16(val_u16, option);
  162. dest += sprintf(dest, "%u", ntohs(val_u16));
  163. break;
  164. }
  165. case OPTION_S32:
  166. case OPTION_U32: {
  167. uint32_t val_u32;
  168. move_from_unaligned32(val_u32, option);
  169. dest += sprintf(dest, type == OPTION_U32 ? "%lu" : "%ld", (unsigned long) ntohl(val_u32));
  170. break;
  171. }
  172. case OPTION_STRING:
  173. memcpy(dest, option, len);
  174. dest[len] = '\0';
  175. return ret; /* Short circuit this case */
  176. case OPTION_STATIC_ROUTES: {
  177. /* Option binary format:
  178. * mask [one byte, 0..32]
  179. * ip [big endian, 0..4 bytes depending on mask]
  180. * router [big endian, 4 bytes]
  181. * may be repeated
  182. *
  183. * We convert it to a string "IP/MASK ROUTER IP2/MASK2 ROUTER2"
  184. */
  185. const char *pfx = "";
  186. while (len >= 1 + 4) { /* mask + 0-byte ip + router */
  187. uint32_t nip;
  188. uint8_t *p;
  189. unsigned mask;
  190. int bytes;
  191. mask = *option++;
  192. if (mask > 32)
  193. break;
  194. len--;
  195. nip = 0;
  196. p = (void*) &nip;
  197. bytes = (mask + 7) / 8; /* 0 -> 0, 1..8 -> 1, 9..16 -> 2 etc */
  198. while (--bytes >= 0) {
  199. *p++ = *option++;
  200. len--;
  201. }
  202. if (len < 4)
  203. break;
  204. /* print ip/mask */
  205. dest += sprint_nip(dest, pfx, (void*) &nip);
  206. pfx = " ";
  207. dest += sprintf(dest, "/%u ", mask);
  208. /* print router */
  209. dest += sprint_nip(dest, "", option);
  210. option += 4;
  211. len -= 4;
  212. }
  213. return ret;
  214. }
  215. #if ENABLE_FEATURE_UDHCP_RFC3397
  216. case OPTION_DNS_STRING:
  217. /* unpack option into dest; use ret for prefix (i.e., "optname=") */
  218. dest = dname_dec(option, len, ret);
  219. if (dest) {
  220. free(ret);
  221. return dest;
  222. }
  223. /* error. return "optname=" string */
  224. return ret;
  225. case OPTION_SIP_SERVERS:
  226. /* Option binary format:
  227. * type: byte
  228. * type=0: domain names, dns-compressed
  229. * type=1: IP addrs
  230. */
  231. option++;
  232. len--;
  233. if (option[-1] == 0) {
  234. dest = dname_dec(option, len, ret);
  235. if (dest) {
  236. free(ret);
  237. return dest;
  238. }
  239. } else
  240. if (option[-1] == 1) {
  241. const char *pfx = "";
  242. while (1) {
  243. len -= 4;
  244. if (len < 0)
  245. break;
  246. dest += sprint_nip(dest, pfx, option);
  247. pfx = " ";
  248. option += 4;
  249. }
  250. }
  251. return ret;
  252. #endif
  253. } /* switch */
  254. option += optlen;
  255. len -= optlen;
  256. // TODO: it can be a list only if (optflag->flags & OPTION_LIST).
  257. // Should we bail out/warn if we see multi-ip option which is
  258. // not allowed to be such (for example, DHCP_BROADCAST)? -
  259. if (len <= 0 /* || !(optflag->flags & OPTION_LIST) */)
  260. break;
  261. *dest++ = ' ';
  262. *dest = '\0';
  263. }
  264. return ret;
  265. }
  266. /* put all the parameters into the environment */
  267. static char **fill_envp(struct dhcp_packet *packet)
  268. {
  269. int envc;
  270. int i;
  271. char **envp, **curr;
  272. const char *opt_name;
  273. uint8_t *temp;
  274. uint8_t overload = 0;
  275. #define BITMAP unsigned
  276. #define BBITS (sizeof(BITMAP) * 8)
  277. #define BMASK(i) (1 << (i & (sizeof(BITMAP) * 8 - 1)))
  278. #define FOUND_OPTS(i) (found_opts[(unsigned)i / BBITS])
  279. BITMAP found_opts[256 / BBITS];
  280. memset(found_opts, 0, sizeof(found_opts));
  281. /* We need 6 elements for:
  282. * "interface=IFACE"
  283. * "ip=N.N.N.N" from packet->yiaddr
  284. * "siaddr=IP" from packet->siaddr_nip (unless 0)
  285. * "boot_file=FILE" from packet->file (unless overloaded)
  286. * "sname=SERVER_HOSTNAME" from packet->sname (unless overloaded)
  287. * terminating NULL
  288. */
  289. envc = 6;
  290. /* +1 element for each option, +2 for subnet option: */
  291. if (packet) {
  292. /* note: do not search for "pad" (0) and "end" (255) options */
  293. for (i = 1; i < 255; i++) {
  294. temp = udhcp_get_option(packet, i);
  295. if (temp) {
  296. if (i == DHCP_OPTION_OVERLOAD)
  297. overload = *temp;
  298. else if (i == DHCP_SUBNET)
  299. envc++; /* for mton */
  300. envc++;
  301. /*if (i != DHCP_MESSAGE_TYPE)*/
  302. FOUND_OPTS(i) |= BMASK(i);
  303. }
  304. }
  305. }
  306. curr = envp = xzalloc(sizeof(envp[0]) * envc);
  307. *curr = xasprintf("interface=%s", client_config.interface);
  308. putenv(*curr++);
  309. if (!packet)
  310. return envp;
  311. *curr = xmalloc(sizeof("ip=255.255.255.255"));
  312. sprint_nip(*curr, "ip=", (uint8_t *) &packet->yiaddr);
  313. putenv(*curr++);
  314. opt_name = dhcp_option_strings;
  315. i = 0;
  316. while (*opt_name) {
  317. uint8_t code = dhcp_optflags[i].code;
  318. BITMAP *found_ptr = &FOUND_OPTS(code);
  319. BITMAP found_mask = BMASK(code);
  320. if (!(*found_ptr & found_mask))
  321. goto next;
  322. *found_ptr &= ~found_mask; /* leave only unknown options */
  323. temp = udhcp_get_option(packet, code);
  324. *curr = xmalloc_optname_optval(temp, &dhcp_optflags[i], opt_name);
  325. putenv(*curr++);
  326. if (code == DHCP_SUBNET) {
  327. /* Subnet option: make things like "$ip/$mask" possible */
  328. uint32_t subnet;
  329. move_from_unaligned32(subnet, temp);
  330. *curr = xasprintf("mask=%d", mton(subnet));
  331. putenv(*curr++);
  332. }
  333. next:
  334. opt_name += strlen(opt_name) + 1;
  335. i++;
  336. }
  337. if (packet->siaddr_nip) {
  338. *curr = xmalloc(sizeof("siaddr=255.255.255.255"));
  339. sprint_nip(*curr, "siaddr=", (uint8_t *) &packet->siaddr_nip);
  340. putenv(*curr++);
  341. }
  342. if (!(overload & FILE_FIELD) && packet->file[0]) {
  343. /* watch out for invalid packets */
  344. *curr = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file);
  345. putenv(*curr++);
  346. }
  347. if (!(overload & SNAME_FIELD) && packet->sname[0]) {
  348. /* watch out for invalid packets */
  349. *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname);
  350. putenv(*curr++);
  351. }
  352. /* Handle unknown options */
  353. for (i = 0; i < 256;) {
  354. BITMAP bitmap = FOUND_OPTS(i);
  355. if (!bitmap) {
  356. i += BBITS;
  357. continue;
  358. }
  359. if (bitmap & BMASK(i)) {
  360. unsigned len, ofs;
  361. temp = udhcp_get_option(packet, i);
  362. /* udhcp_get_option returns ptr to data portion,
  363. * need to go back to get len
  364. */
  365. len = temp[-OPT_DATA + OPT_LEN];
  366. *curr = xmalloc(sizeof("optNNN=") + 1 + len*2);
  367. ofs = sprintf(*curr, "opt%u=", i);
  368. bin2hex(*curr + ofs, (void*) temp, len)[0] = '\0';
  369. putenv(*curr++);
  370. }
  371. i++;
  372. }
  373. return envp;
  374. }
  375. /* Call a script with a par file and env vars */
  376. static void udhcp_run_script(struct dhcp_packet *packet, const char *name)
  377. {
  378. char **envp, **curr;
  379. char *argv[3];
  380. if (client_config.script == NULL)
  381. return;
  382. envp = fill_envp(packet);
  383. /* call script */
  384. log1("Executing %s %s", client_config.script, name);
  385. argv[0] = (char*) client_config.script;
  386. argv[1] = (char*) name;
  387. argv[2] = NULL;
  388. spawn_and_wait(argv);
  389. for (curr = envp; *curr; curr++) {
  390. log2(" %s", *curr);
  391. bb_unsetenv_and_free(*curr);
  392. }
  393. free(envp);
  394. }
  395. /*** Sending/receiving packets ***/
  396. static ALWAYS_INLINE uint32_t random_xid(void)
  397. {
  398. return rand();
  399. }
  400. /* Initialize the packet with the proper defaults */
  401. static void init_packet(struct dhcp_packet *packet, char type)
  402. {
  403. uint16_t secs;
  404. /* Fill in: op, htype, hlen, cookie fields; message type option: */
  405. udhcp_init_header(packet, type);
  406. packet->xid = random_xid();
  407. client_config.last_secs = monotonic_sec();
  408. if (client_config.first_secs == 0)
  409. client_config.first_secs = client_config.last_secs;
  410. secs = client_config.last_secs - client_config.first_secs;
  411. packet->secs = htons(secs);
  412. memcpy(packet->chaddr, client_config.client_mac, 6);
  413. if (client_config.clientid)
  414. udhcp_add_binary_option(packet, client_config.clientid);
  415. }
  416. static void add_client_options(struct dhcp_packet *packet)
  417. {
  418. uint8_t c;
  419. int i, end, len;
  420. udhcp_add_simple_option(packet, DHCP_MAX_SIZE, htons(IP_UDP_DHCP_SIZE));
  421. /* Add a "param req" option with the list of options we'd like to have
  422. * from stubborn DHCP servers. Pull the data from the struct in common.c.
  423. * No bounds checking because it goes towards the head of the packet. */
  424. end = udhcp_end_option(packet->options);
  425. len = 0;
  426. for (i = 0; (c = dhcp_optflags[i].code) != 0; i++) {
  427. if (( (dhcp_optflags[i].flags & OPTION_REQ)
  428. && !client_config.no_default_options
  429. )
  430. || (client_config.opt_mask[c >> 3] & (1 << (c & 7)))
  431. ) {
  432. packet->options[end + OPT_DATA + len] = c;
  433. len++;
  434. }
  435. }
  436. if (len) {
  437. packet->options[end + OPT_CODE] = DHCP_PARAM_REQ;
  438. packet->options[end + OPT_LEN] = len;
  439. packet->options[end + OPT_DATA + len] = DHCP_END;
  440. }
  441. if (client_config.vendorclass)
  442. udhcp_add_binary_option(packet, client_config.vendorclass);
  443. if (client_config.hostname)
  444. udhcp_add_binary_option(packet, client_config.hostname);
  445. if (client_config.fqdn)
  446. udhcp_add_binary_option(packet, client_config.fqdn);
  447. /* Request broadcast replies if we have no IP addr */
  448. if ((option_mask32 & OPT_B) && packet->ciaddr == 0)
  449. packet->flags |= htons(BROADCAST_FLAG);
  450. /* Add -x options if any */
  451. {
  452. struct option_set *curr = client_config.options;
  453. while (curr) {
  454. udhcp_add_binary_option(packet, curr->data);
  455. curr = curr->next;
  456. }
  457. // if (client_config.sname)
  458. // strncpy((char*)packet->sname, client_config.sname, sizeof(packet->sname) - 1);
  459. // if (client_config.boot_file)
  460. // strncpy((char*)packet->file, client_config.boot_file, sizeof(packet->file) - 1);
  461. }
  462. }
  463. /* RFC 2131
  464. * 4.4.4 Use of broadcast and unicast
  465. *
  466. * The DHCP client broadcasts DHCPDISCOVER, DHCPREQUEST and DHCPINFORM
  467. * messages, unless the client knows the address of a DHCP server.
  468. * The client unicasts DHCPRELEASE messages to the server. Because
  469. * the client is declining the use of the IP address supplied by the server,
  470. * the client broadcasts DHCPDECLINE messages.
  471. *
  472. * When the DHCP client knows the address of a DHCP server, in either
  473. * INIT or REBOOTING state, the client may use that address
  474. * in the DHCPDISCOVER or DHCPREQUEST rather than the IP broadcast address.
  475. * The client may also use unicast to send DHCPINFORM messages
  476. * to a known DHCP server. If the client receives no response to DHCP
  477. * messages sent to the IP address of a known DHCP server, the DHCP
  478. * client reverts to using the IP broadcast address.
  479. */
  480. static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet)
  481. {
  482. return udhcp_send_raw_packet(packet,
  483. /*src*/ INADDR_ANY, CLIENT_PORT,
  484. /*dst*/ INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR,
  485. client_config.ifindex);
  486. }
  487. /* Broadcast a DHCP discover packet to the network, with an optionally requested IP */
  488. /* NOINLINE: limit stack usage in caller */
  489. static NOINLINE int send_discover(uint32_t xid, uint32_t requested)
  490. {
  491. struct dhcp_packet packet;
  492. /* Fill in: op, htype, hlen, cookie, chaddr fields,
  493. * random xid field (we override it below),
  494. * client-id option (unless -C), message type option:
  495. */
  496. init_packet(&packet, DHCPDISCOVER);
  497. packet.xid = xid;
  498. if (requested)
  499. udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
  500. /* Add options: maxsize,
  501. * optionally: hostname, fqdn, vendorclass,
  502. * "param req" option according to -O, options specified with -x
  503. */
  504. add_client_options(&packet);
  505. bb_info_msg("Sending discover...");
  506. return raw_bcast_from_client_config_ifindex(&packet);
  507. }
  508. /* Broadcast a DHCP request message */
  509. /* RFC 2131 3.1 paragraph 3:
  510. * "The client _broadcasts_ a DHCPREQUEST message..."
  511. */
  512. /* NOINLINE: limit stack usage in caller */
  513. static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requested)
  514. {
  515. struct dhcp_packet packet;
  516. struct in_addr addr;
  517. /*
  518. * RFC 2131 4.3.2 DHCPREQUEST message
  519. * ...
  520. * If the DHCPREQUEST message contains a 'server identifier'
  521. * option, the message is in response to a DHCPOFFER message.
  522. * Otherwise, the message is a request to verify or extend an
  523. * existing lease. If the client uses a 'client identifier'
  524. * in a DHCPREQUEST message, it MUST use that same 'client identifier'
  525. * in all subsequent messages. If the client included a list
  526. * of requested parameters in a DHCPDISCOVER message, it MUST
  527. * include that list in all subsequent messages.
  528. */
  529. /* Fill in: op, htype, hlen, cookie, chaddr fields,
  530. * random xid field (we override it below),
  531. * client-id option (unless -C), message type option:
  532. */
  533. init_packet(&packet, DHCPREQUEST);
  534. packet.xid = xid;
  535. udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
  536. udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
  537. /* Add options: maxsize,
  538. * optionally: hostname, fqdn, vendorclass,
  539. * "param req" option according to -O, and options specified with -x
  540. */
  541. add_client_options(&packet);
  542. addr.s_addr = requested;
  543. bb_info_msg("Sending select for %s...", inet_ntoa(addr));
  544. return raw_bcast_from_client_config_ifindex(&packet);
  545. }
  546. /* Unicast or broadcast a DHCP renew message */
  547. /* NOINLINE: limit stack usage in caller */
  548. static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
  549. {
  550. struct dhcp_packet packet;
  551. /*
  552. * RFC 2131 4.3.2 DHCPREQUEST message
  553. * ...
  554. * DHCPREQUEST generated during RENEWING state:
  555. *
  556. * 'server identifier' MUST NOT be filled in, 'requested IP address'
  557. * option MUST NOT be filled in, 'ciaddr' MUST be filled in with
  558. * client's IP address. In this situation, the client is completely
  559. * configured, and is trying to extend its lease. This message will
  560. * be unicast, so no relay agents will be involved in its
  561. * transmission. Because 'giaddr' is therefore not filled in, the
  562. * DHCP server will trust the value in 'ciaddr', and use it when
  563. * replying to the client.
  564. */
  565. /* Fill in: op, htype, hlen, cookie, chaddr fields,
  566. * random xid field (we override it below),
  567. * client-id option (unless -C), message type option:
  568. */
  569. init_packet(&packet, DHCPREQUEST);
  570. packet.xid = xid;
  571. packet.ciaddr = ciaddr;
  572. /* Add options: maxsize,
  573. * optionally: hostname, fqdn, vendorclass,
  574. * "param req" option according to -O, and options specified with -x
  575. */
  576. add_client_options(&packet);
  577. bb_info_msg("Sending renew...");
  578. if (server)
  579. return udhcp_send_kernel_packet(&packet,
  580. ciaddr, CLIENT_PORT,
  581. server, SERVER_PORT);
  582. return raw_bcast_from_client_config_ifindex(&packet);
  583. }
  584. #if ENABLE_FEATURE_UDHCPC_ARPING
  585. /* Broadcast a DHCP decline message */
  586. /* NOINLINE: limit stack usage in caller */
  587. static NOINLINE int send_decline(uint32_t xid, uint32_t server, uint32_t requested)
  588. {
  589. struct dhcp_packet packet;
  590. /* Fill in: op, htype, hlen, cookie, chaddr, random xid fields,
  591. * client-id option (unless -C), message type option:
  592. */
  593. init_packet(&packet, DHCPDECLINE);
  594. /* RFC 2131 says DHCPDECLINE's xid is randomly selected by client,
  595. * but in case the server is buggy and wants DHCPDECLINE's xid
  596. * to match the xid which started entire handshake,
  597. * we use the same xid we used in initial DHCPDISCOVER:
  598. */
  599. packet.xid = xid;
  600. /* DHCPDECLINE uses "requested ip", not ciaddr, to store offered IP */
  601. udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
  602. udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
  603. bb_info_msg("Sending decline...");
  604. return raw_bcast_from_client_config_ifindex(&packet);
  605. }
  606. #endif
  607. /* Unicast a DHCP release message */
  608. static int send_release(uint32_t server, uint32_t ciaddr)
  609. {
  610. struct dhcp_packet packet;
  611. /* Fill in: op, htype, hlen, cookie, chaddr, random xid fields,
  612. * client-id option (unless -C), message type option:
  613. */
  614. init_packet(&packet, DHCPRELEASE);
  615. /* DHCPRELEASE uses ciaddr, not "requested ip", to store IP being released */
  616. packet.ciaddr = ciaddr;
  617. udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
  618. bb_info_msg("Sending release...");
  619. return udhcp_send_kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT);
  620. }
  621. /* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */
  622. /* NOINLINE: limit stack usage in caller */
  623. static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd)
  624. {
  625. int bytes;
  626. struct ip_udp_dhcp_packet packet;
  627. uint16_t check;
  628. memset(&packet, 0, sizeof(packet));
  629. bytes = safe_read(fd, &packet, sizeof(packet));
  630. if (bytes < 0) {
  631. log1("Packet read error, ignoring");
  632. /* NB: possible down interface, etc. Caller should pause. */
  633. return bytes; /* returns -1 */
  634. }
  635. if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) {
  636. log1("Packet is too short, ignoring");
  637. return -2;
  638. }
  639. if (bytes < ntohs(packet.ip.tot_len)) {
  640. /* packet is bigger than sizeof(packet), we did partial read */
  641. log1("Oversized packet, ignoring");
  642. return -2;
  643. }
  644. /* ignore any extra garbage bytes */
  645. bytes = ntohs(packet.ip.tot_len);
  646. /* make sure its the right packet for us, and that it passes sanity checks */
  647. if (packet.ip.protocol != IPPROTO_UDP || packet.ip.version != IPVERSION
  648. || packet.ip.ihl != (sizeof(packet.ip) >> 2)
  649. || packet.udp.dest != htons(CLIENT_PORT)
  650. /* || bytes > (int) sizeof(packet) - can't happen */
  651. || ntohs(packet.udp.len) != (uint16_t)(bytes - sizeof(packet.ip))
  652. ) {
  653. log1("Unrelated/bogus packet, ignoring");
  654. return -2;
  655. }
  656. /* verify IP checksum */
  657. check = packet.ip.check;
  658. packet.ip.check = 0;
  659. if (check != udhcp_checksum(&packet.ip, sizeof(packet.ip))) {
  660. log1("Bad IP header checksum, ignoring");
  661. return -2;
  662. }
  663. /* verify UDP checksum. IP header has to be modified for this */
  664. memset(&packet.ip, 0, offsetof(struct iphdr, protocol));
  665. /* ip.xx fields which are not memset: protocol, check, saddr, daddr */
  666. packet.ip.tot_len = packet.udp.len; /* yes, this is needed */
  667. check = packet.udp.check;
  668. packet.udp.check = 0;
  669. if (check && check != udhcp_checksum(&packet, bytes)) {
  670. log1("Packet with bad UDP checksum received, ignoring");
  671. return -2;
  672. }
  673. memcpy(dhcp_pkt, &packet.data, bytes - (sizeof(packet.ip) + sizeof(packet.udp)));
  674. if (dhcp_pkt->cookie != htonl(DHCP_MAGIC)) {
  675. bb_info_msg("Packet with bad magic, ignoring");
  676. return -2;
  677. }
  678. log1("Got valid DHCP packet");
  679. udhcp_dump_packet(dhcp_pkt);
  680. return bytes - (sizeof(packet.ip) + sizeof(packet.udp));
  681. }
  682. /*** Main ***/
  683. static int sockfd = -1;
  684. #define LISTEN_NONE 0
  685. #define LISTEN_KERNEL 1
  686. #define LISTEN_RAW 2
  687. static smallint listen_mode;
  688. /* initial state: (re)start DHCP negotiation */
  689. #define INIT_SELECTING 0
  690. /* discover was sent, DHCPOFFER reply received */
  691. #define REQUESTING 1
  692. /* select/renew was sent, DHCPACK reply received */
  693. #define BOUND 2
  694. /* half of lease passed, want to renew it by sending unicast renew requests */
  695. #define RENEWING 3
  696. /* renew requests were not answered, lease is almost over, send broadcast renew */
  697. #define REBINDING 4
  698. /* manually requested renew (SIGUSR1) */
  699. #define RENEW_REQUESTED 5
  700. /* release, possibly manually requested (SIGUSR2) */
  701. #define RELEASED 6
  702. static smallint state;
  703. static int udhcp_raw_socket(int ifindex)
  704. {
  705. int fd;
  706. struct sockaddr_ll sock;
  707. /*
  708. * Comment:
  709. *
  710. * I've selected not to see LL header, so BPF doesn't see it, too.
  711. * The filter may also pass non-IP and non-ARP packets, but we do
  712. * a more complete check when receiving the message in userspace.
  713. *
  714. * and filter shamelessly stolen from:
  715. *
  716. * http://www.flamewarmaster.de/software/dhcpclient/
  717. *
  718. * There are a few other interesting ideas on that page (look under
  719. * "Motivation"). Use of netlink events is most interesting. Think
  720. * of various network servers listening for events and reconfiguring.
  721. * That would obsolete sending HUP signals and/or make use of restarts.
  722. *
  723. * Copyright: 2006, 2007 Stefan Rompf <sux@loplof.de>.
  724. * License: GPL v2.
  725. *
  726. * TODO: make conditional?
  727. */
  728. static const struct sock_filter filter_instr[] = {
  729. /* load 9th byte (protocol) */
  730. BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9),
  731. /* jump to L1 if it is IPPROTO_UDP, else to L4 */
  732. BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6),
  733. /* L1: load halfword from offset 6 (flags and frag offset) */
  734. BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6),
  735. /* jump to L4 if any bits in frag offset field are set, else to L2 */
  736. BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0),
  737. /* L2: skip IP header (load index reg with header len) */
  738. BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0),
  739. /* load udp destination port from halfword[header_len + 2] */
  740. BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2),
  741. /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */
  742. BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1),
  743. /* L3: accept packet */
  744. BPF_STMT(BPF_RET|BPF_K, 0xffffffff),
  745. /* L4: discard packet */
  746. BPF_STMT(BPF_RET|BPF_K, 0),
  747. };
  748. static const struct sock_fprog filter_prog = {
  749. .len = sizeof(filter_instr) / sizeof(filter_instr[0]),
  750. /* casting const away: */
  751. .filter = (struct sock_filter *) filter_instr,
  752. };
  753. log1("Opening raw socket on ifindex %d", ifindex); //log2?
  754. fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
  755. log1("Got raw socket fd %d", fd); //log2?
  756. sock.sll_family = AF_PACKET;
  757. sock.sll_protocol = htons(ETH_P_IP);
  758. sock.sll_ifindex = ifindex;
  759. xbind(fd, (struct sockaddr *) &sock, sizeof(sock));
  760. if (CLIENT_PORT == 68) {
  761. /* Use only if standard port is in use */
  762. /* Ignoring error (kernel may lack support for this) */
  763. if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog,
  764. sizeof(filter_prog)) >= 0)
  765. log1("Attached filter to raw socket fd %d", fd); // log?
  766. }
  767. log1("Created raw socket");
  768. return fd;
  769. }
  770. static void change_listen_mode(int new_mode)
  771. {
  772. log1("Entering listen mode: %s",
  773. new_mode != LISTEN_NONE
  774. ? (new_mode == LISTEN_KERNEL ? "kernel" : "raw")
  775. : "none"
  776. );
  777. listen_mode = new_mode;
  778. if (sockfd >= 0) {
  779. close(sockfd);
  780. sockfd = -1;
  781. }
  782. if (new_mode == LISTEN_KERNEL)
  783. sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT, client_config.interface);
  784. else if (new_mode != LISTEN_NONE)
  785. sockfd = udhcp_raw_socket(client_config.ifindex);
  786. /* else LISTEN_NONE: sockfd stays closed */
  787. }
  788. /* Called only on SIGUSR1 */
  789. static void perform_renew(void)
  790. {
  791. bb_info_msg("Performing a DHCP renew");
  792. switch (state) {
  793. case BOUND:
  794. change_listen_mode(LISTEN_KERNEL);
  795. case RENEWING:
  796. case REBINDING:
  797. state = RENEW_REQUESTED;
  798. break;
  799. case RENEW_REQUESTED: /* impatient are we? fine, square 1 */
  800. udhcp_run_script(NULL, "deconfig");
  801. case REQUESTING:
  802. case RELEASED:
  803. change_listen_mode(LISTEN_RAW);
  804. state = INIT_SELECTING;
  805. break;
  806. case INIT_SELECTING:
  807. break;
  808. }
  809. }
  810. static void perform_release(uint32_t requested_ip, uint32_t server_addr)
  811. {
  812. char buffer[sizeof("255.255.255.255")];
  813. struct in_addr temp_addr;
  814. /* send release packet */
  815. if (state == BOUND || state == RENEWING || state == REBINDING) {
  816. temp_addr.s_addr = server_addr;
  817. strcpy(buffer, inet_ntoa(temp_addr));
  818. temp_addr.s_addr = requested_ip;
  819. bb_info_msg("Unicasting a release of %s to %s",
  820. inet_ntoa(temp_addr), buffer);
  821. send_release(server_addr, requested_ip); /* unicast */
  822. udhcp_run_script(NULL, "deconfig");
  823. }
  824. bb_info_msg("Entering released state");
  825. change_listen_mode(LISTEN_NONE);
  826. state = RELEASED;
  827. }
  828. static uint8_t* alloc_dhcp_option(int code, const char *str, int extra)
  829. {
  830. uint8_t *storage;
  831. int len = strnlen(str, 255);
  832. storage = xzalloc(len + extra + OPT_DATA);
  833. storage[OPT_CODE] = code;
  834. storage[OPT_LEN] = len + extra;
  835. memcpy(storage + extra + OPT_DATA, str, len);
  836. return storage;
  837. }
  838. #if BB_MMU
  839. static void client_background(void)
  840. {
  841. bb_daemonize(0);
  842. logmode &= ~LOGMODE_STDIO;
  843. /* rewrite pidfile, as our pid is different now */
  844. write_pidfile(client_config.pidfile);
  845. }
  846. #endif
  847. //usage:#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
  848. //usage:# define IF_UDHCP_VERBOSE(...) __VA_ARGS__
  849. //usage:#else
  850. //usage:# define IF_UDHCP_VERBOSE(...)
  851. //usage:#endif
  852. //usage:#define udhcpc_trivial_usage
  853. //usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"oCRB] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n"
  854. //usage: " [-H HOSTNAME] [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]")
  855. //usage:#define udhcpc_full_usage "\n"
  856. //usage: IF_LONG_OPTS(
  857. //usage: "\n -i,--interface IFACE Interface to use (default eth0)"
  858. //usage: "\n -p,--pidfile FILE Create pidfile"
  859. //usage: "\n -s,--script PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"
  860. //usage: "\n -B,--broadcast Request broadcast replies"
  861. //usage: "\n -t,--retries N Send up to N discover packets"
  862. //usage: "\n -T,--timeout N Pause between packets (default 3 seconds)"
  863. //usage: "\n -A,--tryagain N Wait N seconds after failure (default 20)"
  864. //usage: "\n -f,--foreground Run in foreground"
  865. //usage: USE_FOR_MMU(
  866. //usage: "\n -b,--background Background if lease is not obtained"
  867. //usage: )
  868. //usage: "\n -n,--now Exit if lease is not obtained"
  869. //usage: "\n -q,--quit Exit after obtaining lease"
  870. //usage: "\n -R,--release Release IP on exit"
  871. //usage: "\n -S,--syslog Log to syslog too"
  872. //usage: IF_FEATURE_UDHCP_PORT(
  873. //usage: "\n -P,--client-port N Use port N (default 68)"
  874. //usage: )
  875. //usage: IF_FEATURE_UDHCPC_ARPING(
  876. //usage: "\n -a,--arping Use arping to validate offered address"
  877. //usage: )
  878. //usage: "\n -O,--request-option OPT Request option OPT from server (cumulative)"
  879. //usage: "\n -o,--no-default-options Don't request any options (unless -O is given)"
  880. //usage: "\n -r,--request IP Request this IP address"
  881. //usage: "\n -x OPT:VAL Include option OPT in sent packets (cumulative)"
  882. //usage: "\n Examples of string, numeric, and hex byte opts:"
  883. //usage: "\n -x hostname:bbox - option 12"
  884. //usage: "\n -x lease:3600 - option 51 (lease time)"
  885. //usage: "\n -x 0x3d:0100BEEFC0FFEE - option 61 (client id)"
  886. //usage: "\n -F,--fqdn NAME Ask server to update DNS mapping for NAME"
  887. //usage: "\n -H,-h,--hostname NAME Send NAME as client hostname (default none)"
  888. //usage: "\n -V,--vendorclass VENDOR Vendor identifier (default 'udhcp VERSION')"
  889. //usage: "\n -C,--clientid-none Don't send MAC as client identifier"
  890. //usage: IF_UDHCP_VERBOSE(
  891. //usage: "\n -v Verbose"
  892. //usage: )
  893. //usage: )
  894. //usage: IF_NOT_LONG_OPTS(
  895. //usage: "\n -i IFACE Interface to use (default eth0)"
  896. //usage: "\n -p FILE Create pidfile"
  897. //usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"
  898. //usage: "\n -B Request broadcast replies"
  899. //usage: "\n -t N Send up to N discover packets"
  900. //usage: "\n -T N Pause between packets (default 3 seconds)"
  901. //usage: "\n -A N Wait N seconds (default 20) after failure"
  902. //usage: "\n -f Run in foreground"
  903. //usage: USE_FOR_MMU(
  904. //usage: "\n -b Background if lease is not obtained"
  905. //usage: )
  906. //usage: "\n -n Exit if lease is not obtained"
  907. //usage: "\n -q Exit after obtaining lease"
  908. //usage: "\n -R Release IP on exit"
  909. //usage: "\n -S Log to syslog too"
  910. //usage: IF_FEATURE_UDHCP_PORT(
  911. //usage: "\n -P N Use port N (default 68)"
  912. //usage: )
  913. //usage: IF_FEATURE_UDHCPC_ARPING(
  914. //usage: "\n -a Use arping to validate offered address"
  915. //usage: )
  916. //usage: "\n -O OPT Request option OPT from server (cumulative)"
  917. //usage: "\n -o Don't request any options (unless -O is given)"
  918. //usage: "\n -r IP Request this IP address"
  919. //usage: "\n -x OPT:VAL Include option OPT in sent packets (cumulative)"
  920. //usage: "\n Examples of string, numeric, and hex byte opts:"
  921. //usage: "\n -x hostname:bbox - option 12"
  922. //usage: "\n -x lease:3600 - option 51 (lease time)"
  923. //usage: "\n -x 0x3d:0100BEEFC0FFEE - option 61 (client id)"
  924. //usage: "\n -F NAME Ask server to update DNS mapping for NAME"
  925. //usage: "\n -H,-h NAME Send NAME as client hostname (default none)"
  926. //usage: "\n -V VENDOR Vendor identifier (default 'udhcp VERSION')"
  927. //usage: "\n -C Don't send MAC as client identifier"
  928. //usage: IF_UDHCP_VERBOSE(
  929. //usage: "\n -v Verbose"
  930. //usage: )
  931. //usage: )
  932. //usage: "\nSignals:"
  933. //usage: "\n USR1 Renew current lease"
  934. //usage: "\n USR2 Release current lease"
  935. int udhcpc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  936. int udhcpc_main(int argc UNUSED_PARAM, char **argv)
  937. {
  938. uint8_t *temp, *message;
  939. const char *str_V, *str_h, *str_F, *str_r;
  940. IF_FEATURE_UDHCP_PORT(char *str_P;)
  941. void *clientid_mac_ptr;
  942. llist_t *list_O = NULL;
  943. llist_t *list_x = NULL;
  944. int tryagain_timeout = 20;
  945. int discover_timeout = 3;
  946. int discover_retries = 3;
  947. uint32_t server_addr = server_addr; /* for compiler */
  948. uint32_t requested_ip = 0;
  949. uint32_t xid = 0;
  950. uint32_t lease_seconds = 0; /* can be given as 32-bit quantity */
  951. int packet_num;
  952. int timeout; /* must be signed */
  953. unsigned already_waited_sec;
  954. unsigned opt;
  955. int max_fd;
  956. int retval;
  957. struct timeval tv;
  958. struct dhcp_packet packet;
  959. fd_set rfds;
  960. /* Default options */
  961. IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;)
  962. IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;)
  963. client_config.interface = "eth0";
  964. client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT;
  965. str_V = "udhcp "BB_VER;
  966. /* Parse command line */
  967. /* O,x: list; -T,-t,-A take numeric param */
  968. opt_complementary = "O::x::T+:t+:A+"
  969. #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
  970. ":vv"
  971. #endif
  972. ;
  973. IF_LONG_OPTS(applet_long_options = udhcpc_longopts;)
  974. opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB"
  975. USE_FOR_MMU("b")
  976. IF_FEATURE_UDHCPC_ARPING("a")
  977. IF_FEATURE_UDHCP_PORT("P:")
  978. "v"
  979. , &str_V, &str_h, &str_h, &str_F
  980. , &client_config.interface, &client_config.pidfile, &str_r /* i,p */
  981. , &client_config.script /* s */
  982. , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */
  983. , &list_O
  984. , &list_x
  985. IF_FEATURE_UDHCP_PORT(, &str_P)
  986. #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
  987. , &dhcp_verbose
  988. #endif
  989. );
  990. if (opt & (OPT_h|OPT_H))
  991. client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0);
  992. if (opt & OPT_F) {
  993. /* FQDN option format: [0x51][len][flags][0][0]<fqdn> */
  994. client_config.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3);
  995. /* Flag bits: 0000NEOS
  996. * S: 1 = Client requests server to update A RR in DNS as well as PTR
  997. * O: 1 = Server indicates to client that DNS has been updated regardless
  998. * E: 1 = Name is in DNS format, i.e. <4>host<6>domain<3>com<0>,
  999. * not "host.domain.com". Format 0 is obsolete.
  1000. * N: 1 = Client requests server to not update DNS (S must be 0 then)
  1001. * Two [0] bytes which follow are deprecated and must be 0.
  1002. */
  1003. client_config.fqdn[OPT_DATA + 0] = 0x1;
  1004. /*client_config.fqdn[OPT_DATA + 1] = 0; - xzalloc did it */
  1005. /*client_config.fqdn[OPT_DATA + 2] = 0; */
  1006. }
  1007. if (opt & OPT_r)
  1008. requested_ip = inet_addr(str_r);
  1009. #if ENABLE_FEATURE_UDHCP_PORT
  1010. if (opt & OPT_P) {
  1011. CLIENT_PORT = xatou16(str_P);
  1012. SERVER_PORT = CLIENT_PORT - 1;
  1013. }
  1014. #endif
  1015. if (opt & OPT_o)
  1016. client_config.no_default_options = 1;
  1017. while (list_O) {
  1018. char *optstr = llist_pop(&list_O);
  1019. unsigned n = bb_strtou(optstr, NULL, 0);
  1020. if (errno || n > 254) {
  1021. n = udhcp_option_idx(optstr);
  1022. n = dhcp_optflags[n].code;
  1023. }
  1024. client_config.opt_mask[n >> 3] |= 1 << (n & 7);
  1025. }
  1026. while (list_x) {
  1027. char *optstr = llist_pop(&list_x);
  1028. char *colon = strchr(optstr, ':');
  1029. if (colon)
  1030. *colon = ' ';
  1031. /* now it looks similar to udhcpd's config file line:
  1032. * "optname optval", using the common routine: */
  1033. udhcp_str2optset(optstr, &client_config.options);
  1034. }
  1035. if (udhcp_read_interface(client_config.interface,
  1036. &client_config.ifindex,
  1037. NULL,
  1038. client_config.client_mac)
  1039. ) {
  1040. return 1;
  1041. }
  1042. clientid_mac_ptr = NULL;
  1043. if (!(opt & OPT_C) && !udhcp_find_option(client_config.options, DHCP_CLIENT_ID)) {
  1044. /* not suppressed and not set, set the default client ID */
  1045. client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7);
  1046. client_config.clientid[OPT_DATA] = 1; /* type: ethernet */
  1047. clientid_mac_ptr = client_config.clientid + OPT_DATA+1;
  1048. memcpy(clientid_mac_ptr, client_config.client_mac, 6);
  1049. }
  1050. if (str_V[0] != '\0')
  1051. client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0);
  1052. #if !BB_MMU
  1053. /* on NOMMU reexec (i.e., background) early */
  1054. if (!(opt & OPT_f)) {
  1055. bb_daemonize_or_rexec(0 /* flags */, argv);
  1056. logmode = LOGMODE_NONE;
  1057. }
  1058. #endif
  1059. if (opt & OPT_S) {
  1060. openlog(applet_name, LOG_PID, LOG_DAEMON);
  1061. logmode |= LOGMODE_SYSLOG;
  1062. }
  1063. /* Make sure fd 0,1,2 are open */
  1064. bb_sanitize_stdio();
  1065. /* Equivalent of doing a fflush after every \n */
  1066. setlinebuf(stdout);
  1067. /* Create pidfile */
  1068. write_pidfile(client_config.pidfile);
  1069. /* Goes to stdout (unless NOMMU) and possibly syslog */
  1070. bb_info_msg("%s (v"BB_VER") started", applet_name);
  1071. /* Set up the signal pipe */
  1072. udhcp_sp_setup();
  1073. /* We want random_xid to be random... */
  1074. srand(monotonic_us());
  1075. state = INIT_SELECTING;
  1076. udhcp_run_script(NULL, "deconfig");
  1077. change_listen_mode(LISTEN_RAW);
  1078. packet_num = 0;
  1079. timeout = 0;
  1080. already_waited_sec = 0;
  1081. /* Main event loop. select() waits on signal pipe and possibly
  1082. * on sockfd.
  1083. * "continue" statements in code below jump to the top of the loop.
  1084. */
  1085. for (;;) {
  1086. /* silence "uninitialized!" warning */
  1087. unsigned timestamp_before_wait = timestamp_before_wait;
  1088. //bb_error_msg("sockfd:%d, listen_mode:%d", sockfd, listen_mode);
  1089. /* Was opening raw or udp socket here
  1090. * if (listen_mode != LISTEN_NONE && sockfd < 0),
  1091. * but on fast network renew responses return faster
  1092. * than we open sockets. Thus this code is moved
  1093. * to change_listen_mode(). Thus we open listen socket
  1094. * BEFORE we send renew request (see "case BOUND:"). */
  1095. max_fd = udhcp_sp_fd_set(&rfds, sockfd);
  1096. tv.tv_sec = timeout - already_waited_sec;
  1097. tv.tv_usec = 0;
  1098. retval = 0;
  1099. /* If we already timed out, fall through with retval = 0, else... */
  1100. if ((int)tv.tv_sec > 0) {
  1101. timestamp_before_wait = (unsigned)monotonic_sec();
  1102. log1("Waiting on select...");
  1103. retval = select(max_fd + 1, &rfds, NULL, NULL, &tv);
  1104. if (retval < 0) {
  1105. /* EINTR? A signal was caught, don't panic */
  1106. if (errno == EINTR) {
  1107. already_waited_sec += (unsigned)monotonic_sec() - timestamp_before_wait;
  1108. continue;
  1109. }
  1110. /* Else: an error occured, panic! */
  1111. bb_perror_msg_and_die("select");
  1112. }
  1113. }
  1114. /* If timeout dropped to zero, time to become active:
  1115. * resend discover/renew/whatever
  1116. */
  1117. if (retval == 0) {
  1118. /* When running on a bridge, the ifindex may have changed
  1119. * (e.g. if member interfaces were added/removed
  1120. * or if the status of the bridge changed).
  1121. * Refresh ifindex and client_mac:
  1122. */
  1123. if (udhcp_read_interface(client_config.interface,
  1124. &client_config.ifindex,
  1125. NULL,
  1126. client_config.client_mac)
  1127. ) {
  1128. return 1; /* iface is gone? */
  1129. }
  1130. if (clientid_mac_ptr)
  1131. memcpy(clientid_mac_ptr, client_config.client_mac, 6);
  1132. /* We will restart the wait in any case */
  1133. already_waited_sec = 0;
  1134. switch (state) {
  1135. case INIT_SELECTING:
  1136. if (packet_num < discover_retries) {
  1137. if (packet_num == 0)
  1138. xid = random_xid();
  1139. /* broadcast */
  1140. send_discover(xid, requested_ip);
  1141. timeout = discover_timeout;
  1142. packet_num++;
  1143. continue;
  1144. }
  1145. leasefail:
  1146. udhcp_run_script(NULL, "leasefail");
  1147. #if BB_MMU /* -b is not supported on NOMMU */
  1148. if (opt & OPT_b) { /* background if no lease */
  1149. bb_info_msg("No lease, forking to background");
  1150. client_background();
  1151. /* do not background again! */
  1152. opt = ((opt & ~OPT_b) | OPT_f);
  1153. } else
  1154. #endif
  1155. if (opt & OPT_n) { /* abort if no lease */
  1156. bb_info_msg("No lease, failing");
  1157. retval = 1;
  1158. goto ret;
  1159. }
  1160. /* wait before trying again */
  1161. timeout = tryagain_timeout;
  1162. packet_num = 0;
  1163. continue;
  1164. case REQUESTING:
  1165. if (packet_num < discover_retries) {
  1166. /* send broadcast select packet */
  1167. send_select(xid, server_addr, requested_ip);
  1168. timeout = discover_timeout;
  1169. packet_num++;
  1170. continue;
  1171. }
  1172. /* Timed out, go back to init state.
  1173. * "discover...select...discover..." loops
  1174. * were seen in the wild. Treat them similarly
  1175. * to "no response to discover" case */
  1176. change_listen_mode(LISTEN_RAW);
  1177. state = INIT_SELECTING;
  1178. goto leasefail;
  1179. case BOUND:
  1180. /* 1/2 lease passed, enter renewing state */
  1181. state = RENEWING;
  1182. client_config.first_secs = 0; /* make secs field count from 0 */
  1183. change_listen_mode(LISTEN_KERNEL);
  1184. log1("Entering renew state");
  1185. /* fall right through */
  1186. case RENEW_REQUESTED: /* manual (SIGUSR1) renew */
  1187. case_RENEW_REQUESTED:
  1188. case RENEWING:
  1189. if (timeout > 60) {
  1190. /* send an unicast renew request */
  1191. /* Sometimes observed to fail (EADDRNOTAVAIL) to bind
  1192. * a new UDP socket for sending inside send_renew.
  1193. * I hazard to guess existing listening socket
  1194. * is somehow conflicting with it, but why is it
  1195. * not deterministic then?! Strange.
  1196. * Anyway, it does recover by eventually failing through
  1197. * into INIT_SELECTING state.
  1198. */
  1199. send_renew(xid, server_addr, requested_ip);
  1200. timeout >>= 1;
  1201. continue;
  1202. }
  1203. /* Timed out, enter rebinding state */
  1204. log1("Entering rebinding state");
  1205. state = REBINDING;
  1206. /* fall right through */
  1207. case REBINDING:
  1208. /* Switch to bcast receive */
  1209. change_listen_mode(LISTEN_RAW);
  1210. /* Lease is *really* about to run out,
  1211. * try to find DHCP server using broadcast */
  1212. if (timeout > 0) {
  1213. /* send a broadcast renew request */
  1214. send_renew(xid, 0 /*INADDR_ANY*/, requested_ip);
  1215. timeout >>= 1;
  1216. continue;
  1217. }
  1218. /* Timed out, enter init state */
  1219. bb_info_msg("Lease lost, entering init state");
  1220. udhcp_run_script(NULL, "deconfig");
  1221. state = INIT_SELECTING;
  1222. client_config.first_secs = 0; /* make secs field count from 0 */
  1223. /*timeout = 0; - already is */
  1224. packet_num = 0;
  1225. continue;
  1226. /* case RELEASED: */
  1227. }
  1228. /* yah, I know, *you* say it would never happen */
  1229. timeout = INT_MAX;
  1230. continue; /* back to main loop */
  1231. } /* if select timed out */
  1232. /* select() didn't timeout, something happened */
  1233. /* Is it a signal? */
  1234. /* note: udhcp_sp_read checks FD_ISSET before reading */
  1235. switch (udhcp_sp_read(&rfds)) {
  1236. case SIGUSR1:
  1237. client_config.first_secs = 0; /* make secs field count from 0 */
  1238. perform_renew();
  1239. if (state == RENEW_REQUESTED)
  1240. goto case_RENEW_REQUESTED;
  1241. /* Start things over */
  1242. packet_num = 0;
  1243. /* Kill any timeouts, user wants this to hurry along */
  1244. timeout = 0;
  1245. continue;
  1246. case SIGUSR2:
  1247. perform_release(requested_ip, server_addr);
  1248. timeout = INT_MAX;
  1249. continue;
  1250. case SIGTERM:
  1251. bb_info_msg("Received SIGTERM");
  1252. if (opt & OPT_R) /* release on quit */
  1253. perform_release(requested_ip, server_addr);
  1254. goto ret0;
  1255. }
  1256. /* Is it a packet? */
  1257. if (listen_mode == LISTEN_NONE || !FD_ISSET(sockfd, &rfds))
  1258. continue; /* no */
  1259. {
  1260. int len;
  1261. /* A packet is ready, read it */
  1262. if (listen_mode == LISTEN_KERNEL)
  1263. len = udhcp_recv_kernel_packet(&packet, sockfd);
  1264. else
  1265. len = udhcp_recv_raw_packet(&packet, sockfd);
  1266. if (len == -1) {
  1267. /* Error is severe, reopen socket */
  1268. bb_info_msg("Read error: %s, reopening socket", strerror(errno));
  1269. sleep(discover_timeout); /* 3 seconds by default */
  1270. change_listen_mode(listen_mode); /* just close and reopen */
  1271. }
  1272. /* If this packet will turn out to be unrelated/bogus,
  1273. * we will go back and wait for next one.
  1274. * Be sure timeout is properly decreased. */
  1275. already_waited_sec += (unsigned)monotonic_sec() - timestamp_before_wait;
  1276. if (len < 0)
  1277. continue;
  1278. }
  1279. if (packet.xid != xid) {
  1280. log1("xid %x (our is %x), ignoring packet",
  1281. (unsigned)packet.xid, (unsigned)xid);
  1282. continue;
  1283. }
  1284. /* Ignore packets that aren't for us */
  1285. if (packet.hlen != 6
  1286. || memcmp(packet.chaddr, client_config.client_mac, 6) != 0
  1287. ) {
  1288. //FIXME: need to also check that last 10 bytes are zero
  1289. log1("chaddr does not match, ignoring packet"); // log2?
  1290. continue;
  1291. }
  1292. message = udhcp_get_option(&packet, DHCP_MESSAGE_TYPE);
  1293. if (message == NULL) {
  1294. bb_error_msg("no message type option, ignoring packet");
  1295. continue;
  1296. }
  1297. switch (state) {
  1298. case INIT_SELECTING:
  1299. /* Must be a DHCPOFFER to one of our xid's */
  1300. if (*message == DHCPOFFER) {
  1301. /* TODO: why we don't just fetch server's IP from IP header? */
  1302. temp = udhcp_get_option(&packet, DHCP_SERVER_ID);
  1303. if (!temp) {
  1304. bb_error_msg("no server ID, ignoring packet");
  1305. continue;
  1306. /* still selecting - this server looks bad */
  1307. }
  1308. /* it IS unaligned sometimes, don't "optimize" */
  1309. move_from_unaligned32(server_addr, temp);
  1310. /*xid = packet.xid; - already is */
  1311. requested_ip = packet.yiaddr;
  1312. /* enter requesting state */
  1313. state = REQUESTING;
  1314. timeout = 0;
  1315. packet_num = 0;
  1316. already_waited_sec = 0;
  1317. }
  1318. continue;
  1319. case REQUESTING:
  1320. case RENEWING:
  1321. case RENEW_REQUESTED:
  1322. case REBINDING:
  1323. if (*message == DHCPACK) {
  1324. temp = udhcp_get_option(&packet, DHCP_LEASE_TIME);
  1325. if (!temp) {
  1326. bb_error_msg("no lease time with ACK, using 1 hour lease");
  1327. lease_seconds = 60 * 60;
  1328. } else {
  1329. /* it IS unaligned sometimes, don't "optimize" */
  1330. move_from_unaligned32(lease_seconds, temp);
  1331. lease_seconds = ntohl(lease_seconds);
  1332. lease_seconds &= 0x0fffffff; /* paranoia: must not be prone to overflows */
  1333. if (lease_seconds < 10) /* and not too small */
  1334. lease_seconds = 10;
  1335. }
  1336. #if ENABLE_FEATURE_UDHCPC_ARPING
  1337. if (opt & OPT_a) {
  1338. /* RFC 2131 3.1 paragraph 5:
  1339. * "The client receives the DHCPACK message with configuration
  1340. * parameters. The client SHOULD perform a final check on the
  1341. * parameters (e.g., ARP for allocated network address), and notes
  1342. * the duration of the lease specified in the DHCPACK message. At this
  1343. * point, the client is configured. If the client detects that the
  1344. * address is already in use (e.g., through the use of ARP),
  1345. * the client MUST send a DHCPDECLINE message to the server and restarts
  1346. * the configuration process..." */
  1347. if (!arpping(packet.yiaddr,
  1348. NULL,
  1349. (uint32_t) 0,
  1350. client_config.client_mac,
  1351. client_config.interface)
  1352. ) {
  1353. bb_info_msg("Offered address is in use "
  1354. "(got ARP reply), declining");
  1355. send_decline(xid, server_addr, packet.yiaddr);
  1356. if (state != REQUESTING)
  1357. udhcp_run_script(NULL, "deconfig");
  1358. change_listen_mode(LISTEN_RAW);
  1359. state = INIT_SELECTING;
  1360. client_config.first_secs = 0; /* make secs field count from 0 */
  1361. requested_ip = 0;
  1362. timeout = tryagain_timeout;
  1363. packet_num = 0;
  1364. already_waited_sec = 0;
  1365. continue; /* back to main loop */
  1366. }
  1367. }
  1368. #endif
  1369. /* enter bound state */
  1370. timeout = lease_seconds / 2;
  1371. {
  1372. struct in_addr temp_addr;
  1373. temp_addr.s_addr = packet.yiaddr;
  1374. bb_info_msg("Lease of %s obtained, lease time %u",
  1375. inet_ntoa(temp_addr), (unsigned)lease_seconds);
  1376. }
  1377. requested_ip = packet.yiaddr;
  1378. udhcp_run_script(&packet, state == REQUESTING ? "bound" : "renew");
  1379. state = BOUND;
  1380. change_listen_mode(LISTEN_NONE);
  1381. if (opt & OPT_q) { /* quit after lease */
  1382. if (opt & OPT_R) /* release on quit */
  1383. perform_release(requested_ip, server_addr);
  1384. goto ret0;
  1385. }
  1386. /* future renew failures should not exit (JM) */
  1387. opt &= ~OPT_n;
  1388. #if BB_MMU /* NOMMU case backgrounded earlier */
  1389. if (!(opt & OPT_f)) {
  1390. client_background();
  1391. /* do not background again! */
  1392. opt = ((opt & ~OPT_b) | OPT_f);
  1393. }
  1394. #endif
  1395. already_waited_sec = 0;
  1396. continue; /* back to main loop */
  1397. }
  1398. if (*message == DHCPNAK) {
  1399. /* return to init state */
  1400. bb_info_msg("Received DHCP NAK");
  1401. udhcp_run_script(&packet, "nak");
  1402. if (state != REQUESTING)
  1403. udhcp_run_script(NULL, "deconfig");
  1404. change_listen_mode(LISTEN_RAW);
  1405. sleep(3); /* avoid excessive network traffic */
  1406. state = INIT_SELECTING;
  1407. client_config.first_secs = 0; /* make secs field count from 0 */
  1408. requested_ip = 0;
  1409. timeout = 0;
  1410. packet_num = 0;
  1411. already_waited_sec = 0;
  1412. }
  1413. continue;
  1414. /* case BOUND: - ignore all packets */
  1415. /* case RELEASED: - ignore all packets */
  1416. }
  1417. /* back to main loop */
  1418. } /* for (;;) - main loop ends */
  1419. ret0:
  1420. retval = 0;
  1421. ret:
  1422. /*if (client_config.pidfile) - remove_pidfile has its own check */
  1423. remove_pidfile(client_config.pidfile);
  1424. return retval;
  1425. }