tftp.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 2010,2011 Free Software Foundation, Inc.
  4. *
  5. * GRUB is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * GRUB is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <grub/misc.h>
  19. #include <grub/net/udp.h>
  20. #include <grub/net/ip.h>
  21. #include <grub/net/ethernet.h>
  22. #include <grub/net/netbuff.h>
  23. #include <grub/net.h>
  24. #include <grub/mm.h>
  25. #include <grub/dl.h>
  26. #include <grub/file.h>
  27. #include <grub/i18n.h>
  28. GRUB_MOD_LICENSE ("GPLv3+");
  29. /* IP port for the MTFTP server used for Intel's PXE */
  30. enum
  31. {
  32. MTFTP_SERVER_PORT = 75,
  33. MTFTP_CLIENT_PORT = 76,
  34. /* IP port for the TFTP server */
  35. TFTP_SERVER_PORT = 69
  36. };
  37. enum
  38. {
  39. TFTP_DEFAULTSIZE_PACKET = 512,
  40. };
  41. enum
  42. {
  43. TFTP_CODE_EOF = 1,
  44. TFTP_CODE_MORE = 2,
  45. TFTP_CODE_ERROR = 3,
  46. TFTP_CODE_BOOT = 4,
  47. TFTP_CODE_CFG = 5
  48. };
  49. enum
  50. {
  51. TFTP_RRQ = 1,
  52. TFTP_WRQ = 2,
  53. TFTP_DATA = 3,
  54. TFTP_ACK = 4,
  55. TFTP_ERROR = 5,
  56. TFTP_OACK = 6
  57. };
  58. enum
  59. {
  60. TFTP_EUNDEF = 0, /* not defined */
  61. TFTP_ENOTFOUND = 1, /* file not found */
  62. TFTP_EACCESS = 2, /* access violation */
  63. TFTP_ENOSPACE = 3, /* disk full or allocation exceeded */
  64. TFTP_EBADOP = 4, /* illegal TFTP operation */
  65. TFTP_EBADID = 5, /* unknown transfer ID */
  66. TFTP_EEXISTS = 6, /* file already exists */
  67. TFTP_ENOUSER = 7 /* no such user */
  68. };
  69. struct tftphdr {
  70. grub_uint16_t opcode;
  71. union {
  72. grub_int8_t rrq[TFTP_DEFAULTSIZE_PACKET];
  73. struct {
  74. grub_uint16_t block;
  75. grub_int8_t download[0];
  76. } data;
  77. struct {
  78. grub_uint16_t block;
  79. } ack;
  80. struct {
  81. grub_uint16_t errcode;
  82. grub_int8_t errmsg[TFTP_DEFAULTSIZE_PACKET];
  83. } err;
  84. struct {
  85. grub_int8_t data[TFTP_DEFAULTSIZE_PACKET+2];
  86. } oack;
  87. } u;
  88. } GRUB_PACKED ;
  89. typedef struct tftp_data
  90. {
  91. grub_uint64_t file_size;
  92. grub_uint64_t block;
  93. grub_uint32_t block_size;
  94. grub_uint64_t ack_sent;
  95. int have_oack;
  96. struct grub_error_saved save_err;
  97. grub_net_udp_socket_t sock;
  98. } *tftp_data_t;
  99. static grub_err_t
  100. ack (tftp_data_t data, grub_uint64_t block)
  101. {
  102. struct tftphdr *tftph_ack;
  103. grub_uint8_t nbdata[512];
  104. struct grub_net_buff nb_ack;
  105. grub_err_t err;
  106. nb_ack.head = nbdata;
  107. nb_ack.end = nbdata + sizeof (nbdata);
  108. grub_netbuff_clear (&nb_ack);
  109. grub_netbuff_reserve (&nb_ack, 512);
  110. err = grub_netbuff_push (&nb_ack, sizeof (tftph_ack->opcode)
  111. + sizeof (tftph_ack->u.ack.block));
  112. if (err)
  113. return err;
  114. tftph_ack = (struct tftphdr *) nb_ack.data;
  115. tftph_ack->opcode = grub_cpu_to_be16_compile_time (TFTP_ACK);
  116. tftph_ack->u.ack.block = grub_cpu_to_be16 (block);
  117. err = grub_net_send_udp_packet (data->sock, &nb_ack);
  118. if (err)
  119. return err;
  120. data->ack_sent = block;
  121. return GRUB_ERR_NONE;
  122. }
  123. static grub_err_t
  124. tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
  125. struct grub_net_buff *nb,
  126. void *f)
  127. {
  128. grub_file_t file = f;
  129. struct tftphdr *tftph = (void *) nb->data;
  130. tftp_data_t data = file->data;
  131. grub_err_t err;
  132. grub_uint8_t *ptr;
  133. if (nb->tail - nb->data < (grub_ssize_t) sizeof (tftph->opcode))
  134. {
  135. grub_dprintf ("tftp", "TFTP packet too small\n");
  136. return GRUB_ERR_NONE;
  137. }
  138. tftph = (struct tftphdr *) nb->data;
  139. switch (grub_be_to_cpu16 (tftph->opcode))
  140. {
  141. case TFTP_OACK:
  142. data->block_size = TFTP_DEFAULTSIZE_PACKET;
  143. data->have_oack = 1;
  144. for (ptr = nb->data + sizeof (tftph->opcode); ptr < nb->tail;)
  145. {
  146. if (grub_memcmp (ptr, "tsize\0", sizeof ("tsize\0") - 1) == 0)
  147. data->file_size = grub_strtoul ((char *) ptr + sizeof ("tsize\0")
  148. - 1, 0, 0);
  149. if (grub_memcmp (ptr, "blksize\0", sizeof ("blksize\0") - 1) == 0)
  150. data->block_size = grub_strtoul ((char *) ptr + sizeof ("blksize\0")
  151. - 1, 0, 0);
  152. while (ptr < nb->tail && *ptr)
  153. ptr++;
  154. ptr++;
  155. }
  156. data->block = 0;
  157. grub_netbuff_free (nb);
  158. err = ack (data, 0);
  159. grub_error_save (&data->save_err);
  160. return GRUB_ERR_NONE;
  161. case TFTP_DATA:
  162. if (nb->tail - nb->data < (grub_ssize_t) (sizeof (tftph->opcode)
  163. + sizeof (tftph->u.data.block)))
  164. {
  165. grub_dprintf ("tftp", "TFTP packet too small\n");
  166. return GRUB_ERR_NONE;
  167. }
  168. /*
  169. * Ack old/retransmitted block.
  170. *
  171. * The block number is a 16-bit counter, thus the maximum file size that
  172. * could be transfered is 65535 * block size. Most TFTP hosts support to
  173. * roll-over the block counter to allow unlimited transfer file size.
  174. *
  175. * This behavior is not defined in the RFC 1350 [0] but is implemented by
  176. * most TFTP clients and hosts.
  177. *
  178. * [0]: https://tools.ietf.org/html/rfc1350
  179. */
  180. if (grub_be_to_cpu16 (tftph->u.data.block) < ((grub_uint16_t) (data->block + 1)))
  181. ack (data, grub_be_to_cpu16 (tftph->u.data.block));
  182. /* Ignore unexpected block. */
  183. else if (grub_be_to_cpu16 (tftph->u.data.block) > ((grub_uint16_t) (data->block + 1)))
  184. grub_dprintf ("tftp", "TFTP unexpected block # %d\n", tftph->u.data.block);
  185. else
  186. {
  187. unsigned size;
  188. if (file->device->net->packs.count < 50)
  189. {
  190. err = ack (data, data->block + 1);
  191. if (err)
  192. return err;
  193. }
  194. else
  195. file->device->net->stall = 1;
  196. err = grub_netbuff_pull (nb, sizeof (tftph->opcode) +
  197. sizeof (tftph->u.data.block));
  198. if (err)
  199. return err;
  200. size = nb->tail - nb->data;
  201. data->block++;
  202. if (size < data->block_size)
  203. {
  204. if (data->ack_sent < data->block)
  205. ack (data, data->block);
  206. file->device->net->eof = 1;
  207. file->device->net->stall = 1;
  208. grub_net_udp_close (data->sock);
  209. data->sock = NULL;
  210. }
  211. /*
  212. * Prevent garbage in broken cards. Is it still necessary
  213. * given that IP implementation has been fixed?
  214. */
  215. if (size > data->block_size)
  216. {
  217. err = grub_netbuff_unput (nb, size - data->block_size);
  218. if (err)
  219. return err;
  220. }
  221. /* If there is data, puts packet in socket list. */
  222. if ((nb->tail - nb->data) > 0)
  223. {
  224. grub_net_put_packet (&file->device->net->packs, nb);
  225. /* Do not free nb. */
  226. return GRUB_ERR_NONE;
  227. }
  228. }
  229. grub_netbuff_free (nb);
  230. return GRUB_ERR_NONE;
  231. case TFTP_ERROR:
  232. data->have_oack = 1;
  233. grub_error (GRUB_ERR_IO, "%s", tftph->u.err.errmsg);
  234. grub_error_save (&data->save_err);
  235. grub_netbuff_free (nb);
  236. return GRUB_ERR_NONE;
  237. default:
  238. grub_netbuff_free (nb);
  239. return GRUB_ERR_NONE;
  240. }
  241. }
  242. /*
  243. * Create a normalized copy of the filename. Compress any string of consecutive
  244. * forward slashes to a single forward slash.
  245. */
  246. static void
  247. grub_normalize_filename (char *normalized, const char *filename)
  248. {
  249. char *dest = normalized;
  250. const char *src = filename;
  251. while (*src != '\0')
  252. {
  253. if (src[0] == '/' && src[1] == '/')
  254. src++;
  255. else
  256. *dest++ = *src++;
  257. }
  258. *dest = '\0';
  259. }
  260. static grub_err_t
  261. tftp_open (struct grub_file *file, const char *filename)
  262. {
  263. struct tftphdr *tftph;
  264. char *rrq;
  265. int i;
  266. int rrqlen;
  267. int hdrlen;
  268. grub_uint8_t open_data[1500];
  269. struct grub_net_buff nb;
  270. tftp_data_t data;
  271. grub_err_t err;
  272. grub_uint8_t *nbd;
  273. grub_net_network_level_address_t addr;
  274. int port = file->device->net->port;
  275. data = grub_zalloc (sizeof (*data));
  276. if (!data)
  277. return grub_errno;
  278. nb.head = open_data;
  279. nb.end = open_data + sizeof (open_data);
  280. grub_netbuff_clear (&nb);
  281. grub_netbuff_reserve (&nb, 1500);
  282. err = grub_netbuff_push (&nb, sizeof (*tftph));
  283. if (err)
  284. {
  285. grub_free (data);
  286. return err;
  287. }
  288. tftph = (struct tftphdr *) nb.data;
  289. rrq = (char *) tftph->u.rrq;
  290. rrqlen = 0;
  291. tftph->opcode = grub_cpu_to_be16_compile_time (TFTP_RRQ);
  292. /*
  293. * Copy and normalize the filename to work-around issues on some TFTP
  294. * servers when file names are being matched for remapping.
  295. */
  296. grub_normalize_filename (rrq, filename);
  297. rrqlen += grub_strlen (rrq) + 1;
  298. rrq += grub_strlen (rrq) + 1;
  299. grub_strcpy (rrq, "octet");
  300. rrqlen += grub_strlen ("octet") + 1;
  301. rrq += grub_strlen ("octet") + 1;
  302. grub_strcpy (rrq, "blksize");
  303. rrqlen += grub_strlen ("blksize") + 1;
  304. rrq += grub_strlen ("blksize") + 1;
  305. grub_strcpy (rrq, "1024");
  306. rrqlen += grub_strlen ("1024") + 1;
  307. rrq += grub_strlen ("1024") + 1;
  308. grub_strcpy (rrq, "tsize");
  309. rrqlen += grub_strlen ("tsize") + 1;
  310. rrq += grub_strlen ("tsize") + 1;
  311. grub_strcpy (rrq, "0");
  312. rrqlen += grub_strlen ("0") + 1;
  313. rrq += grub_strlen ("0") + 1;
  314. hdrlen = sizeof (tftph->opcode) + rrqlen;
  315. err = grub_netbuff_unput (&nb, nb.tail - (nb.data + hdrlen));
  316. if (err)
  317. {
  318. grub_free (data);
  319. return err;
  320. }
  321. file->not_easily_seekable = 1;
  322. file->data = data;
  323. err = grub_net_resolve_address (file->device->net->server, &addr);
  324. if (err)
  325. {
  326. grub_dprintf ("tftp", "Address resolution failed: %d\n", err);
  327. grub_dprintf ("tftp", "file_size is %" PRIuGRUB_UINT64_T ", block_size is %" PRIuGRUB_UINT32_T "\n",
  328. data->file_size, data->block_size);
  329. grub_free (data);
  330. return err;
  331. }
  332. data->sock = grub_net_udp_open (addr,
  333. port ? port : TFTP_SERVER_PORT, tftp_receive,
  334. file);
  335. if (!data->sock)
  336. {
  337. grub_free (data);
  338. return grub_errno;
  339. }
  340. /* Receive OACK packet. */
  341. nbd = nb.data;
  342. for (i = 0; i < GRUB_NET_TRIES; i++)
  343. {
  344. nb.data = nbd;
  345. err = grub_net_send_udp_packet (data->sock, &nb);
  346. if (err)
  347. {
  348. grub_net_udp_close (data->sock);
  349. grub_free (data);
  350. return err;
  351. }
  352. grub_net_poll_cards (GRUB_NET_INTERVAL + (i * GRUB_NET_INTERVAL_ADDITION),
  353. &data->have_oack);
  354. if (data->have_oack)
  355. break;
  356. }
  357. if (!data->have_oack)
  358. grub_error (GRUB_ERR_TIMEOUT, N_("time out opening `%s'"), filename);
  359. else
  360. grub_error_load (&data->save_err);
  361. if (grub_errno)
  362. {
  363. grub_net_udp_close (data->sock);
  364. grub_free (data);
  365. file->data = NULL;
  366. return grub_errno;
  367. }
  368. file->size = data->file_size;
  369. return GRUB_ERR_NONE;
  370. }
  371. static grub_err_t
  372. tftp_close (struct grub_file *file)
  373. {
  374. tftp_data_t data = file->data;
  375. if (data->sock)
  376. {
  377. grub_uint8_t nbdata[512];
  378. grub_err_t err;
  379. struct grub_net_buff nb_err;
  380. struct tftphdr *tftph;
  381. nb_err.head = nbdata;
  382. nb_err.end = nbdata + sizeof (nbdata);
  383. grub_netbuff_clear (&nb_err);
  384. grub_netbuff_reserve (&nb_err, 512);
  385. err = grub_netbuff_push (&nb_err, sizeof (tftph->opcode)
  386. + sizeof (tftph->u.err.errcode)
  387. + sizeof ("closed"));
  388. if (!err)
  389. {
  390. tftph = (struct tftphdr *) nb_err.data;
  391. tftph->opcode = grub_cpu_to_be16_compile_time (TFTP_ERROR);
  392. tftph->u.err.errcode = grub_cpu_to_be16_compile_time (TFTP_EUNDEF);
  393. grub_memcpy (tftph->u.err.errmsg, "closed", sizeof ("closed"));
  394. err = grub_net_send_udp_packet (data->sock, &nb_err);
  395. }
  396. if (err)
  397. grub_print_error ();
  398. grub_net_udp_close (data->sock);
  399. }
  400. grub_free (data);
  401. file->data = NULL;
  402. return GRUB_ERR_NONE;
  403. }
  404. static grub_err_t
  405. tftp_packets_pulled (struct grub_file *file)
  406. {
  407. tftp_data_t data = file->data;
  408. if (file->device->net->packs.count >= 50)
  409. return 0;
  410. if (!file->device->net->eof)
  411. file->device->net->stall = 0;
  412. if (data->ack_sent >= data->block)
  413. return 0;
  414. return ack (data, data->block);
  415. }
  416. static struct grub_net_app_protocol grub_tftp_protocol =
  417. {
  418. .name = "tftp",
  419. .open = tftp_open,
  420. .close = tftp_close,
  421. .packets_pulled = tftp_packets_pulled
  422. };
  423. GRUB_MOD_INIT (tftp)
  424. {
  425. grub_net_app_level_register (&grub_tftp_protocol);
  426. }
  427. GRUB_MOD_FINI (tftp)
  428. {
  429. grub_net_app_level_unregister (&grub_tftp_protocol);
  430. }