File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / pimdd / pimdd.h
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jun 12 07:58:55 2017 UTC (6 years, 11 months ago) by misho
Branches: pimdd, MAIN
CVS tags: v0_2_1p0, v0_2_1, HEAD
pimdd-dense 0.2.1.0_2

    1: /*
    2:  *  Copyright (c) 1998 by the University of Oregon.
    3:  *  All rights reserved.
    4:  *
    5:  *  Permission to use, copy, modify, and distribute this software and
    6:  *  its documentation in source and binary forms for lawful
    7:  *  purposes and without fee is hereby granted, provided
    8:  *  that the above copyright notice appear in all copies and that both
    9:  *  the copyright notice and this permission notice appear in supporting
   10:  *  documentation, and that any documentation, advertising materials,
   11:  *  and other materials related to such distribution and use acknowledge
   12:  *  that the software was developed by the University of Oregon.
   13:  *  The name of the University of Oregon may not be used to endorse or 
   14:  *  promote products derived from this software without specific prior 
   15:  *  written permission.
   16:  *
   17:  *  THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS
   18:  *  ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  THIS SOFTWARE IS
   19:  *  PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
   20:  *  INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
   21:  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND 
   22:  *  NON-INFRINGEMENT.
   23:  *
   24:  *  IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
   25:  *  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
   26:  *  TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
   27:  *  THE USE OR PERFORMANCE OF THIS SOFTWARE.
   28:  *
   29:  *  Other copyrights might apply to parts of this software and are so
   30:  *  noted when applicable.
   31:  */
   32: /*
   33:  *  Questions concerning this software should be directed to 
   34:  *  Kurt Windisch (kurtw@antc.uoregon.edu)
   35:  *
   36:  *  $Id: pimdd.h,v 1.1.1.1 2017/06/12 07:58:55 misho Exp $
   37:  */
   38: /*
   39:  * Part of this program has been derived from PIM sparse-mode pimd.
   40:  * The pimd program is covered by the license in the accompanying file
   41:  * named "LICENSE.pimd".
   42:  *  
   43:  * The pimd program is COPYRIGHT 1998 by University of Southern California.
   44:  *
   45:  * Part of this program has been derived from mrouted.
   46:  * The mrouted program is covered by the license in the accompanying file
   47:  * named "LICENSE.mrouted".
   48:  * 
   49:  * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
   50:  * Leland Stanford Junior University.
   51:  *
   52:  */
   53: 
   54: #include <netinet/pim.h>
   55: 
   56: #define PIM_PROTOCOL_VERSION	2
   57: #define PIMD_VERSION		PIM_PROTOCOL_VERSION
   58: #define PIMD_SUBVERSION         1
   59: #if 0
   60: #define PIM_CONSTANT            0x000eff00      /* constant portion of 'group' field */
   61: #endif
   62: #define PIM_CONSTANT            0
   63: #define PIMD_LEVEL (PIM_CONSTANT | PIMD_VERSION | (PIMD_SUBVERSION << 8))
   64: 
   65: #define INADDR_ALL_PIM_ROUTERS  (u_int32)0xe000000D	     /* 224.0.0.13 */
   66: 
   67: 
   68: /* PIM protocol timers (in seconds) */
   69: #ifndef TIMER_INTERVAL
   70: #define TIMER_INTERVAL		          5 /* virtual timer granularity */
   71: #endif /* TIMER_INTERVAL */
   72: 
   73: #define PIM_DATA_TIMEOUT                210
   74: #define PIM_TIMER_HELLO_PERIOD 	         30
   75: #define PIM_JOIN_PRUNE_HOLDTIME         210
   76: #define PIM_RANDOM_DELAY_JOIN_TIMEOUT     3
   77: #define PIM_GRAFT_RETRANS_PERIOD          3
   78: #define PIM_TIMER_HELLO_HOLDTIME       (3.5 * PIM_TIMER_HELLO_PERIOD)
   79: #define PIM_ASSERT_TIMEOUT              210
   80: 
   81: 
   82: /* Misc definitions */
   83: #define SINGLE_SRC_MSKLEN	         32 /* the single source mask length */
   84: #define SINGLE_GRP_MSKLEN	         32 /* the single group mask length  */
   85: /* TODO: change? */
   86: #define PIM_GROUP_PREFIX_DEFAULT_MASKLEN 16 /* The default group masklen if
   87: 					     * omitted in the config file.
   88: 					     */
   89: 
   90: #define UCAST_ROUTING_CHECK_INTERVAL       20 /* Unfortunately, if the unicast
   91: 					       * routing changes, the kernel
   92: 					       * or any of the existing
   93: 					       * unicast routing daemons
   94: 					       * don't send us a signal.
   95: 					       * Have to ask periodically the
   96: 					       * kernel for any route changes.
   97: 					       * Default: every 20 seconds.
   98: 					       * Sigh.
   99: 					       */
  100: 
  101: 
  102: #define DEFAULT_PHY_RATE_LIMIT  0             /* default phyint rate limit  */
  103: 
  104: #define DEFAULT_LOCAL_PREF      101           /* Default assert preference */
  105: #define DEFAULT_LOCAL_METRIC    1024          /* Default assert metric */
  106: 
  107: /**************************************************************************
  108:  * PIM Encoded-Unicast, Encoded-Group and Encoded-Source Address formats  *
  109:  *************************************************************************/
  110: /* Address families definition */
  111: #define ADDRF_RESERVED  0
  112: #define ADDRF_IPv4      1
  113: #define ADDRF_IPv6      2
  114: #define ADDRF_NSAP      3
  115: #define ADDRF_HDLC      4
  116: #define ADDRF_BBN1822   5
  117: #define ADDRF_802       6
  118: #define ADDRF_ETHERNET  ADDRF_802
  119: #define ADDRF_E163      7
  120: #define ADDRF_E164      8
  121: #define ADDRF_SMDS      ADDRF_E164
  122: #define ADDRF_ATM       ADDRF_E164
  123: #define ADDRF_F69       9
  124: #define ADDRF_TELEX     ADDRF_F69
  125: #define ADDRF_X121      10
  126: #define ADDRF_X25       ADDRF_X121
  127: #define ADDRF_IPX       11
  128: #define ADDRF_APPLETALK 12
  129: #define ADDRF_DECNET_IV 13
  130: #define ADDRF_BANYAN    14
  131: #define ADDRF_E164_NSAP 15
  132: 
  133: /* Addresses Encoding Type (specific for each Address Family */
  134: #define ADDRT_IPv4      0
  135: 
  136: 
  137: /* Encoded-Unicast: 6 bytes long */
  138: typedef struct pim_encod_uni_addr_ {
  139:     u_int8      addr_family;
  140:     u_int8      encod_type;
  141:     u_int32     unicast_addr;        /* XXX: Note the 32-bit boundary
  142: 				      * misalignment for  the unicast
  143: 				      * address when placed in the
  144: 				      * memory. Must read it byte-by-byte!
  145: 				      */
  146: } pim_encod_uni_addr_t;
  147: 
  148: /* Encoded-Group */
  149: typedef struct pim_encod_grp_addr_ {
  150:     u_int8      addr_family;
  151:     u_int8      encod_type;
  152:     u_int8      reserved;
  153:     u_int8      masklen;
  154:     u_int32     mcast_addr;
  155: } pim_encod_grp_addr_t;
  156: 
  157: /* Encoded-Source */
  158: typedef struct pim_encod_src_addr_ {
  159:     u_int8      addr_family;
  160:     u_int8      encod_type;
  161:     u_int8      flags;
  162:     u_int8      masklen;
  163:     u_int32     src_addr;
  164: } pim_encod_src_addr_t;
  165: #define USADDR_RP_BIT 0x1
  166: #define USADDR_WC_BIT 0x2
  167: #define USADDR_S_BIT  0x4
  168: 
  169: /**************************************************************************
  170:  *                       PIM Messages formats                             *
  171:  *************************************************************************/
  172: /* TODO: XXX: some structures are probably not used at all */
  173: 
  174: typedef struct pim pim_header_t;
  175: 
  176: /* PIM Hello */
  177: typedef struct pim_hello_ {
  178:     u_int16     option_type;   /* Option type */
  179:     u_int16     option_length; /* Length of the Option Value field in bytes */
  180: } pim_hello_t;
  181: 
  182: /* PIM Join/Prune: XXX: all 32-bit addresses misaligned! */
  183: typedef struct pim_jp_header_ {
  184:     pim_encod_uni_addr_t encod_upstream_nbr;
  185:     u_int8     reserved;
  186:     u_int8     num_groups;
  187:     u_int16    holdtime;
  188: } pim_jp_header_t;
  189: 
  190: typedef struct pim_jp_encod_grp_ {
  191:     pim_encod_grp_addr_t   encod_grp;
  192:     u_int16                number_join_src;
  193:     u_int16                number_prune_src;
  194: } pim_jp_encod_grp_t;
  195: 
  196: #define PIM_ACTION_NOTHING 0
  197: #define PIM_ACTION_JOIN    1
  198: #define PIM_ACTION_PRUNE   2
  199: 
  200: #define PIM_IIF_SOURCE     1
  201: #define PIM_IIF_RP         2
  202: 
  203: #define PIM_ASSERT_RPT_BIT 0x80000000
  204: 
  205: 
  206: /* PIM messages type */
  207: #define PIM_HELLO               0
  208: #ifndef PIM_REGISTER
  209: #define PIM_REGISTER            1
  210: #endif
  211: #define PIM_REGISTER_STOP       2
  212: #define PIM_JOIN_PRUNE          3
  213: #define PIM_BOOTSTRAP		4
  214: #define PIM_ASSERT              5
  215: #define PIM_GRAFT               6
  216: #define PIM_GRAFT_ACK           7
  217: #define PIM_CAND_RP_ADV         8
  218: 
  219: #define PIM_V2_HELLO            PIM_HELLO
  220: #define PIM_V2_REGISTER         PIM_REGISTER
  221: #define PIM_V2_REGISTER_STOP    PIM_REGISTER_STOP
  222: #define PIM_V2_JOIN_PRUNE       PIM_JOIN_PRUNE
  223: #define PIM_V2_BOOTSTRAP	PIM_BOOTSTRAP
  224: #define PIM_V2_ASSERT           PIM_ASSERT
  225: #define PIM_V2_GRAFT            PIM_GRAFT
  226: #define PIM_V2_GRAFT_ACK        PIM_GRAFT_ACK
  227: #define PIM_V2_CAND_RP_ADV      PIM_CAND_RP_ADV
  228: 
  229: #define PIM_V1_QUERY            0
  230: #define PIM_V1_REGISTER         1
  231: #define PIM_V1_REGISTER_STOP    2
  232: #define PIM_V1_JOIN_PRUNE       3
  233: #define PIM_V1_RP_REACHABILITY  4
  234: #define PIM_V1_ASSERT           5
  235: #define PIM_V1_GRAFT            6
  236: #define PIM_V1_GRAFT_ACK        7
  237: 
  238: /* Vartious options from PIM messages definitions */
  239: /* PIM_HELLO definitions */
  240: #define PIM_MESSAGE_HELLO_HOLDTIME              1
  241: #define PIM_MESSAGE_HELLO_HOLDTIME_LENGTH       2
  242: #define PIM_MESSAGE_HELLO_HOLDTIME_FOREVER      0xffff
  243: 
  244: 
  245: #define MASK_TO_MASKLEN(mask, masklen)                           \
  246:     do {                                                         \
  247:         register u_int32 tmp_mask = ntohl((mask));               \
  248:         register u_int8  tmp_masklen = sizeof((mask)) << 3;      \
  249:         for ( ; tmp_masklen > 0; tmp_masklen--, tmp_mask >>= 1)  \
  250:             if (tmp_mask & 0x1)                                  \
  251:                 break;                                           \
  252:         (masklen) = tmp_masklen;                                 \
  253:     } while (0)
  254: 
  255: #define MASKLEN_TO_MASK(masklen, mask)                                       \
  256: do {                                                                         \
  257:     (mask) = (masklen)? htonl(~0 << ((sizeof((mask)) << 3) - (masklen))) : 0;\
  258: } while (0)
  259: 
  260: 
  261: /*
  262:  * A bunch of macros because of the lack of 32-bit boundary alignment.
  263:  * All because of one misalligned address format. Hopefully this will be
  264:  * fixed in PIMv3. (cp) must be (u_int8 *) .
  265:  */
  266: /* Originates from Eddy Rusty's (eddy@isi.edu) PIM-SM implementation for
  267:  * gated.
  268:  */
  269: 
  270: /* PUT_NETLONG puts "network ordered" data to the datastream.
  271:  * PUT_HOSTLONG puts "host ordered" data to the datastream.
  272:  * GET_NETLONG gets the data and keeps it in "network order" in the memory
  273:  * GET_HOSTLONG gets the data, but in the memory it is in "host order"
  274:  * The same for all {PUT,GET}_{NET,HOST}{SHORT,LONG}
  275:  */
  276: #define GET_BYTE(val, cp)       ((val) = *(cp)++)
  277: #define PUT_BYTE(val, cp)       (*(cp)++ = (u_int8)(val))
  278: 
  279: #define GET_HOSTSHORT(val, cp)                  \
  280:         do {                                    \
  281:                 register u_int16 Xv;            \
  282:                 Xv = (*(cp)++) << 8;            \
  283:                 Xv |= *(cp)++;                  \
  284:                 (val) = Xv;                     \
  285:         } while (0)
  286: 
  287: #define PUT_HOSTSHORT(val, cp)                  \
  288:         do {                                    \
  289:                 register u_int16 Xv;            \
  290:                 Xv = (u_int16)(val);            \
  291:                 *(cp)++ = (u_int8)(Xv >> 8);    \
  292:                 *(cp)++ = (u_int8)Xv;           \
  293:         } while (0)
  294: 
  295: #if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
  296: #define GET_NETSHORT(val, cp)                   \
  297:         do {                                    \
  298:                 register u_int16 Xv;            \
  299:                 Xv = *(cp)++;                   \
  300:                 Xv |= (*(cp)++) << 8;           \
  301:                 (val) = Xv;                     \
  302:         } while (0)
  303: #define PUT_NETSHORT(val, cp)                   \
  304:         do {                                    \
  305:                 register u_int16 Xv;            \
  306:                 Xv = (u_int16)(val);            \
  307:                 *(cp)++ = (u_int8)Xv;           \
  308:                 *(cp)++ = (u_int8)(Xv >> 8);    \
  309:         } while (0)
  310: #else
  311: #define GET_NETSHORT(val, cp) GET_HOSTSHORT(val, cp)
  312: #define PUT_NETSHORT(val, cp) PUT_HOSTSHORT(val, cp)
  313: #endif /* {GET,PUT}_NETSHORT */
  314: 
  315: #define GET_HOSTLONG(val, cp)                   \
  316:         do {                                    \
  317:                 register u_long Xv;             \
  318:                 Xv  = (*(cp)++) << 24;          \
  319:                 Xv |= (*(cp)++) << 16;          \
  320:                 Xv |= (*(cp)++) <<  8;          \
  321:                 Xv |= *(cp)++;                  \
  322:                 (val) = Xv;                     \
  323:         } while (0)
  324: 
  325: #define PUT_HOSTLONG(val, cp)                   \
  326:         do {                                    \
  327:                 register u_int32 Xv;            \
  328:                 Xv = (u_int32)(val);            \
  329:                 *(cp)++ = (u_int8)(Xv >> 24);   \
  330:                 *(cp)++ = (u_int8)(Xv >> 16);   \
  331:                 *(cp)++ = (u_int8)(Xv >>  8);   \
  332:                 *(cp)++ = (u_int8)Xv;           \
  333:         } while (0)
  334: 
  335: #if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
  336: #define GET_NETLONG(val, cp)                    \
  337:         do {                                    \
  338:                 register u_long Xv;             \
  339:                 Xv  = *(cp)++;                  \
  340:                 Xv |= (*(cp)++) <<  8;          \
  341:                 Xv |= (*(cp)++) << 16;          \
  342:                 Xv |= (*(cp)++) << 24;          \
  343:                 (val) = Xv;                     \
  344:         } while (0)
  345: 
  346: #define PUT_NETLONG(val, cp)                    \
  347:         do {                                    \
  348:                 register u_int32 Xv;            \
  349:                 Xv = (u_int32)(val);            \
  350:                 *(cp)++ = (u_int8)Xv;           \
  351:                 *(cp)++ = (u_int8)(Xv >>  8);   \
  352:                 *(cp)++ = (u_int8)(Xv >> 16);   \
  353:                 *(cp)++ = (u_int8)(Xv >> 24);   \
  354:         } while (0)
  355: #else
  356: #define GET_NETLONG(val, cp) GET_HOSTLONG(val, cp)
  357: #define PUT_NETLONG(val, cp) PUT_HOSTLONG(val, cp)
  358: #endif /* {GET,PUT}_HOSTLONG */
  359: 
  360: 
  361: #define GET_ESADDR(esa, cp)                     \
  362:         do {                                    \
  363:             (esa)->addr_family = *(cp)++;       \
  364:             (esa)->encod_type  = *(cp)++;       \
  365:             (esa)->flags       = *(cp)++;       \
  366:             (esa)->masklen     = *(cp)++;       \
  367:             GET_NETLONG((esa)->src_addr, (cp)); \
  368:         } while(0)
  369: 
  370: #define PUT_ESADDR(addr, masklen, flags, cp)    \
  371:         do {                                    \
  372:             u_int32 mask;                       \
  373:             MASKLEN_TO_MASK((masklen), mask);   \
  374:             *(cp)++ = ADDRF_IPv4; /* family */  \
  375:             *(cp)++ = ADDRT_IPv4; /* type   */  \
  376:             *(cp)++ = (flags);    /* flags  */  \
  377:             *(cp)++ = (masklen);                \
  378:             PUT_NETLONG((addr) & mask, (cp));   \
  379:         } while(0)
  380: 
  381: #define GET_EGADDR(ega, cp)                     \
  382:         do {                                    \
  383:             (ega)->addr_family = *(cp)++;       \
  384:             (ega)->encod_type  = *(cp)++;       \
  385:             (ega)->reserved    = *(cp)++;       \
  386:             (ega)->masklen     = *(cp)++;       \
  387:             GET_NETLONG((ega)->mcast_addr, (cp)); \
  388:         } while(0)
  389: 
  390: #define PUT_EGADDR(addr, masklen, reserved, cp) \
  391:         do {                                    \
  392:             u_int32 mask;                       \
  393:             MASKLEN_TO_MASK((masklen), mask);   \
  394:             *(cp)++ = ADDRF_IPv4; /* family */  \
  395:             *(cp)++ = ADDRT_IPv4; /* type   */  \
  396:             *(cp)++ = (reserved); /* reserved; should be 0 */  \
  397:             *(cp)++ = (masklen);                \
  398:             PUT_NETLONG((addr) & mask, (cp)); \
  399:         } while(0)
  400: 
  401: #define GET_EUADDR(eua, cp)                     \
  402:         do {                                    \
  403:             (eua)->addr_family = *(cp)++;       \
  404:             (eua)->encod_type  = *(cp)++;       \
  405:             GET_NETLONG((eua)->unicast_addr, (cp)); \
  406:         } while(0)
  407: 
  408: #define PUT_EUADDR(addr, cp)                    \
  409:         do {                                    \
  410:             *(cp)++ = ADDRF_IPv4; /* family */  \
  411:             *(cp)++ = ADDRT_IPv4; /* type   */  \
  412:             PUT_NETLONG((addr), (cp));          \
  413:         } while(0)
  414: 
  415: 
  416: /* TODO: Currently not used. Probably not need at all. Delete! */
  417: #ifdef NOSUCHDEF
  418: /* This is completely IGMP related stuff? */
  419: #define PIM_LEAF_TIMEOUT               (3.5 * IGMP_QUERY_INTERVAL)
  420: #endif /* NOSUCHDEF */
  421: 
  422: #if (defined(BSDI) || defined(NetBSD) || defined(IRIX))
  423: /*
  424:  * Struct used to communicate from kernel to multicast router
  425:  * note the convenient similarity to an IP packet
  426:  */ 
  427: struct igmpmsg {
  428:     u_long          unused1;
  429:     u_long          unused2;
  430:     u_char          im_msgtype;                 /* what type of message     */
  431: #define IGMPMSG_NOCACHE         1
  432: #define IGMPMSG_WRONGVIF        2
  433: #define IGMPMSG_WHOLEPKT        3               /* used for user level encap*/
  434:     u_char          im_mbz;                     /* must be zero             */
  435:     u_char          im_vif;                     /* vif rec'd on             */
  436:     u_char          unused3;
  437:     struct in_addr  im_src, im_dst;
  438: };
  439: #endif

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