Assignment 1 ------------ Write a program for receiving and displaying (as a hexudmp) the content of UDP packets. This udpspy shall be controlled via a set of command line parameters and support at least the following options with the respective syntax: udpspy -a -i -s -l -t -D -a: used to specify a transport address that shall be used for listening for incoming UDP packets. Option -a may be given repeatedly and, for each occurrence, a separate UDP socket shall be created for receiving packets. The may use any of the following formats: a.b.c.d/port with a.b.c.d being an IPv4 address in dotted decimal notation. hostname/port with hostname being an hostname that can be resolved into an IPv4 (or IPv6) address by using the name resolution mechanisms offered by the operating system /port only specifies a port number so that INADDR_ANY is used as IP address; this implies unicast reception. a:b:c:d:e:f:g:h/port (voluntary) with a:...:h representing an IPv6 address. Note: RFC2732 contains numerous examples for valid textual notations for IPv6 addresses. All addresses and hostnames may be or resolve to unicast as well as multicast addresses. Remember: multicast addresses are class D IP addresses and are in the range 224.0.0.0 to 239.255.255.255. Just determine the address type and then handle the address accordingly. Note: Resolving IP address using getaddrinfo() or gethostbyname (), etc. may return multiple IP addresses. You only need to process one of these but you need to make sure that the address family is the "right" one. The IP unicast address and the port number (or just the port number) but _not_ the IP multicast address need to be handed to the bind() system call in the data structure struct sockaddr_in (for IPv4). For multicast reception, do not forget the setsockopt() with IP_ADD_MEMBERSHIP. -i: Used in conjunction with multicasting only and allowed to be specified at most once, this option provides the local IP address of the interface that shall be used for joining all multicast groups. This information needs to go along with IP_ADD_MEMBERSHIP in "struct ip_mreq". -s: Short form: turns off the hexdump output and thus creates a single line of output per packet (<80 characters) containing a timestamp with microsecond resolution, source and destination IP address and port number and the packet size. If -s is not given, the output will also have the hexdump. -l: Limits the hexdump output length to the specified number of bytes per packet (otherwise, the full packet contents shall be dumped). -t: Open a listening socket for incoming TCP control connections. If -t is _not_ specified the output will be to stdout. If -t is given, a TCP socket will be created for the specified address and no output will be printed to stdout. Every client that connects to the TCP port number will receive a copy of the output (according to -l and -s) over the TCP connection until it disconnects again. Output need not be buffered. If there is no client, the output is simply discarded. While not a good idea in practice, for the purpose of this assignment, you may assume that clients will receive the data sufficiently fast and you do not have to worry about buffering for clients receiving at different data rates. You may use blocking i/o for all communication tasks in the assignment. Input sent from the client via the TCP connection is read from the socket and immediately discarded. -D: This option is used to specify a duration that the program shall run for. After this time is elapsed the program shall terminate automatically. The time interval shall be specified (as an integer) in seconds. The program shall be orderly terminated when the user sends a SIGINT (equivalent to pressing Control-C) and then print, as a final action, the time elapsed since its invocation, the number of received packets, and the total number of bytes received. This could look like: Duration: 123.123456 seconds, received 57 packets, 4530 bytes total This information shall also be output if the program terminates after a duration specified using -D. Useful functions: ----------------- Command line parsing getopt () Time: gettimeofday () Signal handling: signal () Sockets: gethostbyhame (), getaddrinfo () inet_aton (), inet_addr (), inet_ntoa () socket (), bind (), setsockopt (), close () recvfrom (), sendto (), poll () Output ------ Example for short form output: 14:09:00.123456 134.102.218.59:40000 -> 134.102.218.58:47000 79 Bytes A hexdump could look like that: (remember that packet sizes are not multiples of 16 bytes and the last line of your hexdump still should be readable) Offset Individual bytes in hexadezimal Characters (*) ------ ----------------------------------------------- ---------------- 000000: 00 01 02 00 41 42 43 09 00 64 00 00 00 00 30 39 ....ABC..d....09 000010: 00 00 0a 0d .... (*) Characters with the ASCII codes in the range from 32 to 127 should be printed, all other represented by a ".".