Additional API functions and data-structures A look at how some information from lower-layers of the TCP/IP protocol stack could be accessed Two more socket functions • Besides the ‘sendto()’ and ‘recvfrom()’ socket-functions (or ‘send()’ and ‘recv()’), there are two further functions which will be essential to make use of in particular programming situations ssize_t sendmsg( int sock, struct msghdr *msghdr, int flags ); ssize_t recvmsg( int sock, struct msghdr *msghdr, int flags ); More data-structures… • The ‘sendmsg()’ and ‘recvmsg()’ functions make use of a special data-structure that collects a group of parameters into a neat package, called a ‘message header’, and supports use of ‘scatter-gather’ operations by using an array of ‘I/O-vector’ objects struct iovec { void *iov_base; size_t iov_len; } Each I/O-vector describes a memory-buffer, giving its address and its length Message-header struct msghdr { void socklen_t struct iovec int void int int }; *msg_name; msg_namelen; *msg_iov; msg_iovlen; *msg_control; msg_controllen; flags; // optional address // size of address // scatter/gather array // no. of members // ancillary data buffer // ancillary buffer length // flags on received message This structure is used as a value-result parameter in the ‘recvmsg()’ function, and is used as a value-only parameter in the ‘sendmsg()’ function. Idea for a ‘scatter’ example • If most of your application’s messages are short ones, but sometimes there could be a larger one, then you could allocate one oversized buffer to handle the occasional ‘overflow’ from your small-size buffers char smallbuf[ 128 ], largebuf[ 1400 ]; struct iovec myiovec[ 2 ] = { { smallbuf, 128 }, { largebuf, 1400 } }; Data scattering: The arriving data will be accumulated in the small buffer until it is filled, then any overflow will be accumulated in the large buffer. ‘Ancillary’ data • Our main interest in using the ‘recvmsg()’ socket-function will be to obtain ancillary information – specifically, we want to see details about ‘message-delivery’ failures which normally are not available outside the Linux kernel’s networking subsystem • Some ‘socket options’ will make the extra information available to an application ICMP • The Internet Control Message Protocol is used for relaying information between the code-modules at the ‘network’ level of the TCP/IP protocol stack (e.g., for reporting errors and for various system queries) Application Layer Application Layer Transport Layer Transport Layer Network Layer Network Layer Link Layer Link Layer Physical Layer Physical Layer ICMP packet-format Ethernet Header Type Internet ICMP Protocol Header Header Code Data Checksum Rest of the ICMP Header (layout varies with the Type) 32 bits ICMP messages ICMP Query messages ICMP Error reporting messages Type Message 8 or 0 Echo request or reply 13 or 14 Timestamp request and reply 17 or 18 Address Mask request and reply 10 or 9 Router solicitation and advertisement 3 Destination unreachable 4 Source quench 11 Time exceeded 12 Parameter problem 5 Redirection Type 3: Destination unreachable Code Reason 0 The network is unreachable 1 The host is unreachable 2 The protocol is unreachable 3 The port is unreachable 4 Fragmentation needed (but DF is set) 5 Source routing cannot be accomplished 6 Destination network is unknown 7 Destination host is unknown Several additional code-values can occur for Type 3 Our msgserver and msgclient • We posted a new client-and-server demo in which exchanges of network messages is accomplished by using the ‘sendmsg()’ and the ‘recvmsg()’ socket functions and accompanying ‘message-header’ objects • With ‘nicwatch’ we can use these demos to illustrate the ICMP protocol in action ICMP protocol Type 8: Echo Request ICMP protocol Type 0: Echo Reply UDP protocol ICMP protocol Type 11: Time exceeded Code 0: (always zero for Type 11) UDP protocol ICMP protocol Type 3: Destination unreachable Code 3: The port is unreachable