First, Introduction
TFTP (Trivial file Transfer Protocol) is a protocol for simple file transfer between client and server in the TCP/IP protocol family, providing uncomplicated, inexpensive file transfer services. The port number is 69.
second, message format
TFTP supports 5 types of packages, and the first two bytes of the TFTP datagram are opcode, which identifies these 5 types of packages by opcode:
1. Read request (RRQ)
2. Write request (WRQ)
3. Data (data)
4. Acknowledgment (ACK)
5. Error (Error)
and the Pattern field includes the string "Netascii", "octet" or "Mail", the name is not case-sensitive, here first not to elaborate.
third, the sending process
first, as a TFTP client, host A sends a RRQ message (read request) from the X port to the 69 port on which the TFTP server listens. When the server receives this RRQ message, it starts sending file data back to host a, noting that the port of the postback file data is no longer 69, but a random port on the server, and the Y port in the figure. When host a receives the server's data from the local x port, it sends an ACK response message to the server. This is a RRQ request process. Four, main code: tftp.h:
#ifndef __tftpc_h__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
# Include <strings.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include < netdb.h>
#include <sys/ioctl.h>
#include <assert.h>
#define OPCODE_RRQ (1)
#define OPCODE_WRQ (2)
#define OPCODE_DATA (3)
#define OPCODE_ACK (4)
#define OPCODE_ERR (5)
#define BLOCKSIZE (struct)
tftpheader{short
opcode;
__ATTRIBUTE__ ((packed));
struct tftpwrrq{
struct Tftpheader header;
char *filename;
char *mode;
} __ATTRIBUTE__ ((packed));
struct tftpdata{
struct Tftpheader header;
Short Blocks;
Char data[];
} __ATTRIBUTE__ ((packed));
struct tftpack{
struct Tftpheader header;
Short blocks;
} __ATTRIBUTE__ ((packed));
struct tftperr{
struct Tftpheader header;
Short Errcode;
char *errmsg;
} __ATTRIBUTE__ ((packed));
#endif
tftp_client.c:
#include "tftp.h" #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ socket.h> #include <string.h> #include <errno.h>/************************************************** FILENAME:TFTP_CLIENT.C date:2017-03-05 description:linux Debian System, the implementation of the TFTP protocol RRQ message sent through the Wireshark capture and parse ***********************************************************/int main (int argc, char **argv) {struct hostent *se
Rv_host;
struct sockaddr_in serv_addr;
int sockfd =-1;
int opt = 1;
int ret =-1;
if (argc!= 5)/* Determine whether the entry parameter is 5/{fprintf (stderr, "Usage:%s host port [Get|put] filename\n", argv[0]);
Exit (1);
} char *host = argv[1];
int serv_port = atoi (argv[2]); int opt_code = strcmp (argv[3], "get") = = 0?
1:2;
Char *filename = argv[4];
printf ("Dbg:host =%s, port =%d, opt =%d, filename =%s \ n", host, Serv_port, opt_code, filename); /* Get TFTP suitInformation of the service/if ((Serv_host = gethostbyname (argv[1)) = = NULL) {printf ("host is incorrect!\n");
Exit (1);
} serv_addr.sin_family = Pf_inet;
SERV_ADDR.SIN_ADDR = * ((struct in_addr *) serv_host->h_addr_list[0]);
Serv_addr.sin_port = htons (Serv_port);
/* Get UDP protocol number * * struct protoent *proto; if ((proto = Getprotobyname ("UDP")) = = NULL) {fprintf (stderr, Getprotoname (), failed to find UDP Protoco info\
n ");
Exit (1); /* Create UDP socket/if (SOCKFD = socket (pf_inet, SOCK_DGRAM, Proto->p_proto) < 0) {perror ("ERROR o
Pening socket\n ");
Exit (1);
}/* Constructs a RRQ message * * struct Tftpheader header;
Header.opcode = htons (OPCODE_RRQ);
int filenamelen = strlen (filename) + 1; int packetsize = sizeof (header) + Filenamelen + 5 + 1;
/*5 is the length of the datagram Mode (octet), 1 is the string terminator length/void *packet = malloc (packetsize);
memcpy (packet, &header, sizeof (header)); memcpy (packet + sizeof (HEAder), filename, filenamelen);
Char *mode = "octet";
memcpy (packet + sizeof (header) + Filenamelen, mode, strlen (mode) + 1);
if (SendTo (SOCKFD, packet, PacketSize, 0, (struct sockaddr*) &serv_addr, sizeof (struct sockaddr)) < 0) {
Perror ("SendTo ()");
return 1;
return 0;
}
v. Results analysis:
Linux Debian Execution:
here with the local host as the TFTP server side, 1234 for the server listening port, get the Testfile file on the server. Wireshark Bag result analysis: