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