The example code shown in Listing 2.8 demonstrates how to initialize an AF_INET address with both a wild port number and a wild IP number.Listing 2.8 Initializing an IN_ADDRANY AF_INET A
Trang 1Use of these functions is quite simple For example, to convert a short integer to network order, the following code can be used:
host_short = ntohs(netw_short);
Tip
The h in the function name refers to "host," whereas n refers to
"network." Similarly, s refers to "short" and l refers to "long."
Using these conventions, it is a simple matter to pick the name
of the conversion function you need
Caution
The byteorder(3) functions may be implemented as macros on some systems Linux systems that run on CPUs using the big- endian byte ordering might provide a simple macro instead, because no conversion of the value is required.
Initializing a Wild Internet Address
Now you are ready to create an Internet address The example shown here will request that the address be wild This is often done when you are connecting to a remote service The reason for doing this is that your host might have two or more network interface cards, each with a different IP number Furthermore, Linux also permits the assignment of more than one IP number
to each interface When you specify a wild IP number, you allow the system to pick the route to the remote service The kernel will then determine what your final local socket address will be
at the time the connection is established.
Trang 2There are also times when you want the kernel to assign a local port number for you This is done by specifying sin_port as the value zero The example code shown in Listing 2.8 demonstrates how to initialize an AF_INET address with both a wild port number and a wild IP number.
Listing 2.8 Initializing an IN_ADDRANY AF_INET Address
1: struct sockaddr_in adr_inet;
9: adr_len = sizeof adr_inet;
The steps used in Listing 2.8 are as follows:
1 The value adr_inet is defined using the structure sockaddr_in
(line 1).
2 The address adr_inet is zeroed by calling memset(3) in line 4 (This is optional.)
3 The address family is established by assigning the value
AF_INET to adr_inet.sin_family (line 6).
4 A wild port number is specified in line 7 Notice the use of the function ntohs(3). The value zero indicates a wild port number.
5 A wild IP number is assigned in line 8 Again, note the use
of the ntohl(3) function to perform the endian conversion.
6 The size of the address is simply computed as the size of the structure adr_inet (line 9).
Another commonly used IP number is 127.0.0.1. This refers to the
loopback device The loopback device lets you communicate
with another process on the same host as your process You'll see more of this IP number later For now, just note how the address can be assigned below Line 8 of Listing 2.8 could be changed to the following statement:
adr_inet.sin_addr.s_addr = ntohl(INADDR_LOOPBACK);
This will address your current host through the loopback device
In the next section, you will learn how to set up any IP number and port number
Trang 3Initializing a Specific Internet Address
The previous section dealt with a simple case for AF_INET
addresses Things get more complicated when you want to
establish a specific IP number in the address Listing 2.9 shows
a complete program listing that you can compile by simply
performing the following command:
$ make af_inet
Then, just invoke the compiled program by the name af_inet.
Listing 2.9 af_inet.c— Establishing a Specific AF_INET Address
17: * This function reports the error and
18: * exits back to the shell:
27: main(int argc,char **argv,char **envp) {
28: int z; /* Status return code */
29: int sck_inet; /* Socket */
30: struct sockaddr_in adr_inet;/* AF_INET */
31: int len_inet; /* length */
32: const unsigned char IPno[] = {
Trang 458: /* Display all of our bound sockets */
59: system("netstat -pa tcp 2>/dev/null | "
The steps used in this program are almost identical to the
others shown in Listings 2.3 and 2.5 Lines 43 to 48, however, require some explanation:
1 Line 30 defines the sockaddr_in structure with the name
adr_inet. Additionally, the socket address length is defined
as an integer in line 31 as len_inet.
2 An unsigned character array is defined as IPno[4] in lines 32 and 33 Here the individual bytes spell out a specific IP address 127.0.0.23.
3 Line 43 zeros out adr_inet as usual Note that, again, this is optional.
4 Line 45 establishes the address family as AF_INET.
5 This example chose to establish a TCP/IP port number 9000
in line 46 Note the use of the conversion function htons(3)
in line 46.
6 The character array IPno[4] is copied to the location
adr_inet.sin_addr.s_addr in line 47 Because the bytes are
defined in network order back in step 2, there is no endian conversion required here You will recall that network byte ordering has the most significant byte presented first.
7 The size of the address structure is computed as before (line 48).
Trang 5You might have noticed that Internet addresses have a fixed length If you review Figure 2.3 , this is readily apparent
However, you will remember that the AF_LOCAL address was
variable in length (refer to Figure 2.2 ) For AF_INET addresses, you merely need to supply the size of the socket structure
sockaddr_in. In C language terms, this is
sizeof(struct sockaddr_in)
You should be well equipped now for forming Internet IPv4
addresses To broaden your knowledge on socket addressing, the next sections will show you how some other address
families can be specified.
Specifying an X.25 Address
The socket interface allows the programmer to use other
protocols that are available under Linux with very little effort The only major part of the code that is different has to do with how the sockets are addressed You have already seen the
initialization required for AF_LOCAL and AF_INET addresses The creation of an X.25 address is very similar.
The structure used to define an X.25 protocol address is the
sockaddr_x25 structure The include statement that defines this structure is as follows:
sa_family_t sx25_family; /* Must be AF_X25 */
x25_address sx25_addr; /* X.121 Address */
Trang 6Information about X.25 socket addresses can be found in the
x25(4) man page.
An X.25 network address (the X.121 standard defines this
address) consists of a series of decimal digits The program
af_x25.c has been provided to show you how you can establish an X.25 address and have netstat(1) display it Listing 2.11 shows the program listing.
Listing 2.11 af_x25.c— Establishing an X.25 Protocol Address
16: * This function reports the error and
17: * exits back to the shell:
26: main(int argc,char **argv,char **envp) {
27: int z; /* Status return code */
28: int sck_x25; /* Socket */
29: struct sockaddr_x25 adr_x25;/* AF_X25 */
30: int len_x25; /* length */
31: const char x25_host[] /* X.121 addr */
Trang 7to enable X.25 support if you want to experiment with that
protocol To enable X.25 support you must configure and
recompile your Linux kernel.
The address establishing code consists of the following basic steps:
1 The sockaddr_x25 structure is used in line 29 to define
adr_x25. The length variable len_x25 is defined as an int on line 30.
2 A character array constant x25_host[] is defined on lines 31 and 32 as the X.25 address is to be establish.
3 The address family is specified as AF_X25 in line 41.
4 The host address number is copied into the address
structure with a terminating null byte in line 42.
5 The length of the sockaddr_x25 structure is the correct
length to use with the current Linux implementation (line 43)
Note that the program does not call upon netstat(1) this time This is because netstat(1) does not report AF_X25 sockets at this
Trang 8time Instead, the example program uses cat(1) to copy the
contents of /proc/net/x25 to standard output For this to be
successful, however, you must have the proc file system support compiled into your kernel (this is now standard practice).
Note
Normally socket addresses with variable elements like the
AF_UNIX address family require a computed length of the
address The Linux implementation of the AF_X25 socket address, however, simply requires the fixed length of sizeof(sockaddr_x25)
The host number must be null terminated within the sockaddr_x25
In the program output in Listing 2.12 , you can see the host
number listed under the src_addr column heading as 79400900.
Specifying Other Address Families
The scope of this book does not permit a full coverage of all address families supported by Linux The list of supported
protocols is growing longer with each new year If you are
looking for a fast track to TCP/IP programming, you can skip this section and advance to the next section.
In this section, you will read briefly about a few other protocols that might be of interest to you This section is intended as a roadmap to other places of interest, should you feel like some adventure.
There are at least three more address families that Linux can support They are
• AF_INET6— IPv6, which is under development
Trang 9• AF_AX25— Amateur Radio X.25 protocol
• AF_APPLETALK— Linux AppleTalk protocol implementation Each of these protocols requires that you have the
corresponding support compiled into your kernel Some of these protocols may not be complete implementations—programmer beware! Incomplete or experimental protocols will be buggy or sometimes even crash your system.
Tip
The AF_APPLETALK address family is documented in the ddp(4) man
page.
Listing 2.13 shows some of the C structures that are important
to these other socket address families These structures will help you visualize the address components that must be
initialized when creating an address for the protocol chosen.
Listing 2.13 Other Address Family Structures
uint16_t sin6_port; /* port # */
uint32_t sin6_flowinfo; /* flow info */
struct in6_addr sin6_addr; /* IPv6 address */
Trang 10sa_family_t sat_family; /* addr family */
u_char sat_port; /* port */
struct at_addr sat_addr; /* net/node */
However, if you would like to experiment further with the
AF_AX25 family, there is one other program available for the
purpose in source file af_ax25.c. Using the Makefile provided at the Web site associated with this book, you can compile it as
Trang 11To run this program, the following conditions must be met:
1 You have Amateur Radio AX.25 support compiled into your kernel.
2 You might require an AX.25 compatible interface to
establish a socket name See the note that follows.
3 If condition two is required, and you have no AX.25
interfaces, you can satisfy this requirement by using a BPQ device on top of an ethernet device See instructions that follow the note.
Note
The author found that the program af_ax25 could call bind(3) and establish an AF_AX25 address with no AX.25 interfaces present in the system (using Red Hat Linux 6.0, kernel 2.2.10) However, this may depend upon the kernel release that you have and could be subject to change.
If you require an AX.25 device, either to run the af_ax25 program
or to perform further network programming experiments, you can establish a BPQ interface if you already have an ethernet interface To check, perform the following:
$ netstat -i
Kernel Interface table
Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR OK ERR DRP OVR Flg
# ifconfig bpq0 hw ax25 VE3WWG-5 up
Then, you can check the status of the interface, as shown in Listing 2.14
Listing 2.14 Checking the Interface Status of bpq0
# /sbin/ifconfig
bpq0 Link encap:AMPR AX.25 HWaddr VE3WWG-5
Trang 12UP RUNNING MTU:256 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
eth0 Link encap:Ethernet HWaddr 00:A0:4B:06:F4:8D
inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
RX packets:10945 errors:0 dropped:0 overruns:0 frame:100
TX packets:4959 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
Interrupt:9 Base address:0xe400
The bpq0 interface is a pseudo device, because it interfaces with the real device eth0. However, this trick allows you to
experiment with the AX.25 radio protocol without using any packet radio hardware In the output Listing 2.14 , you can see that the bpq0 interface is up, with the hardware AX.25 address
of VE3WWG-5.
The C macro AF_UNSPEC represents the unspecified address
family This might seem like a rather useless macro, but it does have its uses If you write a program that must work with many different protocols and address families, then you need a way to indicate an unspecified address family Consider the union of different address families in Listing 2.15
Listing 2.15 A Union of Address Families
Trang 13The AF_UNSPEC acts as a safe placeholder for you when you don't know what the address family is yet.
What's Next
Socket addressing is the messiest part of socket programming, but that is all behind you now With the examples that you have worked through, you now know how to apply local addresses, Internet addresses, and a few others You learned that each address structure must have its corresponding address family constant stored in it ( AF_INET, for example).
In this chapter, you learned that the AF_INET address was
sensitive about network ordered bytes in the sin_port and sin_addr
members The byteorder(3) conversion functions were mastered
to deal with this problem.
You also saw that each address family has its own quirks for establishing both the address itself and the length of the
address Consequently, this chapter will continue to serve as a reference for you.
In the next chapter, you'll build upon the concept of network addresses that you've learned and you'll be introduced to new library functions that manipulate addresses for you.
Chapter 3 Address Conversion Functions
In the last chapter, you learned how various types of socket addresses could be allocated and initialized These were all simple cases of initializing from a constant Setting up an
address from a C string with varying addresses requires more programming effort In this chapter, you will focus on the
additional issues pertaining to establishing Internet addresses, and learning about the functions that can assist you in this
area.
In this chapter, you will learn about
• Classes of internet addresses
• IP netmasks
• Private and reserved IP numbers
• Functions that convert IP numbers
Trang 14Before you get started however, it's a good time to review the design of an IP address Then, you'll have a greater insight into the job that is ahead of you.
Internet IP Numbers
The IP number consists of four decimal values separated by decimal points, often referred to as "dots." This convention is
frequently called quad notation, or sometimes
dotted-decimal notation Each dotted-decimal value represents the unsigned
value of one byte, in network byte sequence Remember that network order requires that the most significant bytes appear first.
Each byte is considered as an unsigned 8-bit value This
restricts each byte to a decimal value range of zero to 255
Because the value is unsigned, the value cannot be negative, and a plus sign is not permitted Consider the address
192.168.0.1, for example; you know that the first byte in network order must have the value of 192 decimal.
When you see a movie showing an IP number on the screen with
a value such as 192.168.300.5, you know that the producer knew very little about TCP/IP networking! Although this IP number is syntactically correct, the decimal value 300 obviously exceeds the maximum unsigned value of 255.
Later, starting with the section "Manipulating IP Numbers," you will look at functions that can parse a C string into network address bytes, and range check the decimal values for you.
Internet Address Classes
Internet addresses are made up of two components:
• Network number (most significant bits)
• Host number (least significant bits)
The network number identifies the network where the host can
be contacted The host number identifies one host (your PC, for example) out of several on that particular network.
As you already know, the IP number is a 32-bit value (or four bit bytes) However, the division between the network number and host number components is not at a fixed location The
Trang 158-dividing line depends upon the classification of the address, which is determined by examining the most significant byte of the address Table 3.1 summarizes how IP numbers are
classified.
Table 3.1 Internet Address Classes
Class Lowest Highest Network Bits Host Bits
Class A, B, and C define specific IP addresses of hosts For class
D and E addresses, there are zero host bits available in the
address Class D addresses are used for multicasting where the
28 bits are used to describe a multicast group The 27 bits of the class E address are reserved.
Figure 3.1 helps you visualize the breakdown of the 32-bit IP address The frequently used classes A, B, and C are shown.
Figure 3.1 This figure illustrates the Internet address classes A,
B, and C.
Trang 16Understanding Netmask Values
There are situations in which you must determine the netmask
value of an address This is particularly true if you are setting
up your own network So, just what is a netmask value anyway?
If you take the Internet IP Address as a 32-bit number, then you know that the network ID is specified in the most significant bits
of the address Additionally, the host ID is specified by the least significant bits of the same address (review Figure 3.1 if
necessary) The netmask is simply the value that you would wise and" with the address to leave only the network ID Figure 3.2 illustrates how the IP address 192.168.9.1 is masked to
"bit-extract only the network ID bits.
Tip
You will often hear people use the terms net and subnet
interchangeably Technically speaking, these terms represent two distinctly different network ID values The network ID
identifies the network ID number proper.
However, within an IPv4 number, it is possible to further
subdivide the host ID leaving a subnetwork ID in the most
significant bits of the host ID and the final host ID in the least
Trang 17significant bits When subnetting is used, the netmask value will take into account these additional subnetwork ID bits.
Consequently, when subnetting is in use, the network mask will differ from the ones presented in this chapter.
Figure 3.2 Applying a netmask to 192.168.9.1 yields a network
address.
The resulting most significant bits represent the network
portion of the IP address without the host ID Figure 3.3
illustrates how the network mask is converted from hexadecimal back into dotted-quad notation.
Figure 3.3 Here is the netmask expressed in dotted-quad
notation.
Trang 18If you must set up your own IP network, then you will need to determine what the netmask values should be Table 3.2 lists the netmask values for class A, B, and C addresses.
Table 3.2 Netmask Values by IP Class
Sometimes, in networking software, your software must be able
to classify a network address Sometimes this is simply done in order to determine a default netmask value.
Listing 3.1 provides a short program that illustrates how to classify an IP address, starting from a socket address To
compile and run the provided source code, perform the
The program in Listing 3.1 sets up four different IP addresses in
an Internet socket address structure Then, the address is
examined and classified This is done to demonstrate how you would classify an IP address of a remote client that has
connected to your server.
Listing 3.1 netmask.c— Classifying and Determining a Netmask
13: main(int argc,char **argv) {
14: int x; /* Index variable */
Trang 1915: struct sockaddr_in adr_inet;/* AF_INET */
16: int len_inet; /* length */
17: unsigned msb; /* Most significant byte */
31: * Set up the socket address, to
32: * demonstrate how to classify it:
44: * 1 Get the Most Significant Byte
45: * 2 Classify by that byte
Trang 20The operation of this demonstration program can be
summarized in the following steps:
1 The socket address structure adr_inet is defined in line 15 This will be the address that will be examined for
classification.
2 The addresses to be tested are defined in a static array of structures, defined in lines 20 to 27 You might want to experiment by trying other address numbers in lines 23 to 26.
3 Line 29 starts a loop that will iterate through four entries
in the addresses[] array The subscript value will be the
variable x.
4 A socket address is initialized in lines 34 to 39, from
addresses[x]. This is done in the same manner it was
presented in the last chapter, and should look familiar to you now
5 The most significant byte is extracted out of the socket address adr_inet in line 47 You will remember that the most significant byte is the first byte of the address, in network byte order (big-endian) With this byte lifted from the
socket address, it will be possible to classify the address based upon the high-order bits in this byte.
6 The if statement in line 50 tests to see whether the order bit is zero (review Figure 3.1 , looking at the class A address) If the high-order bit is zero, you know you have a class A address (lines 51 and 52 execute).
high-7 The if statement in line 53 tests to see whether the order bit is 1, and the 2nd highest bit is a 0 (review the class B address in Figure 3.1 ) If this is true, then the
high-statements in lines 54 and 55 classify this address as class B.
8 The if statement in line 56 tests to see whether the highest two bits are 11 (binary), followed by a 0 bit If this is true, then lines 57 and 58 classify the address as a class C
address (review Figure 3.1 for class C addresses).
Trang 219 The if statement in line 59 tests for the high-order bit
pattern of 1110 This causes the address to be classified as
a class D address Note for class D and class E, the
netmask is set to 255.255.255.255 because the entire
address is a network address.
10.The else statement in line 62 evaluates everything
remaining as a class E address, and sets the netmask also
Address 44.135.86.12 is class A netmask 255.0.0.0
Address 127.0.0.1 is class A netmask 255.0.0.0
Address 172.16.23.95 is class B netmask 255.255.0.0
Address 192.168.9.1 is class C netmask 255.255.255.0
Allocating IP Addresses
You learned how Internet addresses are classified in the
previous section IP addresses are allocated to various
individuals and groups by an organization known as the
InterNIC However, some ranges of IP addresses have been set aside for private use, and still others are reserved for special uses.
Private IP Numbers
Normally, IP numbers must be registered by the InterNIC at
rs.internic.net. (Prior to April 1, 1993, this was handled by the NIC
at nic.ddn.mil. ) However, if your system is not directly connected
to the Internet, you do not need to have a globally unique
address You can use "private" IP numbers instead.
Trang 22The first question that immediately follows, then, is "What IP numbers should I use?" This section is provided to help you make that decision, and to act as a future reference guide.
RFC 1597 is an Internet standards document that describes how private IP numbers are allocated Table 3.3 provides a quick summary for you, complete with netmask values.
Table 3.3 Private IP Number Allocations
is small, then a class C address might be sufficient
Alternatively, a class A address allows for one network (without subnetting), but a very large total number of hosts Class B provides a large number of both networks and hosts.
Reserved IP Numbers
There are a large number of reserved IP numbers and these blocks are listed in RFC 1166 As one example of a reserved series of numbers, the Amateur Radio IP number series are shown in Table 3.4 These are used by amateur radio operators using the Internet protocol on packet radio equipment Now that the AX.25 protocol is built into the Linux kernel (as of
2.2.0), it is certain that more radio amateurs will be exercising these IP numbers!
Table 3.4 Amateur Radio Reserved IP Numbers
This brings you to the end of the IP number tour Now, it's time
to apply your knowledge of socket addresses and IP numbers to
Trang 23functions that Linux provides to make IP address conversion easier.
Manipulating IP Numbers
To ease the programming burden of turning IP numbers in
string form into usable socket addresses, a number of
conversion functions have been provided These and other
useful functions will be presented in the following sections.
Using the inet_addr(3) Function
The first function that you will learn about is an older function, which should probably no longer be used in new code However, you will find it in a lot of existing network code, and so you
should become familiar with it and know its limitations.
The synopsis for inet_addr(3) is as follows:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
unsigned long inet_addr(const char *string);
This function accepts an input C string argument string and
parses the dotted-quad notation into a 32-bit Internet address value The 32-bit value returned is in network byte order.
If the input argument string does not represent a valid quad address, the value INADDR_NONE is returned Any other
dotted-returned value represents the converted value.
Note
The 32-bit value returned by inet_addr(3) is in network byte order
Do not use htonl(3) on the returned value, because it is already in network byte order.
Caution
The inet_addr(3) does not establish a reason code in errno when
INADDR_NONE is returned So, do not test errno or report it when
an error indication is returned by this function.
Trang 24The program shown in Listing 3.3 is an example of how you would use this function To compile and run the program,
perform the following:
Listing 3.3 inetaddr.c— Example Program Using inet_addr(3)
16: * This function reports the error and
17: * exits back to the shell:
29: struct sockaddr_in adr_inet;/* AF_INET */
30: int len_inet; /* length */
31: int sck_inet; /* Socket */
32:
33: /* Create a Socket */
34: sck_inet = socket(AF_INET,SOCK_STREAM,0);
35:
Trang 2561: /* Display our socket address */
62: system("netstat -pa tcp 2>/dev/null"
If netstat(1) command on your system does not support the
options used in lines 62 and 63 of Listing 3.3 , substitute the following call if you have lsof installed:
system("lsof -i tcp | grep inetaddr");
The general program structure is very similar to the ones used
in the previous chapter However, the steps used to set up the socket address are a bit different They are
1 The socket address structure is zeroed out in line 40 This
is an optional step, but many find that this helps
debugging should it become necessary.
2 The address family is established as AF_INET in line 42.
3 The port number has been established as port 9000 in this example (line 43).