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

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

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