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 >
C/C++ Source or Header  |  2012-01-18  |  7KB  |  295 lines

  1. /*
  2.  * Copyright (c) 2006, 2007, 2008, 2009, 2011, 2012
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #ifndef lint
  23. static const char rcsid[] =
  24.     "@(#) $Id: route.c 804 2012-01-18 08:45:27Z leres $ (LBL)";
  25. #endif
  26.  
  27. #include <sys/types.h>
  28. #include <sys/time.h>
  29.  
  30. #include <ctype.h>
  31. #include <errno.h>
  32. #include <signal.h>
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #include <sysexits.h>
  37. #include <syslog.h>
  38. #include <unistd.h>
  39.  
  40. #include "acld.h"
  41. #include "cf.h"
  42. #include "child.h"
  43.  
  44. /* Locals */
  45. static struct s2v str2route[] = {
  46.     { "S", ROUTE_STATIC },
  47.     { "D", ROUTE_DYNAMIC },
  48.     { "I", ROUTE_INTERFACE },
  49.     { "N", ROUTE_NULLZERO },
  50.     { NULL,    0 }
  51. };
  52.  
  53. /* Return true if the address is an allowable null zero candidate */
  54. int
  55. goodnullzero(struct cf *cf, struct addr *addrp)
  56. {
  57.     int i;
  58.     struct route *rtp;
  59.  
  60.     for (i = 0, rtp = cf->c_nullzeronets; i < cf->c_nullzeronetslen;
  61.         ++i, ++rtp)
  62.         if (insubnet(&rtp->dst, addrp))
  63.             return (1);
  64.  
  65.     return (0);
  66. }
  67.  
  68. int
  69. nullzeronetadd(struct cf *cf, const char *str)
  70. {
  71.     int an;
  72.     char **av;
  73.     const char *p;
  74.     struct route *rtp;
  75.  
  76.     an = makeargv(str, &av);
  77.     if (an != 1) {
  78.         lg(LOG_ERR, "nullzeronetadd wrong number of args: \"%s\"", str);
  79.         freeargv(av);
  80.         return (0);
  81.     }
  82.  
  83.     DYNARRAY(cf->c_nullzeronets, cf->c_nullzeronetslen,
  84.         &cf->c_nullzeronetssize, sizeof(*cf->c_nullzeronets),
  85.         8, 8, "cf nullzeronets");
  86.     rtp = cf->c_nullzeronets + cf->c_nullzeronetslen;
  87.  
  88.     p = extractaddr(av[0], NULL, &rtp->dst);
  89.     if (p != NULL) {
  90.         lg(LOG_ERR, "nullzeronetadd: extractaddr %s: %s", av[0], p);
  91.         freeargv(av);
  92.         return (0);
  93.     }
  94.     rtp->type = ROUTE_STATIC;
  95.     ++cf->c_nullzeronetslen;
  96.  
  97.     freeargv(av);
  98.     return (1);
  99. }
  100.  
  101. void
  102. routeadd(struct state *sp, struct route *routep)
  103. {
  104.     struct route *rtp;
  105.  
  106.     DYNARRAY(sp->routes, sp->routeslen, &sp->routessize,
  107.         sizeof(*sp->routes), 8, 8, "routeadd");
  108.     rtp = sp->routes + sp->routeslen;
  109.     *rtp = *routep;
  110.     if (rtp->raw != NULL)
  111.         rtp->raw = strsave(rtp->raw);
  112.     ++sp->routeslen;
  113.     if (routep->type == ROUTE_NULLZERO)
  114.         ++sp->nullzerolen;
  115.     stats_sethiwater(&sp->nullzerostats, sp->nullzerolen);
  116. }
  117.  
  118. /* Returns true if successful */
  119. int
  120. routedelete(struct state *sp, struct route *routep)
  121. {
  122.     int i, n;
  123.     struct route *rtp;
  124.  
  125.     for (i = 0, rtp = sp->routes; i < sp->routeslen; ++i, ++rtp)
  126.         if (memcmp(rtp, routep, sizeof(*rtp)) == 0) {
  127.             n = sp->routeslen - (i + 1);
  128.             memmove(rtp, rtp + 1, n * sizeof(*rtp));
  129.             --sp->routeslen;
  130.             memset(sp->routes + sp->routeslen, 0,
  131.                 sizeof(*sp->routes));
  132.             if (routep->type == ROUTE_NULLZERO)
  133.                 --sp->nullzerolen;
  134.             return (1);
  135.         }
  136.     return (0);
  137. }
  138.  
  139. struct route *
  140. routefind(struct state *sp, struct route *routep)
  141. {
  142.     int i;
  143.     struct route *rtp;
  144.  
  145.     for (i = 0, rtp = sp->routes; i < sp->routeslen; ++i, ++rtp)
  146.         if (memcmp(rtp, routep, sizeof(*rtp)) == 0)
  147.             return (rtp);
  148.     return (NULL);
  149. }
  150.  
  151. void
  152. routefree(struct state *sp)
  153. {
  154.     /* Also clean up stats */
  155.     stats_free(&sp->nullzerostats);
  156. }
  157.  
  158. const char *
  159. routeformat(struct route *rtp)
  160. {
  161.     size_t size, len;
  162.     const char *p;
  163.     char *cp;
  164.     static char buf[256];
  165.  
  166.     if (rtp->type == ROUTE_UNKNOWN) {
  167.         (void)snprintf(buf, sizeof(buf), "# unsupported route \"%s\"",
  168.             rtp->raw != NULL ? rtp->raw : "");
  169.         return (buf);
  170.     }
  171.     p = val2str(str2route, rtp->type);
  172.     if (p == NULL)
  173.         p = "?";
  174.  
  175.     cp = buf;
  176.     size = sizeof(buf);
  177.     (void)snprintf(cp, size, "%s %s", p, addr2str(&rtp->dst));
  178.     if (rtp->gw.family != 0) {
  179.         len = strlen(cp);
  180.         size -= len;
  181.         cp += len;
  182.         (void)snprintf(cp, size, " %s", addr2str(&rtp->gw));
  183.     }
  184.  
  185.     return (buf);
  186. }
  187.  
  188. void
  189. routeinit(struct state *sp)
  190. {
  191.     stats_init(&sp->nullzerostats, 10, 60, "routeinit: stats");
  192. }
  193.  
  194. void
  195. routelistsfree(struct state *sp)
  196. {
  197.     int i;
  198.     struct route *rtp;
  199.  
  200.     if (sp->routes != NULL) {
  201.         for (i = 0, rtp = sp->routes; i < sp->routeslen; ++i, ++rtp)
  202.             if (rtp->raw != NULL) {
  203.                 free(rtp->raw);
  204.                 rtp->raw = NULL;
  205.             }
  206.         free(sp->routes);
  207.         sp->routes = NULL;
  208.         sp->routeslen = 0;
  209.         sp->routessize = 0;
  210.         sp->nullzerolen = 0;
  211.     }
  212.     sp->listedroutes = 0;
  213. }
  214.  
  215. int
  216. routestradd(struct state *sp, const char *str)
  217. {
  218.     int an;
  219.     char **av;
  220.     const char *p;
  221.     struct route *rtp;
  222.     struct route route;
  223.  
  224.     /* Eat leading dot; done if there was only one */
  225.     if (*str == '.') {
  226.         ++str;
  227.         if (*str == '\n'|| *str == '\0')
  228.             return (1);
  229.     }
  230.  
  231.     /* syslog any comments we get */
  232.     if (*str == '#') {
  233.         ++str;
  234.         while (*str == ' ')
  235.             ++str;
  236.         lg(LOG_INFO, "listacl: \"%s\"", str);
  237.         return (0);
  238.     }
  239.  
  240.     rtp = &route;
  241.     memset(rtp, 0, sizeof(*rtp));
  242.     an = makeargv(str, &av);
  243.     if (an < 2) {
  244.         lg(LOG_ERR, "routestradd: missing args \"%s\"", str);
  245.         freeargv(av);
  246.         return (0);
  247.     }
  248.  
  249.     rtp->type = str2val(str2route, av[0]);
  250.     switch (rtp->type) {
  251.  
  252.     case ROUTE_STATIC:
  253.     case ROUTE_DYNAMIC:
  254.     case ROUTE_INTERFACE:
  255.     case ROUTE_NULLZERO:
  256.         p = extractaddr(av[1], NULL, &rtp->dst);
  257.         if (p != NULL) {
  258.             lg(LOG_ERR, "routestradd: extractaddr dst %s: %s",
  259.                 av[1], p);
  260.             exit(EX_SOFTWARE);
  261.         }
  262.         if (an >= 3) {
  263.             p = extractaddr(av[2], NULL, &rtp->gw);
  264.             if (p != NULL) {
  265.                 lg(LOG_ERR,
  266.                     "routestradd: extractaddr gw %s: %s",
  267.                     av[2], p);
  268.                 exit(EX_SOFTWARE);
  269.             }
  270.         }
  271.         break;
  272.  
  273.     case ROUTE_UNKNOWN:
  274.         /* Save the raw text so we can print it out later */
  275.         p = strchr(str, '#');
  276.         if (p == NULL)
  277.             p = str;
  278.         else {
  279.             ++p;
  280.             while (isspace((int)*p))
  281.                 ++p;
  282.         }
  283.         rtp->raw = strsave(p);
  284.         break;
  285.  
  286.     default:
  287.         lg(LOG_ERR, "routestradd: no such type \"%s\"", str);
  288.         exit(EX_SOFTWARE);
  289.     }
  290.  
  291.     freeargv(av);
  292.     routeadd(sp, rtp);
  293.     return (0);
  294. }
  295.