File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / lib / prefix.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:11 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>