Annotation of embedaddon/quagga/lib/prefix.c, revision 1.1.1.3

1.1       misho       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"
1.1.1.3 ! misho      30: 
1.1       misho      31: /* Maskbit. */
                     32: static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
                     33:                                 0xf8, 0xfc, 0xfe, 0xff};
                     34: 
1.1.1.2   misho      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: 
1.1       misho     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: 
1.1.1.2   misho     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: }
1.1.1.3 ! misho     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: 
1.1       misho     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: 
1.1.1.3 ! misho     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: 
1.1       misho     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)
1.1.1.2   misho     311:        if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr))
1.1       misho     312:          return 1;
                    313: #ifdef HAVE_IPV6
                    314:       if (p1->family == AF_INET6 )
1.1.1.2   misho     315:        if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr))
1.1       misho     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: 
1.1.1.2   misho     345:   offset = p1->prefixlen / PNBBY;
                    346:   shift = p1->prefixlen % PNBBY;
1.1       misho     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: 
1.1.1.2   misho     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: 
1.1       misho     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: 
1.1.1.2   misho     479: /* Convert masklen into IP address's netmask (network byte order). */
1.1       misho     480: void
1.1.1.2   misho     481: masklen2ip (const int masklen, struct in_addr *netmask)
1.1       misho     482: {
1.1.1.2   misho     483:   assert (masklen >= 0 && masklen <= IPV4_MAX_BITLEN);
1.1       misho     484: 
1.1.1.2   misho     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) */
1.1       misho     488: 
1.1.1.2   misho     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);
1.1       misho     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: {
1.1.1.2   misho     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;
1.1       misho     507: }
                    508: 
1.1.1.2   misho     509: /* Apply mask to IPv4 prefix (network byte order). */
1.1       misho     510: void
                    511: apply_mask_ipv4 (struct prefix_ipv4 *p)
                    512: {
1.1.1.2   misho     513:   struct in_addr mask;
                    514:   masklen2ip(p->prefixlen, &mask);
                    515:   p->prefix.s_addr &= mask.s_addr;
1.1       misho     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: }
1.1.1.3 ! misho     524: 
1.1       misho     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);
1.1.1.2   misho     577:       if (plen > IPV6_MAX_BITLEN)
1.1       misho     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: 
1.1.1.2   misho     597:   while ((*pnt == 0xff) && len < IPV6_MAX_BITLEN)
1.1       misho     598:     {
                    599:       len += 8;
                    600:       pnt++;
                    601:     } 
                    602:   
1.1.1.2   misho     603:   if (len < IPV6_MAX_BITLEN)
1.1       misho     604:     {
                    605:       val = *pnt;
                    606:       while (val) 
                    607:        {
                    608:          len++;
                    609:          val <<= 1;
                    610:        }
                    611:     }
                    612:   return len;
                    613: }
                    614: 
                    615: void
1.1.1.2   misho     616: masklen2ip6 (const int masklen, struct in6_addr *netmask)
1.1       misho     617: {
1.1.1.2   misho     618:   assert (masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
                    619:   memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr));
1.1       misho     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 *
1.1.1.3 ! misho     711: sockunion2hostprefix (const union sockunion *su, struct prefix *prefix)
1.1       misho     712: {
                    713:   if (su->sa.sa_family == AF_INET)
                    714:     {
                    715:       struct prefix_ipv4 *p;
                    716: 
1.1.1.3 ! misho     717:       p = prefix ? (struct prefix_ipv4 *) prefix : prefix_ipv4_new ();
1.1       misho     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: 
1.1.1.3 ! misho     728:       p = prefix ? (struct prefix_ipv6 *) prefix : prefix_ipv6_new ();
1.1       misho     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: 
1.1.1.2   misho     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: 
1.1       misho     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: 
1.1.1.3 ! misho     790: const char *
        !           791: prefix2str (union prefix46constptr pu, char *str, int size)
1.1       misho     792: {
1.1.1.3 ! misho     793:   const struct prefix *p = pu.p;
1.1       misho     794:   char buf[BUFSIZ];
                    795: 
                    796:   inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
                    797:   snprintf (str, size, "%s/%d", buf, p->prefixlen);
1.1.1.3 ! misho     798:   return str;
1.1       misho     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>