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

📄 tftp.c

📁 this gives details of the network programming
💻 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 + -