prefix.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  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 const 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 (afi_t 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. afi_t
  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 (const struct prefix *n, const struct prefix *p)
  62. {
  63. int offset;
  64. int shift;
  65. const u_char *np, *pp;
  66. /* If n's prefix is longer than p's one return 0. */
  67. if (n->prefixlen > p->prefixlen)
  68. return 0;
  69. /* Set both prefix's head pointer. */
  70. np = (const u_char *)&n->u.prefix;
  71. pp = (const u_char *)&p->u.prefix;
  72. offset = n->prefixlen / PNBBY;
  73. shift = n->prefixlen % PNBBY;
  74. if (shift)
  75. if (maskbit[shift] & (np[offset] ^ pp[offset]))
  76. return 0;
  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, const 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_ERR, "prefix_copy(): Unknown address family %d",
  102. src->family);
  103. assert (0);
  104. }
  105. }
  106. /*
  107. * Return 1 if the address/netmask contained in the prefix structure
  108. * is the same, and else return 0. For this routine, 'same' requires
  109. * that not only the prefix length and the network part be the same,
  110. * but also the host part. Thus, 10.0.0.1/8 and 10.0.0.2/8 are not
  111. * the same. Note that this routine has the same return value sense
  112. * as '==' (which is different from prefix_cmp).
  113. */
  114. int
  115. prefix_same (const struct prefix *p1, const struct prefix *p2)
  116. {
  117. if (p1->family == p2->family && p1->prefixlen == p2->prefixlen)
  118. {
  119. if (p1->family == AF_INET)
  120. if (IPV4_ADDR_SAME (&p1->u.prefix, &p2->u.prefix))
  121. return 1;
  122. #ifdef HAVE_IPV6
  123. if (p1->family == AF_INET6 )
  124. if (IPV6_ADDR_SAME (&p1->u.prefix, &p2->u.prefix))
  125. return 1;
  126. #endif /* HAVE_IPV6 */
  127. }
  128. return 0;
  129. }
  130. /*
  131. * Return 0 if the network prefixes represented by the struct prefix
  132. * arguments are the same prefix, and 1 otherwise. Network prefixes
  133. * are considered the same if the prefix lengths are equal and the
  134. * network parts are the same. Host bits (which are considered masked
  135. * by the prefix length) are not significant. Thus, 10.0.0.1/8 and
  136. * 10.0.0.2/8 are considered equivalent by this routine. Note that
  137. * this routine has the same return sense as strcmp (which is different
  138. * from prefix_same).
  139. */
  140. int
  141. prefix_cmp (const struct prefix *p1, const struct prefix *p2)
  142. {
  143. int offset;
  144. int shift;
  145. /* Set both prefix's head pointer. */
  146. const u_char *pp1 = (const u_char *)&p1->u.prefix;
  147. const u_char *pp2 = (const u_char *)&p2->u.prefix;
  148. if (p1->family != p2->family || p1->prefixlen != p2->prefixlen)
  149. return 1;
  150. offset = p1->prefixlen / 8;
  151. shift = p1->prefixlen % 8;
  152. if (shift)
  153. if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
  154. return 1;
  155. while (offset--)
  156. if (pp1[offset] != pp2[offset])
  157. return 1;
  158. return 0;
  159. }
  160. /* Return prefix family type string. */
  161. const char *
  162. prefix_family_str (const struct prefix *p)
  163. {
  164. if (p->family == AF_INET)
  165. return "inet";
  166. #ifdef HAVE_IPV6
  167. if (p->family == AF_INET6)
  168. return "inet6";
  169. #endif /* HAVE_IPV6 */
  170. return "unspec";
  171. }
  172. /* Allocate new prefix_ipv4 structure. */
  173. struct prefix_ipv4 *
  174. prefix_ipv4_new ()
  175. {
  176. struct prefix_ipv4 *p;
  177. /* Call prefix_new to allocate a full-size struct prefix to avoid problems
  178. where the struct prefix_ipv4 is cast to struct prefix and unallocated
  179. bytes were being referenced (e.g. in structure assignments). */
  180. p = (struct prefix_ipv4 *)prefix_new();
  181. p->family = AF_INET;
  182. return p;
  183. }
  184. /* Free prefix_ipv4 structure. */
  185. void
  186. prefix_ipv4_free (struct prefix_ipv4 *p)
  187. {
  188. prefix_free((struct prefix *)p);
  189. }
  190. /* When string format is invalid return 0. */
  191. int
  192. str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p)
  193. {
  194. int ret;
  195. int plen;
  196. char *pnt;
  197. char *cp;
  198. /* Find slash inside string. */
  199. pnt = strchr (str, '/');
  200. /* String doesn't contail slash. */
  201. if (pnt == NULL)
  202. {
  203. /* Convert string to prefix. */
  204. ret = inet_aton (str, &p->prefix);
  205. if (ret == 0)
  206. return 0;
  207. /* If address doesn't contain slash we assume it host address. */
  208. p->family = AF_INET;
  209. p->prefixlen = IPV4_MAX_BITLEN;
  210. return ret;
  211. }
  212. else
  213. {
  214. cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
  215. strncpy (cp, str, pnt - str);
  216. *(cp + (pnt - str)) = '\0';
  217. ret = inet_aton (cp, &p->prefix);
  218. XFREE (MTYPE_TMP, cp);
  219. /* Get prefix length. */
  220. plen = (u_char) atoi (++pnt);
  221. if (plen > IPV4_MAX_PREFIXLEN)
  222. return 0;
  223. p->family = AF_INET;
  224. p->prefixlen = plen;
  225. }
  226. return ret;
  227. }
  228. /* Convert masklen into IP address's netmask. */
  229. void
  230. masklen2ip (int masklen, struct in_addr *netmask)
  231. {
  232. u_char *pnt;
  233. int bit;
  234. int offset;
  235. memset (netmask, 0, sizeof (struct in_addr));
  236. pnt = (unsigned char *) netmask;
  237. offset = masklen / 8;
  238. bit = masklen % 8;
  239. while (offset--)
  240. *pnt++ = 0xff;
  241. if (bit)
  242. *pnt = maskbit[bit];
  243. }
  244. /* Convert IP address's netmask into integer. We assume netmask is
  245. sequential one. Argument netmask should be network byte order. */
  246. u_char
  247. ip_masklen (struct in_addr netmask)
  248. {
  249. u_char len;
  250. u_char *pnt;
  251. u_char *end;
  252. u_char val;
  253. len = 0;
  254. pnt = (u_char *) &netmask;
  255. end = pnt + 4;
  256. while ((pnt < end) && (*pnt == 0xff))
  257. {
  258. len+= 8;
  259. pnt++;
  260. }
  261. if (pnt < end)
  262. {
  263. val = *pnt;
  264. while (val)
  265. {
  266. len++;
  267. val <<= 1;
  268. }
  269. }
  270. return len;
  271. }
  272. /* Apply mask to IPv4 prefix. */
  273. void
  274. apply_mask_ipv4 (struct prefix_ipv4 *p)
  275. {
  276. u_char *pnt;
  277. int index;
  278. int offset;
  279. index = p->prefixlen / 8;
  280. if (index < 4)
  281. {
  282. pnt = (u_char *) &p->prefix;
  283. offset = p->prefixlen % 8;
  284. pnt[index] &= maskbit[offset];
  285. index++;
  286. while (index < 4)
  287. pnt[index++] = 0;
  288. }
  289. }
  290. /* If prefix is 0.0.0.0/0 then return 1 else return 0. */
  291. int
  292. prefix_ipv4_any (const struct prefix_ipv4 *p)
  293. {
  294. return (p->prefix.s_addr == 0 && p->prefixlen == 0);
  295. }
  296. #ifdef HAVE_IPV6
  297. /* Allocate a new ip version 6 route */
  298. struct prefix_ipv6 *
  299. prefix_ipv6_new (void)
  300. {
  301. struct prefix_ipv6 *p;
  302. /* Allocate a full-size struct prefix to avoid problems with structure
  303. size mismatches. */
  304. p = (struct prefix_ipv6 *)prefix_new();
  305. p->family = AF_INET6;
  306. return p;
  307. }
  308. /* Free prefix for IPv6. */
  309. void
  310. prefix_ipv6_free (struct prefix_ipv6 *p)
  311. {
  312. prefix_free((struct prefix *)p);
  313. }
  314. /* If given string is valid return pin6 else return NULL */
  315. int
  316. str2prefix_ipv6 (const char *str, struct prefix_ipv6 *p)
  317. {
  318. char *pnt;
  319. char *cp;
  320. int ret;
  321. pnt = strchr (str, '/');
  322. /* If string doesn't contain `/' treat it as host route. */
  323. if (pnt == NULL)
  324. {
  325. ret = inet_pton (AF_INET6, str, &p->prefix);
  326. if (ret == 0)
  327. return 0;
  328. p->prefixlen = IPV6_MAX_BITLEN;
  329. }
  330. else
  331. {
  332. int plen;
  333. cp = XMALLOC (0, (pnt - str) + 1);
  334. strncpy (cp, str, pnt - str);
  335. *(cp + (pnt - str)) = '\0';
  336. ret = inet_pton (AF_INET6, cp, &p->prefix);
  337. free (cp);
  338. if (ret == 0)
  339. return 0;
  340. plen = (u_char) atoi (++pnt);
  341. if (plen > 128)
  342. return 0;
  343. p->prefixlen = plen;
  344. }
  345. p->family = AF_INET6;
  346. return ret;
  347. }
  348. /* Convert struct in6_addr netmask into integer.
  349. * FIXME return u_char as ip_maskleni() does. */
  350. int
  351. ip6_masklen (struct in6_addr netmask)
  352. {
  353. int len = 0;
  354. unsigned char val;
  355. unsigned char *pnt;
  356. pnt = (unsigned char *) & netmask;
  357. while ((*pnt == 0xff) && len < 128)
  358. {
  359. len += 8;
  360. pnt++;
  361. }
  362. if (len < 128)
  363. {
  364. val = *pnt;
  365. while (val)
  366. {
  367. len++;
  368. val <<= 1;
  369. }
  370. }
  371. return len;
  372. }
  373. void
  374. masklen2ip6 (int masklen, struct in6_addr *netmask)
  375. {
  376. unsigned char *pnt;
  377. int bit;
  378. int offset;
  379. memset (netmask, 0, sizeof (struct in6_addr));
  380. pnt = (unsigned char *) netmask;
  381. offset = masklen / 8;
  382. bit = masklen % 8;
  383. while (offset--)
  384. *pnt++ = 0xff;
  385. if (bit)
  386. *pnt = maskbit[bit];
  387. }
  388. void
  389. apply_mask_ipv6 (struct prefix_ipv6 *p)
  390. {
  391. u_char *pnt;
  392. int index;
  393. int offset;
  394. index = p->prefixlen / 8;
  395. if (index < 16)
  396. {
  397. pnt = (u_char *) &p->prefix;
  398. offset = p->prefixlen % 8;
  399. pnt[index] &= maskbit[offset];
  400. index++;
  401. while (index < 16)
  402. pnt[index++] = 0;
  403. }
  404. }
  405. void
  406. str2in6_addr (const char *str, struct in6_addr *addr)
  407. {
  408. int i;
  409. unsigned int x;
  410. /* %x must point to unsinged int */
  411. for (i = 0; i < 16; i++)
  412. {
  413. sscanf (str + (i * 2), "%02x", &x);
  414. addr->s6_addr[i] = x & 0xff;
  415. }
  416. }
  417. #endif /* HAVE_IPV6 */
  418. void
  419. apply_mask (struct prefix *p)
  420. {
  421. switch (p->family)
  422. {
  423. case AF_INET:
  424. apply_mask_ipv4 ((struct prefix_ipv4 *)p);
  425. break;
  426. #ifdef HAVE_IPV6
  427. case AF_INET6:
  428. apply_mask_ipv6 ((struct prefix_ipv6 *)p);
  429. break;
  430. #endif /* HAVE_IPV6 */
  431. default:
  432. break;
  433. }
  434. return;
  435. }
  436. /* Utility function of convert between struct prefix <=> union sockunion.
  437. * FIXME This function isn't used anywhere. */
  438. struct prefix *
  439. sockunion2prefix (const union sockunion *dest,
  440. const union sockunion *mask)
  441. {
  442. if (dest->sa.sa_family == AF_INET)
  443. {
  444. struct prefix_ipv4 *p;
  445. p = prefix_ipv4_new ();
  446. p->family = AF_INET;
  447. p->prefix = dest->sin.sin_addr;
  448. p->prefixlen = ip_masklen (mask->sin.sin_addr);
  449. return (struct prefix *) p;
  450. }
  451. #ifdef HAVE_IPV6
  452. if (dest->sa.sa_family == AF_INET6)
  453. {
  454. struct prefix_ipv6 *p;
  455. p = prefix_ipv6_new ();
  456. p->family = AF_INET6;
  457. p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
  458. memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
  459. return (struct prefix *) p;
  460. }
  461. #endif /* HAVE_IPV6 */
  462. return NULL;
  463. }
  464. /* Utility function of convert between struct prefix <=> union sockunion. */
  465. struct prefix *
  466. sockunion2hostprefix (const union sockunion *su)
  467. {
  468. if (su->sa.sa_family == AF_INET)
  469. {
  470. struct prefix_ipv4 *p;
  471. p = prefix_ipv4_new ();
  472. p->family = AF_INET;
  473. p->prefix = su->sin.sin_addr;
  474. p->prefixlen = IPV4_MAX_BITLEN;
  475. return (struct prefix *) p;
  476. }
  477. #ifdef HAVE_IPV6
  478. if (su->sa.sa_family == AF_INET6)
  479. {
  480. struct prefix_ipv6 *p;
  481. p = prefix_ipv6_new ();
  482. p->family = AF_INET6;
  483. p->prefixlen = IPV6_MAX_BITLEN;
  484. memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
  485. return (struct prefix *) p;
  486. }
  487. #endif /* HAVE_IPV6 */
  488. return NULL;
  489. }
  490. int
  491. prefix_blen (const struct prefix *p)
  492. {
  493. switch (p->family)
  494. {
  495. case AF_INET:
  496. return IPV4_MAX_BYTELEN;
  497. break;
  498. #ifdef HAVE_IPV6
  499. case AF_INET6:
  500. return IPV6_MAX_BYTELEN;
  501. break;
  502. #endif /* HAVE_IPV6 */
  503. }
  504. return 0;
  505. }
  506. /* Generic function for conversion string to struct prefix. */
  507. int
  508. str2prefix (const char *str, struct prefix *p)
  509. {
  510. int ret;
  511. /* First we try to convert string to struct prefix_ipv4. */
  512. ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
  513. if (ret)
  514. return ret;
  515. #ifdef HAVE_IPV6
  516. /* Next we try to convert string to struct prefix_ipv6. */
  517. ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
  518. if (ret)
  519. return ret;
  520. #endif /* HAVE_IPV6 */
  521. return 0;
  522. }
  523. int
  524. prefix2str (const struct prefix *p, char *str, int size)
  525. {
  526. char buf[BUFSIZ];
  527. inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
  528. snprintf (str, size, "%s/%d", buf, p->prefixlen);
  529. return 0;
  530. }
  531. struct prefix *
  532. prefix_new ()
  533. {
  534. struct prefix *p;
  535. p = XCALLOC (MTYPE_PREFIX, sizeof *p);
  536. return p;
  537. }
  538. /* Free prefix structure. */
  539. void
  540. prefix_free (struct prefix *p)
  541. {
  542. XFREE (MTYPE_PREFIX, p);
  543. }
  544. /* Utility function. Check the string only contains digit
  545. * character.
  546. * FIXME str.[c|h] would be better place for this function. */
  547. int
  548. all_digit (const char *str)
  549. {
  550. for (; *str != '\0'; str++)
  551. if (!isdigit ((int) *str))
  552. return 0;
  553. return 1;
  554. }
  555. /* Utility function to convert ipv4 prefixes to Classful prefixes */
  556. void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
  557. {
  558. u_int32_t destination;
  559. destination = ntohl (p->prefix.s_addr);
  560. if (p->prefixlen == IPV4_MAX_PREFIXLEN);
  561. /* do nothing for host routes */
  562. else if (IN_CLASSC (destination))
  563. {
  564. p->prefixlen=24;
  565. apply_mask_ipv4(p);
  566. }
  567. else if (IN_CLASSB(destination))
  568. {
  569. p->prefixlen=16;
  570. apply_mask_ipv4(p);
  571. }
  572. else
  573. {
  574. p->prefixlen=8;
  575. apply_mask_ipv4(p);
  576. }
  577. }
  578. in_addr_t
  579. ipv4_network_addr (in_addr_t hostaddr, int masklen)
  580. {
  581. struct in_addr mask;
  582. masklen2ip (masklen, &mask);
  583. return hostaddr & mask.s_addr;
  584. }
  585. in_addr_t
  586. ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
  587. {
  588. struct in_addr mask;
  589. masklen2ip (masklen, &mask);
  590. return (masklen != IPV4_MAX_PREFIXLEN-1) ?
  591. /* normal case */
  592. (hostaddr | ~mask.s_addr) :
  593. /* special case for /31 */
  594. (hostaddr ^ ~mask.s_addr);
  595. }
  596. /* Utility function to convert ipv4 netmask to prefixes
  597. ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
  598. ex.) "1.0.0.0" NULL => "1.0.0.0/8" */
  599. int
  600. netmask_str2prefix_str (const char *net_str, const char *mask_str,
  601. char *prefix_str)
  602. {
  603. struct in_addr network;
  604. struct in_addr mask;
  605. u_char prefixlen;
  606. u_int32_t destination;
  607. int ret;
  608. ret = inet_aton (net_str, &network);
  609. if (! ret)
  610. return 0;
  611. if (mask_str)
  612. {
  613. ret = inet_aton (mask_str, &mask);
  614. if (! ret)
  615. return 0;
  616. prefixlen = ip_masklen (mask);
  617. }
  618. else
  619. {
  620. destination = ntohl (network.s_addr);
  621. if (network.s_addr == 0)
  622. prefixlen = 0;
  623. else if (IN_CLASSC (destination))
  624. prefixlen = 24;
  625. else if (IN_CLASSB (destination))
  626. prefixlen = 16;
  627. else if (IN_CLASSA (destination))
  628. prefixlen = 8;
  629. else
  630. return 0;
  631. }
  632. sprintf (prefix_str, "%s/%d", net_str, prefixlen);
  633. return 1;
  634. }
  635. #ifdef HAVE_IPV6
  636. /* Utility function for making IPv6 address string. */
  637. const char *
  638. inet6_ntoa (struct in6_addr addr)
  639. {
  640. static char buf[INET6_ADDRSTRLEN];
  641. inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
  642. return buf;
  643. }
  644. #endif /* HAVE_IPV6 */