Line data Source code
1 : /* $Id: igmp_proto.h 346474 2009-11-14 10:18:58Z ssiano $ 2 : * 3 : * igmp_proto.h - IGMP protocol message definitions 4 : * 5 : * Dave Katz, March 2008 6 : * 7 : * Copyright (c) 2008, Juniper Networks, Inc. 8 : * All rights reserved. 9 : */ 10 : 11 : #ifndef __IGMP_PROTO_H__ 12 : #define __IGMP_PROTO_H__ 13 : 14 : /* 15 : * This module defines the message formats for IGMP, as well as some 16 : * helper routines. 17 : */ 18 : 19 : 20 : /* 21 : * IGMP packet header format 22 : * 23 : * The IGMP header qualifies the contents of the rest of the packet. 24 : */ 25 : typedef struct igmp_hdr_ { 26 : uint8_t igmp_hdr_type; /* packet type */ 27 : uint8_t igmp_hdr_maxresp; /* Max resp code or reserved */ 28 : uint16_t igmp_hdr_cksum; /* Checksum */ 29 : } igmp_hdr; 30 : 31 : #define IGMP_TYPE_QUERY 0x11 /* Query (all versions) */ 32 : #define IGMP_TYPE_V1_REPORT 0x12 /* Version 1 Report */ 33 : #define IGMP_TYPE_V2_REPORT 0x16 /* Version 2 Report */ 34 : #define IGMP_TYPE_V2_LEAVE 0x17 /* Version 2 Leave */ 35 : #define IGMP_TYPE_V3_REPORT 0x22 /* Version 3 Report */ 36 : 37 : /* 38 : * Version 1 and version 2 packets 39 : * 40 : * All IGMP v1 and v2 packets have the same format. 41 : */ 42 : typedef struct igmp_v1v2_pkt_ { 43 : igmp_hdr igmp_v1v2_pkt_hdr; /* Packet header */ 44 : uint8_t igmp_v1v2_pkt_group[IPV4_ADDR_LEN]; /* Group address */ 45 : } igmp_v1v2_pkt; 46 : 47 : 48 : /* 49 : * Version 3 Query packet 50 : */ 51 : typedef struct igmp_v3_query_ { 52 : igmp_hdr igmp_v3_query_hdr; /* Packet header */ 53 : uint8_t igmp_v3_query_group[IPV4_ADDR_LEN]; /* Group address */ 54 : uint8_t igmp_v3_query_s_qrv; /* S/QRV fields */ 55 : uint8_t igmp_v3_query_qqic; /* QQIC */ 56 : uint16_t igmp_v3_query_num_srcs; /* Number of sources */ 57 : uint8_t igmp_v3_query_source[0]; /* Array of sources */ 58 : } igmp_v3_query; 59 : 60 : #define IGMP_SUPP_RTR_PROC_MASK 0x8 /* "S" bit in s_qrv field */ 61 : #define IGMP_QRV_MASK 0x7 /* QRV value in s_qrv field */ 62 : 63 : 64 : /* 65 : * Version 3 Report packet 66 : * 67 : * Version 3 reports have one or more group records. 68 : */ 69 : typedef struct igmp_v3_rpt_rcrd_ { 70 : uint8_t igmp_v3_rpt_rec_type; /* Record type */ 71 : uint8_t igmp_v3_rpt_aux_len; /* Auxiliary data length */ 72 : uint16_t igmp_v3_rpt_num_srcs; /* Number of sources */ 73 : uint8_t igmp_v3_rpt_group[IPV4_ADDR_LEN]; /* Group address */ 74 : } igmp_v3_rpt_rcrd; 75 : 76 : /* Array of sources */ 77 59 : static inline uint8_t* get_igmp_v3_rpt_source(igmp_v3_rpt_rcrd *ptr) { 78 59 : return (uint8_t*)(ptr + 1); 79 : } 80 : 81 : typedef struct igmp_v3_report_ { 82 : igmp_hdr igmp_v3_report_hdr; /* Packet header */ 83 : uint16_t igmp_v3_report_rsvd; /* Reserved */ 84 : uint16_t igmp_v3_report_num_rcrds; /* Number of records */ 85 : igmp_v3_rpt_rcrd igmp_v3_report_rcrd[0]; /* Set records */ 86 : } igmp_v3_report; 87 : 88 : 89 : /* 90 : * Naked header 91 : * 92 : * This is a hack to access the header to determine the packet type. 93 : */ 94 : typedef struct igmp_naked_header_ { 95 : igmp_hdr igmp_naked_header_hdr; /* Packet header */ 96 : } igmp_naked_header; 97 : 98 : 99 : /* 100 : * IGMP Packet 101 : * 102 : * This is a union of all types to aid in type coercion. 103 : */ 104 : typedef union igmp_packet_ { 105 : igmp_naked_header igmp_pkt_naked; /* Naked header */ 106 : igmp_v1v2_pkt igmp_pkt_v1v2; /* V1/V2 packet */ 107 : igmp_v3_query igmp_pkt_v3_query; /* V3 query */ 108 : igmp_v3_report igmp_pkt_v3_rpt; /* V3 report */ 109 : } igmp_packet; 110 : 111 : 112 : /* 113 : * Max Resp and QQIC fields 114 : * 115 : * The Max Resp and QQIC fields in version 3 can be fixed or floating point. 116 : */ 117 : #define IGMP_FIXFLOAT_FLAG 0x80 /* Set if floating point */ 118 : #define IGMP_FLOAT_EXP_MASK 0x70 /* Floating point exponent mask */ 119 : #define IGMP_FLOAT_EXP_SHIFT 4 /* Shift count for exponent */ 120 : #define IGMP_FLOAT_MANT_MASK 0x0F /* Floating point mantissa mask */ 121 : #define IGMP_FLOAT_MANT_HIGHBIT 0x10 /* High bit of mantissa */ 122 : #define IGMP_FLOAT_MAX_MANT 0x1F /* Max mantissa portion */ 123 : #define IGMP_FLOAT_MANT_SHIFT 0 /* Shift count for mantissa */ 124 : #define IGMP_FLOAT_EXP_OFFSET 3 /* Offset bits to add */ 125 : #define IGMP_FLOAT_MAX_EXP 0x07 /* Maximum exponent value */ 126 : #define IGMP_MAX_FLOAT_ENCODABLE \ 127 : ((IGMP_FLOAT_MANT_MASK | IGMP_FLOAT_MANT_HIGHBIT) << \ 128 : (IGMP_FLOAT_MAX_EXP + IGMP_FLOAT_EXP_OFFSET)) 129 : /* Maximum encodable value */ 130 : 131 : 132 : #define IGMP_MAX_RESP_MSEC 100 /* Max Resp is in units of 100 msec */ 133 : #define IGMP_MAX_RESP_DEFAULT 100 /* Default Max Resp val (* 100 msec) */ 134 : #define IGMP_V2_MAX_MAX_RESP 0xFF /* Maximum Max Resp value for V2 */ 135 : 136 : 137 : /* 138 : * igmp_addr_is_mcast 139 : * 140 : * Returns TRUE if the address is multicast, or FALSE if not. 141 : */ 142 : static inline boolean 143 140 : igmp_addr_is_mcast (const uint8_t *addr) 144 : { 145 140 : return ((*addr & 0xf0) == 0xe0); 146 : } 147 : 148 : #endif /* __IGMP_PROTO_H__ */