Socket options A way for network applications to ‘tweak’ the processing done at lower-levels of the TCP/IP stack The TCP/IP stack Application layer FTP, HTTP, SSH, DHCP, etc The sockets API Transport layer TCP, UDP, etc Network layer IP, ICMP, etc Link layer ARP, RARP, etc Physical layer DSL, FDDI, etc Encapsulation message data Application segment UDP Header data Transport data Network datagram IP Header UDP Header frame Frame Header IP Header UDP Header data Frame CRC data Frame CRC Link stream-of-bits preamble Frame Headerd IP Header UDP Header Inter-Frame Gap Key library functions • • • • • • • int int int int int int int socket() bind(), int connect() listen(), int accept() write(), int read() send(), int recv() sendto(), int recvfrom() shutdown(), int close() Simple program-flow example int sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); connect( sock, (sockaddr*)&saddr, sizeof( saddr ) ); write( sock, message, sizeof( message ) ); close( sock ); socket-address object struct sockaddr_in socklen_t bzero( &saddr, salen ); saddr; salen = sizeof( saddr ); saddr.sin_family = AF_INET; saddr.sin_port = htons( port_number ); saddr.sin_addr.s_addr = htonl( peer_ip_address ); Using the sockets API requires allocating and initializing data-objects known as ‘socket-addresses’ (aka ‘socket-names’), with some numeric fields which require using the Internet’s standard ‘big-endian’ byte-order, rather than the ‘little-endian’ byte-order employed within Intel’s x86 processors. But helperfunctions, like htons() and htonl(), will convert host-order into network-order. Using socket ‘options’ • The default behavior of the kernel routines for the lower-layers of the TCP/IP protocol stack may not be fully suitable for the aims of particular network application programs • But applications usually can’t alter code in an operating system’s protected kernel • The sockets API offers a ‘workaround’ for such situations, i.e.: int setsockopt() Function prototypes int getsockopt( int sd, int level, int optname, void *optval, socklen_t *optlen ); int setsockopt( int sd, int level, int optname, void *optval, socklen_t optlen ); There are various socket options, which apply to various levels in the networking system’s software hierarchy, and which selectively apply to various types of sockets -- and which are implemented to varying degrees within different versions of popular operating systems. We will demonstrate use of two socket options available in Linux for datagram sockets: SO_BROADCAST and SO_BINDTODEVICE. Our demo also illustrate the use of ‘write()’ for a connected socket. Demo: ‘bindtoif.cpp’ • This program lets a privileged user write a ‘broadcast’ message to all of the hosts on our classroom’s Local Area Network – as you can confirm using our ‘nicwatch’ tool • And -- the user can choose the interface! • Normally an application wouldn’t be able to send a ‘broadcast’ message, nor be able to select which interface gets used Overview Get the name of the desired network interface from the command-line Open an internet datagram socket Turn on the ‘SO_BROADCAST’ socket-option Bind the chosen network interface to that socket Connect the socket to the network‘s broadcast address Write a message to the connected socket Show the user a confirmation message Programming details • Now we take a ‘timeout’ from these slides to look carefully line-by-line at the sourcecode which will implement those steps • Then we will be ready to compile and run our ‘bindtoif’ demo-program (using ‘sudo’) • You should all be able to watch the arrival of the broadcast message at your desktop! ‘ifconfig’ • Remember that your classroom computer leaves the ‘eth1’ interface disabled after a reboot – so you will need to use ‘ifconfig’ to enable that interface and also assign it an appropriate Internet Protocol address: $ sudo /sbin/ifconfig eth1 192.168.1.xxx up