19.3 Dumping the Security Association
Database (SADB)
To dump the current SADB, a process uses the
SADB_DUMP message. This is the simplest message to send
since the message does not require any extensions, simply the
16-byte sadb_msg header. After the process sends the
SADB_DUMP message to the kernel on a key management
socket, the kernel replies with a series of SADB_DUMP
messages back to the same socket, each with one entry from the
SADB. The end of the list is indicated by a message with a value of
0 for the sadb_msg_seq field.
The type of SA can be limited by setting the
sadb_msg_satype field in the request to one of the values
in Figure 19.3. If it is
set to SADB_SATYPE_UNSPEC, then all SAs in the database
are returned. Otherwise, only SAs of the specified type are
returned. Not all types of security associations are supported by
all implementations. The KAME implementation only supports IPsec
SAs (SADB_SATYPE_AH and SADB_SATYPE_ESP), so an
attempt to dump SADB_SATYPE_RIPV2 SADB entries will get an
error reply with errno EINVAL. When requesting a specific
type whose table is empty, the errno ENOENT is
returned.
Our program to dump the SADB follows in
Figure 19.5.
Figure 19.5
Program to issue SADB_DUMP command on key management
socket.
key/dump.c
1 void
2 sadb_dump(int type)
3 {
4 int s;
5 char buf[4096];
6 struct sadb_msg msg;
7 int goteof;
8 s = Socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
9 /* Build and write SADB_DUMP request */
10 bzero(&msg, sizeof (msg));
11 msg.sadb_msg_version = PF_KEY_V2;
12 msg.sadb_msg_type = SADB_DUMP;
13 msg.sadb_msg_satype = type;
14 msg.sadb_msg_len = sizeof (msg) / 8;
15 msg.sadb_msg_pid = getpid();
16 printf("Sending dump message:\n");
17 print_sadb_msg (&msg, sizeof (msg));
18 Write(s, &msg, sizeof (msg));
19 printf("\nMessages returned:\n");
20 /* Read and print SADB_DUMP replies until done */
21 goteof = 0;
22 while (goteof == 0) {
23 int msglen;
24 struct sadb_msg *msgp;
25 msglen = Read(s, &buf, sizeof (buf));
26 msgp = (struct sadb_msg *) &buf;
27 print_sadb_msg(msgp, msglen);
28 if (msgp->sadb_msg_seq == 0)
29 goteof = 1;
30 }
31 close(s);
32 }
33 int
34 main(int argc, char **argv)
35 {
36 int satype = SADB_SATYPE_UNSPEC;
37 int c;
38 opterr = 0; /* don't want getopt () writing to stderr */
39 while ( (c = getopt(argc, argv, "t:")) != -1) {
40 switch (c) {
41 case 't':
42 if ( (satype = getsatypebyname (optarg) ) == -1)
43 err_quit("invalid -t option %s", optarg);
44 break;
45 default:
46 err_quit("unrecognized option: %c", c);
47 }
48 }
49 sadb_dump(satype);
50 }
This is our first encounter with the POSIX
getopt function. The third argument is a character string
specifying the characters that we allow as command-line arguments,
just t in this example. It is followed by a colon,
indicating that the option takes an argument. In programs that take
more than one option, they are concatenated together; for example,
Figure 29.7 passes
0i:l:v to indicate that it accepts four options;
i and l take an argument and 0 and
v don't. This function works with four global variables
that are defined by including <unistd.h>.
extern char *optarg;
extern int optind, opterr, optopt;
Before calling getopt, we set
opterr to 0 to prevent the function from writing error
messages to standard error in case of an error, because we want to
handle these. POSIX states that if the first character of the third
argument is a colon, this also prevents the function from writing
to standard error, but not all implementations support this.
Open PF_KEY socket
1鈥? We
first open a PF_KEY socket. This requires system
privileges, as described earlier, since this allows access to
sensitive keying material.
Build SADB_DUMP request
9鈥?5
We first zero out the sadb_msg struct so that we can skip
initializing the fields that we wish to remain zero. We fill in
each remaining field in the sadb_msg struct individually.
All messages on sockets opened with PF_KEY_V2 as the third
argument must also use PF_KEY_V2 as the message version.
The message type is SADB_DUMP. We set the length to the
length of the base header with no extensions since the dump message
does not take extensions. Finally, we set the process ID (PID) to
our own PID since all messages must be identified by the PID of the
sender.
Display and write SADB_DUMP
message
16鈥?8
We display the message using our print_sadb_msg routine.
We don't show this routine since it is long and uninteresting, but
it is included in the freely available source code. This routine
accepts a message that is being written to or has been received
from a key management socket and prints all the information from
the message in a human-readable form. We then write the message to
the socket.
Read replies
19鈥?0
We loop, reading replies and printing them using our
print_sadb_msg function. The last message in the dump
sequence has a message sequence number of zero, so we use this as
our "end-of-file" indication.
Close PF_KEY socket
31
Finally, we close the socket that we opened.
Handle command-line arguments
38鈥?8
The main function has very little work to do. This program
takes a single optional argument, which is the type of SA to dump.
By default, the type is SADB_SATYPE_UNSPEC, which dumps
all SAs of any type. By specifying a command-line argument, the
user can select which type of SAs to dump. This program uses our
getsatypebyname function, which returns the type value for
a text string.
Call sadb_dump routine
49
Finally, we call the sadb_dump function we defined above
to do all the work.
Sample Run
The following is a sample run of the dump
program on a system with two static SAs.
macosx % dump
Sending dump message:
SADB Message Dump, errno 0, satype Unspecified, seq 0, pid 20623
Messages returned:
SADB Message Dump, errno 0, satype IPsec AH, seq 1, pid 20623
SA: SPI=258 Replay Window=0 State=Mature
Authentication Algorithm: HMAC-MD5
Encryption Algorithm: None
[unknown extension 19]
Current lifetime:
0 allocations, 0 bytes
added at Sun May 18 16:28:11 2003, never used
Source address: 2.3.4.5/128 (IP proto 255)
Dest address: 6.7.8.9/128 (IP proto 255)
Authentication key, 128 bits: 0x20202020202020200202020202020202
SADB Message Dump, errno 0, satype IPsec AH, seq 0, pid 20623
SA: SPI=257 Replay Window=0 State=Mature
Authentication Algorithm: HMAC-MD5
Encryption Algorithm: None
[unknown extension 19]
Current lifetime:
0 allocations, 0 bytes
added at Sun May 18 16:26:24 2003, never used
Source address: 1.2.3.4/128 (IP proto 255)
Dest address: 5.6.7.8/128 (IP proto 255)
Authentication key, 128 bits: 0x10101010101010100101010101010101
|