Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <netdb.h>
- #include <syslog.h>
- #include <netinet/in.h>
- #include <signal.h>
- #include <strings.h>
- #include <string.h>
- #include <stdlib.h>
- #include <pthread.h>
- #include <regex.h>
- #define MAX_BUFF 516
- #define DATA_SIZE 512
- #define CTRL 64
- int is_daemon=0;
- struct arguments {
- unsigned short opcode;
- char filename[CTRL];
- char mode[CTRL];
- struct sockaddr_in sender;
- };
- struct ackpacket {
- unsigned short opcode;
- unsigned short blockno;
- };
- struct datapacket {
- unsigned short opcode;
- unsigned short blockno;
- char data[DATA_SIZE];
- };
- struct errorpacket {
- unsigned short opcode;
- unsigned short errcode;
- char errtext[CTRL];
- };
- void *con_accept(void *senderargs);
- uint16_t getopcode(const char *addr);
- void usage(void);
- int main(int argc, char *argv[]) {
- int socketfd, connectfd, port_no, c_arg, cli_len, c_msg, i;
- char buffer[MAX_BUFF];
- struct sockaddr_in server_ad;
- struct sockaddr_in client_ad;
- struct arguments *senderargs;
- struct servent *myserv;
- FILE *infile;
- pthread_t tid;
- regex_t portre;
- regcomp(&portre, "^[0-9]+$", REG_EXTENDED);
- opterr=0;
- fflush (stderr);
- while ((c_arg= getopt(argc, argv, "d")) != -1) {
- switch (c_arg)
- {
- case 'd':
- is_daemon=1;
- break;
- case '?':
- if (isprint(optopt)) {
- fprintf(stderr, "Nepoznata opcija -%c\n", optopt);
- usage();
- return -1;
- }
- else {
- fprintf(stderr, "Nepoznata opcija\n");
- usage();
- return -1;
- }
- return -1;
- }
- }
- if(!argv[optind]) {
- usage();
- return -1;
- }
- if(!regexec (&portre, argv[optind], 0, NULL, 0)) {
- port_no = strtol(argv[optind], NULL, 10);
- }
- else {
- myserv = getservbyname(argv[optind], NULL);
- port_no = ntohs(myserv->s_port);
- }
- if(is_daemon)
- daemon(0,0);
- chdir("/tftpboot/");
- signal(SIGCHLD, SIG_IGN);
- if((socketfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- perror("Error creating socket");
- return 2;
- }
- cli_len = sizeof(struct sockaddr_in);
- memset(&server_ad, 0, cli_len);
- server_ad.sin_family=AF_INET;
- server_ad.sin_addr.s_addr=INADDR_ANY;
- server_ad.sin_port=htons(port_no);
- if (bind(socketfd, (struct sockaddr *) &server_ad, cli_len) < 0)
- perror("Error binding to socket");
- while (1) {
- memset(buffer,0,MAX_BUFF);
- senderargs = malloc(sizeof(struct arguments));
- if((c_msg=recvfrom(socketfd, buffer, MAX_BUFF, 0, (struct sockaddr *) &server_ad, &cli_len)) < 0) {
- perror("Error recieving message");
- return -2;
- }
- senderargs->opcode = getopcode(buffer);
- //senderargs->sender = malloc(sizeof (struct sockaddr_in));
- memcpy (&senderargs->sender, &server_ad, sizeof(struct sockaddr_in));
- strncpy ( senderargs->filename, (buffer+2), CTRL);
- strncpy( senderargs->mode, buffer+strlen(buffer+2)+3, CTRL);
- pthread_create(&tid, NULL, con_accept, (void *) senderargs);
- }
- return 0;
- }
- uint16_t getopcode(const char *addr) {
- return ntohs(*((uint16_t *) addr));
- }
- void usage(void) {
- fprintf(stderr, "Usage: tftpserver [-d] port_name_or_number");
- }
- void *con_accept(void *senderargs) {
- int i=0, socksend, sent, overflow=0, check=0;
- int c_msg, s_rez, c_len=sizeof(struct sockaddr_in);
- unsigned int blkcnt=1;
- char buffer[MAX_BUFF]={0};
- struct arguments argssender = *((struct arguments *) senderargs);
- struct ackpacket myack;
- struct datapacket mydata;
- struct errorpacket myerror;
- struct sockaddr_in client_ad;
- struct timeval mytime;
- fd_set myset;
- FILE *input;
- regex_t re1, re2;
- openlog("MrePro tftpserver", LOG_PID, LOG_FTP);
- regcomp(&re1, "^/tftpboot/[^/]+$", REG_EXTENDED);
- regcomp(&re2, "^[^/]+$", REG_EXTENDED);
- mytime.tv_sec = 3;
- mytime.tv_usec = 0;
- if(is_daemon)
- syslog(LOG_INFO, "%s->%s", inet_ntoa(argssender.sender.sin_addr), argssender.filename);
- else
- fprintf(stderr, "%s->%s", inet_ntoa(argssender.sender.sin_addr), argssender.filename);
- if((socksend = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- perror("Error creating socket");
- free(senderargs);
- return;
- }
- if(regexec (&re1, argssender.filename, 0, NULL, 0) && regexec (&re2, argssender.filename, 0, NULL, 0)) {
- if(is_daemon)
- syslog(LOG_INFO, "TFTP ERROR 2 nm44814");
- else
- fprintf(stderr, "TFTP ERROR 2 nm44814\n");
- myerror.opcode = htons((uint16_t) 5);
- myerror.errcode = htons((uint16_t) 2);
- strncpy(myerror.errtext, "TFTP ERROR 2 nm44814", CTRL);
- c_msg=sendto(socksend, &myerror, sizeof(myerror), 0, (const struct sockaddr *) &(argssender.sender), c_len);
- free(senderargs);
- close(socksend);
- return;
- }
- if((input=fopen(argssender.filename, "rb"))==NULL) {
- if(is_daemon)
- syslog(LOG_INFO, "TFTP ERROR 1 nm44814");
- else
- fprintf(stderr, "TFTP ERROR 1 nm44814\n");
- myerror.opcode = htons((uint16_t) 5);
- myerror.errcode = htons((uint16_t) 1);
- strncpy(myerror.errtext, "TFTP ERROR 1 nm44814", CTRL);
- c_msg=sendto(socksend, &myerror, sizeof(myerror), 0, (const struct sockaddr *) &(argssender.sender), c_len);
- free(senderargs);
- close(socksend);
- return;
- }
- while(!feof(input)) {
- memset(mydata.data, 0, DATA_SIZE);
- mydata.opcode = htons((uint16_t) 3);
- mydata.blockno = htons ((uint16_t) blkcnt);
- printf ("%s %s %d\n", argssender.filename, argssender.mode, blkcnt);
- fflush(stdout);
- if(!strcasecmp("octet", argssender.mode)) {
- sent = fread(mydata.data, 1, DATA_SIZE, input);
- }
- else if (!strcasecmp("netascii", argssender.mode)) {
- for(sent=0; sent<DATA_SIZE; sent++) {
- if(overflow) {
- mydata.data[sent++]='\n';
- overflow=0;
- }
- if(fread(&mydata.data[sent],1,1,input)!=1) {
- break;
- }
- if(mydata.data[sent]=='\n') {
- mydata.data[sent++]='\r';
- if(sent < DATA_SIZE) {
- mydata.data[sent]='\n';
- }
- else {
- overflow=1;
- }
- }
- }
- }
- check=0;
- for(i=0; i<4; i++) {
- FD_ZERO(&myset);
- FD_SET(socksend, &myset);
- c_msg=sendto(socksend, &mydata, sent+2*sizeof(unsigned short), 0, (const struct sockaddr *) &(argssender.sender), c_len);
- s_rez=select(socksend+1, &myset, NULL, NULL, &mytime);
- if(!s_rez) {
- //printf("Propustio %d\n", i+1);
- //fflush(stdout);
- continue;
- }
- else if(s_rez > 0) {
- if(FD_ISSET(socksend, &myset)) {
- c_msg = recvfrom(socksend, &myack, sizeof(myack), 0, ( struct sockaddr *) &client_ad, &c_len);
- if(ntohs(myack.opcode) == 4 && ntohs(myack.blockno) == blkcnt) {
- printf("Got ACK with block count = %d\n", ntohs(myack.blockno));
- fflush(stdout);
- break;
- }
- else if(ntohs(myack.opcode) == 4 && (ntohs(myack.blockno) == blkcnt-1) && check==0) {
- i--;
- check=1;
- continue;
- }
- }
- }
- else if (s_rez < 0){
- return;
- }
- }
- if(i==4) {
- close(socksend);
- free(senderargs);
- return;
- }
- blkcnt++;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement