1 / 55

CSCD433 Advanced Networks Winter 2019 Lecture 14

Raw vs. Cooked Sockets C Language. CSCD433 Advanced Networks Winter 2019 Lecture 14. Introduction. Raw Sockets in C Review of Sockets in C Look at how to write Raw Sockets in C Contrast with Java. Sockets in C. Normal socket operation in C is more detailed

sguillen
Télécharger la présentation

CSCD433 Advanced Networks Winter 2019 Lecture 14

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Raw vs. Cooked Sockets C Language CSCD433Advanced NetworksWinter 2019Lecture 14

  2. Introduction • Raw Sockets in C • Review of Sockets in C • Look at how to write Raw Sockets in C • Contrast with Java

  3. Sockets in C • Normal socket operation in C is more detailed • More steps to implement Client/Server connection • Does not take care of details like address translation • Programmers need to know more about network connections

  4. Normal Socket Operations • Look at TCP Client/Server example in C • Then, look at a Raw Socket implementation in C • For fun, see a Java Raw Socket example

  5. Using Regular C Sockets Steps to create a socket in C for Server and Client • Server operations • Create a Socket • Fill in the Socket Address structure • Set the Port Number / IP Address • Name a Socket • Create a Socket Queue • Accept Connections • Do something with the Connection – read or write data • Close a Socket • Client operations • Request Connections • Use data from Server

  6. Creating a Socket in C • socket() system call • Socket system call returns a descriptor similar to low-level file descriptor • Socket created is one end point of a communication channel #include <sys/types.h> #include <sys/socket.h> int socket (int domain, int type, int protocol);

  7. Socket() System Call int socket (int family, int type, int protocol); Example: sockfd=socket(AF_INET,SOCK_STREAM,0); • sockfd is the file descriptor for the socket • AF_INET says it is an Internet family of socket • SOCK_STREAM says it is a TCP type of socket • 0 for the protocol means it is an IP type of socket On success, a file descriptor for the new socket is returned. “Everything is a file” Unix paradigm. The first parameter, family, is also sometimes referred to as “domain”.

  8. Socket(): Family A family is a suite of protocols Each family is a subdirectory of linux/net E.g., linux/net/ipv4, linux/net/decnet, linux/net/packet IPv4: PF_INET or AF_INET IPv6: PF_INET6. Packet sockets: PF_PACKET Operates at the link layers pcap library for Linux uses PF_PACKET sockets pcap library is used by sniffers such as tcpdump Protocol Family == Address Family PF_INET == AF_INET (in /include/linux/socket.h)

  9. Socket Layer Architecture Application User BSD Socket Layer Socket Interface PF_INET PF_PACKET PF_UNIX PF_IPX SOCK_ STREAM SOCK_ DGRAM SOCK _RAW …. …. Protocol Layers SOCK _RAW SOCK_ DGRAM TCP UDP IPV4 Kernel Network Device Layer Device Layer Ethernet Token Ring PPP SLIP FDDI Intel E1000 Hardware

  10. Address/Protocol Families /* Supported address families. */ #define AF_UNSPEC 0 #define AF_UNIX 1 /* Unix domain sockets */ #define AF_LOCAL 1 /* POSIX name for AF_UNIX */ #define AF_INET 2 /* Internet IP Protocol */ #define AF_AX25 3 /* Amateur Radio AX.25 */ #define AF_IPX 4 /* Novell IPX */ #define AF_APPLETALK 5 /* AppleTalk DDP */ #define AF_NETROM 6 /* Amateur Radio NET/ROM */ #define AF_BRIDGE 7 /* Multiprotocol bridge */ #define AF_ATMPVC 8 /* ATM PVCs */ #define AF_X25 9 /* Reserved for X.25 project */ #define AF_INET6 10 /* IP version 6 */ #define AF_ROSE 11 /* Amateur Radio X.25 PLP */ #define AF_DECnet 12 /* Reserved for DECnet project */ #define AF_NETBEUI 13 /* Reserved for 802.2LLC project*/ #define AF_SECURITY 14 /* Security callback pseudo AF */ #define AF_KEY 15 /* PF_KEY key management API */ .. #define AF_ISDN 34 /* mISDN sockets */ #define AF_PHONET 35 /* Phonet sockets */ #define AF_IEEE802154 36 /* IEEE802154 sockets */ #define AF_MAX 37 /* For now.. */ include/linux/socket.h

  11. Socket(): Type SOCK_STREAM and SOCK_DGRAM are most used types SOCK_STREAM for TCP, SCTP SOCK_DGRAM for UDP SOCK_RAW for RAW sockets

  12. Socket(): Protocol Protocol is protocol number within a family. Internet protocols are assigned by IANA http://www.iana.org/assignments/protocol-numbers/ For AF_INET, it’s usually 0. IPPROTO_IP is 0, see: include/linux/in.h. For SCTP (Stream Controlled Transport Protocol): protocol is IPPROTO_SCTP (132) sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); For UDP-Lite: protocol is IPPROTO_UDPLITE (136)

  13. Example SocketAF_INET • For AF_INET socket (Ipv4 socket) struct sockaddr_in { short int sin_family; /* AF_INET */ unsigned short int sin_port; /* Port number */ struct in_addr sin_addr; /* IP address */ }; struct in_addr { unsigned long int s_addr; };

  14. Name a SocketAF_INET • AF_INET sockets are associated with an IP/ port number • bind() system call assigns address specified in parameter, address, to unnamed socket and a port number #include <sys/socket.h> int bind(int socket, const struct sockaddr *address, size_t address_len);

  15. Create a Socket QueueAF_INET • A server program must create a queue to store pending requests, uses listen() system call • Allows incoming connections to be pending while server is busy dealing with previous client • Return values same as for bind #include <sys/socket.h> int listen ( int socket, int backlog );

  16. Accept Connections • Wait for connections to socket by using accept() system call • Creates a new socket to communicate with the client and returns its descriptor #include <sys/socket.h> int accept(int socket, struct sockaddr *address, size_t *address_len);

  17. Sending or Writing to Socket sendmsg (fd, msgstruct, flags); sendmsg() is used to transmit a message to another socket fd is file descriptor from socket call msgstruct is used to pass information flags can be passed as 0, parameters for data being passed write (fd, data, length); write is the “normal” write function; can be used with both files and sockets

  18. Sending or Writing to Socket send (fd, data, length, flags); sendto (fd, data, length, flags, destaddress, addresslen); send() is used for TCP SOCK_STREAM connected sockets, and sendto() is used for UDP SOCK_DGRAM unconnected datagram sockets or RAW sockets With unconnected sockets, you must specify destination of a packet each time you send one

  19. Receiving or Reading From Socket recv (int s, void *buf, size_t len, int flags); recvfrom (int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); recv() is for TCP SOCK_STREAM sockets recvfrom() is for UDP SOCK_DGRAM or RAW sockets • Both functions take socket descriptor s, a pointer to buffer buf, size (in bytes) of buffer, len, and a set of flags that control how the functions work • recvfrom() takes a struct sockaddr*, from that will tell you where the data came from, and will fill in fromlen with the size of struct sockaddr

  20. Receiving or Reading from Socket recvmsg (int sockfd, struct msghdr *msg, int flags); read (int fd, void *buf, size_t count); recvmsg() offers some additional features that recv() does not, ancillary data fields in msghdr read () attempts to read up to count bytes from file descriptor fd into buffer starting at buf File descriptor can also be a socket descriptor

  21. SERVER AND CLIENTS TCP Server From: UNIX Network Programming Volume 1, figure 4.1 socket() bind() TCP Client listen() socket() accept() connection establishment connect() data request read() write() datareply write() read() read() end-of-file notification close() 21 close()

  22. TCP Date and Time Server

  23. TCP Date and Time Server • Server starts • Waits for a client to contact it • Client connects – TCP C socket • Server gets the Current Date and Time • Writes it to the Client • Client displays it and closes connection

  24. Server Side: Date and Time Server #include <sys/socket.h> #include <netinet/in.h> ... int main (int argc, char *argv[]) { int listenfd = 0, connfd = 0; struct sockaddr_in serv_addr; // Will hold Server address and port number char sendBuff[1025]; time_t ticks; listenfd = socket (AF_INET, SOCK_STREAM, 0); // Create a TCP socket memset (&serv_addr, '0', sizeof(serv_addr)); memset (sendBuff, '0', sizeof(sendBuff)); serv_addr.sin_family = AF_INET; // Set the Socket type serv_addr.sin_addr.s_addr = htonl (INADDR_ANY); // Set server address serv_addr.sin_port = htons(5000); // Set server port

  25. Server Side: Date and Time Server bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); // Bind & Listen on port listen(listenfd, 10); // while(1) { connfd = accept(listenfd, (struct sockaddr*) // Accept connection from client NULL, NULL); ticks = time(NULL); // Read the time and date snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks)); //Put in buffer write(connfd, sendBuff, strlen(sendBuff)); // Write to socket close(connfd); // Close the connection sleep(1); } }

  26. Client: Date and Time include <sys/socket.h> #include <sys/types.h> … int main(int argc, char *argv[]) { int sockfd = 0, n = 0; char recvBuff[1024]; struct sockaddr_in serv_addr; if (argc != 2) // Give it IP address in command line { printf("\n Usage: %s <ip of server> \n",argv[0]); return 1; } memset(recvBuff, '0',sizeof(recvBuff)); // Set up Receive buffer if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) // Open TCP Socket { printf("\n Error : Could not create socket \n"); return 1; } memset(&serv_addr, '0', sizeof(serv_addr)); serv_addr.sin_family = AF_INET; // Set socket family type serv_addr.sin_port = htons(5000); // Set port number

  27. Client: Date and Time if (inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0) { // Convert into network address printf("\n inet_pton error occured\n"); return 1; } if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) //Connect to socket at server addr { printf("\n Error : Connect Failed \n"); return 1; } while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0) // Read from the socket into buffer { recvBuff[n] = 0; if(fputs(recvBuff, stdout) == EOF) // Write the buffer to the screen { printf("\n Error : Fputs error\n"); } } if(n < 0) { printf("\n Read error \n"); } return 0; }

  28. Demo

  29. Defining a Raw Socket in CAF_INET Just like normal sockets, we create raw sockets with the socket(2) system call: int socket(int domain, int type, int protocol) Domain is set to AF_INET which operates at layer 3 of protocol stack However, type and protocol parameters are set to SOCK_RAW and protocol name accordingly, this example is for ICMP: if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) { .. } Also:IPPROTO_TCP, IPPROTO_UDP and IPPROTO_IP and others

  30. Defining a Raw Socket in CPF_PACKET PF_PACKET interface sends/receives packets at layer 2 of the OS All packets received will be complete with all headers and data including Ethernet headers All packets sent will be transmitted without modification by the kernel to the medium

  31. Creating a Raw Socket Call socket() with appropriate arguments.Socket(PF_PACKET, SOCK_RAW, int protocol) Protocol is ETH_P_IP for IP networks. To receive all types of packets ETH_P_IP is used.

  32. Socket Layer Architecture Application User BSD Socket Layer Socket Interface PF_INET PF_PACKET PF_UNIX PF_IPX SOCK_ STREAM SOCK_ DGRAM SOCK _RAW …. …. Protocol Layers SOCK _RAW SOCK_ DGRAM TCP UDP IPV4 Kernel Network Device Layer Device Layer Ethernet Token Ring PPP SLIP FDDI Intel E1000 Hardware

  33. Raw SocketsAF_INET Two ways to define a raw socket 1. Let kernel fill in the IP header and we just create transport protocol header or 2. We are responsible for the whole packet and create both the IP header and underlying protocol headers

  34. Creating Raw Sockets int sockfd; sockfd = socket(AF_INET, SOCK_RAW, protocol); 1. This creates a raw socket and lets the kernel fill in the ip header, we will fill in the protocol header for ICMP or IGMP or TCP or UDP - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - – - - - - - - const int on = 1; setsockopt (sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on); 2. Setting option, IP_HDRINCL allows us to create our own IP header and not let the kernel do it for us IPPROTO_ICMP IPPROTO_IGMP

  35. Raw Sockets Operation (ICMP) User Space Kernel Space Socket App Protocol Linux Create socket ICMP socket ( ) OK Pass data thru local stack to remote host IP, Internet sendto( ) OK 35

  36. Raw Socket Output • Normal output performed using sendto or sendmsg • Write or send can be used if the socket has been connected • If IP_HDRINCL not set, starting addr of data (buf) specifies first byte following IP header that kernel builds • If IP_HDRINCL is set, starting addr of data identifies first byte of IP header, that we build 36

  37. Raw Socket Input • Most ICMP packets are passed to raw socket • Some exceptions for Berkeley-derived implementations • All IGMP packets are passed to a raw socket • All IP datagrams with protocol field that kernel does not understand (process) are passed to a raw socket • If packet has been fragmented, packet is reassembled before being passed to raw socket 37

  38. Byte Order Issues • Packets containing integers traveling in network are all big-endian, meaning most significant bit of the octet is transferred first • Includes port numbers and ip addresses • If host system uses different byte-ordering scheme • e.g. i386 architecture is little-endian • Includes data in address fields • Data must be converted to network byte order or vice versa • On receive path, and if host byte ordering scheme is different from network byte order, • Data must be converted from big-endian to little-endian • On send path, reverse operation • Little-endian to big-endian

  39. Byte Ordering Functions htons(3) and htonl(3) convert 16 bit and 32 bit quantities from host byte order into the network byte order respectively Similarly, ntohs(3) and ntohl(3) macros convert 16-bit and 32-bit quantities from network byte order into the host byte order. On machines which have a byte order same as the network order, routines are defined as null macros

  40. 12 40 119 128 128 119 40 12 htonl ntohl 128 119 40 12 128 119 40 12 NETWORK BYTE-ORDERING u_long htonl(u_long x); u_short htons(u_short x); u_long ntohl(u_long x); u_short ntohs(u_short x); • On big-endian machines, these routines do nothing • On little-endian machines, they reverse the byte order Big-Endian machine Little-Endian machine 128.119.40.12 128.119.40.12 40 From: Dan Rubenstein’s slides: http://www.cs.columbia.edu/~danr/courses/6761/Summer03/intro/6761-1b-sockets.ppt

  41. Compute Internet Checksum • You will also have to compute the packet checksum if you choose to construct headers yourself including ICMP • Ready made routines to cut and paste into your code • Checksums are normally computed for IP, ICMP, UDP and TCP packets • Mostly done for sending out packets

  42. ICMP Header Fields ICMP packet structure shows checksum Checksum here

  43. Raw ICMP Packet Example • We will look at a simpler version of an ICMP program using Raw Sockets • Ping program !!!

  44. Ping.c Example static int in_cksum(unsigned short *buf, int sz) { The checksum is calculated by forming the ones' complement of the ones' complement sum of the header's 16-bit words } …... static void ping(const char *host) { struct hostent *h; // structure stores, host name, address, any aliases for host struct sockaddr_in pingaddr; // create the socket address for ping target struct icmp *pkt; // ICMP Header structure, predefined for you int pingsock, c; char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; // max length if ((pingsock = socket (AF_INET, SOCK_RAW, 1)) < 0) { // Create socket, 1 == ICMP/ perror("ping: creating a raw socket"); exit(1); }

  45. Ping.c pingaddr.sin_family = AF_INET; // Set domain if (!(h = gethostbyname(host))) { // get IP address fprintf(stderr, "ping: unknown host %s\n", host); exit(1); } memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr)); //Set up host addr hostname = h->h_name;

  46. ping.c • Build the icmp packet + checksum, send it pkt = (struct icmp *) packet; memset(pkt, 0, sizeof(packet)); pkt->icmp_type = ICMP_ECHO; //Set ICMP type pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet)); c = sendto(pingsock, packet, sizeof(packet), 0, (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in));

  47. ping.c /* listen for replies */ while (1) { struct sockaddr_in from; size_t fromlen = sizeof(from); if ((c = recvfrom(pingsock, packet, sizeof(packet), 0, (struct sockaddr *) &from, &fromlen)) < 0) { if (errno == EINTR) continue; perror("ping: recvfrom"); continue; }

  48. ping.c if (c >= 76) { /* ip + icmp */ struct iphdr *iphdr = (struct iphdr *) packet; pkt = (struct icmp *) (packet + (iphdr->ihl << 2)); /* skip ip hdr */ if (pkt->icmp_type == ICMP_ECHOREPLY) break; } } printf("%s is alive!\n", hostname); return;

  49. ping.c int main () { ping ("www.yahoo.com"); } Demo of ping program !!!

  50. Some More Examples This URL provides good examples for each type of common network traffic and how to spoof an IP address: http://www.enderunix.org/docs/en/rawipspoof/

More Related