📄 tftp.c
字号:
TftpCount = -1; return(-1); } SendTFTPAck(ehdr,block); return(0);}/* SendTFTPRRQ(): * Pass the ether and ip address of the TFTP server, along with the * filename and mode to start up a target-initiated TFTP download. * The initial TftpState value is TFTPSENTRRQ, this is done so that incoming * TFTP_DAT packets can be verified... * - If a TFTP_DAT packet is received and TftpState is TFTPSENTRRQ, then * the block number should be 1. If this is true, then that server's * source port is stored away in TftpRmtPort so that all subsequent * TFTP_DAT packets will be compared to the initial source port. If no * match, then respond with a TFTP error or ICMP PortUnreachable message. * - If a TFTP_DAT packet is received and TftpState is TFTPSENTRRQ, then * if the block number is not 1, generate a error. */intSendTFTPRRQ(uchar *ipadd,uchar *eadd,char *filename,char *mode,uchar *loc){ uchar *tftpdat; ushort ip_len; struct ether_header *te; struct ip *ti; struct Udphdr *tu; TftpChopCount = 0; tftpGotoState(TFTPSENTRRQ); TftpAddr = loc; TftpCount = 0; /* Retrieve an ethernet buffer from the driver and populate the * ethernet level of packet: */ te = (struct ether_header *) getXmitBuffer(); memcpy((char *)&te->ether_shost,BinEnetAddr,6); memcpy((char *)&te->ether_dhost,eadd,6); te->ether_type = ecs(ETHERTYPE_IP); /* Move to the IP portion of the packet and populate it appropriately: */ ti = (struct ip *) (te + 1); ti->ip_vhl = IP_HDR_VER_LEN; ti->ip_tos = 0; ip_len = sizeof(struct ip) + sizeof(struct Udphdr) + strlen(filename) + strlen(mode) + 4; ti->ip_len = ecs(ip_len); ti->ip_id = ipId(); ti->ip_off = 0; ti->ip_ttl = UDP_TTL; ti->ip_p = IP_UDP; memcpy((char *)&ti->ip_src.s_addr,BinIpAddr,4); memcpy((char *)&ti->ip_dst.s_addr,ipadd,4); /* Now udp... */ tu = (struct Udphdr *) (ti + 1); tu->uh_sport = getTftpSrcPort(); self_ecs(tu->uh_sport); tu->uh_dport = ecs(TftpPort); tu->uh_ulen = ecs((ushort)(ip_len - sizeof(struct ip))); /* Finally, the TFTP specific stuff... */ tftpdat = (uchar *)(tu+1); *(ushort *)(tftpdat) = ecs(TFTP_RRQ); strcpy(tftpdat+2,filename); strcpy(tftpdat+2+strlen(filename)+1,mode); if (!strcmp(mode,"netascii")) TftpWrqMode = MODE_NETASCII; else TftpWrqMode = MODE_OCTET; storePktAndSend(ti, te,TFTPACKSIZE+strlen(filename)+strlen(mode)); if (EtherVerbose & SHOW_TFTP) printf("\n Sent TFTP_RRQ (file=%s)\n",filename); return(0);}/* SendTFTPAck(): */intSendTFTPAck(struct ether_header *re,ushort block){ uchar *tftpdat; ushort ip_len; struct ether_header *te; struct ip *ti, *ri; struct Udphdr *tu, *ru; te = EtherCopy(re); ti = (struct ip *) (te + 1); ri = (struct ip *) (re + 1); ti->ip_vhl = ri->ip_vhl; ti->ip_tos = ri->ip_tos; ip_len = sizeof(struct ip) + sizeof(struct Udphdr) + 4; ti->ip_len = ecs(ip_len); ti->ip_id = ipId(); ti->ip_off = ri->ip_off; ti->ip_ttl = UDP_TTL; ti->ip_p = IP_UDP; memcpy((char *)&(ti->ip_src.s_addr),(char *)&(ri->ip_dst.s_addr), sizeof(struct in_addr)); memcpy((char *)&(ti->ip_dst.s_addr),(char *)&(ri->ip_src.s_addr), sizeof(struct in_addr)); tu = (struct Udphdr *) (ti + 1); ru = (struct Udphdr *) (ri + 1); tu->uh_sport = ru->uh_dport; tu->uh_dport = ru->uh_sport; tu->uh_ulen = ecs((ushort)(ip_len - sizeof(struct ip))); tftpdat = (uchar *)(tu+1); *(ushort *)(tftpdat) = ecs(TFTP_ACK); *(ushort *)(tftpdat+2) = ecs(block); storePktAndSend(ti,te,TFTPACKSIZE); if (EtherVerbose & SHOW_TFTP) printf(" Sent TFTP_ACK (blk#%d)\n",block); return(0);}/* SendTFTPErr(): */intSendTFTPErr(struct ether_header *re,short errno,char *errmsg,int changestate){ short len, tftplen, hdrlen; uchar *tftpmsg; struct ether_header *te; struct ip *ti, *ri; struct Udphdr *tu, *ru; if (changestate) tftpGotoState(TFTPERROR); tftplen = strlen(errmsg) + 1 + 4; hdrlen = sizeof(struct ip) + sizeof(struct Udphdr); len = tftplen + hdrlen ; te = EtherCopy(re); ti = (struct ip *) (te + 1); ri = (struct ip *) (re + 1); ti->ip_vhl = ri->ip_vhl; ti->ip_tos = ri->ip_tos; ti->ip_len = ecs(len); ti->ip_id = ipId(); ti->ip_off = ri->ip_off; ti->ip_ttl = UDP_TTL; ti->ip_p = IP_UDP; memcpy((char *)&(ti->ip_src.s_addr),(char *)&(ri->ip_dst.s_addr), sizeof(struct in_addr)); memcpy((char *)&(ti->ip_dst.s_addr),(char *)&(ri->ip_src.s_addr), sizeof(struct in_addr)); tu = (struct Udphdr *) (ti + 1); ru = (struct Udphdr *) (ri + 1); tu->uh_sport = ru->uh_dport; tu->uh_dport = ru->uh_sport; tu->uh_ulen = sizeof(struct Udphdr) + tftplen; self_ecs(tu->uh_ulen); tftpmsg = (uchar *)(tu+1); *(ushort *)(tftpmsg) = ecs(TFTP_ERR); * (ushort *)(tftpmsg+2) = ecs(errno); strcpy(tftpmsg+4,errmsg); storePktAndSend(ti,te,TFTPACKSIZE + strlen(errmsg) + 1); if (EtherVerbose & SHOW_TFTP) printf(" Sent TFTP Err#%d (%s) \n",errno,errmsg); return(0);}/* SendTFTPData(): */intSendTFTPData(struct ether_header *re,ushort block,uchar *data,int count){ int len, tftplen, hdrlen; uchar *tftpmsg; struct ether_header *te; struct ip *ti, *ri; struct Udphdr *tu, *ru; if (count > TFTP_DATAMAX) count = TFTP_DATAMAX; tftplen = count + 2 + 2; /* sizeof (data + opcode + blockno) */ hdrlen = sizeof(struct ip) + sizeof(struct Udphdr); len = tftplen + hdrlen ; te = EtherCopy(re); ti = (struct ip *) (te + 1); ri = (struct ip *) (re + 1); ti->ip_vhl = ri->ip_vhl; ti->ip_tos = ri->ip_tos; ti->ip_len = ecs(len); ti->ip_id = ipId(); ti->ip_off = ri->ip_off; ti->ip_ttl = UDP_TTL; ti->ip_p = IP_UDP; memcpy((char *)&(ti->ip_src.s_addr),(char *)&(ri->ip_dst.s_addr), sizeof(struct in_addr)); memcpy((char *)&(ti->ip_dst.s_addr),(char *)&(ri->ip_src.s_addr), sizeof(struct in_addr)); tu = (struct Udphdr *) (ti + 1); ru = (struct Udphdr *) (ri + 1); tu->uh_sport = ru->uh_dport; tu->uh_dport = ru->uh_sport; tu->uh_ulen = sizeof(struct Udphdr) + tftplen; self_ecs(tu->uh_ulen); tftpmsg = (uchar *)(tu+1); *(ushort *)(tftpmsg) = ecs(TFTP_DAT); *(ushort *)(tftpmsg+2) = ecs(block); memcpy(tftpmsg+4,data,count); len+=sizeof(struct ether_header); storePktAndSend(ti,te,len); if (EtherVerbose & SHOW_TFTP) printf(" Sent TFTP data blk#%d (%d bytes @ 0x%lx) \n", block,count,(ulong)data); return(0);}/* Tftp(): * Initiate a tftp transfer at the target (target is client). * Command line: * tftp [options] {IP} {get|put} {file|addr} [len]... * tftp [options] {IP} get file dest_addr * tftp [options] {IP} put addr dest_file len * Currently, only "get" is supported. */char *TftpHelp[] = { "Trivial file transfer protocol", "-[aF:f:i:nvV] [on|off|IP] {get filename [addr]}", " -a use netascii mode", " -F {file} name of tfs file to copy to", " -f {flgs} file flags (see tfs)", " -i {info} file info (see tfs)", " -v low verbosity", " -V high verbosity", 0,};intTftp(int argc,char *argv[]){ int opt; char *mode, *file, *info, *flags; ulong addr; file = (char *)0; info = (char *)0; flags = (char *)0; mode = "octet"; while ((opt=getopt(argc,argv,"aF:f:i:vV")) != -1) { switch(opt) { case 'a': mode = "netascii"; break; case 'f': flags = optarg; break; case 'F': file = optarg; break; case 'i': info = optarg; break; case 'v': EtherVerbose |= SHOW_TFTP; break; case 'V': EtherVerbose = SHOW_TFTP | SHOW_INCOMING | SHOW_OUTGOING; break; default: return(CMD_PARAM_ERROR); } } if (argc < (optind+1)) return(CMD_PARAM_ERROR); if (argc == optind+1) { if (!strcmp(argv[optind],"on")) TftpTurnedOff = 0; else if (!strcmp(argv[optind],"off")) { TftpTurnedOff = 1; tftpGotoState(TFTPIDLE); } else return(CMD_PARAM_ERROR); return(CMD_SUCCESS); } /* If either the info or flags field has been specified, but the */ /* filename is not specified, error here... */ if ((info || flags) && (!file)) { printf("Filename missing\n"); return(CMD_FAILURE); } TftpTurnedOff = 0; if (!strcmp(argv[optind+1],"get")) { if (argc == optind+4) addr = (ulong)strtol(argv[optind+3],0,0); else if (argc == optind+3) addr = getAppRamStart(); else return(CMD_PARAM_ERROR); tftpGet(addr,argv[optind],mode,argv[optind+2],file,flags,info); EtherVerbose = 0; } else if ((argc == optind+5) && !strcmp(argv[optind+1],"put")) { printf("tftp 'put' not yet supported\n"); } else return(CMD_PARAM_ERROR); return(CMD_SUCCESS);}voidShowTftpStats(){ printf("Current TFTP state: %s\n",tftpStringState(TftpState));}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -