⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tftp.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 3 页
字号:
        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 + -