main.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <door.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <libintl.h>
#include <locale.h>
#include "conflib.h"
#include "mipagentstat_door.h"
/*
* Main for mipagentstat. This uses the protocol defined in
* "mipagentstat_door.h" to act as a door client to mipagent.
* It displays statistics tables for home and foreign agents
* by enumerating the registration tables in mipagent. Each
* door call retrieves an single entry from the table. Doors
* are fast enough that performance is good for this approach,
* and memory usage (particularly in mipagent) is small and
* non-disruptive to the rest of the process. This is a priority
* since we expect that mipagent may eventually be required to
* service thousands of nodes.
*
* mipagentstat follows the following logic flow:
*
* 1. (main) Process command-line arguments
* 2. (main) Call enumerate_stats for each agent to stat
* 3. (enumerate_stats) Display table banner if there are any entries
* 4. (enumerate_stats)
* while more entries forthcoming
* get next entry via a door_call
* display the entry with display_entry
* 5. (display_entry) convert address to printable format; print it.
*/
/* Flag to tell display function whether or not to resolve host names */
#define NO_NAME_RESOLUTION 0x01
#define PEER_PROTECTION 0x02
/*
* Displays the header for the mobile node stats listing. Column widths for
* the fields are defined by the macros M*_ADDR_COL_WIDTH and TIME_COL_WIDTH.
*
* type IN Foreign or Home Agent
*/
(void) printf("\n%-*.*s %-*.*s %-*.*s %-*.*s %-*.*s\n",
(void) printf("%*s %-*.*s %-*.*s %-*.*s\n",
(void) printf("%-*.*s %-*.*s %-*.*s %-*.*s %-*.*s\n",
"-------------------------------------------------",
"-------------------------------------------------",
"-------------------------------------------------",
"-------------------------------------------------",
"-------------------------------------------------");
}
/*
* Displays the header for the agent stats listing. Column widths for the
* fields are defined by the macros PEER_ADDR_COL_WIDTH, and
* PROT_TYPE_COL_WIDTH.
*/
(void) printf("\n%-*.*s %-*.*s\n",
"..... Security Association(s) .....");
(void) printf("%-*.*s %-*.*s %-*.*s %-*.*s %-*.*s\n",
(void) printf("%-*.*s %-*.*s %-*.*s %-*.*s %-*.*s\n",
"-------------------------------------------------",
"-------------------------------------------------",
"-------------------------------------------------",
"-------------------------------------------------",
"-------------------------------------------------");
}
/*
* Converts the address in src to a string. If NO_NAME_RESOLUTION is
* not set in flags, we try to resolve the address to a host name
* using getipnodebyaddr. If this fails (for any reason) or if
* NO_NAME_RESOLUTION is set in flags, we just convert the address
* to presentation format using inet_ntop.
*
* af IN Address familiy of src
* src IN Address to resolve or convert to presentation
* srclen IN Length of src buffer
* enough to hold either an address or a fully
* qualified host name string.
* bufsz IN Size of buf
* flags IN Special flags
*
* Returns A pointer to a character buffer containing the
* printable address or host name. Never returns
* NULL. The pointer may point into buf; either
* way, the caller must not free the result.
*/
void *src,
char *buf,
int flags) {
char *answer;
int err;
/*
* If -n wasn't given at the command line, try to resolve
* the hostname into an address.
*/
if ((flags & NO_NAME_RESOLUTION) == 0) {
/* Set the addrlen according to the AF */
switch (af) {
case AF_INET:
break;
case AF_INET6:
break;
default:
break;
}
return (buf);
}
}
/*
* Else we shouldn't or couldn't resolve the hostname,
* so just convert to presentation format.
*/
}
/*
* Displays a single mobile node entry, formatting the fields
* according to the macros M*_ADDR_COL_WIDTH and TIME_COL_WIDTH
* and using addr2str to conver the addresses in stat_args into
* printable strings.
*
* stat_args IN An entry returned from the stat door call
* flags IN Passed through to addr2str
*/
char node_str[NI_MAXHOST];
char agent_str[NI_MAXHOST];
char service_str[FLAG_COL_WIDTH];
/* Calculate what to print in the Service Flags column */
"S" : "."),
"B" : "."),
"D" : "."),
"M" : "."),
"G" : "."),
"V" : "."),
"T" : "."),
"?" : "."));
/* When the last reg bit becomes defined, it *replaces* the ? entry. */
(void) printf("%-*.*s %-*.*s %-*lu %-*lu %*.*s\n",
/* Mobile Node */
flags),
/* Agent */
flags),
/* Time granted and expires */
0 :
/* Flags indicating services for the mn */
}
/*
* Displays a single agent-peer entry, formatting the fields
* according to the macros M*_ADDR_COL_WIDTH and PROT_TYPE_COL_WIDTH
* and using addr2str to conver the addresses in stat_args into
* printable strings depending on whether the '-n' flag was set.
*
* stat_args IN An entry returned from the stat door call
* flags IN Passed through to addr2str
*/
char agent_str[MA_ADDR_COL_WIDTH];
/* calculate what to print in the protection columns */
}
}
}
}
}
}
}
}
(void) printf("%-*.*s %-*.*s %-*.*s %-*.*s %-*.*s\n",
/* agent-peer */
flags),
/* protection info */
}
/*
* Enumerates through mipagent's entire table of foreign or home
* agent entries. We use a doors IPC to communicate with mipagent.
* Each door call retrieves a single entry, keeping memory usage
* low. Memory management is simplified by using the automatic
* variable stat_args to allocate all needed memory. Each entry
* is displayed based on the flags passed in. If flags indicate
* the user wants to see the protection in place (-p) with our
* agent peers, then display_agent_entry() is called, otherwise
* the user wants mobile nodes, and we call display_mn_entry().
*
* type IN Foreign or Home Agent
* flags IN Passed through to display_*_entries()
*/
if (fd == -1) {
exit(1);
}
/* Set up door args */
/* Do the first entry. If the server is down, we find out here. */
exit(1);
}
/*
* Now that we know the server is up, display the banner,
* then display information, or at least the fact that
* there's nothing to display!
*/
if (flags & PEER_PROTECTION)
/* display the mobility agent peer stat header */
else
/* display the mn-stat header */
goto done;
}
/* Switch to next entry mode for the rest of the enumeration */
/* Enumerate */
break;
}
if (flags & PEER_PROTECTION)
else
perror("door_call");
break;
}
}
done:
}
}
/*
* Entry point for mipagentstat. main simply processes the command
* line arguments and uses them to dispatch foreign or home agent
* statistics enumerations. If no arguments are given, we retrieve
* both home and foreign agent stats.
*/
int
int c;
int type = 0;
int flags = 0;
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
switch (c) {
case 'f':
break;
case 'h':
break;
case 'n':
/*
* private flag: if true, we don't try to resolve
* addresses into host names. This can result in
* a significantly faster listing, and follows the
* tried and true behavior of utilities like netstat.
*/
break;
case 'p':
/*
* User wants to see the protection with our agent peers.
* This is set in type because doors doesn't see any flags.
*/
flags |= PEER_PROTECTION;
break;
default:
exit(1);
}
}
/* Neither is set, so user didn't specify, therefore do both. */
if (flags & PEER_PROTECTION) {
/* user types -fp, wants peers of the FA = HA-peers */
/* user types -hp, wants peers of the HA = FA-peers */
} else {
}
return (0);
}