Introduction to Information Security Networking Transmission Control Protocol

  • Slides: 18
Download presentation
Introduction to Information Security Networking

Introduction to Information Security Networking

Transmission Control Protocol (aka TCP) • Most widely used protocol • A ‘reliable’ (but

Transmission Control Protocol (aka TCP) • Most widely used protocol • A ‘reliable’ (but not secure!) protocol • A TCP Connection is defined by the 4 -tuple – o o Source IP Destination IP Source port Destination port • Also important – o Source byte counter o Destination byte counter

TCP/IP Continued • In order to establish a TCP connection, a 3 -way handshake

TCP/IP Continued • In order to establish a TCP connection, a 3 -way handshake occurs – o Client -> Server: SYN o Server -> Client: SYN + ACK o Client -> Server: ACK • Once the handshake is established and the connection is up and running TCP ensures – o Delivery of ALL the data in both directions o Delivery in order o Delivery with no errors

Server Implementation • The server listens on a specific port (aka the destination port)

Server Implementation • The server listens on a specific port (aka the destination port) • Once a connection is established, the server can accept more connections while handling the first connection • Establish multi processing of connections can be gained by: o o Fork() – Multi process solution Multi-Threaded solutions Select() – Single process solutions Other OS specific solutions

Client implementation • Usually handles only one connection at a time. (extreme contrary example:

Client implementation • Usually handles only one connection at a time. (extreme contrary example: u. Torrent) • Source port is randomized by operating system (unless application requires otherwise)

#!usr/bin/python Python client from socket import * PORT = 1948 def main(): sock =

#!usr/bin/python Python client from socket import * PORT = 1948 def main(): sock = socket(AF_INET, SOCK_STREAM) sock. connect(("127. 0. 0. 1", PORT)) res = sock. recv(1000) # 1000 = Maximum number of bytes to # receive, however, it may return with less bytes # than expected print res sock. close() if __name__ == '__main__': main()

Python server example #!usr/bin/python from socket import * PORT = 1948 def main(): sock

Python server example #!usr/bin/python from socket import * PORT = 1948 def main(): sock = socket(AF_INET, SOCK_STREAM) sock. bind(("0. 0", PORT)) sock. listen(10) # set backlog while 1: (client_sock, peer_info) = sock. accept() print "Got incoming connection from %s: %d " %(peer_info) res = client_sock. send("Hello, World!") client_sock. close() if __name__ == '__main__': main()

C programming reference • Most popular guide ever released for network programming is beej’s

C programming reference • Most popular guide ever released for network programming is beej’s guide which is a very good starter reference o http: //beej. us/guide/bgnet/output/html/singlepage/bgnet. html

Server implementation in C (taken from beej) - includes /* ** server. c -

Server implementation in C (taken from beej) - includes /* ** server. c - a stream socket server demo */ #include <stdio. h> #include <stdlib. h> #include <unistd. h> #include <errno. h> #include <string. h> #include <sys/types. h> #include <sys/socket. h> #include <netinet/in. h> #include <arpa/inet. h> #include <sys/wait. h> #include <signal. h>

C-Server Cleanup and defines #define MYPORT 1948 // the port users will be connecting

C-Server Cleanup and defines #define MYPORT 1948 // the port users will be connecting to #define BACKLOG 10 // how many pending connections queue will hold //Cleaning up dead child processes: void sigchld_handler(int s) { while(waitpid(-1, NULL, WNOHANG) > 0); }

C-Server main int main(void) { int sockfd, new_fd; // listen on sock_fd, new connection

C-Server main int main(void) { int sockfd, new_fd; // listen on sock_fd, new connection on new_fd struct sockaddr_in my_addr; // my address information struct sockaddr_in their_addr; // connector’s address information socklen_t sin_size; struct sigaction sa; int yes=1; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } my_addr. sin_family = AF_INET; // host byte order my_addr. sin_port = htons(MYPORT); // short, network byte order my_addr. sin_addr. s_addr = INADDR_ANY; // automatically fill with my IP memset(&(my_addr. sin_zero), '', 8); // zero the rest of the struct

C-Server continued if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) perror("bind"); exit(1); } if (listen(sockfd,

C-Server continued if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) perror("bind"); exit(1); } if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } sa. sa_handler = sigchld_handler; // reap all dead processes sigemptyset(&sa. sa_mask); sa. sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } == -1) {

C-Server continued while(1) { // main accept() loop sin_size = sizeof(struct sockaddr_in); if ((new_fd

C-Server continued while(1) { // main accept() loop sin_size = sizeof(struct sockaddr_in); if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size) ) == -1) { perror("accept"); continue; } printf("server: got connection from %sn", inet_ntoa(their_addr. sin_addr)); if (!fork()) { // this is the child process close(sockfd); // child doesn't need the listener if (send(new_fd, "Hello, world!n", 14, 0) == -1) perror("send"); close(new_fd); exit(0); } close(new_fd); // parent doesn't need this } return 0; }

C-Client - includes /* ** client. c - a stream socket client demo */

C-Client - includes /* ** client. c - a stream socket client demo */ #include <stdio. h> #include <stdlib. h> #include <unistd. h> #include <errno. h> #include <string. h> #include <netdb. h> #include <sys/types. h> #include <netinet/in. h> #include <sys/socket. h> #define PORT 1948 // the port client will be connecting to #define MAXDATASIZE 100 // max number of bytes we can get at once

 • • • • • C-Client main int main(int argc, char *argv[]) {

• • • • • C-Client main int main(int argc, char *argv[]) { int sockfd, numbytes; char buf[MAXDATASIZE]; struct hostent *he; struct sockaddr_in their_addr; // connector's address information if (argc != 2) { fprintf(stderr, "usage: client hostnamen"); exit(1); } if ((he=gethostbyname(argv[1])) == NULL) { // get the host info perror("gethostbyname"); exit(1); } if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); }

 • • • • • C-Client main continued 1) { their_addr. sin_family =

• • • • • C-Client main continued 1) { their_addr. sin_family = AF_INET; // host byte order their_addr. sin_port = htons(PORT); // short, network byte order their_addr. sin_addr = *((struct in_addr *)he->h_addr); memset(&(their_addr. sin_zero), 8); // zero the rest of the struct if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == perror("connect"); exit(1); } if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { perror("recv"); exit(1); } buf[numbytes] = ''; printf("Received: %s", buf); close(sockfd); return 0; }

File descriptors • Serially assigned to process and can be shared between father and

File descriptors • Serially assigned to process and can be shared between father and child processes • Reference based (file closes when the last descriptor closes) • Popular descriptors: o o 0 – stdin 1 – stdout 2 – stderr 3 – graphics • Can be dup()licated using dup() and dup 2()

dup 2() • dup 2() can be used to easily connect process inputs and

dup 2() • dup 2() can be used to easily connect process inputs and outputs to an existing (connected) TCP socket! • Assuming sockfd is an already created and connected file descriptor we call: dup 2(sockfd, 0); // dup standard input dup 2(sockfd, 1); // dup standard output dup 2(sockfd, 2); // dup standard error output • Now we can run: execv(“someprocess”, NULL)