NETWORK PROGRAMMING CSC- 341 Instructor: Junaid Tariq, Lecturer, Department of Computer Science Lecture 11 PART 2 SOCKETS INTRODUCTION CHAPTER 3 SOCKET ADDRESS STRUCTURE Socket = IP address + TCP or UDP port number Used in a socket function as a argument (as pointer). Socket Address Structure includes: IP address, TCP or UDP port number, length of structure ..... Each protocol define its own Socket Address Structure(IPv4, IPv6....) IPV4 SOCKET struct in_addr{ in_addr_t }; ADDRESS STRUCTURE s_addr; struct sockaddr_in { uint8_t sin_len; sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; char sin_zero[8]; }; /* included in <netinet/in.h> */ /*32bit IPv4 address*/ /*network byte ordered*/ /* length of structure(16) */ /* AF_INET */ /* 16bit TCP or UDP port number */ /*network byte ordered*/ /* 32bit IPv4 address */ /*network byte ordered*/ /* unused */ IPV4 SOCKET ADDRESS STRUCTURE The length member, sin_len, was added with 4.3BSD-Reno Even if the length field is present, we never need to examine it, unless we are dealing with routing sockets (Chapter 17). It is used within the kernel by the routines that deal with socket address structures from various protocol families The four socket functions that pass a socket address structure from the process to the kernel, bind, connect, sendto, and sendmsg, This function copies the socket address structure from the process and explicitly sets its sin_len member to the size of the structure. The five socket functions that pass a socket address structure from the kernel to the process, accept, recvfrom, recvmsg, getpeername, and getsockname, all set the sin_len member before returning to the process. IPV4 SOCKET ADDRESS STRUCTURE The 32-bit IPv4 address can be accessed in two different ways. serv.sin_addr references the 32-bit IPv4 address as an in_addr structure, if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) err_quit("inet_pton error for %s", argv[1]); serv.sin_addr.s_addr references the same 32-bit IPv4 address as an in_addr_t (typically an unsigned 32-bit integer). We must be certain that we are referencing the IPv4 address correctly, especially when it is used as an argument to a function, because compilers often pass structures differently from integers. servaddr.sin_addr.s_addr = htonl(INADDR_ANY); GENERIC SOCKET ADDRESS STRUCTURE <sys/socket.h> : Generic Socket address structure struct sockaddr { uint8_t sa_len; sa_family_t sa_family; char sa_data[14]; } /*address family: AF_xxx value*/ /*protocol specific address*/ Generic Socket address structure int bind(int sockfd, struct sockaddr * , socklen_t); struct sockaddr_in serv; /*IPv4 socket address structure*/ /* fill in serv{} */ bind(sockfd, (struct sockaddr *) &serv, sizeof(serv)); bind(sockfd, (SA *) &servaddr, sizeof(servaddr)); IPV6 SOCKET ADDRESS STRUCTURE struct in6_addr{ uint8_t s6_addr[16]; }; /*128bit IPv6 address*/ /*network byte ordered*/ struct sockaddr_in6 { uint8_t sin6_len; /* length of structure(24) */ sa_family_t sin6_family; /* AF_INET6*/ in_port_t sin6_port; /* Transport layer port# */ /*network byte ordered*/ uint32_t sin6_flowinfo; /* priority & flow label */ /*network byte ordered*/ struct in6_addr sin6_addr; /* IPv6 address */ /*network byte ordered*/ }; /* included in <netinet/in.h> */ COMPARISON OF SOCKET ADDRESS STRUCTURE VALUE-RESULT ARGUMENT socket address structure is always passed by reference to socket functions. The length of the structure is also passed. The way the length is passed depends on which direction the structure is being passed Socket address structure pass. int User length Socket Address structure value process Protocol address Kernel Bind, connect, sendto Socket address structure pass. int * length User value result Socket Address structure process Protocol address Kernel Accept, recvfrom, getsockname, getpeername Process to Kernel Kernel to Process struct sockaddr_in serv /* fill in serv{} */ struct sockaddr_in cli connect(sockfd, (SA *)&serv, sizeof(serv)); socklen_t len; len = sizeof(cli); accept(listenfd, (SA *) &cli, &len); /* len is filled in by the kernel. */ BYTE ORDERING FUNCTION Increasing memory address Little-endian byte order: Address A+1 High-order byte MSB big-endian byte order: Address A low-order byte 16bit value High-order byte LSB low-order byte Address A Address A+1 Increasing memory address FIGURE3.9 DETERMINE HOST BYTE ORDER int main(int argc, char **argv) { union { short s; char c[sizeof(short)]; } un; un.s = 0x0102; if (sizeof(short) == 2) { if (un.c[0] == 1 && un.c[1] == 2) printf("big-endian\n"); else if (un.c[0] == 2 && un.c[1] == 1) printf("little-endian\n"); else printf("unknown\n"); } else printf("sizeof(short) = %d\n", sizeof(short)); exit(0); }