Sunday, August 7, 2011

Interfaces and Addressing


Before you move onto other aspects of socket programming in the chapters that follow, there is one other concept related to socket addresses that must be understood. This is the concept of interface addresses.
Using the familiar telephone example again, imagine the President's office where there are two (or more) telephones on his desk. Using one of the telephones, he can contact his wife to see how her day is going. On the other hand, using the red telephone gets him in touch with the Russian president. Each of these two telephones is, in a sense, an interface between two different networks. These are
  • The normal domestic telephone network.
  • A private network to the Russian president's high-ranking office(s) on secure lines.

The important point in this example is that you must use the correct interface (telephone) to reach the correct network. For example, the President would be unable to call his wife on the red telephone. Conversely, the domestic telephone would not be able to reach the Russian president's highranking office telephones, which are on secure lines.

In a similar manner, there are times when you want your socket program to specify which interface to use when attempting to contact a remote socket. This is done when you know that one interface is the only way to reach the destination network.
When you are expecting to receive a telephone call, there are times when you want to receive calls only on a particular telephone. 
For example, the teenage daughter might want to receive calls only on the telephone installed in her bedroom. For others in the household, they expect to receive telephone calls only in a downstairs room where the other telephone is installed. Your socket program will likewise sometimes want to accept connections from only one specific interface and ignore all others.

Specifying an Interface Address Example

A concrete example is shown in Figure 5.1, which specifies an interface address.

In the middle of Figure 5.1, you see a server that is acting as a firewall between an internal organization and an external one that is not trusted. Assume that you have written a socket program that runs on the firewall server, which accepts firewall control commands from your workstation at the extreme right of the figure (from within the internal organization). The server program accepts connections from the internal network by permitting connections to arrive only on the network interface ''B."
For security reasons, your control program on the firewall host will not accept connection attempts from the external organization. This is done by ignoring all connection attempts on the firewall network interface "A." This protects your control program from attempted break-ins that might be initiated by the workstation at the extreme left in Figure 5.1.

Binding a Specific Interface Address

In order to specify a particular interface for communications, you must perform the following steps:
  1. Create your socket using the socket(2) function as usual.
  2. Bind the IP address of the interface that you are willing to accept connections onto the local socket using the function bind(2).

In Figure 5.1, you would use the IP address of interface "B" in your call to bind(2), in order to accept connections from the internal network only.
Listing below shows how to bind to a specific network interface address, using some lines of code that you have seen before. This must be done before any socket communication begins.

Listing: Binding a Specific IP Interface

int z;
int sck_inet; /* Socket */
struct sockaddr_in adr_inet; /* AF_INET */
int len_inet; /* length */
sck_inet = socket(AF_INET,SOCK_STREAM,0);
if ( sck_inet == -1 ) {
   abort(); /* Failed */
}
/* Establish address */
memset(&adr_inet,0,sizeof adr_inet);
adr_inet.sin_family = AF_INET;
adr_inet.sin_port = htons(9000);
adr_inet.sin_addr.s_addr("192.168.0.1");
adr_inet.sin_addr.s_addr == INADDR_NONE )
abort(); /* Failed */
len_inet = sizeof adr_inet;
z = bind(sck_inet, (struct sockaddr *)&adr_inet, len_inet);

The steps shown in Listing below are as follows:
  1. A socket is created by calling socket(2) and assigning the descriptor to variable sck_inet. Errors are also tested for and, in this example, abort(3) is called for simplicity if an error occurs.
  2. An IP address of 192.168.0.1 is established prior to calling upon bind(2). TCP port 9000 was arbitrarily used in this example.
  3. The function bind(2) is called, which then binds the established address.

Note that the bind(2) function call will fail if there is no interface with that IP number for that
host.

Binding for Any Interface

How do you accept connections from any interface? You perform the following steps:
  1. Create your socket using the socket(2) function as usual.
  2. Bind the IP address INADDR_ANY to the socket using the function bind(2).

Listing below : Specifying Any Interface Using bind(2)

int z;
int sck_inet; /* Socket */
struct sockaddr_in adr_inet; /* AF_INET */
int len_inet; /* length */
sck_inet = socket(AF_INET,SOCK_STREAM,0);
if ( sck_inet == -1 ) {
   abort(); /* Failed */
}
/* Establish address */
memset(&adr_inet,0,sizeof adr_inet);
adr_inet.sin_family = AF_INET;
adr_inet.sin_port = htons(9000);
adr_inet.sin_addr.s_addr = htonl(INADDR_ANY);
if ( adr_inet.sin_addr.s_addr == INADDR_NONE ) {
   abort(); /* Failed */
}
len_inet = sizeof adr_inet;
z = bind(sck_inet, (struct sockaddr *)&adr_inet, len_inet);

Listing above is functionally identical to Listing for (specific address), with the exception that the address value assigned
was htonl(INADDR_ANY) instead of a specific IP address. A socket bound in this way can accept connections from any interface. It can also connect to a remote socket going out from any
interface (this is automatically determined by routing tables).

NOTE
The value INADDR_ANY is also known as a wildcard address.

No comments:

Post a Comment