Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288
  1. /*
  2. * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. FILE_LICENCE ( GPL2_OR_LATER );
  19. #include <stdint.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <strings.h>
  24. #include <byteswap.h>
  25. #include <errno.h>
  26. #include <assert.h>
  27. #include <gpxe/refcnt.h>
  28. #include <gpxe/xfer.h>
  29. #include <gpxe/open.h>
  30. #include <gpxe/uri.h>
  31. #include <gpxe/tcpip.h>
  32. #include <gpxe/retry.h>
  33. #include <gpxe/features.h>
  34. #include <gpxe/bitmap.h>
  35. #include <gpxe/settings.h>
  36. #include <gpxe/dhcp.h>
  37. #include <gpxe/uri.h>
  38. #include <gpxe/tftp.h>
  39. /** @file
  40. *
  41. * TFTP protocol
  42. *
  43. */
  44. FEATURE ( FEATURE_PROTOCOL, "TFTP", DHCP_EB_FEATURE_TFTP, 1 );
  45. /* TFTP-specific error codes */
  46. #define ETFTP_INVALID_BLKSIZE EUNIQ_01
  47. #define ETFTP_INVALID_TSIZE EUNIQ_02
  48. #define ETFTP_MC_NO_PORT EUNIQ_03
  49. #define ETFTP_MC_NO_MC EUNIQ_04
  50. #define ETFTP_MC_INVALID_MC EUNIQ_05
  51. #define ETFTP_MC_INVALID_IP EUNIQ_06
  52. #define ETFTP_MC_INVALID_PORT EUNIQ_07
  53. /**
  54. * A TFTP request
  55. *
  56. * This data structure holds the state for an ongoing TFTP transfer.
  57. */
  58. struct tftp_request {
  59. /** Reference count */
  60. struct refcnt refcnt;
  61. /** Data transfer interface */
  62. struct xfer_interface xfer;
  63. /** URI being fetched */
  64. struct uri *uri;
  65. /** Transport layer interface */
  66. struct xfer_interface socket;
  67. /** Multicast transport layer interface */
  68. struct xfer_interface mc_socket;
  69. /** Data block size
  70. *
  71. * This is the "blksize" option negotiated with the TFTP
  72. * server. (If the TFTP server does not support TFTP options,
  73. * this will default to 512).
  74. */
  75. unsigned int blksize;
  76. /** File size
  77. *
  78. * This is the value returned in the "tsize" option from the
  79. * TFTP server. If the TFTP server does not support the
  80. * "tsize" option, this value will be zero.
  81. */
  82. unsigned long tsize;
  83. /** Server port
  84. *
  85. * This is the port to which RRQ packets are sent.
  86. */
  87. unsigned int port;
  88. /** Peer address
  89. *
  90. * The peer address is determined by the first response
  91. * received to the TFTP RRQ.
  92. */
  93. struct sockaddr_tcpip peer;
  94. /** Request flags */
  95. unsigned int flags;
  96. /** MTFTP timeout count */
  97. unsigned int mtftp_timeouts;
  98. /** Block bitmap */
  99. struct bitmap bitmap;
  100. /** Maximum known length
  101. *
  102. * We don't always know the file length in advance. In
  103. * particular, if the TFTP server doesn't support the tsize
  104. * option, or we are using MTFTP, then we don't know the file
  105. * length until we see the end-of-file block (which, in the
  106. * case of MTFTP, may not be the last block we see).
  107. *
  108. * This value is updated whenever we obtain information about
  109. * the file length.
  110. */
  111. size_t filesize;
  112. /** Retransmission timer */
  113. struct retry_timer timer;
  114. };
  115. /** TFTP request flags */
  116. enum {
  117. /** Send ACK packets */
  118. TFTP_FL_SEND_ACK = 0x0001,
  119. /** Request blksize and tsize options */
  120. TFTP_FL_RRQ_SIZES = 0x0002,
  121. /** Request multicast option */
  122. TFTP_FL_RRQ_MULTICAST = 0x0004,
  123. /** Perform MTFTP recovery on timeout */
  124. TFTP_FL_MTFTP_RECOVERY = 0x0008,
  125. /** Only get filesize and then abort the transfer */
  126. TFTP_FL_SIZEONLY = 0x0010,
  127. };
  128. /** Maximum number of MTFTP open requests before falling back to TFTP */
  129. #define MTFTP_MAX_TIMEOUTS 3
  130. /**
  131. * Free TFTP request
  132. *
  133. * @v refcnt Reference counter
  134. */
  135. static void tftp_free ( struct refcnt *refcnt ) {
  136. struct tftp_request *tftp =
  137. container_of ( refcnt, struct tftp_request, refcnt );
  138. uri_put ( tftp->uri );
  139. bitmap_free ( &tftp->bitmap );
  140. free ( tftp );
  141. }
  142. /**
  143. * Mark TFTP request as complete
  144. *
  145. * @v tftp TFTP connection
  146. * @v rc Return status code
  147. */
  148. static void tftp_done ( struct tftp_request *tftp, int rc ) {
  149. DBGC ( tftp, "TFTP %p finished with status %d (%s)\n",
  150. tftp, rc, strerror ( rc ) );
  151. /* Stop the retry timer */
  152. stop_timer ( &tftp->timer );
  153. /* Close all data transfer interfaces */
  154. xfer_nullify ( &tftp->socket );
  155. xfer_close ( &tftp->socket, rc );
  156. xfer_nullify ( &tftp->mc_socket );
  157. xfer_close ( &tftp->mc_socket, rc );
  158. xfer_nullify ( &tftp->xfer );
  159. xfer_close ( &tftp->xfer, rc );
  160. }
  161. /**
  162. * Reopen TFTP socket
  163. *
  164. * @v tftp TFTP connection
  165. * @ret rc Return status code
  166. */
  167. static int tftp_reopen ( struct tftp_request *tftp ) {
  168. struct sockaddr_tcpip server;
  169. int rc;
  170. /* Close socket */
  171. xfer_close ( &tftp->socket, 0 );
  172. /* Disable ACK sending. */
  173. tftp->flags &= ~TFTP_FL_SEND_ACK;
  174. /* Reset peer address */
  175. memset ( &tftp->peer, 0, sizeof ( tftp->peer ) );
  176. /* Open socket */
  177. memset ( &server, 0, sizeof ( server ) );
  178. server.st_port = htons ( tftp->port );
  179. if ( ( rc = xfer_open_named_socket ( &tftp->socket, SOCK_DGRAM,
  180. ( struct sockaddr * ) &server,
  181. tftp->uri->host, NULL ) ) != 0 ) {
  182. DBGC ( tftp, "TFTP %p could not open socket: %s\n",
  183. tftp, strerror ( rc ) );
  184. return rc;
  185. }
  186. return 0;
  187. }
  188. /**
  189. * Reopen TFTP multicast socket
  190. *
  191. * @v tftp TFTP connection
  192. * @v local Local socket address
  193. * @ret rc Return status code
  194. */
  195. static int tftp_reopen_mc ( struct tftp_request *tftp,
  196. struct sockaddr *local ) {
  197. int rc;
  198. /* Close multicast socket */
  199. xfer_close ( &tftp->mc_socket, 0 );
  200. /* Open multicast socket. We never send via this socket, so
  201. * use the local address as the peer address (since the peer
  202. * address cannot be NULL).
  203. */
  204. if ( ( rc = xfer_open_socket ( &tftp->mc_socket, SOCK_DGRAM,
  205. local, local ) ) != 0 ) {
  206. DBGC ( tftp, "TFTP %p could not open multicast "
  207. "socket: %s\n", tftp, strerror ( rc ) );
  208. return rc;
  209. }
  210. return 0;
  211. }
  212. /**
  213. * Presize TFTP receive buffers and block bitmap
  214. *
  215. * @v tftp TFTP connection
  216. * @v filesize Known minimum file size
  217. * @ret rc Return status code
  218. */
  219. static int tftp_presize ( struct tftp_request *tftp, size_t filesize ) {
  220. unsigned int num_blocks;
  221. int rc;
  222. /* Do nothing if we are already large enough */
  223. if ( filesize <= tftp->filesize )
  224. return 0;
  225. /* Record filesize */
  226. tftp->filesize = filesize;
  227. /* Notify recipient of file size */
  228. xfer_seek ( &tftp->xfer, filesize, SEEK_SET );
  229. xfer_seek ( &tftp->xfer, 0, SEEK_SET );
  230. /* Calculate expected number of blocks. Note that files whose
  231. * length is an exact multiple of the blocksize will have a
  232. * trailing zero-length block, which must be included.
  233. */
  234. num_blocks = ( ( filesize / tftp->blksize ) + 1 );
  235. if ( ( rc = bitmap_resize ( &tftp->bitmap, num_blocks ) ) != 0 ) {
  236. DBGC ( tftp, "TFTP %p could not resize bitmap to %d blocks: "
  237. "%s\n", tftp, num_blocks, strerror ( rc ) );
  238. return rc;
  239. }
  240. return 0;
  241. }
  242. /**
  243. * TFTP requested blocksize
  244. *
  245. * This is treated as a global configuration parameter.
  246. */
  247. static unsigned int tftp_request_blksize = TFTP_MAX_BLKSIZE;
  248. /**
  249. * Set TFTP request blocksize
  250. *
  251. * @v blksize Requested block size
  252. */
  253. void tftp_set_request_blksize ( unsigned int blksize ) {
  254. if ( blksize < TFTP_DEFAULT_BLKSIZE )
  255. blksize = TFTP_DEFAULT_BLKSIZE;
  256. tftp_request_blksize = blksize;
  257. }
  258. /**
  259. * MTFTP multicast receive address
  260. *
  261. * This is treated as a global configuration parameter.
  262. */
  263. static struct sockaddr_in tftp_mtftp_socket = {
  264. .sin_family = AF_INET,
  265. .sin_addr.s_addr = htonl ( 0xefff0101 ),
  266. .sin_port = htons ( 3001 ),
  267. };
  268. /**
  269. * Set MTFTP multicast address
  270. *
  271. * @v address Multicast IPv4 address
  272. */
  273. void tftp_set_mtftp_address ( struct in_addr address ) {
  274. tftp_mtftp_socket.sin_addr = address;
  275. }
  276. /**
  277. * Set MTFTP multicast port
  278. *
  279. * @v port Multicast port
  280. */
  281. void tftp_set_mtftp_port ( unsigned int port ) {
  282. tftp_mtftp_socket.sin_port = htons ( port );
  283. }
  284. /**
  285. * Transmit RRQ
  286. *
  287. * @v tftp TFTP connection
  288. * @ret rc Return status code
  289. */
  290. static int tftp_send_rrq ( struct tftp_request *tftp ) {
  291. struct tftp_rrq *rrq;
  292. const char *path;
  293. size_t len;
  294. struct io_buffer *iobuf;
  295. /* Strip initial '/' if present. If we were opened via the
  296. * URI interface, then there will be an initial '/', since a
  297. * full tftp:// URI provides no way to specify a non-absolute
  298. * path. However, many TFTP servers (particularly Windows
  299. * TFTP servers) complain about having an initial '/', and it
  300. * violates user expectations to have a '/' silently added to
  301. * the DHCP-specified filename.
  302. */
  303. path = tftp->uri->path;
  304. if ( *path == '/' )
  305. path++;
  306. DBGC ( tftp, "TFTP %p requesting \"%s\"\n", tftp, path );
  307. /* Allocate buffer */
  308. len = ( sizeof ( *rrq ) + strlen ( path ) + 1 /* NUL */
  309. + 5 + 1 /* "octet" + NUL */
  310. + 7 + 1 + 5 + 1 /* "blksize" + NUL + ddddd + NUL */
  311. + 5 + 1 + 1 + 1 /* "tsize" + NUL + "0" + NUL */
  312. + 9 + 1 + 1 /* "multicast" + NUL + NUL */ );
  313. iobuf = xfer_alloc_iob ( &tftp->socket, len );
  314. if ( ! iobuf )
  315. return -ENOMEM;
  316. /* Build request */
  317. rrq = iob_put ( iobuf, sizeof ( *rrq ) );
  318. rrq->opcode = htons ( TFTP_RRQ );
  319. iob_put ( iobuf, snprintf ( iobuf->tail, iob_tailroom ( iobuf ),
  320. "%s%coctet", path, 0 ) + 1 );
  321. if ( tftp->flags & TFTP_FL_RRQ_SIZES ) {
  322. iob_put ( iobuf, snprintf ( iobuf->tail,
  323. iob_tailroom ( iobuf ),
  324. "blksize%c%d%ctsize%c0", 0,
  325. tftp_request_blksize, 0, 0 ) + 1 );
  326. }
  327. if ( tftp->flags & TFTP_FL_RRQ_MULTICAST ) {
  328. iob_put ( iobuf, snprintf ( iobuf->tail,
  329. iob_tailroom ( iobuf ),
  330. "multicast%c", 0 ) + 1 );
  331. }
  332. /* RRQ always goes to the address specified in the initial
  333. * xfer_open() call
  334. */
  335. return xfer_deliver_iob ( &tftp->socket, iobuf );
  336. }
  337. /**
  338. * Transmit ACK
  339. *
  340. * @v tftp TFTP connection
  341. * @ret rc Return status code
  342. */
  343. static int tftp_send_ack ( struct tftp_request *tftp ) {
  344. struct tftp_ack *ack;
  345. struct io_buffer *iobuf;
  346. struct xfer_metadata meta = {
  347. .dest = ( struct sockaddr * ) &tftp->peer,
  348. };
  349. unsigned int block;
  350. /* Determine next required block number */
  351. block = bitmap_first_gap ( &tftp->bitmap );
  352. DBGC2 ( tftp, "TFTP %p sending ACK for block %d\n", tftp, block );
  353. /* Allocate buffer */
  354. iobuf = xfer_alloc_iob ( &tftp->socket, sizeof ( *ack ) );
  355. if ( ! iobuf )
  356. return -ENOMEM;
  357. /* Build ACK */
  358. ack = iob_put ( iobuf, sizeof ( *ack ) );
  359. ack->opcode = htons ( TFTP_ACK );
  360. ack->block = htons ( block );
  361. /* ACK always goes to the peer recorded from the RRQ response */
  362. return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta );
  363. }
  364. /**
  365. * Transmit ERROR (Abort)
  366. *
  367. * @v tftp TFTP connection
  368. * @v errcode TFTP error code
  369. * @v errmsg Error message string
  370. * @ret rc Return status code
  371. */
  372. static int tftp_send_error ( struct tftp_request *tftp, int errcode,
  373. const char *errmsg ) {
  374. struct tftp_error *err;
  375. struct io_buffer *iobuf;
  376. struct xfer_metadata meta = {
  377. .dest = ( struct sockaddr * ) &tftp->peer,
  378. };
  379. size_t msglen;
  380. DBGC2 ( tftp, "TFTP %p sending ERROR %d: %s\n", tftp, errcode,
  381. errmsg );
  382. /* Allocate buffer */
  383. msglen = sizeof ( *err ) + strlen ( errmsg ) + 1 /* NUL */;
  384. iobuf = xfer_alloc_iob ( &tftp->socket, msglen );
  385. if ( ! iobuf )
  386. return -ENOMEM;
  387. /* Build ERROR */
  388. err = iob_put ( iobuf, msglen );
  389. err->opcode = htons ( TFTP_ERROR );
  390. err->errcode = htons ( errcode );
  391. strcpy ( err->errmsg, errmsg );
  392. /* ERR always goes to the peer recorded from the RRQ response */
  393. return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta );
  394. }
  395. /**
  396. * Transmit next relevant packet
  397. *
  398. * @v tftp TFTP connection
  399. * @ret rc Return status code
  400. */
  401. static int tftp_send_packet ( struct tftp_request *tftp ) {
  402. /* Update retransmission timer. While name resolution takes place the
  403. * window is zero. Avoid unnecessary delay after name resolution
  404. * completes by retrying immediately.
  405. */
  406. stop_timer ( &tftp->timer );
  407. if ( xfer_window ( &tftp->socket ) ) {
  408. start_timer ( &tftp->timer );
  409. } else {
  410. start_timer_nodelay ( &tftp->timer );
  411. }
  412. /* Send RRQ or ACK as appropriate */
  413. if ( ! tftp->peer.st_family ) {
  414. return tftp_send_rrq ( tftp );
  415. } else {
  416. if ( tftp->flags & TFTP_FL_SEND_ACK ) {
  417. return tftp_send_ack ( tftp );
  418. } else {
  419. return 0;
  420. }
  421. }
  422. }
  423. /**
  424. * Handle TFTP retransmission timer expiry
  425. *
  426. * @v timer Retry timer
  427. * @v fail Failure indicator
  428. */
  429. static void tftp_timer_expired ( struct retry_timer *timer, int fail ) {
  430. struct tftp_request *tftp =
  431. container_of ( timer, struct tftp_request, timer );
  432. int rc;
  433. /* If we are doing MTFTP, attempt the various recovery strategies */
  434. if ( tftp->flags & TFTP_FL_MTFTP_RECOVERY ) {
  435. if ( tftp->peer.st_family ) {
  436. /* If we have received any response from the server,
  437. * try resending the RRQ to restart the download.
  438. */
  439. DBGC ( tftp, "TFTP %p attempting reopen\n", tftp );
  440. if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
  441. goto err;
  442. } else {
  443. /* Fall back to plain TFTP after several attempts */
  444. tftp->mtftp_timeouts++;
  445. DBGC ( tftp, "TFTP %p timeout %d waiting for MTFTP "
  446. "open\n", tftp, tftp->mtftp_timeouts );
  447. if ( tftp->mtftp_timeouts > MTFTP_MAX_TIMEOUTS ) {
  448. DBGC ( tftp, "TFTP %p falling back to plain "
  449. "TFTP\n", tftp );
  450. tftp->flags = TFTP_FL_RRQ_SIZES;
  451. /* Close multicast socket */
  452. xfer_close ( &tftp->mc_socket, 0 );
  453. /* Reset retry timer */
  454. start_timer_nodelay ( &tftp->timer );
  455. /* The blocksize may change: discard
  456. * the block bitmap
  457. */
  458. bitmap_free ( &tftp->bitmap );
  459. memset ( &tftp->bitmap, 0,
  460. sizeof ( tftp->bitmap ) );
  461. /* Reopen on standard TFTP port */
  462. tftp->port = TFTP_PORT;
  463. if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
  464. goto err;
  465. }
  466. }
  467. } else {
  468. /* Not doing MTFTP (or have fallen back to plain
  469. * TFTP); fail as per normal.
  470. */
  471. if ( fail ) {
  472. rc = -ETIMEDOUT;
  473. goto err;
  474. }
  475. }
  476. tftp_send_packet ( tftp );
  477. return;
  478. err:
  479. tftp_done ( tftp, rc );
  480. }
  481. /**
  482. * Process TFTP "blksize" option
  483. *
  484. * @v tftp TFTP connection
  485. * @v value Option value
  486. * @ret rc Return status code
  487. */
  488. static int tftp_process_blksize ( struct tftp_request *tftp,
  489. const char *value ) {
  490. char *end;
  491. tftp->blksize = strtoul ( value, &end, 10 );
  492. if ( *end ) {
  493. DBGC ( tftp, "TFTP %p got invalid blksize \"%s\"\n",
  494. tftp, value );
  495. return -( EINVAL | ETFTP_INVALID_BLKSIZE );
  496. }
  497. DBGC ( tftp, "TFTP %p blksize=%d\n", tftp, tftp->blksize );
  498. return 0;
  499. }
  500. /**
  501. * Process TFTP "tsize" option
  502. *
  503. * @v tftp TFTP connection
  504. * @v value Option value
  505. * @ret rc Return status code
  506. */
  507. static int tftp_process_tsize ( struct tftp_request *tftp,
  508. const char *value ) {
  509. char *end;
  510. tftp->tsize = strtoul ( value, &end, 10 );
  511. if ( *end ) {
  512. DBGC ( tftp, "TFTP %p got invalid tsize \"%s\"\n",
  513. tftp, value );
  514. return -( EINVAL | ETFTP_INVALID_TSIZE );
  515. }
  516. DBGC ( tftp, "TFTP %p tsize=%ld\n", tftp, tftp->tsize );
  517. return 0;
  518. }
  519. /**
  520. * Process TFTP "multicast" option
  521. *
  522. * @v tftp TFTP connection
  523. * @v value Option value
  524. * @ret rc Return status code
  525. */
  526. static int tftp_process_multicast ( struct tftp_request *tftp,
  527. const char *value ) {
  528. union {
  529. struct sockaddr sa;
  530. struct sockaddr_in sin;
  531. } socket;
  532. char buf[ strlen ( value ) + 1 ];
  533. char *addr;
  534. char *port;
  535. char *port_end;
  536. char *mc;
  537. char *mc_end;
  538. int rc;
  539. /* Split value into "addr,port,mc" fields */
  540. memcpy ( buf, value, sizeof ( buf ) );
  541. addr = buf;
  542. port = strchr ( addr, ',' );
  543. if ( ! port ) {
  544. DBGC ( tftp, "TFTP %p multicast missing port,mc\n", tftp );
  545. return -( EINVAL | ETFTP_MC_NO_PORT );
  546. }
  547. *(port++) = '\0';
  548. mc = strchr ( port, ',' );
  549. if ( ! mc ) {
  550. DBGC ( tftp, "TFTP %p multicast missing mc\n", tftp );
  551. return -( EINVAL | ETFTP_MC_NO_MC );
  552. }
  553. *(mc++) = '\0';
  554. /* Parse parameters */
  555. if ( strtoul ( mc, &mc_end, 0 ) == 0 )
  556. tftp->flags &= ~TFTP_FL_SEND_ACK;
  557. if ( *mc_end ) {
  558. DBGC ( tftp, "TFTP %p multicast invalid mc %s\n", tftp, mc );
  559. return -( EINVAL | ETFTP_MC_INVALID_MC );
  560. }
  561. DBGC ( tftp, "TFTP %p is%s the master client\n",
  562. tftp, ( ( tftp->flags & TFTP_FL_SEND_ACK ) ? "" : " not" ) );
  563. if ( *addr && *port ) {
  564. socket.sin.sin_family = AF_INET;
  565. if ( inet_aton ( addr, &socket.sin.sin_addr ) == 0 ) {
  566. DBGC ( tftp, "TFTP %p multicast invalid IP address "
  567. "%s\n", tftp, addr );
  568. return -( EINVAL | ETFTP_MC_INVALID_IP );
  569. }
  570. DBGC ( tftp, "TFTP %p multicast IP address %s\n",
  571. tftp, inet_ntoa ( socket.sin.sin_addr ) );
  572. socket.sin.sin_port = htons ( strtoul ( port, &port_end, 0 ) );
  573. if ( *port_end ) {
  574. DBGC ( tftp, "TFTP %p multicast invalid port %s\n",
  575. tftp, port );
  576. return -( EINVAL | ETFTP_MC_INVALID_PORT );
  577. }
  578. DBGC ( tftp, "TFTP %p multicast port %d\n",
  579. tftp, ntohs ( socket.sin.sin_port ) );
  580. if ( ( rc = tftp_reopen_mc ( tftp, &socket.sa ) ) != 0 )
  581. return rc;
  582. }
  583. return 0;
  584. }
  585. /** A TFTP option */
  586. struct tftp_option {
  587. /** Option name */
  588. const char *name;
  589. /** Option processor
  590. *
  591. * @v tftp TFTP connection
  592. * @v value Option value
  593. * @ret rc Return status code
  594. */
  595. int ( * process ) ( struct tftp_request *tftp, const char *value );
  596. };
  597. /** Recognised TFTP options */
  598. static struct tftp_option tftp_options[] = {
  599. { "blksize", tftp_process_blksize },
  600. { "tsize", tftp_process_tsize },
  601. { "multicast", tftp_process_multicast },
  602. { NULL, NULL }
  603. };
  604. /**
  605. * Process TFTP option
  606. *
  607. * @v tftp TFTP connection
  608. * @v name Option name
  609. * @v value Option value
  610. * @ret rc Return status code
  611. */
  612. static int tftp_process_option ( struct tftp_request *tftp,
  613. const char *name, const char *value ) {
  614. struct tftp_option *option;
  615. for ( option = tftp_options ; option->name ; option++ ) {
  616. if ( strcasecmp ( name, option->name ) == 0 )
  617. return option->process ( tftp, value );
  618. }
  619. DBGC ( tftp, "TFTP %p received unknown option \"%s\" = \"%s\"\n",
  620. tftp, name, value );
  621. /* Unknown options should be silently ignored */
  622. return 0;
  623. }
  624. /**
  625. * Receive OACK
  626. *
  627. * @v tftp TFTP connection
  628. * @v buf Temporary data buffer
  629. * @v len Length of temporary data buffer
  630. * @ret rc Return status code
  631. */
  632. static int tftp_rx_oack ( struct tftp_request *tftp, void *buf, size_t len ) {
  633. struct tftp_oack *oack = buf;
  634. char *end = buf + len;
  635. char *name;
  636. char *value;
  637. char *next;
  638. int rc = 0;
  639. /* Sanity check */
  640. if ( len < sizeof ( *oack ) ) {
  641. DBGC ( tftp, "TFTP %p received underlength OACK packet "
  642. "length %zd\n", tftp, len );
  643. rc = -EINVAL;
  644. goto done;
  645. }
  646. /* Process each option in turn */
  647. for ( name = oack->data ; name < end ; name = next ) {
  648. /* Parse option name and value
  649. *
  650. * We treat parsing errors as non-fatal, because there
  651. * exists at least one TFTP server (IBM Tivoli PXE
  652. * Server 5.1.0.3) that has been observed to send
  653. * malformed OACKs containing trailing garbage bytes.
  654. */
  655. value = ( name + strnlen ( name, ( end - name ) ) + 1 );
  656. if ( value > end ) {
  657. DBGC ( tftp, "TFTP %p received OACK with malformed "
  658. "option name:\n", tftp );
  659. DBGC_HD ( tftp, oack, len );
  660. break;
  661. }
  662. if ( value == end ) {
  663. DBGC ( tftp, "TFTP %p received OACK missing value "
  664. "for option \"%s\"\n", tftp, name );
  665. DBGC_HD ( tftp, oack, len );
  666. break;
  667. }
  668. next = ( value + strnlen ( value, ( end - value ) ) + 1 );
  669. if ( next > end ) {
  670. DBGC ( tftp, "TFTP %p received OACK with malformed "
  671. "value for option \"%s\":\n", tftp, name );
  672. DBGC_HD ( tftp, oack, len );
  673. break;
  674. }
  675. /* Process option */
  676. if ( ( rc = tftp_process_option ( tftp, name, value ) ) != 0 )
  677. goto done;
  678. }
  679. /* Process tsize information, if available */
  680. if ( tftp->tsize ) {
  681. if ( ( rc = tftp_presize ( tftp, tftp->tsize ) ) != 0 )
  682. goto done;
  683. }
  684. /* Abort request if only trying to determine file size */
  685. if ( tftp->flags & TFTP_FL_SIZEONLY ) {
  686. rc = 0;
  687. tftp_send_error ( tftp, 0, "TFTP Aborted" );
  688. tftp_done ( tftp, rc );
  689. return rc;
  690. }
  691. /* Request next data block */
  692. tftp_send_packet ( tftp );
  693. done:
  694. if ( rc )
  695. tftp_done ( tftp, rc );
  696. return rc;
  697. }
  698. /**
  699. * Receive DATA
  700. *
  701. * @v tftp TFTP connection
  702. * @v iobuf I/O buffer
  703. * @ret rc Return status code
  704. *
  705. * Takes ownership of I/O buffer.
  706. */
  707. static int tftp_rx_data ( struct tftp_request *tftp,
  708. struct io_buffer *iobuf ) {
  709. struct tftp_data *data = iobuf->data;
  710. struct xfer_metadata meta;
  711. unsigned int block;
  712. off_t offset;
  713. size_t data_len;
  714. int rc;
  715. if ( tftp->flags & TFTP_FL_SIZEONLY ) {
  716. /* If we get here then server doesn't support SIZE option */
  717. rc = -ENOTSUP;
  718. tftp_send_error ( tftp, 0, "TFTP Aborted" );
  719. goto done;
  720. }
  721. /* Sanity check */
  722. if ( iob_len ( iobuf ) < sizeof ( *data ) ) {
  723. DBGC ( tftp, "TFTP %p received underlength DATA packet "
  724. "length %zd\n", tftp, iob_len ( iobuf ) );
  725. rc = -EINVAL;
  726. goto done;
  727. }
  728. /* Calculate block number */
  729. block = ( ( bitmap_first_gap ( &tftp->bitmap ) + 1 ) & ~0xffff );
  730. if ( data->block == 0 && block == 0 ) {
  731. DBGC ( tftp, "TFTP %p received data block 0\n", tftp );
  732. rc = -EINVAL;
  733. goto done;
  734. }
  735. block += ( ntohs ( data->block ) - 1 );
  736. /* Extract data */
  737. offset = ( block * tftp->blksize );
  738. iob_pull ( iobuf, sizeof ( *data ) );
  739. data_len = iob_len ( iobuf );
  740. if ( data_len > tftp->blksize ) {
  741. DBGC ( tftp, "TFTP %p received overlength DATA packet "
  742. "length %zd\n", tftp, data_len );
  743. rc = -EINVAL;
  744. goto done;
  745. }
  746. /* Deliver data */
  747. memset ( &meta, 0, sizeof ( meta ) );
  748. meta.whence = SEEK_SET;
  749. meta.offset = offset;
  750. if ( ( rc = xfer_deliver_iob_meta ( &tftp->xfer, iob_disown ( iobuf ),
  751. &meta ) ) != 0 ) {
  752. DBGC ( tftp, "TFTP %p could not deliver data: %s\n",
  753. tftp, strerror ( rc ) );
  754. goto done;
  755. }
  756. /* Ensure block bitmap is ready */
  757. if ( ( rc = tftp_presize ( tftp, ( offset + data_len ) ) ) != 0 )
  758. goto done;
  759. /* Mark block as received */
  760. bitmap_set ( &tftp->bitmap, block );
  761. /* Acknowledge block */
  762. tftp_send_packet ( tftp );
  763. /* If all blocks have been received, finish. */
  764. if ( bitmap_full ( &tftp->bitmap ) )
  765. tftp_done ( tftp, 0 );
  766. done:
  767. free_iob ( iobuf );
  768. if ( rc )
  769. tftp_done ( tftp, rc );
  770. return rc;
  771. }
  772. /** Translation between TFTP errors and internal error numbers */
  773. static const int tftp_errors[] = {
  774. [TFTP_ERR_FILE_NOT_FOUND] = ENOENT,
  775. [TFTP_ERR_ACCESS_DENIED] = EACCES,
  776. [TFTP_ERR_ILLEGAL_OP] = ENOTSUP,
  777. };
  778. /**
  779. * Receive ERROR
  780. *
  781. * @v tftp TFTP connection
  782. * @v buf Temporary data buffer
  783. * @v len Length of temporary data buffer
  784. * @ret rc Return status code
  785. */
  786. static int tftp_rx_error ( struct tftp_request *tftp, void *buf, size_t len ) {
  787. struct tftp_error *error = buf;
  788. unsigned int err;
  789. int rc = 0;
  790. /* Sanity check */
  791. if ( len < sizeof ( *error ) ) {
  792. DBGC ( tftp, "TFTP %p received underlength ERROR packet "
  793. "length %zd\n", tftp, len );
  794. return -EINVAL;
  795. }
  796. DBGC ( tftp, "TFTP %p received ERROR packet with code %d, message "
  797. "\"%s\"\n", tftp, ntohs ( error->errcode ), error->errmsg );
  798. /* Determine final operation result */
  799. err = ntohs ( error->errcode );
  800. if ( err < ( sizeof ( tftp_errors ) / sizeof ( tftp_errors[0] ) ) )
  801. rc = -tftp_errors[err];
  802. if ( ! rc )
  803. rc = -ENOTSUP;
  804. /* Close TFTP request */
  805. tftp_done ( tftp, rc );
  806. return 0;
  807. }
  808. /**
  809. * Receive new data
  810. *
  811. * @v tftp TFTP connection
  812. * @v iobuf I/O buffer
  813. * @v meta Transfer metadata
  814. * @ret rc Return status code
  815. */
  816. static int tftp_rx ( struct tftp_request *tftp,
  817. struct io_buffer *iobuf,
  818. struct xfer_metadata *meta ) {
  819. struct sockaddr_tcpip *st_src;
  820. struct tftp_common *common = iobuf->data;
  821. size_t len = iob_len ( iobuf );
  822. int rc = -EINVAL;
  823. /* Sanity checks */
  824. if ( len < sizeof ( *common ) ) {
  825. DBGC ( tftp, "TFTP %p received underlength packet length "
  826. "%zd\n", tftp, len );
  827. goto done;
  828. }
  829. if ( ! meta->src ) {
  830. DBGC ( tftp, "TFTP %p received packet without source port\n",
  831. tftp );
  832. goto done;
  833. }
  834. /* Filter by TID. Set TID on first response received */
  835. st_src = ( struct sockaddr_tcpip * ) meta->src;
  836. if ( ! tftp->peer.st_family ) {
  837. memcpy ( &tftp->peer, st_src, sizeof ( tftp->peer ) );
  838. DBGC ( tftp, "TFTP %p using remote port %d\n", tftp,
  839. ntohs ( tftp->peer.st_port ) );
  840. } else if ( memcmp ( &tftp->peer, st_src,
  841. sizeof ( tftp->peer ) ) != 0 ) {
  842. DBGC ( tftp, "TFTP %p received packet from wrong source (got "
  843. "%d, wanted %d)\n", tftp, ntohs ( st_src->st_port ),
  844. ntohs ( tftp->peer.st_port ) );
  845. goto done;
  846. }
  847. switch ( common->opcode ) {
  848. case htons ( TFTP_OACK ):
  849. rc = tftp_rx_oack ( tftp, iobuf->data, len );
  850. break;
  851. case htons ( TFTP_DATA ):
  852. rc = tftp_rx_data ( tftp, iob_disown ( iobuf ) );
  853. break;
  854. case htons ( TFTP_ERROR ):
  855. rc = tftp_rx_error ( tftp, iobuf->data, len );
  856. break;
  857. default:
  858. DBGC ( tftp, "TFTP %p received strange packet type %d\n",
  859. tftp, ntohs ( common->opcode ) );
  860. break;
  861. };
  862. done:
  863. free_iob ( iobuf );
  864. return rc;
  865. }
  866. /**
  867. * Receive new data via socket
  868. *
  869. * @v socket Transport layer interface
  870. * @v iobuf I/O buffer
  871. * @v meta Transfer metadata
  872. * @ret rc Return status code
  873. */
  874. static int tftp_socket_deliver_iob ( struct xfer_interface *socket,
  875. struct io_buffer *iobuf,
  876. struct xfer_metadata *meta ) {
  877. struct tftp_request *tftp =
  878. container_of ( socket, struct tftp_request, socket );
  879. /* Enable sending ACKs when we receive a unicast packet. This
  880. * covers three cases:
  881. *
  882. * 1. Standard TFTP; we should always send ACKs, and will
  883. * always receive a unicast packet before we need to send the
  884. * first ACK.
  885. *
  886. * 2. RFC2090 multicast TFTP; the only unicast packets we will
  887. * receive are the OACKs; enable sending ACKs here (before
  888. * processing the OACK) and disable it when processing the
  889. * multicast option if we are not the master client.
  890. *
  891. * 3. MTFTP; receiving a unicast datagram indicates that we
  892. * are the "master client" and should send ACKs.
  893. */
  894. tftp->flags |= TFTP_FL_SEND_ACK;
  895. return tftp_rx ( tftp, iobuf, meta );
  896. }
  897. /** TFTP socket operations */
  898. static struct xfer_interface_operations tftp_socket_operations = {
  899. .close = ignore_xfer_close,
  900. .vredirect = xfer_vreopen,
  901. .window = unlimited_xfer_window,
  902. .alloc_iob = default_xfer_alloc_iob,
  903. .deliver_iob = tftp_socket_deliver_iob,
  904. .deliver_raw = xfer_deliver_as_iob,
  905. };
  906. /**
  907. * Receive new data via multicast socket
  908. *
  909. * @v mc_socket Multicast transport layer interface
  910. * @v iobuf I/O buffer
  911. * @v meta Transfer metadata
  912. * @ret rc Return status code
  913. */
  914. static int tftp_mc_socket_deliver_iob ( struct xfer_interface *mc_socket,
  915. struct io_buffer *iobuf,
  916. struct xfer_metadata *meta ) {
  917. struct tftp_request *tftp =
  918. container_of ( mc_socket, struct tftp_request, mc_socket );
  919. return tftp_rx ( tftp, iobuf, meta );
  920. }
  921. /** TFTP multicast socket operations */
  922. static struct xfer_interface_operations tftp_mc_socket_operations = {
  923. .close = ignore_xfer_close,
  924. .vredirect = xfer_vreopen,
  925. .window = unlimited_xfer_window,
  926. .alloc_iob = default_xfer_alloc_iob,
  927. .deliver_iob = tftp_mc_socket_deliver_iob,
  928. .deliver_raw = xfer_deliver_as_iob,
  929. };
  930. /**
  931. * Close TFTP data transfer interface
  932. *
  933. * @v xfer Data transfer interface
  934. * @v rc Reason for close
  935. */
  936. static void tftp_xfer_close ( struct xfer_interface *xfer, int rc ) {
  937. struct tftp_request *tftp =
  938. container_of ( xfer, struct tftp_request, xfer );
  939. DBGC ( tftp, "TFTP %p interface closed: %s\n",
  940. tftp, strerror ( rc ) );
  941. tftp_done ( tftp, rc );
  942. }
  943. /**
  944. * Check flow control window
  945. *
  946. * @v xfer Data transfer interface
  947. * @ret len Length of window
  948. */
  949. static size_t tftp_xfer_window ( struct xfer_interface *xfer ) {
  950. struct tftp_request *tftp =
  951. container_of ( xfer, struct tftp_request, xfer );
  952. /* We abuse this data-xfer method to convey the blocksize to
  953. * the caller. This really should be done using some kind of
  954. * stat() method, but we don't yet have the facility to do
  955. * that.
  956. */
  957. return tftp->blksize;
  958. }
  959. /** TFTP data transfer interface operations */
  960. static struct xfer_interface_operations tftp_xfer_operations = {
  961. .close = tftp_xfer_close,
  962. .vredirect = ignore_xfer_vredirect,
  963. .window = tftp_xfer_window,
  964. .alloc_iob = default_xfer_alloc_iob,
  965. .deliver_iob = xfer_deliver_as_raw,
  966. .deliver_raw = ignore_xfer_deliver_raw,
  967. };
  968. /**
  969. * Initiate TFTP/TFTM/MTFTP download
  970. *
  971. * @v xfer Data transfer interface
  972. * @v uri Uniform Resource Identifier
  973. * @ret rc Return status code
  974. */
  975. static int tftp_core_open ( struct xfer_interface *xfer, struct uri *uri,
  976. unsigned int default_port,
  977. struct sockaddr *multicast,
  978. unsigned int flags ) {
  979. struct tftp_request *tftp;
  980. int rc;
  981. /* Sanity checks */
  982. if ( ! uri->host )
  983. return -EINVAL;
  984. if ( ! uri->path )
  985. return -EINVAL;
  986. /* Allocate and populate TFTP structure */
  987. tftp = zalloc ( sizeof ( *tftp ) );
  988. if ( ! tftp )
  989. return -ENOMEM;
  990. tftp->refcnt.free = tftp_free;
  991. xfer_init ( &tftp->xfer, &tftp_xfer_operations, &tftp->refcnt );
  992. tftp->uri = uri_get ( uri );
  993. xfer_init ( &tftp->socket, &tftp_socket_operations, &tftp->refcnt );
  994. xfer_init ( &tftp->mc_socket, &tftp_mc_socket_operations,
  995. &tftp->refcnt );
  996. tftp->blksize = TFTP_DEFAULT_BLKSIZE;
  997. tftp->flags = flags;
  998. tftp->timer.expired = tftp_timer_expired;
  999. /* Open socket */
  1000. tftp->port = uri_port ( tftp->uri, default_port );
  1001. if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
  1002. goto err;
  1003. /* Open multicast socket */
  1004. if ( multicast ) {
  1005. if ( ( rc = tftp_reopen_mc ( tftp, multicast ) ) != 0 )
  1006. goto err;
  1007. }
  1008. /* Start timer to initiate RRQ */
  1009. start_timer_nodelay ( &tftp->timer );
  1010. /* Attach to parent interface, mortalise self, and return */
  1011. xfer_plug_plug ( &tftp->xfer, xfer );
  1012. ref_put ( &tftp->refcnt );
  1013. return 0;
  1014. err:
  1015. DBGC ( tftp, "TFTP %p could not create request: %s\n",
  1016. tftp, strerror ( rc ) );
  1017. tftp_done ( tftp, rc );
  1018. ref_put ( &tftp->refcnt );
  1019. return rc;
  1020. }
  1021. /**
  1022. * Initiate TFTP download
  1023. *
  1024. * @v xfer Data transfer interface
  1025. * @v uri Uniform Resource Identifier
  1026. * @ret rc Return status code
  1027. */
  1028. static int tftp_open ( struct xfer_interface *xfer, struct uri *uri ) {
  1029. return tftp_core_open ( xfer, uri, TFTP_PORT, NULL,
  1030. TFTP_FL_RRQ_SIZES );
  1031. }
  1032. /** TFTP URI opener */
  1033. struct uri_opener tftp_uri_opener __uri_opener = {
  1034. .scheme = "tftp",
  1035. .open = tftp_open,
  1036. };
  1037. /**
  1038. * Initiate TFTP-size request
  1039. *
  1040. * @v xfer Data transfer interface
  1041. * @v uri Uniform Resource Identifier
  1042. * @ret rc Return status code
  1043. */
  1044. static int tftpsize_open ( struct xfer_interface *xfer, struct uri *uri ) {
  1045. return tftp_core_open ( xfer, uri, TFTP_PORT, NULL,
  1046. ( TFTP_FL_RRQ_SIZES |
  1047. TFTP_FL_SIZEONLY ) );
  1048. }
  1049. /** TFTP URI opener */
  1050. struct uri_opener tftpsize_uri_opener __uri_opener = {
  1051. .scheme = "tftpsize",
  1052. .open = tftpsize_open,
  1053. };
  1054. /**
  1055. * Initiate TFTM download
  1056. *
  1057. * @v xfer Data transfer interface
  1058. * @v uri Uniform Resource Identifier
  1059. * @ret rc Return status code
  1060. */
  1061. static int tftm_open ( struct xfer_interface *xfer, struct uri *uri ) {
  1062. return tftp_core_open ( xfer, uri, TFTP_PORT, NULL,
  1063. ( TFTP_FL_RRQ_SIZES |
  1064. TFTP_FL_RRQ_MULTICAST ) );
  1065. }
  1066. /** TFTM URI opener */
  1067. struct uri_opener tftm_uri_opener __uri_opener = {
  1068. .scheme = "tftm",
  1069. .open = tftm_open,
  1070. };
  1071. /**
  1072. * Initiate MTFTP download
  1073. *
  1074. * @v xfer Data transfer interface
  1075. * @v uri Uniform Resource Identifier
  1076. * @ret rc Return status code
  1077. */
  1078. static int mtftp_open ( struct xfer_interface *xfer, struct uri *uri ) {
  1079. return tftp_core_open ( xfer, uri, MTFTP_PORT,
  1080. ( struct sockaddr * ) &tftp_mtftp_socket,
  1081. TFTP_FL_MTFTP_RECOVERY );
  1082. }
  1083. /** MTFTP URI opener */
  1084. struct uri_opener mtftp_uri_opener __uri_opener = {
  1085. .scheme = "mtftp",
  1086. .open = mtftp_open,
  1087. };
  1088. /******************************************************************************
  1089. *
  1090. * Settings
  1091. *
  1092. ******************************************************************************
  1093. */
  1094. /** TFTP server setting */
  1095. struct setting next_server_setting __setting = {
  1096. .name = "next-server",
  1097. .description = "TFTP server",
  1098. .tag = DHCP_EB_SIADDR,
  1099. .type = &setting_type_ipv4,
  1100. };
  1101. /**
  1102. * Apply TFTP configuration settings
  1103. *
  1104. * @ret rc Return status code
  1105. */
  1106. static int tftp_apply_settings ( void ) {
  1107. static struct in_addr tftp_server = { 0 };
  1108. struct in_addr last_tftp_server;
  1109. char uri_string[32];
  1110. struct uri *uri;
  1111. /* Retrieve TFTP server setting */
  1112. last_tftp_server = tftp_server;
  1113. fetch_ipv4_setting ( NULL, &next_server_setting, &tftp_server );
  1114. /* If TFTP server setting has changed, set the current working
  1115. * URI to match. Do it only when the TFTP server has changed
  1116. * to try to minimise surprises to the user, who probably
  1117. * won't expect the CWURI to change just because they updated
  1118. * an unrelated setting and triggered all the settings
  1119. * applicators.
  1120. */
  1121. if ( tftp_server.s_addr != last_tftp_server.s_addr ) {
  1122. snprintf ( uri_string, sizeof ( uri_string ),
  1123. "tftp://%s/", inet_ntoa ( tftp_server ) );
  1124. uri = parse_uri ( uri_string );
  1125. if ( ! uri )
  1126. return -ENOMEM;
  1127. churi ( uri );
  1128. uri_put ( uri );
  1129. }
  1130. return 0;
  1131. }
  1132. /** TFTP settings applicator */
  1133. struct settings_applicator tftp_settings_applicator __settings_applicator = {
  1134. .apply = tftp_apply_settings,
  1135. };