+ printf("Using %s device\n", eth_get_name());
+ printf("Listening for TFTP transfer on %pI4\n", &NetOurIP);
+ printf("Load address: 0x%lx\n", load_addr);
+
+ puts("Loading: *\b");
+
+ TftpTimeoutCountMax = TIMEOUT_COUNT;
+ TftpTimeoutCount = 0;
+ TftpTimeoutMSecs = TIMEOUT;
+ NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
+
+ /* Revert TftpBlkSize to dflt */
+ TftpBlkSize = TFTP_BLOCK_SIZE;
+ TftpBlock = 0;
+ TftpOurPort = WELL_KNOWN_PORT;
+
+#ifdef CONFIG_TFTP_TSIZE
+ TftpTsize = 0;
+ TftpNumchars = 0;
+#endif
+
+ TftpState = STATE_RECV_WRQ;
+ net_set_udp_handler(TftpHandler);
+
+ /* zero out server ether in case the server ip has changed */
+ memset(NetServerEther, 0, 6);
+}
+#endif /* CONFIG_CMD_TFTPSRV */
+
+#ifdef CONFIG_MCAST_TFTP
+/* Credits: atftp project.
+ */
+
+/* pick up BcastAddr, Port, and whether I am [now] the master-client. *
+ * Frame:
+ * +-------+-----------+---+-------~~-------+---+
+ * | opc | multicast | 0 | addr, port, mc | 0 |
+ * +-------+-----------+---+-------~~-------+---+
+ * The multicast addr/port becomes what I listen to, and if 'mc' is '1' then
+ * I am the new master-client so must send ACKs to DataBlocks. If I am not
+ * master-client, I'm a passive client, gathering what DataBlocks I may and
+ * making note of which ones I got in my bitmask.
+ * In theory, I never go from master->passive..
+ * .. this comes in with pkt already pointing just past opc
+ */
+static void parse_multicast_oack(char *pkt, int len)
+{
+ int i;
+ IPaddr_t addr;
+ char *mc_adr, *port, *mc;
+
+ mc_adr = port = mc = NULL;
+ /* march along looking for 'multicast\0', which has to start at least
+ * 14 bytes back from the end.
+ */
+ for (i = 0; i < len-14; i++)
+ if (strcmp(pkt+i, "multicast") == 0)
+ break;
+ if (i >= (len-14)) /* non-Multicast OACK, ign. */
+ return;
+
+ i += 10; /* strlen multicast */
+ mc_adr = pkt+i;
+ for (; i < len; i++) {
+ if (*(pkt+i) == ',') {
+ *(pkt+i) = '\0';
+ if (port) {
+ mc = pkt+i+1;
+ break;
+ } else {
+ port = pkt+i+1;
+ }
+ }
+ }
+ if (!port || !mc_adr || !mc)
+ return;
+ if (Multicast && MasterClient) {
+ printf("I got a OACK as master Client, WRONG!\n");
+ return;
+ }
+ /* ..I now accept packets destined for this MCAST addr, port */
+ if (!Multicast) {
+ if (Bitmap) {
+ printf("Internal failure! no mcast.\n");
+ free(Bitmap);
+ Bitmap = NULL;
+ ProhibitMcast = 1;
+ return ;
+ }
+ /* I malloc instead of pre-declare; so that if the file ends
+ * up being too big for this bitmap I can retry
+ */
+ Bitmap = malloc(Mapsize);
+ if (!Bitmap) {
+ printf("No Bitmap, no multicast. Sorry.\n");
+ ProhibitMcast = 1;
+ return;
+ }
+ memset(Bitmap, 0, Mapsize);
+ PrevBitmapHole = 0;
+ Multicast = 1;
+ }
+ addr = string_to_ip(mc_adr);
+ if (Mcast_addr != addr) {
+ if (Mcast_addr)
+ eth_mcast_join(Mcast_addr, 0);
+ Mcast_addr = addr;
+ if (eth_mcast_join(Mcast_addr, 1)) {
+ printf("Fail to set mcast, revert to TFTP\n");
+ ProhibitMcast = 1;
+ mcast_cleanup();
+ NetStartAgain();
+ }
+ }
+ MasterClient = (unsigned char)simple_strtoul((char *)mc, NULL, 10);
+ Mcast_port = (unsigned short)simple_strtoul(port, NULL, 10);
+ printf("Multicast: %s:%d [%d]\n", mc_adr, Mcast_port, MasterClient);
+ return;