LCOV - code coverage report
Current view: top level - lib - prefix.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 133 311 42.8 %
Date: 2015-11-19 Functions: 21 39 53.8 %

          Line data    Source code
       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             : 
      23             : #include <zebra.h>
      24             : 
      25             : #include "prefix.h"
      26             : #include "vty.h"
      27             : #include "sockunion.h"
      28             : #include "memory.h"
      29             : #include "log.h"
      30             : 
      31             : /* Maskbit. */
      32             : static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
      33             :                                  0xf8, 0xfc, 0xfe, 0xff};
      34             : 
      35             : static const struct in6_addr maskbytes6[] =
      36             : {
      37             :   /* /0   */ { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      38             :   /* /1   */ { { { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      39             :   /* /2   */ { { { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      40             :   /* /3   */ { { { 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      41             :   /* /4   */ { { { 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      42             :   /* /5   */ { { { 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      43             :   /* /6   */ { { { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      44             :   /* /7   */ { { { 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      45             :   /* /8   */ { { { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      46             :   /* /9   */ { { { 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      47             :   /* /10  */ { { { 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      48             :   /* /11  */ { { { 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      49             :   /* /12  */ { { { 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      50             :   /* /13  */ { { { 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      51             :   /* /14  */ { { { 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      52             :   /* /15  */ { { { 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      53             :   /* /16  */ { { { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      54             :   /* /17  */ { { { 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      55             :   /* /18  */ { { { 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      56             :   /* /19  */ { { { 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      57             :   /* /20  */ { { { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      58             :   /* /21  */ { { { 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      59             :   /* /22  */ { { { 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      60             :   /* /23  */ { { { 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      61             :   /* /24  */ { { { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      62             :   /* /25  */ { { { 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      63             :   /* /26  */ { { { 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      64             :   /* /27  */ { { { 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      65             :   /* /28  */ { { { 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      66             :   /* /29  */ { { { 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      67             :   /* /30  */ { { { 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      68             :   /* /31  */ { { { 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      69             :   /* /32  */ { { { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      70             :   /* /33  */ { { { 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      71             :   /* /34  */ { { { 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      72             :   /* /35  */ { { { 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      73             :   /* /36  */ { { { 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      74             :   /* /37  */ { { { 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      75             :   /* /38  */ { { { 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      76             :   /* /39  */ { { { 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      77             :   /* /40  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      78             :   /* /41  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      79             :   /* /42  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      80             :   /* /43  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      81             :   /* /44  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      82             :   /* /45  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      83             :   /* /46  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      84             :   /* /47  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      85             :   /* /48  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      86             :   /* /49  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      87             :   /* /50  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      88             :   /* /51  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      89             :   /* /52  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      90             :   /* /53  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      91             :   /* /54  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      92             :   /* /55  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      93             :   /* /56  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      94             :   /* /57  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      95             :   /* /58  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      96             :   /* /59  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      97             :   /* /60  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      98             :   /* /61  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
      99             :   /* /62  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     100             :   /* /63  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     101             :   /* /64  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     102             :   /* /65  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     103             :   /* /66  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     104             :   /* /67  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     105             :   /* /68  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     106             :   /* /69  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     107             :   /* /70  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     108             :   /* /71  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     109             :   /* /72  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     110             :   /* /73  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     111             :   /* /74  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     112             :   /* /75  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     113             :   /* /76  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     114             :   /* /77  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     115             :   /* /78  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     116             :   /* /79  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     117             :   /* /80  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     118             :   /* /81  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     119             :   /* /82  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     120             :   /* /83  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     121             :   /* /84  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     122             :   /* /85  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     123             :   /* /86  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     124             :   /* /87  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     125             :   /* /88  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
     126             :   /* /89  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00 } } },
     127             :   /* /90  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00 } } },
     128             :   /* /91  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00 } } },
     129             :   /* /92  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 } } },
     130             :   /* /93  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00 } } },
     131             :   /* /94  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00 } } },
     132             :   /* /95  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00 } } },
     133             :   /* /96  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } },
     134             :   /* /97  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00 } } },
     135             :   /* /98  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00 } } },
     136             :   /* /99  */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00 } } },
     137             :   /* /100 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 } } },
     138             :   /* /101 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00 } } },
     139             :   /* /102 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00 } } },
     140             :   /* /103 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00 } } },
     141             :   /* /104 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } } },
     142             :   /* /105 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00 } } },
     143             :   /* /106 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00 } } },
     144             :   /* /107 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00 } } },
     145             :   /* /108 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00 } } },
     146             :   /* /109 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00 } } },
     147             :   /* /110 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00 } } },
     148             :   /* /111 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00 } } },
     149             :   /* /112 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } },
     150             :   /* /113 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00 } } },
     151             :   /* /114 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00 } } },
     152             :   /* /115 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00 } } },
     153             :   /* /116 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00 } } },
     154             :   /* /117 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00 } } },
     155             :   /* /118 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00 } } },
     156             :   /* /119 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00 } } },
     157             :   /* /120 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 } } },
     158             :   /* /121 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 } } },
     159             :   /* /122 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0 } } },
     160             :   /* /123 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0 } } },
     161             :   /* /124 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0 } } },
     162             :   /* /125 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8 } } },
     163             :   /* /126 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc } } },
     164             :   /* /127 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe } } },
     165             :   /* /128 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } }
     166             : };
     167             : 
     168             : /* Number of bits in prefix type. */
     169             : #ifndef PNBBY
     170             : #define PNBBY 8
     171             : #endif /* PNBBY */
     172             : 
     173             : #define MASKBIT(offset)  ((0xff << (PNBBY - (offset))) & 0xff)
     174             : 
     175             : unsigned int
     176     1091070 : prefix_bit (const u_char *prefix, const u_char prefixlen)
     177             : {
     178     1091070 :   unsigned int offset = prefixlen / 8;
     179     1091070 :   unsigned int shift  = 7 - (prefixlen % 8);
     180             :   
     181     1091070 :   return (prefix[offset] >> shift) & 1;
     182             : }
     183             : 
     184             : unsigned int
     185           0 : prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen)
     186             : {
     187           0 :   return prefix_bit((const u_char *) &prefix->s6_addr, prefixlen);
     188             : }
     189             : 
     190             : /* Address Famiy Identifier to Address Family converter. */
     191             : int
     192           0 : afi2family (afi_t afi)
     193             : {
     194           0 :   if (afi == AFI_IP)
     195           0 :     return AF_INET;
     196             : #ifdef HAVE_IPV6
     197           0 :   else if (afi == AFI_IP6)
     198           0 :     return AF_INET6;
     199             : #endif /* HAVE_IPV6 */
     200           0 :   return 0;
     201             : }
     202             : 
     203             : afi_t
     204           0 : family2afi (int family)
     205             : {
     206           0 :   if (family == AF_INET)
     207           0 :     return AFI_IP;
     208             : #ifdef HAVE_IPV6
     209           0 :   else if (family == AF_INET6)
     210           0 :     return AFI_IP6;
     211             : #endif /* HAVE_IPV6 */
     212           0 :   return 0;
     213             : }
     214             : 
     215             : /* If n includes p prefix then return 1 else return 0. */
     216             : int
     217     1332918 : prefix_match (const struct prefix *n, const struct prefix *p)
     218             : {
     219             :   int offset;
     220             :   int shift;
     221             :   const u_char *np, *pp;
     222             : 
     223             :   /* If n's prefix is longer than p's one return 0. */
     224     1332918 :   if (n->prefixlen > p->prefixlen)
     225           0 :     return 0;
     226             : 
     227             :   /* Set both prefix's head pointer. */
     228     1332918 :   np = (const u_char *)&n->u.prefix;
     229     1332918 :   pp = (const u_char *)&p->u.prefix;
     230             :   
     231     1332918 :   offset = n->prefixlen / PNBBY;
     232     1332918 :   shift =  n->prefixlen % PNBBY;
     233             : 
     234     1332918 :   if (shift)
     235     1094670 :     if (maskbit[shift] & (np[offset] ^ pp[offset]))
     236         418 :       return 0;
     237             :   
     238     4670508 :   while (offset--)
     239     2005784 :     if (np[offset] != pp[offset])
     240         276 :       return 0;
     241     1332224 :   return 1;
     242             : }
     243             : 
     244             : /* Copy prefix from src to dest. */
     245             : void
     246        1500 : prefix_copy (struct prefix *dest, const struct prefix *src)
     247             : {
     248        1500 :   dest->family = src->family;
     249        1500 :   dest->prefixlen = src->prefixlen;
     250             : 
     251        1500 :   if (src->family == AF_INET)
     252         437 :     dest->u.prefix4 = src->u.prefix4;
     253             : #ifdef HAVE_IPV6
     254        1063 :   else if (src->family == AF_INET6)
     255        1063 :     dest->u.prefix6 = src->u.prefix6;
     256             : #endif /* HAVE_IPV6 */
     257           0 :   else if (src->family == AF_UNSPEC)
     258             :     {
     259           0 :       dest->u.lp.id = src->u.lp.id;
     260           0 :       dest->u.lp.adv_router = src->u.lp.adv_router;
     261             :     }
     262             :   else
     263             :     {
     264           0 :       zlog (NULL, LOG_ERR, "prefix_copy(): Unknown address family %d",
     265           0 :               src->family);
     266           0 :       assert (0);
     267             :     }
     268        1500 : }
     269             : 
     270             : /* 
     271             :  * Return 1 if the address/netmask contained in the prefix structure
     272             :  * is the same, and else return 0.  For this routine, 'same' requires
     273             :  * that not only the prefix length and the network part be the same,
     274             :  * but also the host part.  Thus, 10.0.0.1/8 and 10.0.0.2/8 are not
     275             :  * the same.  Note that this routine has the same return value sense
     276             :  * as '==' (which is different from prefix_cmp).
     277             :  */
     278             : int
     279         283 : prefix_same (const struct prefix *p1, const struct prefix *p2)
     280             : {
     281         283 :   if (p1->family == p2->family && p1->prefixlen == p2->prefixlen)
     282             :     {
     283         145 :       if (p1->family == AF_INET)
     284          98 :         if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr))
     285          10 :           return 1;
     286             : #ifdef HAVE_IPV6
     287         135 :       if (p1->family == AF_INET6 )
     288          47 :         if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr))
     289           7 :           return 1;
     290             : #endif /* HAVE_IPV6 */
     291             :     }
     292         266 :   return 0;
     293             : }
     294             : 
     295             : /*
     296             :  * Return 0 if the network prefixes represented by the struct prefix
     297             :  * arguments are the same prefix, and 1 otherwise.  Network prefixes
     298             :  * are considered the same if the prefix lengths are equal and the
     299             :  * network parts are the same.  Host bits (which are considered masked
     300             :  * by the prefix length) are not significant.  Thus, 10.0.0.1/8 and
     301             :  * 10.0.0.2/8 are considered equivalent by this routine.  Note that
     302             :  * this routine has the same return sense as strcmp (which is different
     303             :  * from prefix_same).
     304             :  */
     305             : int
     306          18 : prefix_cmp (const struct prefix *p1, const struct prefix *p2)
     307             : {
     308             :   int offset;
     309             :   int shift;
     310             : 
     311             :   /* Set both prefix's head pointer. */
     312          18 :   const u_char *pp1 = (const u_char *)&p1->u.prefix;
     313          18 :   const u_char *pp2 = (const u_char *)&p2->u.prefix;
     314             : 
     315          18 :   if (p1->family != p2->family || p1->prefixlen != p2->prefixlen)
     316           0 :     return 1;
     317             : 
     318          18 :   offset = p1->prefixlen / PNBBY;
     319          18 :   shift = p1->prefixlen % PNBBY;
     320             : 
     321          18 :   if (shift)
     322          14 :     if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
     323           0 :       return 1;
     324             : 
     325          82 :   while (offset--)
     326          46 :     if (pp1[offset] != pp2[offset])
     327           0 :       return 1;
     328             : 
     329          18 :   return 0;
     330             : }
     331             : 
     332             : /*
     333             :  * Count the number of common bits in 2 prefixes. The prefix length is
     334             :  * ignored for this function; the whole prefix is compared. If the prefix
     335             :  * address families don't match, return -1; otherwise the return value is
     336             :  * in range 0 ... maximum prefix length for the address family.
     337             :  */
     338             : int
     339           0 : prefix_common_bits (const struct prefix *p1, const struct prefix *p2)
     340             : {
     341             :   int pos, bit;
     342           0 :   int length = 0;
     343             :   u_char xor;
     344             : 
     345             :   /* Set both prefix's head pointer. */
     346           0 :   const u_char *pp1 = (const u_char *)&p1->u.prefix;
     347           0 :   const u_char *pp2 = (const u_char *)&p2->u.prefix;
     348             : 
     349           0 :   if (p1->family == AF_INET)
     350           0 :     length = IPV4_MAX_BYTELEN;
     351             : #ifdef HAVE_IPV6
     352           0 :   if (p1->family == AF_INET6)
     353           0 :     length = IPV6_MAX_BYTELEN;
     354             : #endif
     355           0 :   if (p1->family != p2->family || !length)
     356           0 :     return -1;
     357             : 
     358           0 :   for (pos = 0; pos < length; pos++)
     359           0 :     if (pp1[pos] != pp2[pos])
     360           0 :       break;
     361           0 :   if (pos == length)
     362           0 :     return pos * 8;
     363             : 
     364           0 :   xor = pp1[pos] ^ pp2[pos];
     365           0 :   for (bit = 0; bit < 8; bit++)
     366           0 :     if (xor & (1 << (7 - bit)))
     367           0 :       break;
     368             : 
     369           0 :   return pos * 8 + bit;
     370             : }
     371             : 
     372             : /* Return prefix family type string. */
     373             : const char *
     374          12 : prefix_family_str (const struct prefix *p)
     375             : {
     376          12 :   if (p->family == AF_INET)
     377           6 :     return "inet";
     378             : #ifdef HAVE_IPV6
     379           6 :   if (p->family == AF_INET6)
     380           6 :     return "inet6";
     381             : #endif /* HAVE_IPV6 */
     382           0 :   return "unspec";
     383             : }
     384             : 
     385             : /* Allocate new prefix_ipv4 structure. */
     386             : struct prefix_ipv4 *
     387         112 : prefix_ipv4_new ()
     388             : {
     389             :   struct prefix_ipv4 *p;
     390             : 
     391             :   /* Call prefix_new to allocate a full-size struct prefix to avoid problems
     392             :      where the struct prefix_ipv4 is cast to struct prefix and unallocated
     393             :      bytes were being referenced (e.g. in structure assignments). */
     394         112 :   p = (struct prefix_ipv4 *)prefix_new();
     395         112 :   p->family = AF_INET;
     396         112 :   return p;
     397             : }
     398             : 
     399             : /* Free prefix_ipv4 structure. */
     400             : void
     401           0 : prefix_ipv4_free (struct prefix_ipv4 *p)
     402             : {
     403           0 :   prefix_free((struct prefix *)p);
     404           0 : }
     405             : 
     406             : /* When string format is invalid return 0. */
     407             : int
     408          68 : str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p)
     409             : {
     410             :   int ret;
     411             :   int plen;
     412             :   char *pnt;
     413             :   char *cp;
     414             : 
     415             :   /* Find slash inside string. */
     416          68 :   pnt = strchr (str, '/');
     417             : 
     418             :   /* String doesn't contail slash. */
     419          68 :   if (pnt == NULL) 
     420             :     {
     421             :       /* Convert string to prefix. */
     422           0 :       ret = inet_aton (str, &p->prefix);
     423           0 :       if (ret == 0)
     424           0 :         return 0;
     425             : 
     426             :       /* If address doesn't contain slash we assume it host address. */
     427           0 :       p->family = AF_INET;
     428           0 :       p->prefixlen = IPV4_MAX_BITLEN;
     429             : 
     430           0 :       return ret;
     431             :     }
     432             :   else
     433             :     {
     434          68 :       cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
     435          68 :       strncpy (cp, str, pnt - str);
     436          68 :       *(cp + (pnt - str)) = '\0';
     437          68 :       ret = inet_aton (cp, &p->prefix);
     438          68 :       XFREE (MTYPE_TMP, cp);
     439             : 
     440             :       /* Get prefix length. */
     441          68 :       plen = (u_char) atoi (++pnt);
     442          68 :       if (plen > IPV4_MAX_PREFIXLEN)
     443           0 :         return 0;
     444             : 
     445          68 :       p->family = AF_INET;
     446          68 :       p->prefixlen = plen;
     447             :     }
     448             : 
     449          68 :   return ret;
     450             : }
     451             : 
     452             : /* Convert masklen into IP address's netmask (network byte order). */
     453             : void
     454         553 : masklen2ip (const int masklen, struct in_addr *netmask)
     455             : {
     456         553 :   assert (masklen >= 0 && masklen <= IPV4_MAX_BITLEN);
     457             : 
     458             :   /* left shift is only defined for less than the size of the type.
     459             :    * we unconditionally use long long in case the target platform
     460             :    * has defined behaviour for << 32 (or has a 64-bit left shift) */
     461             : 
     462             :   if (sizeof(unsigned long long) > 4)
     463         553 :     netmask->s_addr = htonl(0xffffffffULL << (32 - masklen));
     464             :   else
     465             :     netmask->s_addr = htonl(masklen ? 0xffffffffU << (32 - masklen) : 0);
     466         553 : }
     467             : 
     468             : /* Convert IP address's netmask into integer. We assume netmask is
     469             :    sequential one. Argument netmask should be network byte order. */
     470             : u_char
     471           0 : ip_masklen (struct in_addr netmask)
     472             : {
     473           0 :   uint32_t tmp = ~ntohl(netmask.s_addr);
     474           0 :   if (tmp)
     475             :     /* clz: count leading zeroes. sadly, the behaviour of this builtin
     476             :      * is undefined for a 0 argument, even though most CPUs give 32 */
     477           0 :     return __builtin_clz(tmp);
     478             :   else
     479           0 :     return 32;
     480             : }
     481             : 
     482             : /* Apply mask to IPv4 prefix (network byte order). */
     483             : void
     484         551 : apply_mask_ipv4 (struct prefix_ipv4 *p)
     485             : {
     486             :   struct in_addr mask;
     487         551 :   masklen2ip(p->prefixlen, &mask);
     488         551 :   p->prefix.s_addr &= mask.s_addr;
     489         551 : }
     490             : 
     491             : /* If prefix is 0.0.0.0/0 then return 1 else return 0. */
     492             : int
     493         115 : prefix_ipv4_any (const struct prefix_ipv4 *p)
     494             : {
     495         115 :   return (p->prefix.s_addr == 0 && p->prefixlen == 0);
     496             : }
     497             : 
     498             : #ifdef HAVE_IPV6
     499             : 
     500             : /* Allocate a new ip version 6 route */
     501             : struct prefix_ipv6 *
     502         171 : prefix_ipv6_new (void)
     503             : {
     504             :   struct prefix_ipv6 *p;
     505             : 
     506             :   /* Allocate a full-size struct prefix to avoid problems with structure
     507             :      size mismatches. */
     508         171 :   p = (struct prefix_ipv6 *)prefix_new();
     509         171 :   p->family = AF_INET6;
     510         171 :   return p;
     511             : }
     512             : 
     513             : /* Free prefix for IPv6. */
     514             : void
     515           0 : prefix_ipv6_free (struct prefix_ipv6 *p)
     516             : {
     517           0 :   prefix_free((struct prefix *)p);
     518           0 : }
     519             : 
     520             : /* If given string is valid return pin6 else return NULL */
     521             : int
     522           1 : str2prefix_ipv6 (const char *str, struct prefix_ipv6 *p)
     523             : {
     524             :   char *pnt;
     525             :   char *cp;
     526             :   int ret;
     527             : 
     528           1 :   pnt = strchr (str, '/');
     529             : 
     530             :   /* If string doesn't contain `/' treat it as host route. */
     531           1 :   if (pnt == NULL) 
     532             :     {
     533           0 :       ret = inet_pton (AF_INET6, str, &p->prefix);
     534           0 :       if (ret == 0)
     535           0 :         return 0;
     536           0 :       p->prefixlen = IPV6_MAX_BITLEN;
     537             :     }
     538             :   else 
     539             :     {
     540             :       int plen;
     541             : 
     542           1 :       cp = XMALLOC (0, (pnt - str) + 1);
     543           1 :       strncpy (cp, str, pnt - str);
     544           1 :       *(cp + (pnt - str)) = '\0';
     545           1 :       ret = inet_pton (AF_INET6, cp, &p->prefix);
     546           1 :       free (cp);
     547           1 :       if (ret == 0)
     548           0 :         return 0;
     549           1 :       plen = (u_char) atoi (++pnt);
     550           1 :       if (plen > IPV6_MAX_BITLEN)
     551           0 :         return 0;
     552           1 :       p->prefixlen = plen;
     553             :     }
     554           1 :   p->family = AF_INET6;
     555             : 
     556           1 :   return ret;
     557             : }
     558             : 
     559             : /* Convert struct in6_addr netmask into integer.
     560             :  * FIXME return u_char as ip_maskleni() does. */
     561             : int
     562           0 : ip6_masklen (struct in6_addr netmask)
     563             : {
     564           0 :   int len = 0;
     565             :   unsigned char val;
     566             :   unsigned char *pnt;
     567             :   
     568           0 :   pnt = (unsigned char *) & netmask;
     569             : 
     570           0 :   while ((*pnt == 0xff) && len < IPV6_MAX_BITLEN)
     571             :     {
     572           0 :       len += 8;
     573           0 :       pnt++;
     574             :     } 
     575             :   
     576           0 :   if (len < IPV6_MAX_BITLEN)
     577             :     {
     578           0 :       val = *pnt;
     579           0 :       while (val) 
     580             :         {
     581           0 :           len++;
     582           0 :           val <<= 1;
     583             :         }
     584             :     }
     585           0 :   return len;
     586             : }
     587             : 
     588             : void
     589           0 : masklen2ip6 (const int masklen, struct in6_addr *netmask)
     590             : {
     591           0 :   assert (masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
     592           0 :   memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr));
     593           0 : }
     594             : 
     595             : void
     596        1799 : apply_mask_ipv6 (struct prefix_ipv6 *p)
     597             : {
     598             :   u_char *pnt;
     599             :   int index;
     600             :   int offset;
     601             : 
     602        1799 :   index = p->prefixlen / 8;
     603             : 
     604        1799 :   if (index < 16)
     605             :     {
     606        1695 :       pnt = (u_char *) &p->prefix;
     607        1695 :       offset = p->prefixlen % 8;
     608             : 
     609        1695 :       pnt[index] &= maskbit[offset];
     610        1695 :       index++;
     611             : 
     612       17343 :       while (index < 16)
     613       13953 :         pnt[index++] = 0;
     614             :     }
     615        1799 : }
     616             : 
     617             : void
     618           0 : str2in6_addr (const char *str, struct in6_addr *addr)
     619             : {
     620             :   int i;
     621             :   unsigned int x;
     622             : 
     623             :   /* %x must point to unsinged int */
     624           0 :   for (i = 0; i < 16; i++)
     625             :     {
     626           0 :       sscanf (str + (i * 2), "%02x", &x);
     627           0 :       addr->s6_addr[i] = x & 0xff;
     628             :     }
     629           0 : }
     630             : #endif /* HAVE_IPV6 */
     631             : 
     632             : void
     633        1327 : apply_mask (struct prefix *p)
     634             : {
     635        1327 :   switch (p->family)
     636             :     {
     637             :       case AF_INET:
     638         113 :         apply_mask_ipv4 ((struct prefix_ipv4 *)p);
     639         113 :         break;
     640             : #ifdef HAVE_IPV6
     641             :       case AF_INET6:
     642        1214 :         apply_mask_ipv6 ((struct prefix_ipv6 *)p);
     643        1214 :         break;
     644             : #endif /* HAVE_IPV6 */
     645             :       default:
     646           0 :         break;
     647             :     }
     648        1327 :   return;
     649             : }
     650             : 
     651             : /* Utility function of convert between struct prefix <=> union sockunion.
     652             :  * FIXME This function isn't used anywhere. */
     653             : struct prefix *
     654           0 : sockunion2prefix (const union sockunion *dest,
     655             :                   const union sockunion *mask)
     656             : {
     657           0 :   if (dest->sa.sa_family == AF_INET)
     658             :     {
     659             :       struct prefix_ipv4 *p;
     660             : 
     661           0 :       p = prefix_ipv4_new ();
     662           0 :       p->family = AF_INET;
     663           0 :       p->prefix = dest->sin.sin_addr;
     664           0 :       p->prefixlen = ip_masklen (mask->sin.sin_addr);
     665           0 :       return (struct prefix *) p;
     666             :     }
     667             : #ifdef HAVE_IPV6
     668           0 :   if (dest->sa.sa_family == AF_INET6)
     669             :     {
     670             :       struct prefix_ipv6 *p;
     671             : 
     672           0 :       p = prefix_ipv6_new ();
     673           0 :       p->family = AF_INET6;
     674           0 :       p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
     675           0 :       memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
     676           0 :       return (struct prefix *) p;
     677             :     }
     678             : #endif /* HAVE_IPV6 */
     679           0 :   return NULL;
     680             : }
     681             : 
     682             : /* Utility function of convert between struct prefix <=> union sockunion. */
     683             : struct prefix *
     684           0 : sockunion2hostprefix (const union sockunion *su)
     685             : {
     686           0 :   if (su->sa.sa_family == AF_INET)
     687             :     {
     688             :       struct prefix_ipv4 *p;
     689             : 
     690           0 :       p = prefix_ipv4_new ();
     691           0 :       p->family = AF_INET;
     692           0 :       p->prefix = su->sin.sin_addr;
     693           0 :       p->prefixlen = IPV4_MAX_BITLEN;
     694           0 :       return (struct prefix *) p;
     695             :     }
     696             : #ifdef HAVE_IPV6
     697           0 :   if (su->sa.sa_family == AF_INET6)
     698             :     {
     699             :       struct prefix_ipv6 *p;
     700             : 
     701           0 :       p = prefix_ipv6_new ();
     702           0 :       p->family = AF_INET6;
     703           0 :       p->prefixlen = IPV6_MAX_BITLEN;
     704           0 :       memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
     705           0 :       return (struct prefix *) p;
     706             :     }
     707             : #endif /* HAVE_IPV6 */
     708           0 :   return NULL;
     709             : }
     710             : 
     711             : void
     712           0 : prefix2sockunion (const struct prefix *p, union sockunion *su)
     713             : {
     714           0 :   memset (su, 0, sizeof (*su));
     715             : 
     716           0 :   su->sa.sa_family = p->family;
     717           0 :   if (p->family == AF_INET)
     718           0 :     su->sin.sin_addr = p->u.prefix4;
     719             : #ifdef HAVE_IPV6
     720           0 :   if (p->family == AF_INET6)
     721           0 :     memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
     722             : #endif /* HAVE_IPV6 */
     723           0 : }
     724             : 
     725             : int
     726           0 : prefix_blen (const struct prefix *p)
     727             : {
     728           0 :   switch (p->family) 
     729             :     {
     730             :     case AF_INET:
     731           0 :       return IPV4_MAX_BYTELEN;
     732             :       break;
     733             : #ifdef HAVE_IPV6
     734             :     case AF_INET6:
     735           0 :       return IPV6_MAX_BYTELEN;
     736             :       break;
     737             : #endif /* HAVE_IPV6 */
     738             :     }
     739           0 :   return 0;
     740             : }
     741             : 
     742             : /* Generic function for conversion string to struct prefix. */
     743             : int
     744           5 : str2prefix (const char *str, struct prefix *p)
     745             : {
     746             :   int ret;
     747             : 
     748             :   /* First we try to convert string to struct prefix_ipv4. */
     749           5 :   ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
     750           5 :   if (ret)
     751           5 :     return ret;
     752             : 
     753             : #ifdef HAVE_IPV6
     754             :   /* Next we try to convert string to struct prefix_ipv6. */
     755           0 :   ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
     756           0 :   if (ret)
     757           0 :     return ret;
     758             : #endif /* HAVE_IPV6 */
     759             : 
     760           0 :   return 0;
     761             : }
     762             : 
     763             : int
     764          43 : prefix2str (const struct prefix *p, char *str, int size)
     765             : {
     766             :   char buf[BUFSIZ];
     767             : 
     768          43 :   inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
     769          43 :   snprintf (str, size, "%s/%d", buf, p->prefixlen);
     770          43 :   return 0;
     771             : }
     772             : 
     773             : struct prefix *
     774         283 : prefix_new ()
     775             : {
     776             :   struct prefix *p;
     777             : 
     778         283 :   p = XCALLOC (MTYPE_PREFIX, sizeof *p);
     779         283 :   return p;
     780             : }
     781             : 
     782             : /* Free prefix structure. */
     783             : void
     784          10 : prefix_free (struct prefix *p)
     785             : {
     786          10 :   XFREE (MTYPE_PREFIX, p);
     787          10 : }
     788             : 
     789             : /* Utility function.  Check the string only contains digit
     790             :  * character.
     791             :  * FIXME str.[c|h] would be better place for this function. */
     792             : int
     793           0 : all_digit (const char *str)
     794             : {
     795           0 :   for (; *str != '\0'; str++)
     796           0 :     if (!isdigit ((int) *str))
     797           0 :       return 0;
     798           0 :   return 1;
     799             : }
     800             : 
     801             : /* Utility function to convert ipv4 prefixes to Classful prefixes */
     802           0 : void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
     803             : {
     804             : 
     805             :   u_int32_t destination;
     806             :   
     807           0 :   destination = ntohl (p->prefix.s_addr);
     808             :   
     809           0 :   if (p->prefixlen == IPV4_MAX_PREFIXLEN);
     810             :   /* do nothing for host routes */
     811           0 :   else if (IN_CLASSC (destination)) 
     812             :     {
     813           0 :       p->prefixlen=24;
     814           0 :       apply_mask_ipv4(p);
     815             :     }
     816           0 :   else if (IN_CLASSB(destination)) 
     817             :     {
     818           0 :       p->prefixlen=16;
     819           0 :       apply_mask_ipv4(p);
     820             :     }
     821             :   else 
     822             :     {
     823           0 :       p->prefixlen=8;
     824           0 :       apply_mask_ipv4(p);
     825             :     }
     826           0 : }
     827             : 
     828             : in_addr_t
     829           0 : ipv4_network_addr (in_addr_t hostaddr, int masklen)
     830             : {
     831             :   struct in_addr mask;
     832             : 
     833           0 :   masklen2ip (masklen, &mask);
     834           0 :   return hostaddr & mask.s_addr;
     835             : }
     836             : 
     837             : in_addr_t
     838           2 : ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
     839             : {
     840             :   struct in_addr mask;
     841             : 
     842           2 :   masklen2ip (masklen, &mask);
     843           2 :   return (masklen != IPV4_MAX_PREFIXLEN-1) ?
     844             :          /* normal case */
     845           2 :          (hostaddr | ~mask.s_addr) :
     846             :          /* special case for /31 */
     847           0 :          (hostaddr ^ ~mask.s_addr);
     848             : }
     849             : 
     850             : /* Utility function to convert ipv4 netmask to prefixes 
     851             :    ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
     852             :    ex.) "1.0.0.0" NULL => "1.0.0.0/8"                   */
     853             : int
     854           0 : netmask_str2prefix_str (const char *net_str, const char *mask_str,
     855             :                         char *prefix_str)
     856             : {
     857             :   struct in_addr network;
     858             :   struct in_addr mask;
     859             :   u_char prefixlen;
     860             :   u_int32_t destination;
     861             :   int ret;
     862             : 
     863           0 :   ret = inet_aton (net_str, &network);
     864           0 :   if (! ret)
     865           0 :     return 0;
     866             : 
     867           0 :   if (mask_str)
     868             :     {
     869           0 :       ret = inet_aton (mask_str, &mask);
     870           0 :       if (! ret)
     871           0 :         return 0;
     872             : 
     873           0 :       prefixlen = ip_masklen (mask);
     874             :     }
     875             :   else 
     876             :     {
     877           0 :       destination = ntohl (network.s_addr);
     878             : 
     879           0 :       if (network.s_addr == 0)
     880           0 :         prefixlen = 0;
     881           0 :       else if (IN_CLASSC (destination))
     882           0 :         prefixlen = 24;
     883           0 :       else if (IN_CLASSB (destination))
     884           0 :         prefixlen = 16;
     885           0 :       else if (IN_CLASSA (destination))
     886           0 :         prefixlen = 8;
     887             :       else
     888           0 :         return 0;
     889             :     }
     890             : 
     891           0 :   sprintf (prefix_str, "%s/%d", net_str, prefixlen);
     892             : 
     893           0 :   return 1;
     894             : }
     895             : 
     896             : #ifdef HAVE_IPV6
     897             : /* Utility function for making IPv6 address string. */
     898             : const char *
     899         100 : inet6_ntoa (struct in6_addr addr)
     900             : {
     901             :   static char buf[INET6_ADDRSTRLEN];
     902             : 
     903         100 :   inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
     904         100 :   return buf;
     905             : }
     906             : #endif /* HAVE_IPV6 */

Generated by: LCOV version 1.10