📄 tftp.c
字号:
/* TFTP Client code */#include <stdio.h> /* standard C i/o facilities */#include <stdlib.h> /* needed for atoi() */#include <unistd.h> /* defines STDIN_FILENO, system calls,etc */#include <sys/types.h> /* system data type definitions */#include <sys/time.h>#include <sys/socket.h> /* socket specific definitions */#include <netinet/in.h> /* INET constants and stuff */#include <arpa/inet.h> /* IP address conversion stuff */#include <netdb.h> /* gethostbyname *//* code for building messages */enum opcodes {RRQ=1,WRQ=2,DATA=3,ACK=4,ERR=5};/* build rrq or wrq messages *//* assumes that msg can hold at least 516 bytes! *//* returns size of message or -1 */int build_request(char *msg, unsigned short opcode, char *filename, char *mode) { if (strlen(filename)>100) { printf("File name too long\n"); return(-1); } if (strlen(mode)>100) { printf("Transfer mode too long\n"); return(-1); } if ((opcode != RRQ) && (opcode != WRQ)) { printf("build_request: invalid opcode (%d)\n",opcode); return(-1); } opcode=htons(opcode); memcpy(msg,&opcode,2); strcpy(msg+2,filename); strcpy(msg+2+strlen(filename)+1,mode); return(2+strlen(filename)+1+strlen(mode)+1);}unsigned short get_shortval( char *p ) { unsigned short tmp; memcpy(&tmp,p,2); tmp = ntohs(tmp); return(tmp);}char *opcode_strings[] = { "RRQ", "WRQ", "DATA", "ACK", "ERR" };/* print out a TFTP message */void print_msg( char *msg, int len ) { unsigned short opcode,blocknum,errcode; opcode = get_shortval(msg); if (opcode> ERR) { printf("Error - invalid opcode: %d\n",opcode); return; } printf("%s: ",opcode_strings[opcode-1]); switch(opcode) { case RRQ: case WRQ: printf("<%s> <%s>\n",msg+2,msg+2+strlen(msg+2)+1); break; case DATA: blocknum = get_shortval(msg+2); printf("BLOCK: %d (%d bytes)\n",blocknum,len-4); break; case ACK: blocknum = get_shortval(msg+2); printf("BLOCK: %d\n",blocknum); break; case ERR: errcode = get_shortval(msg+2); printf("CODE: %d <%s>\n",errcode,msg+4); break; }}/*void testit(int sk, struct sockaddr_in s) { char buff[1000]; int len; int sent; int received; len = build_request(buff,RRQ,"small","octet"); printf("SENDING "); print_msg(buff,len); if (len<0) { printf("Error, invalid request\n"); return; } sent = sendto(sk,buff,len,NULL,&s,sizeof(s)); if (sent!=len) { printf("Some kind of error sending!\n"); return; } while (1) { len = sizeof(s); received = recvfrom(sk,buff,1000,NULL,&s,&len); if (received<0) { printf("Error calling recvfrom\n"); return; } printf("RECEIVED: "); print_msg(buff,received); }}*/int wait_for_response(int sk,struct sockaddr_in *s,char *buff, int max) { int len=max; fd_set rfds; struct timeval t = { 2,0 }; /* 2 seconds */ int received; FD_ZERO(&rfds); FD_SET(sk,&rfds); if (select(sk+1,&rfds,NULL,NULL,&t)==0) { return(0); } else if (FD_ISSET(sk,&rfds)) { received = recvfrom(sk,buff,1000,0,s,&len); if (received<0) { printf("Error calling recvfrom\n"); return(0); } printf("RECEIVED: "); print_msg(buff,received); return(received); } return(0);}void testmsg(int sk, struct sockaddr_in *s, char *msg, int len ) { int sent; char buff[1000]; sent = sendto(sk,msg,len,0,s,sizeof(*s)); if (sent!=len) { printf("Some kind of error sending (from sendto)!\n"); return; } if (wait_for_response(sk,s,buff,1000)==0) { printf("No Response\n"); }}char invalidopcode[]= "\x00\x08HiDave\x00";char badrrq[] = "\x00\x01medium";char rrq[] = "\x00\x01medium\x00octet\x00";char rrq2[] = "\x00\x04\x00\x01";char rrq3[] = "\x00\x02\x00\x01";void tests(int sk, struct sockaddr_in *s, int subtest) { struct sockaddr_in orig; memcpy(&orig,s,sizeof(struct sockaddr_in)); /* send invalid opcode */ if (subtest == 0 || subtest == 1) { printf("Sending invalid opcode\n"); testmsg(sk,s,invalidopcode,sizeof(invalidopcode)); } if (subtest == 0 || subtest == 2) { /* send a RRQ with invalid filename (no null) */ memcpy(s,&orig,sizeof(struct sockaddr_in)); printf("Sending invalid RRQ\n"); testmsg(sk,s,badrrq,sizeof(badrrq)-1); /* one byte too few - no null!*/ } if (subtest == 0 || subtest == 3) { /* send a valid RRQ */ memcpy(s,&orig,sizeof(struct sockaddr_in)); printf("Sending valid RRQ to get transfer started\n"); testmsg(sk,s,rrq,sizeof(rrq)-1); /* now send 1st ACK to new port */ printf("Sending ACK\n"); testmsg(sk,s,rrq2,sizeof(rrq2)-1); /* now send garbage to new port */ printf("Sending Invalid stuff\n"); testmsg(sk,s,rrq3,sizeof(rrq3)); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -