170 likes | 395 Views
An IP-header’s TOS field. On setting and inspecting the ‘Type-of-Service’ field for outgoing or incoming datagrams. Recall IP header format. 32 bits. IP version. Header length. Type of Service. Total Length (in bytes). Identification. D. M. Fragment offset. Time-to-Live. Protocol
E N D
An IP-header’s TOS field On setting and inspecting the ‘Type-of-Service’ field for outgoing or incoming datagrams
Recall IP header format 32 bits IP version Header length Type of Service Total Length (in bytes) Identification D M Fragment offset Time-to-Live Protocol ID-number Header Checksum Source IP-address Destination IP-address Options
Type-Of-Service 7 6 5 4 3 2 1 0 precedence D T R ECN This 8-bit field in the IPv4 Header has been variously defined over the years. In a modern definition it has a 6-bit field called Differentiated Services Code Point (DSCP) and a 2-bit field called Explicit Congestion Notification (ECN). Routers may use this ToS value when selecting a destination for the packet. Legend: D = requests low Delay T = requests high Throughput R = requests high Reliability
Precedence Meanings for the 3-bit precedence field have been defined in Request For Comment documents (RFC791, RFC971): 111: Network Control 110: Internetwork Control 101: CRITIC/ECP 100: Flash Override 011: Flash 010: Immediate 001: Priority 000: Routine Here the middle four values pertain to national security and military communications having various levels of severity or urgency, (such as an outbreak of hostilities or a nuclear device detonation)
Caveat • It should be mentioned that the ToS field’s ‘precedence’ bits are no longer used within contemporary networking systems for their originally envisioned purposes, and hence incoming IP packets which have these bits set ought to be regarded with suspicion – i.e., ask who is sending them, and why?
Nevertheless… • We can employ one of the Linux ‘socket options’ to let applications manipulate the value that a socket places in the TOS field of its outgoing packets (SOL_IP, IP_TOS) • And we can employ another of the socket options to enable an application to inspect the TOS value of incoming IPv4 packets (SOL_IP, IP_RECVTOS)
‘msghdr’ and ‘cmsghdr’ • This will give us yet another example of a client-and-server application which makes use of socket options and ancillary data delivered via the ‘recvmsg()’ function ‘tweaktos.cpp’ ‘clonetos.cpp’ ‘client’ application ‘server’ application The ‘client’ sends a message having a user-specified TOS-value, and the ‘server’ echos back that message using an identical TOS-value.
Our ‘private’ LAN • It’s probably a good idea, when we try out this client-and-server application, to do it on one of our ‘private’ local networks that does not ‘route’ any of our packets to any public networks (or to the Internet), so the ‘unusual’ TOS values in our ‘test-packets’ won’t arouse any unwarranted suspicions about who we are and what we’re up to!
Recall ‘msghdr’ structure struct msghdr { void *msg_name; // optional address socklen_t msg_namelen; // size of address struct iovec *msg_iov; // scatter/gather array int msg_iovlen; // no. of members void *msg_control; // ancillary data buffer int msg_controllen; // ancillary buffer length int flags; // flags on received message }; struct iovec { void *iov_base; size_t iov_len; }
Recall ‘cmsghdr’ structure struct cmsghdr { socklen_t cmsg_len; // data byte count, including header int cmsg_level; // originating protocol’s ID-number int cmsg_type; // protocol-specific type ID-number unsigned char cmsg_data[0]; // variable amount of data follows }; Our buffer for receiving ancillary data: ‘packages’ of ancillary data
Recall the ‘CMSG’ macros int rxtos = 0; // to be filled in with incoming packet’s TOS struct smsghdr *cmsg; // for use as the loop variable for( cmsg = CMSG_FIRSTHDR( &mymsghdr ); cmsg != NULL; cmsg = CMSG_NXTHDR( &mymsghdr, cmsg ) ) { if (( cmsg->cmsg_level == SOL_IP ) &&( cmsg->cmsg_type == IP_TOS )) memcpy( &rxtos, CMSG_DATA( cmsg ), 1 ); }
Viewing memory • While learning about (or debugging) how your ancillary data arrives via ‘recvmsg()’, it may be instructive and helpful if you can get a look at memory-buffer’s contents • You can insert (temporarily) the following block of code (or some suitable variation) so you’ll see a memory ‘dump’ onscreen
‘hex’ and ‘ascii’ # shows the contents of the n-byte memory-area whose address is ‘buf’ unsigned char *cp = (unsigned char*)buf; for (int i = 0; i < n; i += 16) { printf( “\n %03X: “, i ); for (int j = 0; j < 16; j++) { if ( i+j < n ) printf( “%02X “, cp[ i+j ] ); else printf( “ “ ); } for (int j = 0; j < 16; j++) { int ch = ( i+j < n ) ? cp[ i+j ] : ‘ ‘; if (( ch < 0x20 )||( ch > 0x7E )) ch = ‘.’; printf( “%c”, ch ); } } printf( “\n\n” );
In-class exercise #1 • Modify our ‘tweaktos.cpp’ program so that it will draw a ‘dump’ of the contents of its ancillary data buffer (named ‘cbuf’) before terminating
In-class exercise #2 • Modify our ‘tweaktos.cpp’ demo so that it will ALSO receive an incoming packet’s ‘Time-to-Live’ field, as well as continuing to receive its ‘Type-Of-Service’ field, and display a ‘dump’ of the ancillary data’s memory buffer to see both these items arranged as successive records in ‘cbuf’