prefix.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:13k
源码类别:

网络

开发平台:

Unix_Linux

  1. /*
  2.  * Prefix related functions.
  3.  * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
  4.  *
  5.  * This file is part of GNU Zebra.
  6.  *
  7.  * GNU Zebra is free software; you can redistribute it and/or modify it
  8.  * under the terms of the GNU General Public License as published by the
  9.  * Free Software Foundation; either version 2, or (at your option) any
  10.  * later version.
  11.  *
  12.  * GNU Zebra is distributed in the hope that it will be useful, but
  13.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
  19.  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  20.  * 02111-1307, USA.  
  21.  */
  22. #include <zebra.h>
  23. #include "prefix.h"
  24. #include "vty.h"
  25. #include "sockunion.h"
  26. #include "memory.h"
  27. #include "log.h"
  28. /* Maskbit. */
  29. static u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
  30.          0xf8, 0xfc, 0xfe, 0xff};
  31. /* Number of bits in prefix type. */
  32. #ifndef PNBBY
  33. #define PNBBY 8
  34. #endif /* PNBBY */
  35. #define MASKBIT(offset)  ((0xff << (PNBBY - (offset))) & 0xff)
  36. /* Address Famiy Identifier to Address Family converter. */
  37. int
  38. afi2family (int afi)
  39. {
  40.   if (afi == AFI_IP)
  41.     return AF_INET;
  42. #ifdef HAVE_IPV6
  43.   else if (afi == AFI_IP6)
  44.     return AF_INET6;
  45. #endif /* HAVE_IPV6 */
  46.   return 0;
  47. }
  48. int
  49. family2afi (int family)
  50. {
  51.   if (family == AF_INET)
  52.     return AFI_IP;
  53. #ifdef HAVE_IPV6
  54.   else if (family == AF_INET6)
  55.     return AFI_IP6;
  56. #endif /* HAVE_IPV6 */
  57.   return 0;
  58. }
  59. /* If n includes p prefix then return 1 else return 0. */
  60. int
  61. prefix_match (struct prefix *n, struct prefix *p)
  62. {
  63.   int offset;
  64.   int shift;
  65.   /* Set both prefix's head pointer. */
  66.   u_char *np = (u_char *)&n->u.prefix;
  67.   u_char *pp = (u_char *)&p->u.prefix;
  68.   /* If n's prefix is longer than p's one return 0. */
  69.   if (n->prefixlen > p->prefixlen)
  70.     return 0;
  71.   offset = n->prefixlen / PNBBY;
  72.   shift =  n->prefixlen % PNBBY;
  73.   if (shift)
  74.     if (maskbit[shift] & (np[offset] ^ pp[offset]))
  75.       return 0;
  76.   
  77.   while (offset--)
  78.     if (np[offset] != pp[offset])
  79.       return 0;
  80.   return 1;
  81. }
  82. /* Copy prefix from src to dest. */
  83. void
  84. prefix_copy (struct prefix *dest, struct prefix *src)
  85. {
  86.   dest->family = src->family;
  87.   dest->prefixlen = src->prefixlen;
  88.   if (src->family == AF_INET)
  89.     dest->u.prefix4 = src->u.prefix4;
  90. #ifdef HAVE_IPV6
  91.   else if (src->family == AF_INET6)
  92.     dest->u.prefix6 = src->u.prefix6;
  93. #endif /* HAVE_IPV6 */
  94.   else if (src->family == AF_UNSPEC)
  95.     {
  96.       dest->u.lp.id = src->u.lp.id;
  97.       dest->u.lp.adv_router = src->u.lp.adv_router;
  98.     }
  99.   else
  100.     {
  101.       zlog (NULL, LOG_INFO, "prefix_copy(): Unknown address family %d",
  102.       src->family);
  103.       assert (0);
  104.     }
  105. }
  106. /* If both prefix structure is same then return 1 else return 0. */
  107. int
  108. prefix_same (struct prefix *p1, struct prefix *p2)
  109. {
  110.   if (p1->family == p2->family && p1->prefixlen == p2->prefixlen)
  111.     {
  112.       if (p1->family == AF_INET)
  113. if (IPV4_ADDR_SAME (&p1->u.prefix, &p2->u.prefix))
  114.   return 1;
  115. #ifdef HAVE_IPV6
  116.       if (p1->family == AF_INET6 )
  117. if (IPV6_ADDR_SAME (&p1->u.prefix, &p2->u.prefix))
  118.   return 1;
  119. #endif /* HAVE_IPV6 */
  120.     }
  121.   return 0;
  122. }
  123. /* When both prefix structure is not same, but will be same after
  124.    applying mask, return 0. otherwise, return 1 */
  125. int
  126. prefix_cmp (struct prefix *p1, struct prefix *p2)
  127. {
  128.   int offset;
  129.   int shift;
  130.   /* Set both prefix's head pointer. */
  131.   u_char *pp1 = (u_char *)&p1->u.prefix;
  132.   u_char *pp2 = (u_char *)&p2->u.prefix;
  133.   if (p1->family != p2->family || p1->prefixlen != p2->prefixlen)
  134.     return 1;
  135.   offset = p1->prefixlen / 8;
  136.   shift = p1->prefixlen % 8;
  137.   if (shift)
  138.     if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
  139.       return 1;
  140.   while (offset--)
  141.     if (pp1[offset] != pp2[offset])
  142.       return 1;
  143.   return 0;
  144. }
  145. /* Return prefix family type string. */
  146. char *
  147. prefix_family_str (struct prefix *p)
  148. {
  149.   if (p->family == AF_INET)
  150.     return "inet";
  151. #ifdef HAVE_IPV6
  152.   if (p->family == AF_INET6)
  153.     return "inet6";
  154. #endif /* HAVE_IPV6 */
  155.   return "unspec";
  156. }
  157. /* Allocate new prefix_ipv4 structure. */
  158. struct prefix_ipv4 *
  159. prefix_ipv4_new ()
  160. {
  161.   struct prefix_ipv4 *p;
  162.   p = XCALLOC (MTYPE_PREFIX_IPV4, sizeof *p);
  163.   p->family = AF_INET;
  164.   return p;
  165. }
  166. /* Free prefix_ipv4 structure. */
  167. void
  168. prefix_ipv4_free (struct prefix_ipv4 *p)
  169. {
  170.   XFREE (MTYPE_PREFIX_IPV4, p);
  171. }
  172. /* When string format is invalid return 0. */
  173. int
  174. str2prefix_ipv4 (char *str, struct prefix_ipv4 *p)
  175. {
  176.   int ret;
  177.   int plen;
  178.   char *pnt;
  179.   char *cp;
  180.   /* Find slash inside string. */
  181.   pnt = strchr (str, '/');
  182.   /* String doesn't contail slash. */
  183.   if (pnt == NULL) 
  184.     {
  185.       /* Convert string to prefix. */
  186.       ret = inet_aton (str, &p->prefix);
  187.       if (ret == 0)
  188. return 0;
  189.       /* If address doesn't contain slash we assume it host address. */
  190.       p->family = AF_INET;
  191.       p->prefixlen = IPV4_MAX_BITLEN;
  192.       return ret;
  193.     }
  194.   else
  195.     {
  196.       cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
  197.       strncpy (cp, str, pnt - str);
  198.       *(cp + (pnt - str)) = '';
  199.       ret = inet_aton (cp, &p->prefix);
  200.       XFREE (MTYPE_TMP, cp);
  201.       /* Get prefix length. */
  202.       plen = (u_char) atoi (++pnt);
  203.       if (plen > 32)
  204. return 0;
  205.       p->family = AF_INET;
  206.       p->prefixlen = plen;
  207.     }
  208.   return ret;
  209. }
  210. /* Convert masklen into IP address's netmask. */
  211. void
  212. masklen2ip (int masklen, struct in_addr *netmask)
  213. {
  214.   u_char *pnt;
  215.   int bit;
  216.   int offset;
  217.   memset (netmask, 0, sizeof (struct in_addr));
  218.   pnt = (unsigned char *) netmask;
  219.   offset = masklen / 8;
  220.   bit = masklen % 8;
  221.   
  222.   while (offset--)
  223.     *pnt++ = 0xff;
  224.   if (bit)
  225.     *pnt = maskbit[bit];
  226. }
  227. /* Convert IP address's netmask into integer. We assume netmask is
  228.    sequential one. Argument netmask should be network byte order. */
  229. u_char
  230. ip_masklen (struct in_addr netmask)
  231. {
  232.   u_char len;
  233.   u_char *pnt;
  234.   u_char *end;
  235.   u_char val;
  236.   len = 0;
  237.   pnt = (u_char *) &netmask;
  238.   end = pnt + 4;
  239.   while ((*pnt == 0xff) && pnt < end)
  240.     {
  241.       len+= 8;
  242.       pnt++;
  243.     } 
  244.   if (pnt < end)
  245.     {
  246.       val = *pnt;
  247.       while (val)
  248. {
  249.   len++;
  250.   val <<= 1;
  251. }
  252.     }
  253.   return len;
  254. }
  255. /* Apply mask to IPv4 prefix. */
  256. void
  257. apply_mask_ipv4 (struct prefix_ipv4 *p)
  258. {
  259.   u_char *pnt;
  260.   int index;
  261.   int offset;
  262.   index = p->prefixlen / 8;
  263.   if (index < 4)
  264.     {
  265.       pnt = (u_char *) &p->prefix;
  266.       offset = p->prefixlen % 8;
  267.       pnt[index] &= maskbit[offset];
  268.       index++;
  269.       while (index < 4)
  270. pnt[index++] = 0;
  271.     }
  272. }
  273. /* If prefix is 0.0.0.0/0 then return 1 else return 0. */
  274. int
  275. prefix_ipv4_any (struct prefix_ipv4 *p)
  276. {
  277.   return (p->prefix.s_addr == 0 && p->prefixlen == 0);
  278. }
  279. #ifdef HAVE_IPV6
  280. /* Allocate a new ip version 6 route */
  281. struct prefix_ipv6 *
  282. prefix_ipv6_new ()
  283. {
  284.   struct prefix_ipv6 *p;
  285.   p = XCALLOC (MTYPE_PREFIX_IPV6, sizeof (struct prefix_ipv6));
  286.   p->family = AF_INET6;
  287.   return p;
  288. }
  289. /* Free prefix for IPv6. */
  290. void
  291. prefix_ipv6_free (struct prefix_ipv6 *p)
  292. {
  293.   XFREE (MTYPE_PREFIX_IPV6, p);
  294. }
  295. /* If given string is valid return pin6 else return NULL */
  296. int
  297. str2prefix_ipv6 (char *str, struct prefix_ipv6 *p)
  298. {
  299.   char *pnt;
  300.   char *cp;
  301.   int ret;
  302.   pnt = strchr (str, '/');
  303.   /* If string doesn't contain `/' treat it as host route. */
  304.   if (pnt == NULL) 
  305.     {
  306.       ret = inet_pton (AF_INET6, str, &p->prefix);
  307.       if (ret != 1)
  308. return 0;
  309.       p->prefixlen = IPV6_MAX_BITLEN;
  310.     }
  311.   else 
  312.     {
  313.       int plen;
  314.       cp = XMALLOC (0, (pnt - str) + 1);
  315.       strncpy (cp, str, pnt - str);
  316.       *(cp + (pnt - str)) = '';
  317.       ret = inet_pton (AF_INET6, cp, &p->prefix);
  318.       free (cp);
  319.       if (ret != 1)
  320. return 0;
  321.       plen = (u_char) atoi (++pnt);
  322.       if (plen > 128)
  323. return 0;
  324.       p->prefixlen = plen;
  325.     }
  326.   p->family = AF_INET6;
  327.   return ret;
  328. }
  329. /* Convert struct in6_addr netmask into integer. */
  330. int
  331. ip6_masklen (struct in6_addr netmask)
  332. {
  333.   int len = 0;
  334.   unsigned char val;
  335.   unsigned char *pnt;
  336.   
  337.   pnt = (unsigned char *) & netmask;
  338.   while ((*pnt == 0xff) && len < 128) 
  339.     {
  340.       len += 8;
  341.       pnt++;
  342.     } 
  343.   
  344.   if (len < 128) 
  345.     {
  346.       val = *pnt;
  347.       while (val) 
  348. {
  349.   len++;
  350.   val <<= 1;
  351. }
  352.     }
  353.   return len;
  354. }
  355. void
  356. masklen2ip6 (int masklen, struct in6_addr *netmask)
  357. {
  358.   unsigned char *pnt;
  359.   int bit;
  360.   int offset;
  361.   memset (netmask, 0, sizeof (struct in6_addr));
  362.   pnt = (unsigned char *) netmask;
  363.   offset = masklen / 8;
  364.   bit = masklen % 8;
  365.   while (offset--)
  366.     *pnt++ = 0xff;
  367.   if (bit)
  368.     *pnt = maskbit[bit];
  369. }
  370. void
  371. apply_mask_ipv6 (struct prefix_ipv6 *p)
  372. {
  373.   u_char *pnt;
  374.   int index;
  375.   int offset;
  376.   index = p->prefixlen / 8;
  377.   if (index < 16)
  378.     {
  379.       pnt = (u_char *) &p->prefix;
  380.       offset = p->prefixlen % 8;
  381.       pnt[index] &= maskbit[offset];
  382.       index++;
  383.       while (index < 16)
  384. pnt[index++] = 0;
  385.     }
  386. }
  387. void
  388. str2in6_addr (char *str, struct in6_addr *addr)
  389. {
  390.   int i;
  391.   unsigned int x;
  392.   /* %x must point to unsinged int */
  393.   for (i = 0; i < 16; i++)
  394.     {
  395.       sscanf (str + (i * 2), "%02x", &x);
  396.       addr->s6_addr[i] = x & 0xff;
  397.     }
  398. }
  399. #endif /* HAVE_IPV6 */
  400. void
  401. apply_mask (struct prefix *p)
  402. {
  403.   switch (p->family)
  404.     {
  405.       case AF_INET:
  406.         apply_mask_ipv4 ((struct prefix_ipv4 *)p);
  407.         break;
  408. #ifdef HAVE_IPV6
  409.       case AF_INET6:
  410.         apply_mask_ipv6 ((struct prefix_ipv6 *)p);
  411.         break;
  412. #endif /* HAVE_IPV6 */
  413.       default:
  414.         break;
  415.     }
  416.   return;
  417. }
  418. /* Utility function of convert between struct prefix <=> union sockunion */
  419. struct prefix *
  420. sockunion2prefix (union sockunion *dest,
  421.   union sockunion *mask)
  422. {
  423.   if (dest->sa.sa_family == AF_INET)
  424.     {
  425.       struct prefix_ipv4 *p;
  426.       p = prefix_ipv4_new ();
  427.       p->family = AF_INET;
  428.       p->prefix = dest->sin.sin_addr;
  429.       p->prefixlen = ip_masklen (mask->sin.sin_addr);
  430.       return (struct prefix *) p;
  431.     }
  432. #ifdef HAVE_IPV6
  433.   if (dest->sa.sa_family == AF_INET6)
  434.     {
  435.       struct prefix_ipv6 *p;
  436.       p = prefix_ipv6_new ();
  437.       p->family = AF_INET6;
  438.       p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
  439.       memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
  440.       return (struct prefix *) p;
  441.     }
  442. #endif /* HAVE_IPV6 */
  443.   return NULL;
  444. }
  445. /* Utility function of convert between struct prefix <=> union sockunion */
  446. struct prefix *
  447. sockunion2hostprefix (union sockunion *su)
  448. {
  449.   if (su->sa.sa_family == AF_INET)
  450.     {
  451.       struct prefix_ipv4 *p;
  452.       p = prefix_ipv4_new ();
  453.       p->family = AF_INET;
  454.       p->prefix = su->sin.sin_addr;
  455.       p->prefixlen = IPV4_MAX_BITLEN;
  456.       return (struct prefix *) p;
  457.     }
  458. #ifdef HAVE_IPV6
  459.   if (su->sa.sa_family == AF_INET6)
  460.     {
  461.       struct prefix_ipv6 *p;
  462.       p = prefix_ipv6_new ();
  463.       p->family = AF_INET6;
  464.       p->prefixlen = IPV6_MAX_BITLEN;
  465.       memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
  466.       return (struct prefix *) p;
  467.     }
  468. #endif /* HAVE_IPV6 */
  469.   return NULL;
  470. }
  471. int
  472. prefix_blen (struct prefix *p)
  473. {
  474.   switch (p->family) 
  475.     {
  476.     case AF_INET:
  477.       return IPV4_MAX_BYTELEN;
  478.       break;
  479. #ifdef HAVE_IPV6
  480.     case AF_INET6:
  481.       return IPV6_MAX_BYTELEN;
  482.       break;
  483. #endif /* HAVE_IPV6 */
  484.     }
  485.   return 0;
  486. }
  487. /* Generic function for conversion string to struct prefix. */
  488. int
  489. str2prefix (char *str, struct prefix *p)
  490. {
  491.   int ret;
  492.   /* First we try to convert string to struct prefix_ipv4. */
  493.   ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
  494.   if (ret)
  495.     return ret;
  496. #ifdef HAVE_IPV6
  497.   /* Next we try to convert string to struct prefix_ipv6. */
  498.   ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
  499.   if (ret)
  500.     return ret;
  501. #endif /* HAVE_IPV6 */
  502.   return 0;
  503. }
  504. int
  505. prefix2str (struct prefix *p, char *str, int size)
  506. {
  507.   char buf[BUFSIZ];
  508.   inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
  509.   snprintf (str, size, "%s/%d", buf, p->prefixlen);
  510.   return 0;
  511. }
  512. struct prefix *
  513. prefix_new ()
  514. {
  515.   struct prefix *p;
  516.   p = XCALLOC (MTYPE_PREFIX, sizeof *p);
  517.   return p;
  518. }
  519. /* Free prefix structure. */
  520. void
  521. prefix_free (struct prefix *p)
  522. {
  523.   XFREE (MTYPE_PREFIX, p);
  524. }
  525. /* Utility function.  Check the string only contains digit
  526.    character. */
  527. int
  528. all_digit (char *str)
  529. {
  530.   for (; *str != ''; str++)
  531.     if (!isdigit ((int) *str))
  532.       return 0;
  533.   return 1;
  534. }
  535. /* Utility function to convert ipv4 prefixes to Classful prefixes */
  536. void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
  537. {
  538.   u_int32_t destination;
  539.   
  540.   destination = ntohl (p->prefix.s_addr);
  541.   
  542.   if (p->prefixlen == 32);
  543.   /* do nothing for host routes */
  544.   else if (IN_CLASSC (destination)) 
  545.     {
  546.       p->prefixlen=24;
  547.       apply_mask_ipv4(p);
  548.     }
  549.   else if (IN_CLASSB(destination)) 
  550.     {
  551.       p->prefixlen=16;
  552.       apply_mask_ipv4(p);
  553.     }
  554.   else 
  555.     {
  556.       p->prefixlen=8;
  557.       apply_mask_ipv4(p);
  558.     }
  559. }
  560. /* Utility function to convert ipv4 netmask to prefixes 
  561.    ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
  562.    ex.) "1.0.0.0" NULL => "1.0.0.0/8"                   */
  563. int
  564. netmask_str2prefix_str (char *net_str, char *mask_str, char *prefix_str)
  565. {
  566.   struct in_addr network;
  567.   struct in_addr mask;
  568.   u_char prefixlen;
  569.   u_int32_t destination;
  570.   int ret;
  571.   ret = inet_aton (net_str, &network);
  572.   if (! ret)
  573.     return 0;
  574.   if (mask_str)
  575.     {
  576.       ret = inet_aton (mask_str, &mask);
  577.       if (! ret)
  578.         return 0;
  579.       prefixlen = ip_masklen (mask);
  580.     }
  581.   else 
  582.     {
  583.       destination = ntohl (network.s_addr);
  584.       if (network.s_addr == 0)
  585. prefixlen = 0;
  586.       else if (IN_CLASSC (destination))
  587. prefixlen = 24;
  588.       else if (IN_CLASSB (destination))
  589. prefixlen = 16;
  590.       else if (IN_CLASSA (destination))
  591. prefixlen = 8;
  592.       else
  593. return 0;
  594.     }
  595.   sprintf (prefix_str, "%s/%d", net_str, prefixlen);
  596.   return 1;
  597. }