Last active
November 21, 2015 17:38
-
-
Save MartelliEnrico/46f89dc5f4ef46caf96c to your computer and use it in GitHub Desktop.
Send ip packet from client to server, and back again.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* cliTCP.c spedisce stringa, riceve stringa traslata | |
| su SunOS compilare con gcc -o cliTCP.c -lsocket -lnsl cliTCP.c | |
| su linux gcc -o cliTCP cliTCP.c | |
| eseguire ad esempio su 137.204.72.49 lanciando la seguente riga di comandi | |
| cliTCP 130.136.2.7 5001 | |
| */ | |
| #include <unistd.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <sys/types.h> | |
| #include <sys/socket.h> | |
| #include <netinet/in.h> | |
| #include <arpa/inet.h> | |
| #include <errno.h> | |
| #include "header.h" | |
| #define SOCKET_ERROR ((int)-1) | |
| #define SIZEBUF 1000000 | |
| #define MAXSIZE 1000000 | |
| void usage(void) | |
| { | |
| printf ("usage: cliTCP REMOTE_IP_NUMBER REMOTE_PORT_NUMBER\n"); | |
| exit(1); | |
| } | |
| int main(int argc, char *argv[]) | |
| { | |
| struct sockaddr_in Local, Serv; | |
| char string_remote_ip_address[100]; | |
| short int remote_port_number, local_port_number; | |
| int socketfd, OptVal, msglen, Fromlen, ris; | |
| int n, i, nread, nwrite, len; | |
| char buf[MAXSIZE]; | |
| if (argc != 3) { printf ("necessari 2 parametri\n"); usage(); exit(1); } | |
| else { | |
| strncpy(string_remote_ip_address, argv[1], 99); | |
| remote_port_number = atoi(argv[2]); | |
| } | |
| /* get a datagram socket */ | |
| //printf ("socket()\n"); | |
| socketfd = socket(AF_INET, SOCK_STREAM, 0); | |
| if (socketfd == SOCKET_ERROR) { | |
| printf ("socket() failed, Err: %d \"%s\"\n", errno, strerror(errno)); | |
| exit(1); | |
| } | |
| /* avoid EADDRINUSE error on bind() */ | |
| OptVal = 1; | |
| //printf ("setsockopt()\n"); | |
| ris = setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, (char *)&OptVal, sizeof(OptVal)); | |
| if (ris == SOCKET_ERROR) { | |
| printf ("setsockopt() SO_REUSEADDR failed, Err: %d \"%s\"\n", errno, strerror(errno)); | |
| exit(1); | |
| } | |
| /* name the socket */ | |
| memset ( &Local, 0, sizeof(Local) ); | |
| Local.sin_family = AF_INET; | |
| /* indicando INADDR_ANY viene collegato il socket all'indirizzo locale IP */ | |
| /* dell'interaccia di rete che verrà utilizzata per inoltrare i dati */ | |
| Local.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard */ | |
| Local.sin_port = htons(0); | |
| //printf ("bind()\n"); | |
| ris = bind(socketfd, (struct sockaddr*) &Local, sizeof(Local)); | |
| if (ris == SOCKET_ERROR) { | |
| printf ("bind() failed, Err: %d \"%s\"\n", errno, strerror(errno)); | |
| exit(1); | |
| } | |
| /* assign our destination address */ | |
| memset ( &Serv, 0, sizeof(Serv) ); | |
| Serv.sin_family = AF_INET; | |
| Serv.sin_addr.s_addr = inet_addr(string_remote_ip_address); | |
| Serv.sin_port = htons(remote_port_number); | |
| /* connection request */ | |
| //printf ("connect()\n"); | |
| ris = connect(socketfd, (struct sockaddr*) &Serv, sizeof(Serv)); | |
| if (ris == SOCKET_ERROR) { | |
| printf ("connect() failed, Err: %d \"%s\"\n", errno, strerror(errno)); | |
| exit(1); | |
| } | |
| //printf ("dopo connect()\n"); | |
| fflush(stdout); | |
| bytes_header h; | |
| h.h.src = inet_network("130.131.100.1"); | |
| h.h.dst = inet_network("132.133.200.2"); | |
| fill_header(&(h.h), 0b111); | |
| // h.h.flags = 0b101; | |
| // h.h.fragment_offset = 0b0011100111000; | |
| printf("datagram prima:\n"); | |
| print_buffer((char *)h.b, 24); | |
| hton_header(&h); | |
| /* scrittura */ | |
| len = sizeof(bytes_header); | |
| i = 0; | |
| //printf("write()\n"); | |
| //fflush(stdout); | |
| while ((n = write(socketfd, &(h.b[i]), len - i)) > 0) | |
| i += n; | |
| if (n < 0) { | |
| char msgerror[1024]; | |
| sprintf(msgerror, "write() failed [err %d] ", errno); | |
| perror(msgerror); | |
| fflush(stdout); | |
| return (1); | |
| } | |
| /* lettura */ | |
| nread = 0; | |
| //printf ("read()\n"); | |
| //fflush(stdout); | |
| while ((len > nread) && ((n = read(socketfd, &(buf[nread]), len - nread )) > 0)) | |
| { | |
| nread += n; | |
| //printf("read effettuata, risultato n = %d, len = %d, nread = %d, len - nread = %d\n", n, len, nread, len - nread ); | |
| //fflush(stdout); | |
| } | |
| if (n < 0) { | |
| char msgerror[1024]; | |
| sprintf(msgerror, "read() failed [err %d] ", errno); | |
| perror(msgerror); | |
| fflush(stdout); | |
| return (1); | |
| } | |
| /*header res = unserialize_header(buf);*/ | |
| for (int i = 0; i < 24; i++) { | |
| h.b[i] = buf[i]; | |
| } | |
| ntoh_header(&h); | |
| /* stampa risultato */ | |
| printf("\ndatagram dopo:\n"); | |
| print_buffer((char *)h.b, 24); | |
| /* sleep(30); inserito per far vedere connessioni con netstat */ | |
| /* chiusura */ | |
| close(socketfd); | |
| return (0); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef _HEADER_H | |
| #define _HEADER_H | |
| void print_buffer(char* buf, int len) { | |
| char bits[9]; | |
| bits[8] = '\0'; | |
| printf("0 8 16 24\n"); | |
| for (int i = 0; i < len; i++) { | |
| char byte = buf[i]; | |
| for (int j = 7; j >= 0; j--) { | |
| bits[j] = '0' + (byte & 0x01); | |
| byte >>= 1; | |
| } | |
| printf("%s ", bits); | |
| if (i % 4 == 3) { | |
| printf("\n"); | |
| } | |
| } | |
| fflush(stdout); | |
| } | |
| typedef struct _header { | |
| unsigned char version: 4; | |
| unsigned char ihl: 4; | |
| unsigned char service_type; | |
| unsigned short length; | |
| unsigned short identification; | |
| unsigned char flags: 3; | |
| unsigned short fragment_offset: 13; | |
| unsigned char ttl; | |
| unsigned char protocol; | |
| unsigned short checksum; | |
| unsigned int src; | |
| unsigned int dst; | |
| unsigned int options: 24; | |
| unsigned char padding: 8; | |
| } header; | |
| typedef union _bytes_header { | |
| header h; | |
| unsigned char b[sizeof(header)]; | |
| } bytes_header; | |
| void fill_header(header* h, unsigned char fill) { | |
| h->version = fill; | |
| h->ihl = fill; | |
| h->service_type = fill; | |
| h->length = fill; | |
| h->identification = fill; | |
| h->flags = fill; | |
| h->fragment_offset = fill; | |
| h->ttl = fill; | |
| h->protocol = fill; | |
| h->checksum = fill; | |
| h->options = fill; | |
| h->padding = fill; | |
| } | |
| void hton_header(bytes_header* bh) { | |
| uint16_t temp_u16; | |
| uint32_t temp_u32; | |
| bh->h.length = htons(bh->h.length); | |
| bh->h.identification = htons(bh->h.identification); | |
| /* | |
| * Per qualche motivo la struct mette prima in memoria i 13bit di fragment_offset, | |
| * e successivamente i 3bit di flags. | |
| */ | |
| memcpy(&temp_u16, &(bh->b[6]), 2); | |
| bh->h.flags = htons(temp_u16) & 0x8; | |
| bh->h.fragment_offset = htons(temp_u16) >> 3; | |
| bh->h.checksum = htons(bh->h.checksum); | |
| bh->h.src = htonl(bh->h.src); | |
| bh->h.dst = htonl(bh->h.dst); | |
| memcpy(&temp_u32, &(bh->b[20]), 4); | |
| bh->h.options = htonl(temp_u32) >> 8; | |
| bh->h.padding = temp_u32 & 0xFF; | |
| } | |
| void ntoh_header(bytes_header* bh) { | |
| uint16_t temp_u16; | |
| uint32_t temp_u32; | |
| bh->h.length = ntohs(bh->h.length); | |
| bh->h.identification = ntohs(bh->h.identification); | |
| memcpy(&temp_u16, &(bh->b[6]), 2); | |
| bh->h.flags = ntohs(temp_u16) >> 13; | |
| bh->h.fragment_offset = temp_u16 & 0x1FFF; | |
| bh->h.checksum = ntohs(bh->h.checksum); | |
| bh->h.src = ntohl(bh->h.src); | |
| bh->h.dst = ntohl(bh->h.dst); | |
| memcpy(&temp_u32, &(bh->b[20]), 4); | |
| bh->h.options = ntohl(temp_u32) >> 8; | |
| bh->h.padding = temp_u32 & 0xFF; | |
| } | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* servTCP.c riceve stringa, trasla i caratteri di 2, e | |
| rispedisce al mittente | |
| su SunOS compilare con gcc -o servTCP.c -lsocket -lnsl servTCP.c | |
| su linux gcc -o servTCP servTCP.c | |
| eseguire ad esempio su 130.136.2.7 lanciando la seguente riga di comandi: | |
| servTCP 5001 | |
| */ | |
| #include <unistd.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <sys/types.h> | |
| #include <sys/socket.h> | |
| #include <netinet/in.h> | |
| #include <arpa/inet.h> | |
| #include <errno.h> | |
| #include "header.h" | |
| #define SOCKET_ERROR ((int)-1) | |
| #define SIZEBUF 1000000 | |
| #define MAXSIZE 1000000 | |
| void usage(void) | |
| { printf ("usage: servTCP LOCAL_PORT_NUMBER\n"); exit(1); } | |
| int main(int argc, char *argv[]) | |
| { | |
| struct sockaddr_in Local, Cli; | |
| short int local_port_number; | |
| int socketfd, newsocketfd, OptVal, ris; | |
| unsigned int len; | |
| int n, nread, nwrite; | |
| char buf[MAXSIZE]; | |
| if (argc != 2) { printf ("necessario 1 parametri\n"); usage(); exit(1); } | |
| else { | |
| local_port_number = atoi(argv[1]); | |
| } | |
| /* get a stream socket */ | |
| //printf ("socket()\n"); | |
| socketfd = socket(AF_INET, SOCK_STREAM, 0); | |
| if (socketfd == SOCKET_ERROR) { | |
| printf ("socket() failed, Err: %d \"%s\"\n", errno, strerror(errno)); | |
| exit(1); | |
| } | |
| /* name the socket */ | |
| memset ( &Local, 0, sizeof(Local) ); | |
| Local.sin_family = AF_INET; | |
| /* indicando INADDR_ANY viene collegato il socket all'indirizzo locale IP */ | |
| /* dell'interaccia di rete che verrà utilizzata per inoltrare il datagram IP */ | |
| Local.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard */ | |
| Local.sin_port = htons(local_port_number); | |
| //printf ("bind()\n"); | |
| ris = bind(socketfd, (struct sockaddr*) &Local, sizeof(Local)); | |
| if (ris == SOCKET_ERROR) { | |
| printf ("bind() failed, Err: %d \"%s\"\n", errno, strerror(errno)); | |
| exit(1); | |
| } | |
| //printf ("listen()\n"); | |
| ris = listen(socketfd, 10 ); | |
| if (ris == SOCKET_ERROR) { | |
| printf ("listen() failed, Err: %d \"%s\"\n", errno, strerror(errno)); | |
| exit(1); | |
| } | |
| /* wait for connection request */ | |
| /* while(1) { */ | |
| do { | |
| memset ( &Cli, 0, sizeof(Cli) ); | |
| len = sizeof(Cli); | |
| //printf ("accept()\n"); | |
| newsocketfd = accept(socketfd, (struct sockaddr*) &Cli, &len); | |
| } while ( (newsocketfd < 0) && (errno == EINTR) ); | |
| if (newsocketfd == SOCKET_ERROR) { | |
| printf ("accept() failed, Err: %d \"%s\"\n", errno, strerror(errno)); | |
| exit(1); | |
| } | |
| /*printf("connection from %s : %d\n", | |
| inet_ntoa(Cli.sin_addr), | |
| ntohs(Cli.sin_port) | |
| );*/ | |
| /* wait for data */ | |
| nread = 0; | |
| len = sizeof(bytes_header); | |
| //printf ("read()\n"); | |
| while ((len > nread) && (n = read(newsocketfd, &(buf[nread]), len - nread )) > 0) { | |
| printf("letti %d bytes tot = %d\n", n, n + nread); | |
| fflush(stdout); | |
| nread += n; | |
| } | |
| if (n <= 0) { | |
| char msgerror[1024]; | |
| sprintf(msgerror, "read() failed [err %d] ", errno); | |
| perror(msgerror); | |
| n = close(newsocketfd); | |
| /* | |
| if(n!=0) | |
| { | |
| perror("close failed: "); | |
| exit(2); | |
| } | |
| */ | |
| return (1); | |
| } | |
| bytes_header h; | |
| for (int i = 0; i < 24; i++) { // strano problema con strncpy | |
| h.b[i] = buf[i]; | |
| } | |
| ntoh_header(&h); | |
| unsigned long src = h.h.src; | |
| unsigned long dst = h.h.dst; | |
| h.h.src = dst; | |
| h.h.dst = src; | |
| fill_header(&(h.h), 0); | |
| hton_header(&h); | |
| /* scrittura */ | |
| nwrite = 0; | |
| //printf ("write()\n"); | |
| while ( (n = write(newsocketfd, &(h.b[nwrite]), nread - nwrite)) > 0 ) | |
| nwrite += n; | |
| if (n < 0) { | |
| char msgerror[1024]; | |
| sprintf(msgerror, "write() failed [err %d] ", errno); | |
| perror(msgerror); return (1); | |
| } | |
| /* chiusura */ | |
| //printf ("close()\n"); | |
| close(newsocketfd); | |
| close(socketfd); | |
| return (0); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment