summaryrefslogtreecommitdiffstats
path: root/usr.sbin/mrouted/config.c
diff options
context:
space:
mode:
authorwollman <wollman@FreeBSD.org>1995-06-13 18:05:16 +0000
committerwollman <wollman@FreeBSD.org>1995-06-13 18:05:16 +0000
commitd7ec2bee9b62915b2bfc4cbeffefb602d913f92d (patch)
tree251f664e3bb6640c0dc6968bd9a6ec402be8d14b /usr.sbin/mrouted/config.c
parent20ad4f8359820cf12331c0335034438fc23ad604 (diff)
downloadFreeBSD-src-d7ec2bee9b62915b2bfc4cbeffefb602d913f92d.zip
FreeBSD-src-d7ec2bee9b62915b2bfc4cbeffefb602d913f92d.tar.gz
This is mrouted version 3.5, with the route-change notification hook from
mrouted-3.5n. This is being splatted onto the head rather than properly imported thanks to the ``delete trailing whitespace'' screw. This code is now actively working in an operational environment (the DARTNET) so I have some confidence that the basic functionality actually works. Obtained from: Bill Fenner, PARC, and ISI
Diffstat (limited to 'usr.sbin/mrouted/config.c')
-rw-r--r--usr.sbin/mrouted/config.c670
1 files changed, 10 insertions, 660 deletions
diff --git a/usr.sbin/mrouted/config.c b/usr.sbin/mrouted/config.c
index 8f232ff..0113807 100644
--- a/usr.sbin/mrouted/config.c
+++ b/usr.sbin/mrouted/config.c
@@ -7,24 +7,13 @@
* Leland Stanford Junior University.
*
*
- * $Id: config.c,v 1.3 1995/04/10 18:42:10 wollman Exp $
+ * $Id: config.c,v 3.5 1995/05/09 01:00:39 fenner Exp $
*/
#include "defs.h"
-char *configfilename = "/etc/mrouted.conf";
-
-extern int cache_lifetime;
-extern int max_prune_lifetime;
-
-/*
- * Forward declarations.
- */
-static char *next_word();
-
-
/*
* Query the kernel to find network interfaces that are multicast-capable
* and install them in the uvifs array.
@@ -32,12 +21,12 @@ static char *next_word();
void config_vifs_from_kernel()
{
struct ifreq ifbuf[32];
- struct ifreq *ifrp, *ifend, *mp;
+ struct ifreq *ifrp, *ifend;
struct ifconf ifc;
register struct uvif *v;
register vifi_t vifi;
- int i, n;
- u_long addr, mask, subnet;
+ int n;
+ u_int32 addr, mask, subnet;
short flags;
ifc.ifc_buf = (char *)ifbuf;
@@ -62,10 +51,11 @@ void config_vifs_from_kernel()
/*
* Ignore any interface for an address family other than IP.
*/
- addr = ((struct sockaddr_in *)&ifrp->ifr_addr)->sin_addr.s_addr;
if (ifrp->ifr_addr.sa_family != AF_INET)
continue;
+ addr = ((struct sockaddr_in *)&ifrp->ifr_addr)->sin_addr.s_addr;
+
/*
* Need a template to preserve address info that is
* used below to locate the next entry. (Otherwise,
@@ -96,8 +86,8 @@ void config_vifs_from_kernel()
addr == subnet ||
addr == (subnet | ~mask)) {
log(LOG_WARNING, 0,
- "ignoring %s, has invalid address (%s) and/or mask (%08x)",
- ifr.ifr_name, inet_fmt(addr, s1), ntohl(mask));
+ "ignoring %s, has invalid address (%s) and/or mask (%s)",
+ ifr.ifr_name, inet_fmt(addr, s1), inet_fmt(mask, s2));
continue;
}
@@ -125,7 +115,7 @@ void config_vifs_from_kernel()
v = &uvifs[numvifs];
v->uv_flags = 0;
v->uv_metric = DEFAULT_METRIC;
- v->uv_rate_limit = DEFAULT_RATE_LIMIT;
+ v->uv_rate_limit = DEFAULT_PHY_RATE_LIMIT;
v->uv_threshold = DEFAULT_THRESHOLD;
v->uv_lcl_addr = addr;
v->uv_rmt_addr = 0;
@@ -136,6 +126,7 @@ void config_vifs_from_kernel()
v->uv_groups = NULL;
v->uv_neighbors = NULL;
v->uv_acl = NULL;
+ v->uv_addrs = NULL;
log(LOG_INFO,0,"installing %s (%s on subnet %s) as vif #%u - rate=%d",
v->uv_name, inet_fmt(addr, s1), inet_fmts(subnet, mask, s2),
@@ -153,644 +144,3 @@ void config_vifs_from_kernel()
}
}
}
-
-static struct ifreq *
-ifconfaddr(ifcp, a)
- struct ifconf *ifcp;
- u_long a;
-{
- int n;
- struct ifreq *ifrp = (struct ifreq *)ifcp->ifc_buf;
- struct ifreq *ifend = (struct ifreq *)((char *)ifrp + ifcp->ifc_len);
-
- while (ifrp < ifend) {
- if (ifrp->ifr_addr.sa_family == AF_INET &&
- ((struct sockaddr_in *)&ifrp->ifr_addr)->sin_addr.s_addr == a)
- return (ifrp);
-#if BSD >= 199006
- n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
- if (n < sizeof(*ifrp))
- ++ifrp;
- else
- ifrp = (struct ifreq *)((char *)ifrp + n);
-#else
- ++ifrp;
-#endif
- }
- return (0);
-}
-
-/*
- * Checks if the string constitutes a valid interface name
- */
-static u_long valid_if(w)
-char *w;
-{
- register vifi_t vifi;
- register struct uvif *v;
-
- for (vifi = 0, v = uvifs; vifi < numvifs; vifi++, v++)
- if (EQUAL(v->uv_name, w))
- return v->uv_lcl_addr;
-
- return NULL;
-}
-
-/*
- * Read the config file to learn about tunnel vifs and
- * non-default phyint parameters.
- */
-void config_vifs_from_file()
-{
- FILE *f;
- char linebuf[100];
- char *w, *s, c;
- u_long lcl_addr, rmt_addr;
- struct ifconf ifc;
- struct ifreq *ifr;
- struct ifreq ffr;
- int i;
- u_int n;
- struct ifreq ifbuf[32];
- vifi_t vifi;
- struct uvif *v;
- u_char order = 0;
- vifi_t prev_vif = NO_VIF;
-
- f = fopen(configfilename, "r");
- if (f == NULL) {
- if (errno != ENOENT)
- log(LOG_ERR, errno, "can't open %s", configfilename);
- return;
- }
-
- ifc.ifc_buf = (char *)ifbuf;
- ifc.ifc_len = sizeof(ifbuf);
- if (ioctl(udp_socket, SIOCGIFCONF, (char *)&ifc) < 0)
- log(LOG_ERR, errno, "ioctl SIOCGIFCONF");
-
- while (fgets(linebuf, sizeof(linebuf), f) != NULL) {
-
- s = linebuf;
- if (EQUAL((w = next_word(&s)), "")) {
- /*
- * blank or comment line; ignore
- */
- }
-
- /* Set the cache_lifetime for kernel entries */
- else if (EQUAL(w, "cache_lifetime")) {
- if (EQUAL((w = next_word(&s)), "")) {
- log(LOG_ERR, 0,
- "missing cache_lifetime value in %s",
- configfilename);
- continue;
- }
- if(sscanf(w, "%u%c", &n, &c) != 1 ||
- n < 300 || n > 86400 ) {
- log(LOG_ERR, 0,
- "invalid cache_lifetime '%s' (300<n>86400) in %s",
- w, configfilename);
- break;
- }
- prev_vif = NO_VIF;
- cache_lifetime = n;
- max_prune_lifetime = cache_lifetime * 2;
- }
-
- /* Check if pruning is to be turned off */
- else if (EQUAL(w, "pruning")) {
- if (!EQUAL((w = next_word(&s)), "off") &&
- !EQUAL(w, "on")) {
- log(LOG_ERR, 0,
- "invalid word '%s' in %s",
- w, configfilename);
- continue;
- }
- if (EQUAL(w, "off"))
- pruning = 0;
-
- prev_vif = NO_VIF;
- }
-
- /* Check for boundary statements (as continuation of a prev. line) */
- else if (EQUAL(w, "boundary") && prev_vif != NO_VIF) {
- register struct vif_acl *v_acl;
- register u_long baddr;
-
- v = &uvifs[prev_vif];
-
- if (EQUAL((w = next_word(&s)), "")) {
- log(LOG_ERR, 0,
- "missing group address for boundary %s in %s",
- inet_fmt(lcl_addr, s1), configfilename);
- w = "garbage";
- break;
- }
-
- if ((sscanf(w, "%[0-9.]/%d", s1, &n) != 2) ||
- n < 0 || n> 32) {
- log(LOG_ERR, 0,
- "incorrect boundary format %s in %s",
- w, configfilename);
- w = "garbage";
- break;
- }
-
- if ((baddr = inet_parse(s1)) == 0xffffffff ||
- (ntohl(baddr) & 0xff000000) != 0xef000000) {
- log(LOG_ERR, 0,
- "incorrect boundary address %s in %s",
- s1, configfilename);
- continue;
- }
-
- v_acl = (struct vif_acl *)malloc(sizeof(struct vif_acl));
- if (v_acl == NULL)
- log(LOG_ERR, 0,
- "out of memory");
- VAL_TO_MASK(v_acl->acl_mask, n);
- v_acl->acl_addr = baddr & v_acl->acl_mask;
-
- /*
- * link into data structure
- */
- v_acl->acl_next = v->uv_acl;
- v->uv_acl = v_acl;
- }
-
- else if (EQUAL(w, "phyint")) {
- /*
- * phyint <local-addr> [disable] [metric <m>] [threshold <t>]
- * [rate_limit <b>]
- */
-
- /*
- * Check if phyint was the first line - scream if not
- */
- if (order) {
- log(LOG_ERR, 0,
- "phyint stmnts should occur before tunnel stmnts in %s",
- configfilename);
- continue;
- }
-
- /*
- * Parse the local address.
- */
- if (EQUAL((w = next_word(&s)), "")) {
- log(LOG_ERR, 0,
- "missing phyint address in %s",
- configfilename);
- continue;
- }
-
- if (isalpha(*w) && !(lcl_addr = valid_if(w))) {
- log(LOG_ERR, 0,
- "invalid phyint name '%s' in %s",
- w, configfilename);
- continue;
- }
-
- if (isdigit(*w)) {
- if ((lcl_addr = inet_parse(w)) == 0xffffffff ||
- !inet_valid_host(lcl_addr)) {
- log(LOG_ERR, 0,
- "invalid phyint address '%s' in %s",
- w, configfilename);
- continue;
- }
- }
-
- /*
- * Look up the vif with the specified local address.
- */
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (!(v->uv_flags & VIFF_TUNNEL) &&
- lcl_addr == v->uv_lcl_addr) {
- break;
- }
- }
-
- if (vifi == numvifs) {
- log(LOG_ERR, 0,
- "phyint %s in %s is not a configured interface",
- inet_fmt(lcl_addr, s1), configfilename);
- continue;
- }
-
- /*
- * Look for "disable", "metric", "threshold", "rate_limit"
- * and "boundary" options.
- */
- prev_vif = vifi;
-
- while (!EQUAL((w = next_word(&s)), "")) {
- if (EQUAL(w, "disable")) {
- v->uv_flags |= VIFF_DISABLED;
- }
- else if (EQUAL(w, "metric")) {
- if(EQUAL((w = next_word(&s)), "")) {
- log(LOG_ERR, 0,
- "missing metric for phyint %s in %s",
- inet_fmt(lcl_addr, s1), configfilename);
- w = "garbage";
- break;
- }
- if(sscanf(w, "%u%c", &n, &c) != 1 ||
- n < 1 || n >= UNREACHABLE ) {
- log(LOG_ERR, 0,
- "invalid metric '%s' for phyint %s in %s",
- w, inet_fmt(lcl_addr, s1), configfilename);
- break;
- }
- v->uv_metric = n;
- }
- else if (EQUAL(w, "threshold")) {
- if(EQUAL((w = next_word(&s)), "")) {
- log(LOG_ERR, 0,
- "missing threshold for phyint %s in %s",
- inet_fmt(lcl_addr, s1), configfilename);
- w = "garbage";
- break;
- }
- if(sscanf(w, "%u%c", &n, &c) != 1 ||
- n < 1 || n > 255 ) {
- log(LOG_ERR, 0,
- "invalid threshold '%s' for phyint %s in %s",
- w, inet_fmt(lcl_addr, s1), configfilename);
- break;
- }
- v->uv_threshold = n;
- }
- else if (EQUAL(w, "rate_limit")) {
- if (EQUAL((w = next_word(&s)), "")) {
- log(LOG_ERR, 0,
- "missing rate_limit for phyint %s in %s",
- inet_fmt(rmt_addr, s1), configfilename);
- w = "garbage";
- break;
- }
- if(sscanf(w, "%u%c", &n, &c) != 1 ||
- n < 0 || n > MAX_RATE_LIMIT ) {
- log(LOG_ERR, 0,
- "invalid rate limit '%s' for phyint %s in %s",
- w, inet_fmt(lcl_addr, s1), configfilename);
- break;
- }
- v->uv_rate_limit = n;
- }
- else if (EQUAL(w, "boundary")) {
- register struct vif_acl *v_acl;
- register u_long baddr;
-
- if (EQUAL((w = next_word(&s)), "")) {
- log(LOG_ERR, 0,
- "missing group address for boundary %s in %s",
- inet_fmt(lcl_addr, s1), configfilename);
- w = "garbage";
- break;
- }
-
- if ((sscanf(w, "%[0-9.]/%d", s1, &n) != 2) ||
- n < 0 || n> 32) {
- log(LOG_ERR, 0,
- "incorrect boundary format %s in %s",
- w, configfilename);
- w = "garbage";
- break;
- }
-
- if ((baddr = inet_parse(s1)) == 0xffffffff ||
- (ntohl(baddr) & 0xef000000) != 0xef000000) {
- log(LOG_ERR, 0,
- "incorrect boundary address %s in %s",
- s1, configfilename);
- continue;
- }
-
- v_acl = (struct vif_acl *)malloc(sizeof(struct vif_acl));
- if (v_acl == NULL)
- log(LOG_ERR, 0,
- "out of memory");
- VAL_TO_MASK(v_acl->acl_mask, n);
- v_acl->acl_addr = baddr & v_acl->acl_mask;
-
- /*
- * link into data structure
- */
- v_acl->acl_next = v->uv_acl;
- v->uv_acl = v_acl;
- }
- else {
- log(LOG_ERR, 0,
- "invalid keyword (%s) in %s",
- w, configfilename);
- break;
- }
- }
- if (!EQUAL(w, "")) continue;
- }
-
- else if (EQUAL(w, "tunnel")) {
- /*
- * tunnel <local-addr> <remote-addr> [srcrt] [metric <m>]
- * [threshold <t>] [rate_limit <b>]
- */
-
- order++;
-
- /*
- * Parse the local address.
- */
- if (EQUAL((w = next_word(&s)), "")) {
- log(LOG_ERR, 0,
- "missing tunnel local address in %s",
- configfilename);
- continue;
- }
- if ((lcl_addr = inet_parse(w)) == 0xffffffff ||
- !inet_valid_host(lcl_addr)) {
- log(LOG_ERR, 0,
- "invalid tunnel local address '%s' in %s",
- w, configfilename);
- continue;
- }
-
- /*
- * Make sure the local address is one of ours.
- */
- ifr = ifconfaddr(&ifc, lcl_addr);
- if (ifr == 0) {
- log(LOG_ERR, 0,
- "tunnel local address %s in %s is not one of ours",
- inet_fmt(lcl_addr, s1), configfilename);
- continue;
- }
-
- /*
- * Make sure the local address doesn't name a loopback interface..
- */
- strncpy(ffr.ifr_name, ifr->ifr_name, IFNAMSIZ);
- if (ioctl(udp_socket, SIOCGIFFLAGS, (char *)&ffr) < 0) {
- log(LOG_ERR, errno,
- "ioctl SIOCGIFFLAGS for %s", ffr.ifr_name);
- }
- if (ffr.ifr_flags & IFF_LOOPBACK) {
- log(LOG_ERR, 0,
- "tunnel local address %s in %s is a loopback interface",
- inet_fmt(lcl_addr, s1), configfilename);
- continue;
- }
-
- /*
- * Parse the remote address.
- */
- if (EQUAL((w = next_word(&s)), "")) {
- log(LOG_ERR, 0,
- "missing tunnel remote address in %s",
- configfilename);
- continue;
- }
- if ((rmt_addr = inet_parse(w)) == 0xffffffff ||
- !inet_valid_host(rmt_addr)) {
- log(LOG_ERR, 0,
- "invalid tunnel remote address %s in %s",
- w, configfilename);
- continue;
- }
-
- /*
- * Make sure the remote address is not one of ours.
- */
- if (ifconfaddr(&ifc, rmt_addr) != 0) {
- log(LOG_ERR, 0,
- "tunnel remote address %s in %s is one of ours",
- inet_fmt(rmt_addr, s1), configfilename);
- continue;
- }
-
- /*
- * Make sure the remote address has not been used for another
- * tunnel and does not belong to a subnet to which we have direct
- * access on an enabled phyint.
- */
- for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
- if (v->uv_flags & VIFF_TUNNEL) {
- if (rmt_addr == v->uv_rmt_addr) {
- log(LOG_ERR, 0,
- "duplicate tunnel remote address %s in %s",
- inet_fmt(rmt_addr, s1), configfilename);
- break;
- }
- }
- else if (!(v->uv_flags & VIFF_DISABLED)) {
- if ((rmt_addr & v->uv_subnetmask) == v->uv_subnet) {
- log(LOG_ERR, 0,
- "unnecessary tunnel remote address %s in %s",
- inet_fmt(rmt_addr, s1), configfilename);
- break;
- }
- }
- }
- if (vifi != numvifs) continue;
-
- /*
- * OK, let's initialize a uvif structure for the tunnel.
- */
- if (numvifs == MAXVIFS) {
- log(LOG_ERR, 0, "too many vifs, ignoring tunnel to %s",
- inet_fmt(rmt_addr, s1));
- continue;
- }
- v = &uvifs[numvifs];
- v->uv_flags = VIFF_TUNNEL;
- v->uv_metric = DEFAULT_METRIC;
- v->uv_rate_limit = DEFAULT_RATE_LIMIT;
- v->uv_threshold = DEFAULT_THRESHOLD;
- v->uv_lcl_addr = lcl_addr;
- v->uv_rmt_addr = rmt_addr;
- v->uv_subnet = 0;
- v->uv_subnetmask = 0;
- v->uv_subnetbcast = 0;
- strncpy(v->uv_name, ffr.ifr_name, IFNAMSIZ);
- v->uv_groups = NULL;
- v->uv_neighbors = NULL;
- v->uv_acl = NULL;
-
- /*
- * set variable to define which interface
- */
- prev_vif = numvifs;
-
- /*
- * Look for "metric", "threshold", "srcrt", "rate_limit"
- * and "boundary" options.
- */
- while (!EQUAL((w = next_word(&s)), "")) {
- if (EQUAL(w, "metric")) {
- if(EQUAL((w = next_word(&s)), "")) {
- log(LOG_ERR, 0,
- "missing metric for tunnel to %s in %s",
- inet_fmt(rmt_addr, s1), configfilename);
- w = "garbage";
- break;
- }
- if(sscanf(w, "%u%c", &n, &c) != 1 ||
- n < 1 || n >= UNREACHABLE ) {
- log(LOG_ERR, 0,
- "invalid metric '%s' for tunnel to %s in %s",
- w, inet_fmt(rmt_addr, s1), configfilename);
- break;
- }
- v->uv_metric = n;
- }
- else if (EQUAL(w, "threshold")) {
- if(EQUAL((w = next_word(&s)), "")) {
- log(LOG_ERR, 0,
- "missing threshold for tunnel to %s in %s",
- inet_fmt(rmt_addr, s1), configfilename);
- w = "garbage";
- break;
- }
- if(sscanf(w, "%u%c", &n, &c) != 1 ||
- n < 1 || n > 255 ) {
- log(LOG_ERR, 0,
- "invalid threshold '%s' for tunnel to %s in %s",
- w, inet_fmt(rmt_addr, s1), configfilename);
- break;
- }
- v->uv_threshold = n;
- }
- else if (EQUAL(w, "srcrt") || EQUAL(w, "sourceroute")) {
- v->uv_flags |= VIFF_SRCRT;
- }
- else if (EQUAL(w, "rate_limit")) {
- if (EQUAL((w = next_word(&s)), "")) {
- log(LOG_ERR, 0,
- "missing rate_limit for tunnel to %s in %s",
- inet_fmt(rmt_addr, s1), configfilename);
- w = "garbage";
- break;
- }
- if(sscanf(w, "%u%c", &n, &c) != 1 ||
- n < 0 || n > MAX_RATE_LIMIT ) {
- log(LOG_ERR, 0,
- "invalid rate_limit '%s' for tunnel to %s in %s",
- w, inet_fmt(rmt_addr, s1), configfilename);
- break;
- }
- v->uv_rate_limit = n;
- }
- else if (EQUAL(w, "boundary")) {
- register struct vif_acl *v_acl;
- register u_long baddr;
-
- if (EQUAL((w = next_word(&s)), "")) {
- log(LOG_ERR, 0,
- "missing group address for tunnel to %s in %s",
- inet_fmt(rmt_addr, s1), configfilename);
- w = "garbage";
- break;
- }
-
- if ((sscanf(w, "%[0-9.]/%d", s1, &n) != 2) ||
- n < 0 || n> 32) {
- log(LOG_ERR, 0,
- "incorrect format '%s' for tunnel to %s in %s",
- w, inet_fmt(rmt_addr, s1), configfilename);
- break;
- }
-
- if ((baddr = inet_parse(s1)) == 0xffffffff ||
- (ntohl(baddr) & 0xef000000) != 0xef000000) {
- log(LOG_ERR, 0,
- "incorrect address %s for tunnel to %s in %s",
- s1, inet_fmt(rmt_addr, s1), configfilename);
- continue;
- }
-
- v_acl = (struct vif_acl *)malloc(sizeof(struct vif_acl));
- if (v_acl == NULL)
- log(LOG_ERR, 0,
- "out of memory");
- VAL_TO_MASK(v_acl->acl_mask, n);
- v_acl->acl_addr = baddr & v_acl->acl_mask;
-
- /*
- * link into data structure
- */
- v_acl->acl_next = v->uv_acl;
- v->uv_acl = v_acl;
- }
- else {
- log(LOG_ERR, 0,
- "invalid keyword (%s) in %s",
- w, configfilename);
- break;
- }
- }
- if (!EQUAL(w, "")) continue;
-
- log(LOG_INFO, 0,
- "installing %stunnel from %s to %s as vif #%u - rate=%d",
- v->uv_flags & VIFF_SRCRT? "srcrt " : "",
- inet_fmt(lcl_addr, s1), inet_fmt(rmt_addr, s2),
- numvifs, v->uv_rate_limit);
-
- ++numvifs;
-
- if (!(ffr.ifr_flags & IFF_UP)) {
- v->uv_flags |= VIFF_DOWN;
- vifs_down = TRUE;
- }
- }
-
- else {
- log(LOG_ERR, 0,
- "unknown command '%s' in %s", w, configfilename);
- }
- }
-
- close(f);
-}
-
-
-/*
- * Return a pointer to the next "word" in the string to which '*s' points,
- * lower-cased and null terminated, and advance '*s' to point beyond the word.
- * Words are separated by blanks and/or tabs, and the input string is
- * considered to terminate at a newline, '#' (comment), or null character.
- * If no words remain, a pointer to a null string ("") is returned.
- * Warning: This function clobbers the input string.
- */
-static char *next_word(s)
- char **s;
-{
- char *w;
-
- w = *s;
- while (*w == ' ' || *w == '\t')
- ++w;
-
- *s = w;
- for(;;) {
- switch (**s) {
-
- case ' ' :
- case '\t' : **s = '\0';
- ++*s;
- return (w);
-
- case '\n' :
- case '#' : **s = '\0';
- return (w);
-
- case '\0' : return (w);
-
- default : if (isascii(**s) && isupper(**s))
- **s = tolower(**s);
- ++*s;
- }
- }
-}
OpenPOWER on IntegriCloud