xorp

pim_proto.h

00001 /* -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*- */
00002 
00003 /*
00004  * Copyright (c) 2001-2011 XORP, Inc and Others
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License, Version 2, June
00008  * 1991 as published by the Free Software Foundation. Redistribution
00009  * and/or modification of this program under the terms of any other
00010  * version of the GNU General Public License is not permitted.
00011  * 
00012  * This program is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00015  * see the GNU General Public License, Version 2, a copy of which can be
00016  * found in the XORP LICENSE.gpl file.
00017  * 
00018  * XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00019  * http://xorp.net
00020  */
00021 
00022 #ifndef __PIM_PIM_PROTO_H__
00023 #define __PIM_PIM_PROTO_H__
00024 
00025 
00026 /*
00027  * Protocol Independent Multicast protocol-specific definitions
00028  * (both for PIM-SMv2 and PIM-DMv2, as per
00029  * draft-ietf-pim-sm-v2-new-11.txt and draft-ietf-pim-dm-new-v2-03.txt)
00030  */
00031 
00032 
00033 /* XXX: _PIM_VT is needed if we want the extra features of <netinet/pim.h> */
00034 #define _PIM_VT 1
00035 
00036 #ifdef HAVE_NETINET_IN_H
00037 #include <netinet/in.h>
00038 #endif
00039 #ifdef HAVE_NETINET_IN_SYSTM_H
00040 #include <netinet/in_systm.h>
00041 #endif
00042 #ifdef HAVE_NETINET_IP_H
00043 #include <netinet/ip.h>
00044 #endif
00045 #ifdef HAVE_NETINET_IP6_H
00046 #include <netinet/ip6.h>
00047 #endif
00048 
00049 // XXX: _PIM_VT is needed if we want the extra features of <netinet/pim.h>
00050 #define _PIM_VT 1
00051 #if defined(HAVE_NETINET_PIM_H) && defined(HAVE_STRUCT_PIM_PIM_VT)
00052 #include <netinet/pim.h>
00053 #else
00054 #include "mrt/include/netinet/pim.h"
00055 #endif
00056 
00057 
00058 /*
00059  * Conditionally define constants that may be missing from <netinet/pim.h>
00060  */
00061 #ifndef PIM_MINLEN
00062 #define PIM_MINLEN      8   /* PIM message min. length  */
00063 #endif
00064 #ifndef PIM_REG_MINLEN
00065 #define PIM_REG_MINLEN  (PIM_MINLEN+20) /* PIM Register hdr + inner IPv4 hdr */
00066 #endif
00067 #ifndef PIM6_REG_MINLEN
00068 #define PIM6_REG_MINLEN (PIM_MINLEN+40) /* PIM Register hdr + inner IPv6 hdr */
00069 #endif
00070 
00071 /*
00072  * Constants definitions
00073  */
00074 #ifndef IPPROTO_PIM
00075 #define IPPROTO_PIM             103
00076 #endif
00077 
00078 /* PIM versions definition */
00079 #define PIMSM_V1                1
00080 #define PIMSM_V2                2
00081 #define PIMSM_VERSION_MIN           PIMSM_V2
00082 #define PIMSM_VERSION_MAX           PIMSM_V2
00083 #define PIMSM_VERSION_DEFAULT           PIMSM_V2
00084 #define PIMDM_V1                1
00085 #define PIMDM_V2                2
00086 #define PIMDM_VERSION_MIN           PIMDM_V2
00087 #define PIMDM_VERSION_MAX           PIMDM_V2
00088 #define PIMDM_VERSION_DEFAULT           PIMDM_V2
00089 #define PIM_V1                  (proto_is_pimsm() ?       \
00090                             PIMSM_V1          \
00091                             : PIMDM_V1)
00092 #define PIM_V2                  (proto_is_pimsm() ?       \
00093                             PIMSM_V2          \
00094                             : PIMDM_V2)
00095 #define PIM_VERSION_MIN             (proto_is_pimsm() ?       \
00096                             PIMSM_VERSION_MIN     \
00097                             : PIMDM_VERSION_MIN)
00098 #define PIM_VERSION_MAX             (proto_is_pimsm() ?       \
00099                             PIMSM_VERSION_MAX     \
00100                             : PIMDM_VERSION_MAX)
00101 #define PIM_VERSION_DEFAULT         (proto_is_pimsm() ?       \
00102                             PIMSM_VERSION_DEFAULT \
00103                             : PIMDM_VERSION_DEFAULT)
00104 
00105 /*
00106  * Protocol messages specific definitions.
00107  * XXX: all intervals are in seconds.
00108  */
00109 
00110 /* PIM_HELLO-related definitions */
00111 #define PIM_HELLO_HOLDTIME_OPTION       1
00112 #define PIM_HELLO_HOLDTIME_LENGTH       2
00113 #define PIM_HELLO_HOLDTIME_FOREVER      0xffff
00114 #define PIM_HELLO_LAN_PRUNE_DELAY_OPTION    2
00115 #define PIM_HELLO_LAN_PRUNE_DELAY_LENGTH    4
00116 #define PIM_HELLO_LAN_PRUNE_DELAY_TBIT      ((uint16_t)(1 << 15))
00117 #define PIM_HELLO_DR_PRIORITY_OPTION        19
00118 #define PIM_HELLO_DR_PRIORITY_LENGTH        4
00119 #define PIM_HELLO_DR_PRIORITY_DEFAULT       1
00120 #define PIM_HELLO_DR_PRIORITY_LOWEST        0
00121 #define PIM_HELLO_DR_PRIORITY_HIGHEST       0xffffffffU
00122 #define PIM_HELLO_GENID_OPTION          20
00123 #define PIM_HELLO_GENID_LENGTH          4
00124 #define PIM_HELLO_ADDRESS_LIST_OPTION       24
00125 
00126 #define PIM_HELLO_HELLO_TRIGGERED_DELAY_DEFAULT 5
00127 #define PIM_HELLO_HELLO_PERIOD_DEFAULT      30
00128 #define PIM_HELLO_HELLO_HOLDTIME_PERIOD_RATIO   3.5
00129 #define PIM_HELLO_HELLO_HOLDTIME_DEFAULT    ((int)(PIM_HELLO_HELLO_HOLDTIME_PERIOD_RATIO * PIM_HELLO_HELLO_PERIOD_DEFAULT))
00130 
00131 #define PIM_PROPAGATION_DELAY_MSEC_DEFAULT  500 /* Propagation_delay_default */
00132 #define PIM_OVERRIDE_INTERVAL_MSEC_DEFAULT  2500   /* t_override_default */
00133 
00134 
00135 /* PIM_JOIN_PRUNE-related definitions */
00136 #define PIM_JOIN_PRUNE_PERIOD_DEFAULT       60
00137 #define PIM_JOIN_PRUNE_HOLDTIME_PERIOD_RATIO    3.5
00138 #define PIM_JOIN_PRUNE_HOLDTIME_DEFAULT     ((int)(PIM_JOIN_PRUNE_HOLDTIME_PERIOD_RATIO * PIM_JOIN_PRUNE_PERIOD_DEFAULT))
00139 #define PIM_JOIN_PRUNE_SUPPRESSION_TIMEOUT_RANDOM_FACTOR_MIN 1.1
00140 #define PIM_JOIN_PRUNE_SUPPRESSION_TIMEOUT_RANDOM_FACTOR_MAX 1.4
00141 #define PIM_JOIN_PRUNE_OIF_HOLDTIME_FOREVER 0xffff
00142 
00143 /* PIM_ASSERT-related definitions */
00144 #define PIM_ASSERT_ASSERT_TIME_DEFAULT      180
00145 #define PIM_ASSERT_ASSERT_OVERRIDE_INTERVAL_DEFAULT 3
00146 #define PIM_ASSERT_MAX_METRIC_PREFERENCE    0x7fffffffU
00147 #define PIM_ASSERT_MAX_METRIC           0xffffffffU
00148 #define PIM_ASSERT_OIF_RATE_LIMIT       1   /* 1 pkt/second */
00149 #define PIM_ASSERT_RPT_BIT          ((uint32_t)(1 << 31))
00150 
00151 /* PIM_REGISTER-related definitions */
00152 #define PIM_REGISTER_SUPPRESSION_TIME_DEFAULT   60
00153 #define PIM_REGISTER_PROBE_TIME_DEFAULT     5
00154 #define PIM_REGISTER_HEADER_LENGTH      8
00155 
00156 /* PIM_CAND_RP_ADV-related definitions */
00157 #define PIM_CAND_RP_ADV_PERIOD_DEFAULT      60
00158 #define PIM_CAND_RP_ADV_RP_HOLDTIME_DEFAULT ((int)(2.5 * PIM_CAND_RP_ADV_PERIOD_DEFAULT))
00159 #define PIM_CAND_RP_ADV_RP_PRIORITY_DEFAULT 192
00160 
00161 /* PIM_BOOTSTRAP-related definitions */
00162 #define PIM_BOOTSTRAP_LOWEST_PRIORITY       0   /* Larger is better */
00163 #define PIM_BOOTSTRAP_BOOTSTRAP_PERIOD_DEFAULT  60
00164 #define PIM_BOOTSTRAP_BOOTSTRAP_TIMEOUT_DEFAULT ((int)(2 * PIM_BOOTSTRAP_BOOTSTRAP_PERIOD_DEFAULT + 10))
00165 #define PIM_BOOTSTRAP_RAND_OVERRIDE_DEFAULT 5
00166 #define PIM_BOOTSTRAP_SCOPE_ZONE_TIMEOUT_DEFAULT ((int)(10 * PIM_BOOTSTRAP_BOOTSTRAP_TIMEOUT_DEFAULT))
00167 #define PIM_BOOTSTRAP_HASH_MASK_LEN_IPV4_DEFAULT    30
00168 #define PIM_BOOTSTRAP_HASH_MASK_LEN_IPV6_DEFAULT    126
00169 #define PIM_BOOTSTRAP_HASH_MASK_LEN_DEFAULT(ip_family)          \
00170             ((ip_family == AF_INET)?            \
00171                 PIM_BOOTSTRAP_HASH_MASK_LEN_IPV4_DEFAULT \
00172                 : PIM_BOOTSTRAP_HASH_MASK_LEN_IPV6_DEFAULT)
00173 
00174 /* PIM_GRAFT-related definitions */
00175 #define PIM_GRAFT_RETRY_PERIOD_DEFAULT      3
00176 
00177 /* PIM-DM-related definitions */
00178 #define PIM_DM_SOURCE_LIFETIME_DEFAULT      210
00179 #define PIM_DM_REFRESH_INTERVAL_DEFAULT     60
00180 
00181 /* Other timeout default values */
00182 #define PIM_KEEPALIVE_PERIOD_DEFAULT        210
00183 #define PIM_RP_KEEPALIVE_PERIOD_DEFAULT     (3 * PIM_REGISTER_SUPPRESSION_TIME_DEFAULT + PIM_REGISTER_PROBE_TIME_DEFAULT)
00184 
00185 /*
00186  * Structures, typedefs and macros
00187  */
00188 /*
00189  * Address-family related definitions. See this link for a
00190  * complete listing of all address families:
00191  *    http://www.isi.edu/in-notes/iana/assignments/address-family-numbers
00192  */
00193 #define ADDRF_IPv4      1
00194 #define ADDRF_IPv6      2
00195 #define ADDRF_NATIVE_ENCODING   0       /* Type of encoding within
00196                          * a specific address family
00197                          */
00198 
00199 #ifndef HAVE_IPV6
00200 #define ADDRF2IP_ADDRF(addr_family)                 \
00201         (((addr_family) == ADDRF_IPv4) ? (AF_INET) : (-1))
00202 #define IP_ADDRF2ADDRF(ip_family)                   \
00203         (((ip_family) == AF_INET) ? (ADDRF_IPv4) : (-1))
00204 
00205 #else
00206 #define ADDRF2IP_ADDRF(addr_family)                 \
00207         (((addr_family) == ADDRF_IPv4) ? (AF_INET)      \
00208             : ((addr_family) == ADDRF_IPv6) ?       \
00209                 (AF_INET6)              \
00210                 : (-1))
00211 #define IP_ADDRF2ADDRF(ip_family)                   \
00212         (((ip_family) == AF_INET) ? (ADDRF_IPv4)        \
00213             : ((ip_family) == AF_INET6) ?           \
00214                 (ADDRF_IPv6)                \
00215                 : (-1))
00216 
00217 #endif /* HAVE_IPV6 */
00218 
00219 #define ESADDR_RPT_BIT      0x1
00220 #define ESADDR_WC_BIT       0x2
00221 #define ESADDR_S_BIT        0x4
00222 
00223 #define EGADDR_Z_BIT        0x1
00224 
00225 /* PIM message max. payload (IP header and Router Alert IP option excluded) */
00226 #ifndef HAVE_IPV6
00227 #ifndef HOST_OS_WINDOWS
00228 #define PIM_MAXPACKET(ip_family) (((ip_family) == AF_INET) ?        \
00229                     (IP_MAXPACKET           \
00230                         - sizeof(struct ip) \
00231                         - 4*sizeof(uint8_t))    \
00232                     : (0))
00233 #else /* HOST_OS_WINDOWS */
00234 
00235 #define PIM_MAXPACKET(ip_family)    65496
00236 
00237 #endif /* !HOST_OS_WINDOWS */
00238 #else
00239 #ifndef IPV6_MAXPACKET
00240 #define IPV6_MAXPACKET 65535    /* ip6 max packet size without Jumbo payload */
00241 #endif
00242 
00243 #define PIM_MAXPACKET(ip_family) (((ip_family) == AF_INET) ?        \
00244                     (IP_MAXPACKET           \
00245                      - sizeof(struct ip)        \
00246                     - 4*sizeof(uint8_t))        \
00247                     : ((ip_family) == AF_INET6) ?   \
00248                         (IPV6_MAXPACKET     \
00249                         - 4*sizeof(uint8_t))    \
00250                         : (0))
00251 #endif /* HAVE_IPV6 */
00252 
00253 /*
00254  * Macros to get PIM-specific encoded addresses from a datastream.
00255  *
00256  * XXX: the macros below assume that the code has the following
00257  * labels that can be used to jump and process the particular error:
00258  *  'rcvd_family_error' 'rcvd_mask_len_error' 'rcvlen_error'
00259  * The also assume that function family() is defined (to return
00260  * the IP address family within the current context.
00261  */
00262 /* XXX: family2addr_bytelen should be defined somewhere */
00263 #ifndef FAMILY2ADDRSIZE
00264 #define FAMILY2ADDRSIZE(ip_family) family2addr_bytelen(ip_family)
00265 #endif
00266 #ifndef FAMILY2PREFIXLEN
00267 #define FAMILY2PREFIXLEN(ip_family) family2addr_bitlen(ip_family)
00268 #endif
00269 #define GET_ENCODED_UNICAST_ADDR(rcvd_family, unicast_ipaddr, buffer)   \
00270 do {                                    \
00271     int addr_family_;                       \
00272                                     \
00273     BUFFER_GET_OCTET(addr_family_, (buffer));           \
00274     (rcvd_family) = ADDRF2IP_ADDRF(addr_family_);           \
00275     if ((rcvd_family) != family())                  \
00276         goto rcvd_family_error;                 \
00277     BUFFER_GET_SKIP(1, (buffer));       /* Encoding type */ \
00278     BUFFER_GET_IPADDR((rcvd_family), (unicast_ipaddr), (buffer));   \
00279 } while (0)
00280 #define ENCODED_UNICAST_ADDR_SIZE(ip_family)                \
00281             (2*sizeof(uint8_t) + FAMILY2ADDRSIZE(ip_family))
00282 
00283 #define GET_ENCODED_GROUP_ADDR(rcvd_family, group_ipaddr, mask_len, reserved, buffer) \
00284 do {                                    \
00285     int addr_family_;                       \
00286                                     \
00287     BUFFER_GET_OCTET(addr_family_, (buffer));           \
00288     (rcvd_family) = ADDRF2IP_ADDRF(addr_family_);           \
00289     if ((rcvd_family) != family())                  \
00290         goto rcvd_family_error;                 \
00291     BUFFER_GET_SKIP(1, (buffer));       /* Encoding type */ \
00292     BUFFER_GET_OCTET((reserved), (buffer));             \
00293     BUFFER_GET_OCTET((mask_len), (buffer));             \
00294     BUFFER_GET_IPADDR((rcvd_family), (group_ipaddr), (buffer)); \
00295     if ((u_int)(mask_len) > FAMILY2PREFIXLEN((rcvd_family)))    \
00296         goto rcvd_mask_len_error;               \
00297 } while (0)
00298 #define ENCODED_GROUP_ADDR_SIZE(ip_family)              \
00299             (4*sizeof(uint8_t) + FAMILY2ADDRSIZE(ip_family))
00300 
00301 #define GET_ENCODED_SOURCE_ADDR(rcvd_family, source_ipaddr, mask_len, flags, buffer) \
00302 do {                                    \
00303     int addr_family_;                       \
00304                                     \
00305     BUFFER_GET_OCTET(addr_family_, (buffer));           \
00306     (rcvd_family) = ADDRF2IP_ADDRF(addr_family_);           \
00307     if ((rcvd_family) != family())                  \
00308         goto rcvd_family_error;                 \
00309     BUFFER_GET_SKIP(1, (buffer));       /* Encoding type */ \
00310     BUFFER_GET_OCTET((flags), (buffer));                \
00311     BUFFER_GET_OCTET((mask_len), (buffer));             \
00312     BUFFER_GET_IPADDR((rcvd_family), (source_ipaddr), (buffer));    \
00313     if ((u_int)(mask_len) > FAMILY2PREFIXLEN((rcvd_family)))    \
00314         goto rcvd_mask_len_error;               \
00315 } while (0)
00316 #define ENCODED_SOURCE_ADDR_SIZE(ip_family)             \
00317             (4*sizeof(uint8_t) + FAMILY2ADDRSIZE(ip_family))
00318 
00319 /*
00320  * Macros to put PIM-specific encoded addresses to a datastream.
00321  *
00322  * XXX: the macros below assume that the code has the following
00323  * labels that can be used to jump and process the particular error:
00324  *  'invalid_addr_family_error' 'buflen_error'
00325  */
00326 #define PUT_ENCODED_UNICAST_ADDR(ip_family, unicast_ipaddr, buffer) \
00327 do {                                    \
00328     int addr_family_;                       \
00329                                     \
00330     addr_family_ = IP_ADDRF2ADDRF((ip_family));         \
00331     if (addr_family_ < 0)                       \
00332         goto invalid_addr_family_error;             \
00333     BUFFER_PUT_OCTET(addr_family_, (buffer));           \
00334     BUFFER_PUT_OCTET(ADDRF_NATIVE_ENCODING, (buffer));      \
00335     BUFFER_PUT_IPADDR((unicast_ipaddr), (buffer));          \
00336 } while (0)
00337 
00338 #define PUT_ENCODED_GROUP_ADDR(ip_family, group_ipaddr, mask_len, reserved, buffer)\
00339 do {                                    \
00340     int addr_family_;                       \
00341                                     \
00342     addr_family_ = IP_ADDRF2ADDRF((ip_family));         \
00343     if (addr_family_ < 0)                       \
00344         goto invalid_addr_family_error;             \
00345     BUFFER_PUT_OCTET(addr_family_, (buffer));           \
00346     BUFFER_PUT_OCTET(ADDRF_NATIVE_ENCODING, (buffer));      \
00347     BUFFER_PUT_OCTET(reserved, (buffer));   /* E.g., EGADDR_Z_BIT */\
00348     BUFFER_PUT_OCTET((mask_len), (buffer));             \
00349     BUFFER_PUT_IPADDR((group_ipaddr), (buffer));            \
00350 } while (0)
00351 
00352 #define PUT_ENCODED_SOURCE_ADDR(ip_family, source_ipaddr, mask_len, flags, buffer) \
00353 do {                                    \
00354     int addr_family_;                       \
00355                                     \
00356     addr_family_ = IP_ADDRF2ADDRF((ip_family));         \
00357     if (addr_family_ < 0)                       \
00358         goto invalid_addr_family_error;             \
00359     BUFFER_PUT_OCTET(addr_family_, (buffer));           \
00360     BUFFER_PUT_OCTET(ADDRF_NATIVE_ENCODING, (buffer));      \
00361     BUFFER_PUT_OCTET((flags), (buffer));                \
00362     BUFFER_PUT_OCTET((mask_len), (buffer));             \
00363     BUFFER_PUT_IPADDR((source_ipaddr), (buffer));           \
00364 } while (0)
00365 
00366 #define BUFFER_PUT_SKIP_PIM_HEADER(buffer)              \
00367 do {                                    \
00368     BUFFER_PUT_SKIP(sizeof(struct pim), (buffer));          \
00369 } while (0)
00370 
00371 /*
00372  * The ASCII names of the PIM protocol control messages
00373  */
00374 #define PIMTYPE2ASCII(t)                        \
00375 (((t) == PIM_HELLO) ?                           \
00376     "PIM_HELLO"                             \
00377     : ((t) == PIM_REGISTER) ?                       \
00378     "PIM_REGISTER"                          \
00379     : ((t) == PIM_REGISTER_STOP) ?                  \
00380         "PIM_REGISTER_STOP"                     \
00381         : ((t) == PIM_JOIN_PRUNE) ?                 \
00382         "PIM_JOIN_PRUNE"                    \
00383         : ((t) == PIM_BOOTSTRAP) ?              \
00384             "PIM_BOOTSTRAP"                 \
00385             : ((t) == PIM_ASSERT) ?             \
00386             "PIM_ASSERT"                    \
00387             : ((t) == PIM_GRAFT) ?              \
00388                 "PIM_GRAFT"                 \
00389                 : ((t) == PIM_GRAFT_ACK) ?          \
00390                 "PIM_GRAFT_ACK"             \
00391                 : ((t) == PIM_CAND_RP_ADV) ?        \
00392                     "PIM_CAND_RP_ADV"           \
00393                     : ((t) == PIM_ALL_DF_ELECTION) ?    \
00394                     "PIM_ALL_DF_ELECTION"       \
00395                     : "PIM_type_unknown")
00396 
00397 /*
00398  * Global variables
00399  */
00400 
00401 /*
00402  * Global functions prototypes
00403  */
00404 __BEGIN_DECLS
00405 
00406 __END_DECLS
00407 
00408 #endif /* __PIM_PIM_PROTO_H__ */
 All Classes Namespaces Functions Variables Typedefs Enumerations