home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.ee.lbl.gov
/
2014.05.ftp.ee.lbl.gov.tar
/
ftp.ee.lbl.gov
/
acld-1.11.tar.gz
/
acld-1.11.tar
/
acld-1.11
/
route.c
< prev
next >
Wrap
C/C++ Source or Header
|
2012-01-18
|
7KB
|
295 lines
/*
* Copyright (c) 2006, 2007, 2008, 2009, 2011, 2012
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Id: route.c 804 2012-01-18 08:45:27Z leres $ (LBL)";
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <syslog.h>
#include <unistd.h>
#include "acld.h"
#include "cf.h"
#include "child.h"
/* Locals */
static struct s2v str2route[] = {
{ "S", ROUTE_STATIC },
{ "D", ROUTE_DYNAMIC },
{ "I", ROUTE_INTERFACE },
{ "N", ROUTE_NULLZERO },
{ NULL, 0 }
};
/* Return true if the address is an allowable null zero candidate */
int
goodnullzero(struct cf *cf, struct addr *addrp)
{
int i;
struct route *rtp;
for (i = 0, rtp = cf->c_nullzeronets; i < cf->c_nullzeronetslen;
++i, ++rtp)
if (insubnet(&rtp->dst, addrp))
return (1);
return (0);
}
int
nullzeronetadd(struct cf *cf, const char *str)
{
int an;
char **av;
const char *p;
struct route *rtp;
an = makeargv(str, &av);
if (an != 1) {
lg(LOG_ERR, "nullzeronetadd wrong number of args: \"%s\"", str);
freeargv(av);
return (0);
}
DYNARRAY(cf->c_nullzeronets, cf->c_nullzeronetslen,
&cf->c_nullzeronetssize, sizeof(*cf->c_nullzeronets),
8, 8, "cf nullzeronets");
rtp = cf->c_nullzeronets + cf->c_nullzeronetslen;
p = extractaddr(av[0], NULL, &rtp->dst);
if (p != NULL) {
lg(LOG_ERR, "nullzeronetadd: extractaddr %s: %s", av[0], p);
freeargv(av);
return (0);
}
rtp->type = ROUTE_STATIC;
++cf->c_nullzeronetslen;
freeargv(av);
return (1);
}
void
routeadd(struct state *sp, struct route *routep)
{
struct route *rtp;
DYNARRAY(sp->routes, sp->routeslen, &sp->routessize,
sizeof(*sp->routes), 8, 8, "routeadd");
rtp = sp->routes + sp->routeslen;
*rtp = *routep;
if (rtp->raw != NULL)
rtp->raw = strsave(rtp->raw);
++sp->routeslen;
if (routep->type == ROUTE_NULLZERO)
++sp->nullzerolen;
stats_sethiwater(&sp->nullzerostats, sp->nullzerolen);
}
/* Returns true if successful */
int
routedelete(struct state *sp, struct route *routep)
{
int i, n;
struct route *rtp;
for (i = 0, rtp = sp->routes; i < sp->routeslen; ++i, ++rtp)
if (memcmp(rtp, routep, sizeof(*rtp)) == 0) {
n = sp->routeslen - (i + 1);
memmove(rtp, rtp + 1, n * sizeof(*rtp));
--sp->routeslen;
memset(sp->routes + sp->routeslen, 0,
sizeof(*sp->routes));
if (routep->type == ROUTE_NULLZERO)
--sp->nullzerolen;
return (1);
}
return (0);
}
struct route *
routefind(struct state *sp, struct route *routep)
{
int i;
struct route *rtp;
for (i = 0, rtp = sp->routes; i < sp->routeslen; ++i, ++rtp)
if (memcmp(rtp, routep, sizeof(*rtp)) == 0)
return (rtp);
return (NULL);
}
void
routefree(struct state *sp)
{
/* Also clean up stats */
stats_free(&sp->nullzerostats);
}
const char *
routeformat(struct route *rtp)
{
size_t size, len;
const char *p;
char *cp;
static char buf[256];
if (rtp->type == ROUTE_UNKNOWN) {
(void)snprintf(buf, sizeof(buf), "# unsupported route \"%s\"",
rtp->raw != NULL ? rtp->raw : "");
return (buf);
}
p = val2str(str2route, rtp->type);
if (p == NULL)
p = "?";
cp = buf;
size = sizeof(buf);
(void)snprintf(cp, size, "%s %s", p, addr2str(&rtp->dst));
if (rtp->gw.family != 0) {
len = strlen(cp);
size -= len;
cp += len;
(void)snprintf(cp, size, " %s", addr2str(&rtp->gw));
}
return (buf);
}
void
routeinit(struct state *sp)
{
stats_init(&sp->nullzerostats, 10, 60, "routeinit: stats");
}
void
routelistsfree(struct state *sp)
{
int i;
struct route *rtp;
if (sp->routes != NULL) {
for (i = 0, rtp = sp->routes; i < sp->routeslen; ++i, ++rtp)
if (rtp->raw != NULL) {
free(rtp->raw);
rtp->raw = NULL;
}
free(sp->routes);
sp->routes = NULL;
sp->routeslen = 0;
sp->routessize = 0;
sp->nullzerolen = 0;
}
sp->listedroutes = 0;
}
int
routestradd(struct state *sp, const char *str)
{
int an;
char **av;
const char *p;
struct route *rtp;
struct route route;
/* Eat leading dot; done if there was only one */
if (*str == '.') {
++str;
if (*str == '\n'|| *str == '\0')
return (1);
}
/* syslog any comments we get */
if (*str == '#') {
++str;
while (*str == ' ')
++str;
lg(LOG_INFO, "listacl: \"%s\"", str);
return (0);
}
rtp = &route;
memset(rtp, 0, sizeof(*rtp));
an = makeargv(str, &av);
if (an < 2) {
lg(LOG_ERR, "routestradd: missing args \"%s\"", str);
freeargv(av);
return (0);
}
rtp->type = str2val(str2route, av[0]);
switch (rtp->type) {
case ROUTE_STATIC:
case ROUTE_DYNAMIC:
case ROUTE_INTERFACE:
case ROUTE_NULLZERO:
p = extractaddr(av[1], NULL, &rtp->dst);
if (p != NULL) {
lg(LOG_ERR, "routestradd: extractaddr dst %s: %s",
av[1], p);
exit(EX_SOFTWARE);
}
if (an >= 3) {
p = extractaddr(av[2], NULL, &rtp->gw);
if (p != NULL) {
lg(LOG_ERR,
"routestradd: extractaddr gw %s: %s",
av[2], p);
exit(EX_SOFTWARE);
}
}
break;
case ROUTE_UNKNOWN:
/* Save the raw text so we can print it out later */
p = strchr(str, '#');
if (p == NULL)
p = str;
else {
++p;
while (isspace((int)*p))
++p;
}
rtp->raw = strsave(p);
break;
default:
lg(LOG_ERR, "routestradd: no such type \"%s\"", str);
exit(EX_SOFTWARE);
}
freeargv(av);
routeadd(sp, rtp);
return (0);
}