1. What are raw sockets?

A raw socket is a socket that allows access to packet
headers on incoming and outgoing packets. Raw sockets
always receive the packets with the packet header included
as opposed to non-raw sockets which strip the header and
only receive the packet payload.

2. What is Mac, and how is it different from PC? Which one is better for professional users, and why?

Mac OS is the trademarked name for a series of graphical
user interface-based operating systems developed by Apple
Inc. (formerly Apple Computer, Inc.) for their Macintosh
line of computer systems.

PC is Personal computer, a computer whose original sales
price, size, and capabilities make it useful for

Mac OS works on PC. So both are diffrent.. BOth are counter
part of each other. Mac is Software and PC is hardware.

3. What is LILO?

LILO is Linux Loader is a boot loader for Linux. It is used
to load Linux into the memory and start the Operating
system. LILO can be configured to boot other operating
systems as well. LILO is customizable, which means that if
the default configuration is not correct, it can be changed.
Config file for LILO is lilo.conf.

4. How would I put my socket in non-blocking mode?

Technically, fcntl(soc, F_SETFL, O_NONBLOCK) is incorrect since it clobbers all other file flags. Generally one gets away with it since the other flags (O_APPEND for example) don't really apply much to sockets. In a similarly rough vein, you would use fcntl(soc, F_SETFL, 0) to go back to blocking mode.

To do it right, use F_GETFL to get the current flags, set or clear the O_NONBLOCK flag, then use F_SETFL to set the flags.

And yes, the flag can be changed either way at will.

5. How come only the first part of my datagram is getting through?

This has to do with the maximum size of a datagram on the two machines involved. This depends on the sytems involved, and the MTU (Maximum Transmission Unit). According to "UNIX Network Programming", all TCP/IP implementations must support a minimum IP datagram size of 576 bytes, regardless of the MTU. Assuming a 20 byte IP header and 8 byte UDP header, this leaves 548 bytes as a safe maximum size for UDP messages. The maximum size is 65516 bytes. Some platforms support IP fragmentation which will allow datagrams to be broken up (because of MTU values) and then re-assembled on the other end, but not all implementations support this.

Another issue is fragmentation. If a datagram is sent which is too large for the network interface it is sent through, then the sending host will fragment it into smaller packets which are reassembled by the receiving host. Also, if there are intervening routers, then they may also need to fragment the packet(s), which greatly increases the chances of losing one or more fragments (which causes the entire datagram to be dropped). Thus, large UDP datagrams should be avoided for applications that are likely to operate over routed nets or the Internet proper.

6. How can I be sure that UDP messages are received in order?

You can't. What you can do is make sure that messages are processed in order by using a numbering system as mentioned in ``5.5 How can I be sure that a UDP message is received?''. If you need your messages to be received and be received in order you should really consider switching to TCP. It is unlikely that you will be able to do a better job implementing this sort of protocol than the TCP people already have, without a significant investment of time.

7. How can I read ICMP errors from connected UDP sockets?

If the target machine discards the message because there is no process reading on the requested port number, it sends an ICMP message to your machine which will cause the next system call on the socket to return ECONNREFUSED. Since delivery of ICMP messages is not guarenteed you may not recieve this notification on the first transaction.

8. What is the difference between connected and unconnected sockets?

If a UDP socket is unconnected, which is the normal state after a bind() call, then send() or write() are not allowed, since no destination address is available; only sendto() can be used to send data.

Calling connect() on the socket simply records the specified address and port number as being the desired communications partner. That means that send() or write() are now allowed; they use the destination address and port given on the connect call as the destination of the packet.

9. How can I write a multi-homed server?

I want to run a server on a multi-homed host. The host is part of two networks and has two ethernet cards. I want to run a server on this machine, binding to a pre-determined port number. I want clients on either subnet to be able to send broadcast packates to the port and have the server receive them.

Your first question in this scenario is, do you need to know which subnet the packet came from? I'm not at all sure that this can be reliably determined in all cases.

If you don't really care, then all you need is one socket bound to INADDR_ANY. That simplifies things greatly.

If you do care, then you have to bind multiple sockets. You are obviously attempting to do this in your code as posted, so I'll assume you do.

I was hoping that something like the following would work. Will it? This is on Sparcs running Solaris 2.4/2.5.

I don't have access to Solaris, but I'll comment based on my experience with other Unixes.

What you are doing is attempting to bind all the current hosts unicast addresses as listed in hosts/NIS/DNS. This may or may not reflect reality, but much more importantly, neglects the broadcast addresses. It seems to be the case in the majority of implementations that a socket bound to a unicast address will not see incoming packets with broadcast addresses as their destinations.

The approach I've taken is to use SIOCGIFCONF to retrieve the list of active network interfaces, and SIOCGIFFLAGS and SIOCGIFBRDADDR to identify broadcastable interfaces and get the broadcast addresses. Then I bind to each unicast address, each broadcast address, and to INADDR_ANY as well. That last is necessary to catch packets that are on the wire with INADDR_BROADCAST in the destination. (SO_REUSEADDR is necessary to bind INADDR_ANY as well as the specific addresses.)

This gives me very nearly what I want. The wrinkles are:

o I don't assume that getting a packet through a particular socket necessarily means that it actually arrived on that interface.

o I can't tell anything about which subnet a packet originated on if its destination was INADDR_BROADCAST.

o On some stacks, apparently only those with multicast support, I get duplicate incoming messages on the INADDR_ANY socket.

10. How should I choose a port number for my server?

The list of registered port assignments can be found in STD 2 or RFC 1700. Choose one that isn't already registered, and isn't in /etc/services on your system. It is also a good idea to let users customize the port number in case of conflicts with other un- registered port numbers in other servers. The best way of doing this is hardcoding a service name, and using getservbyname() to lookup the actual port number. This method allows users to change the port your server binds to by simply editing the /etc/services file.

Download Interview PDF