]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_util.c
Merge remote-tracking branch 'origin/stable/2.0'
[mirror_frr.git] / pimd / pim_util.c
1 /*
2 PIM for Quagga
3 Copyright (C) 2008 Everton da Silva Marques
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING; if not, write to the
17 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
18 MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "log.h"
24 #include "prefix.h"
25
26 #include "pim_util.h"
27
28 /*
29 RFC 3376: 4.1.7. QQIC (Querier's Query Interval Code)
30
31 If QQIC < 128, QQI = QQIC
32 If QQIC >= 128, QQI = (mant | 0x10) << (exp + 3)
33
34 0 1 2 3 4 5 6 7
35 +-+-+-+-+-+-+-+-+
36 |1| exp | mant |
37 +-+-+-+-+-+-+-+-+
38
39 Since exp=0..7 then (exp+3)=3..10, then QQI has
40 one of the following bit patterns:
41
42 exp=0: QQI = 0000.0000.1MMM.M000
43 exp=1: QQI = 0000.0001.MMMM.0000
44 ...
45 exp=6: QQI = 001M.MMM0.0000.0000
46 exp=7: QQI = 01MM.MM00.0000.0000
47 --------- ---------
48 0x4 0x0 0x0 0x0
49 */
50 uint8_t igmp_msg_encode16to8(uint16_t value)
51 {
52 uint8_t code;
53
54 if (value < 128) {
55 code = value;
56 }
57 else {
58 uint16_t mask = 0x4000;
59 uint8_t exp;
60 uint16_t mant;
61 for (exp = 7; exp > 0; --exp) {
62 if (mask & value)
63 break;
64 mask >>= 1;
65 }
66 mant = 0x000F & (value >> (exp + 3));
67 code = ((uint8_t) 1 << 7) | ((uint8_t) exp << 4) | (uint8_t) mant;
68 }
69
70 return code;
71 }
72
73 /*
74 RFC 3376: 4.1.7. QQIC (Querier's Query Interval Code)
75
76 If QQIC < 128, QQI = QQIC
77 If QQIC >= 128, QQI = (mant | 0x10) << (exp + 3)
78
79 0 1 2 3 4 5 6 7
80 +-+-+-+-+-+-+-+-+
81 |1| exp | mant |
82 +-+-+-+-+-+-+-+-+
83 */
84 uint16_t igmp_msg_decode8to16(uint8_t code)
85 {
86 uint16_t value;
87
88 if (code < 128) {
89 value = code;
90 }
91 else {
92 uint16_t mant = (code & 0x0F);
93 uint8_t exp = (code & 0x70) >> 4;
94 value = (mant | 0x10) << (exp + 3);
95 }
96
97 return value;
98 }
99
100 void pim_pkt_dump(const char *label, const uint8_t *buf, int size)
101 {
102 zlog_debug("%s: pkt dump size=%d",
103 label,
104 size);
105 zlog_hexdump(buf, size);
106 }
107
108 int
109 pim_is_group_224_0_0_0_24 (struct in_addr group_addr)
110 {
111 static int first = 1;
112 static struct prefix group_224;
113 struct prefix group;
114
115 if (first)
116 {
117 str2prefix ("224.0.0.0/24", &group_224);
118 first = 0;
119 }
120
121 group.family = AF_INET;
122 group.u.prefix4 = group_addr;
123 group.prefixlen = 32;
124
125 return prefix_match (&group_224, &group);
126 }
127
128 int
129 pim_is_group_224_4 (struct in_addr group_addr)
130 {
131 static int first = 1;
132 static struct prefix group_all;
133 struct prefix group;
134
135 if (first)
136 {
137 str2prefix ("224.0.0.0/4", &group_all);
138 first = 0;
139 }
140
141 group.family = AF_INET;
142 group.u.prefix4 = group_addr;
143 group.prefixlen = 32;
144
145 return prefix_match (&group_all, &group);
146 }