Skip to content

Commit 36fadcd

Browse files
author
dave.seddon
committed
better type handling
1 parent ba7b060 commit 36fadcd

File tree

2 files changed

+106
-51
lines changed

2 files changed

+106
-51
lines changed

goIGMP_recv.go

Lines changed: 81 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ var (
2222
}
2323
)
2424

25+
const (
26+
ignoreNonActiveInterfaceModulusCst = 100
27+
)
28+
2529
func (r IGMPReporter) recvIGMP(wg *sync.WaitGroup, ctx context.Context, interf side, g destIP) {
2630

2731
defer wg.Done()
@@ -69,9 +73,11 @@ forLoop:
6973
// Ignore traffic on the non-active outside interface
7074
if r.AltOutExists {
7175
if r.ignoreOnNonActiveOutOrAltInterface(&interf) {
72-
debugLog(r.debugLevel > 10,
73-
fmt.Sprintf("recvIGMP(%s) g:%s loops:%d ignoring on non active outside interface",
74-
interf, r.mapIPtoNetAddr[g], loops))
76+
if loops%ignoreNonActiveInterfaceModulusCst == 0 {
77+
debugLog(r.debugLevel > 10,
78+
fmt.Sprintf("recvIGMP(%s) g:%s loops:%d ignoring on non active outside interface",
79+
interf, r.mapIPtoNetAddr[g], loops))
80+
}
7581

7682
bytePool.Put(buf)
7783
continue
@@ -127,40 +133,45 @@ forLoop:
127133
//------------------
128134
// Validate this is IGMP and it's the correct type of IGMP
129135

130-
// https://pkg.go.dev/github.com/tsg/gopacket#hdr-Basic_Usage
131-
// https://github.com/randomizedcoder/gopacket/blob/master/layers/igmp.go#L224
132-
packet := gopacket.NewPacket(*buf, layers.LayerTypeIGMP, gopacket.Default)
136+
// type IGMPType uint8
133137

134-
igmpLayer := packet.Layer(layers.LayerTypeIGMP)
135-
if igmpLayer == nil {
136-
debugLog(r.debugLevel > 10, fmt.Sprintf("recvIGMP(%s) g:%s loops:%d This isn't deserializing to IGMP. Ignoring", interf, r.mapIPtoNetAddr[g], loops))
137-
r.pCrecvIGMP.WithLabelValues("deserializing", interf.String(), r.mapIPtoNetAddr[g].String(), "error").Inc()
138-
bytePool.Put(buf)
139-
continue
140-
}
138+
// const (
139+
// IGMPMembershipQuery IGMPType = 0x11 // General or group specific query
140+
// IGMPMembershipReportV1 IGMPType = 0x12 // Version 1 Membership Report
141+
// IGMPMembershipReportV2 IGMPType = 0x16 // Version 2 Membership Report
142+
// IGMPLeaveGroup IGMPType = 0x17 // Leave Group
143+
// IGMPMembershipReportV3 IGMPType = 0x22 // Version 3 Membership Report
144+
// )
145+
// https://github.com/randomizedcoder/gopacket/blob/master/layers/igmp.go#L18C1-L27C2
141146

142-
igmp, ok := igmpLayer.(*layers.IGMP)
147+
igmpType := layers.IGMPType((*buf)[0])
148+
debugLog(r.debugLevel > 10, fmt.Sprintf("recvIGMP(%s) g:%s loops:%d type:%s", interf, r.mapIPtoNetAddr[g], loops, igmpType))
149+
r.pC.WithLabelValues("recvIGMP", igmpType.String(), "count").Inc()
150+
151+
_, ok := r.mapIPtoIGMPType[g][igmpType]
143152
if !ok {
144-
debugLog(r.debugLevel > 10, fmt.Sprintf("recvIGMP(%s) g:%s loops:%d type cast error igmpLayer.(*layers.IGMP)", interf, r.mapIPtoNetAddr[g], loops))
145-
r.pCrecvIGMP.WithLabelValues("typeCast", interf.String(), r.mapIPtoNetAddr[g].String(), "error").Inc()
153+
debugLog(r.debugLevel > 10, fmt.Sprintf("recvIGMP(%s) g:%s loops:%d Packet is not of a valid IGMP type for this group. Ignoring", interf, r.mapIPtoNetAddr[g], loops))
154+
r.pCrecvIGMP.WithLabelValues("igmpT", interf.String(), r.mapIPtoNetAddr[g].String(), "error").Inc()
146155
bytePool.Put(buf)
147156
continue
148157
}
149158

150-
//debugLog(r.debugLevel > 10, fmt.Sprint(igmp.Type))
159+
// https://pkg.go.dev/github.com/tsg/gopacket#hdr-Basic_Usage
160+
// https://github.com/randomizedcoder/gopacket/blob/master/layers/igmp.go#L224
161+
packet := gopacket.NewPacket(*buf, layers.LayerTypeIGMP, gopacket.Default)
151162

152-
igmpT, ok := r.mapIPtoIGMPType[g][igmp.Type]
153-
if !ok {
154-
debugLog(r.debugLevel > 10, fmt.Sprintf("recvIGMP(%s) g:%s loops:%d Packet is not of a valid IGMP type for this group. Ignoring", interf, r.mapIPtoNetAddr[g], loops))
155-
r.pCrecvIGMP.WithLabelValues("igmpT", interf.String(), r.mapIPtoNetAddr[g].String(), "error").Inc()
163+
igmpLayer := packet.Layer(layers.LayerTypeIGMP)
164+
if igmpLayer == nil {
165+
debugLog(r.debugLevel > 10, fmt.Sprintf("recvIGMP(%s) g:%s loops:%d This isn't deserializing to IGMP. Ignoring", interf, r.mapIPtoNetAddr[g], loops))
166+
r.pCrecvIGMP.WithLabelValues("deserializing", interf.String(), r.mapIPtoNetAddr[g].String(), "error").Inc()
156167
bytePool.Put(buf)
157168
continue
158169
}
159170

160-
switch igmpT {
171+
switch igmpType {
161172

162-
case igmpTypeQuery:
163-
r.pCrecvIGMP.WithLabelValues("igmpTypeQuery", interf.String(), r.mapIPtoNetAddr[g].String(), "counter").Inc()
173+
case layers.IGMPMembershipQuery:
174+
r.pCrecvIGMP.WithLabelValues("IGMPMembershipQuery", interf.String(), r.mapIPtoNetAddr[g].String(), "counter").Inc()
164175

165176
srcIP, err := r.netip2Addr(cm.Src)
166177
if err != nil {
@@ -178,10 +189,46 @@ forLoop:
178189
debugLog(r.debugLevel > 10, fmt.Sprintf("recvIGMP(%s) g:%s loops:%d QueryNotifyCh failed. Channel full? Is something reading from the channel?", interf, r.mapIPtoNetAddr[g], loops))
179190
}
180191
}
181-
case igmpTypeMembershipReport:
182-
r.pCrecvIGMP.WithLabelValues("igmpTypeMembershipReport", interf.String(), r.mapIPtoNetAddr[g].String(), "counter").Inc()
183192

184-
mitems := r.groupRecordsToMembershipItem(igmp.GroupRecords)
193+
case layers.IGMPMembershipReportV2:
194+
r.pCrecvIGMP.WithLabelValues("IGMPMembershipReportV2", interf.String(), r.mapIPtoNetAddr[g].String(), "counter").Inc()
195+
196+
igmpv1or2, okC := igmpLayer.(*layers.IGMPv1or2)
197+
if !okC {
198+
debugLog(r.debugLevel > 10, fmt.Sprintf("recvIGMP(%s) g:%s loops:%d type cast error igmpLayer.(*layers.IGMPv1or2)", interf, r.mapIPtoNetAddr[g], loops))
199+
r.pC.WithLabelValues("recvIGMP", "cast", "error").Inc()
200+
}
201+
202+
na, err := r.netip2Addr(igmpv1or2.GroupAddress)
203+
if err != nil {
204+
log.Fatal("recvIGMP netip2Addr(sa) err", err)
205+
}
206+
207+
var mi MembershipItem
208+
mi.Group = na
209+
mitems := []MembershipItem{mi}
210+
211+
if r.conf.MembershipReportsFromNetwork {
212+
select {
213+
case r.MembershipReportFromNetworkCh <- mitems:
214+
r.pCrecvIGMP.WithLabelValues("MembershipReportFromNetworkCh", interf.String(), r.mapIPtoNetAddr[g].String(), "counter").Inc()
215+
debugLog(r.debugLevel > 10, fmt.Sprintf("recvIGMP(%s) g:%s loops:%d MembershipReportFromNetworkCh", interf, r.mapIPtoNetAddr[g], loops))
216+
default:
217+
r.pCrecvIGMP.WithLabelValues("MembershipReportFromNetworkCh", interf.String(), r.mapIPtoNetAddr[g].String(), "error").Inc()
218+
debugLog(r.debugLevel > 10, fmt.Sprintf("recvIGMP(%s) g:%s loops:%d MembershipReportFromNetworkCh failed. Channel full? Is something reading from the channel?", interf, r.mapIPtoNetAddr[g], loops))
219+
}
220+
}
221+
case layers.IGMPMembershipReportV3:
222+
223+
igmp, ok := igmpLayer.(*layers.IGMP)
224+
if !ok {
225+
debugLog(r.debugLevel > 10, fmt.Sprintf("recvIGMP(%s) g:%s loops:%d type cast error igmpLayer.(*layers.IGMP)", interf, r.mapIPtoNetAddr[g], loops))
226+
r.pCrecvIGMP.WithLabelValues("typeCast", interf.String(), r.mapIPtoNetAddr[g].String(), "error").Inc()
227+
bytePool.Put(buf)
228+
continue
229+
}
230+
231+
mitems := r.IGMPv3GroupRecordsToMembershipItem(igmp.GroupRecords)
185232

186233
if r.conf.MembershipReportsFromNetwork {
187234
select {
@@ -193,6 +240,8 @@ forLoop:
193240
debugLog(r.debugLevel > 10, fmt.Sprintf("recvIGMP(%s) g:%s loops:%d MembershipReportFromNetworkCh failed. Channel full? Is something reading from the channel?", interf, r.mapIPtoNetAddr[g], loops))
194241
}
195242
}
243+
//case layers.IGMPLeaveGroup:
244+
// TODO handle leave
196245

197246
default:
198247
r.pCrecvIGMP.WithLabelValues("WrongType", interf.String(), r.mapIPtoNetAddr[g].String(), "error").Inc()
@@ -258,17 +307,17 @@ func (r IGMPReporter) ignoreOnNonActiveOutOrAltInterface(interf *side) (ignore b
258307
return ignore
259308
}
260309

261-
// groupRecordsToMembershipItem converts the real IGMP packet group memberships
310+
// IGMPv3GroupRecordsToMembershipItem converts the real IGMP packet group memberships
262311
// into the internal representatino as a list of []membershipItem
263-
func (r IGMPReporter) groupRecordsToMembershipItem(groupRecords []layers.IGMPv3GroupRecord) (mitems []MembershipItem) {
312+
func (r IGMPReporter) IGMPv3GroupRecordsToMembershipItem(groupRecords []layers.IGMPv3GroupRecord) (mitems []MembershipItem) {
264313

265314
startTime := time.Now()
266315
defer func() {
267-
r.pH.WithLabelValues("groupRecordsToMembershipItem", "start", "complete").Observe(time.Since(startTime).Seconds())
316+
r.pH.WithLabelValues("IGMPv3GroupRecordsToMembershipItem", "start", "complete").Observe(time.Since(startTime).Seconds())
268317
}()
269-
r.pC.WithLabelValues("groupRecordsToMembershipItem", "start", "count").Inc()
318+
r.pC.WithLabelValues("IGMPv3GroupRecordsToMembershipItem", "start", "count").Inc()
270319

271-
debugLog(r.debugLevel > 100, "groupRecordsToMembershipItem()")
320+
debugLog(r.debugLevel > 100, "IGMPv3GroupRecordsToMembershipItem()")
272321

273322
for _, gr := range groupRecords {
274323
var g MembershipItem

goIGMP_recv_unicast.go

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,21 @@ forLoop:
6767
//------------------
6868
// Validate this is IGMP and it's the correct type of IGMP
6969

70+
// type IGMPType uint8
71+
72+
// const (
73+
// IGMPMembershipQuery IGMPType = 0x11 // General or group specific query
74+
// IGMPMembershipReportV1 IGMPType = 0x12 // Version 1 Membership Report
75+
// IGMPMembershipReportV2 IGMPType = 0x16 // Version 2 Membership Report
76+
// IGMPLeaveGroup IGMPType = 0x17 // Leave Group
77+
// IGMPMembershipReportV3 IGMPType = 0x22 // Version 3 Membership Report
78+
// )
79+
// https://github.com/randomizedcoder/gopacket/blob/master/layers/igmp.go#L18C1-L27C2
80+
81+
igmpType := layers.IGMPType((*buf)[0])
82+
debugLog(r.debugLevel > 10, fmt.Sprintf("recvUnicastIGMP(%s) localIP:%s loops:%d type:%s", interf, localIP, loops, igmpType))
83+
r.pC.WithLabelValues("recvUnicastIGMP", igmpType.String(), "count").Inc()
84+
7085
// https://pkg.go.dev/github.com/tsg/gopacket#hdr-Basic_Usage
7186
// https://github.com/randomizedcoder/gopacket/blob/master/layers/igmp.go#L224
7287
packet := gopacket.NewPacket(*buf, layers.LayerTypeIGMP, gopacket.Default)
@@ -79,24 +94,7 @@ forLoop:
7994
continue
8095
}
8196

82-
igmp, okC := igmpLayer.(*layers.IGMP)
83-
if !okC {
84-
debugLog(r.debugLevel > 10, fmt.Sprintf("recvUnicastIGMP(%s) localIP:%s loops:%d type cast error igmpLayer.(*layers.IGMP)", interf, localIP, loops))
85-
r.pC.WithLabelValues("recvUnicastIGMP", "cast", "error").Inc()
86-
87-
// TODO testing
88-
igmpv1or2, ok := igmpLayer.(*layers.IGMPv1or2)
89-
if !ok {
90-
debugLog(r.debugLevel > 10, fmt.Sprintf("recvUnicastIGMP(%s) loops:%d sendIGMPv1or2 igmpLayer.(*layers.IGMPv1or2) type cast error", interf, loops))
91-
}
92-
debugLog(r.debugLevel > 10, fmt.Sprintf("recvUnicastIGMP(%s) loops:%d igmpv1or2:%v", interf, loops, igmpv1or2))
93-
// TODO testing end
94-
95-
bytePool.Put(buf)
96-
continue
97-
}
98-
99-
_, ok := r.mapUnicastIGMPTypes[igmp.Type]
97+
_, ok := r.mapUnicastIGMPTypes[igmpType]
10098
if !ok {
10199
debugLog(r.debugLevel > 10, fmt.Sprintf("recvUnicastIGMP(%s) localIP:%s loops:%d Packet is not of a valid IGMP type for this interface. Ingnoring", interf, localIP, loops))
102100
r.pC.WithLabelValues("recvUnicastIGMP", "igmpType", "error").Inc()
@@ -119,15 +117,23 @@ forLoop:
119117
}
120118

121119
// For type1/2 we need to decode to find the group address
122-
switch igmp.Type {
120+
switch igmpType {
121+
122+
//case layers.IGMPMembershipQuery:
123+
//TODO implment this
124+
123125
case layers.IGMPMembershipReportV1:
124126
r.sendIGMPv1or2(interf, loops, out, igmpLayer, buf)
127+
125128
case layers.IGMPMembershipReportV2:
126129
r.sendIGMPv1or2(interf, loops, out, igmpLayer, buf)
130+
127131
case layers.IGMPMembershipReportV3:
128132
r.sendIGMPv3(interf, loops, out, buf)
133+
129134
case layers.IGMPLeaveGroup:
130135
r.sendIGMPLeave(interf, loops, out, buf)
136+
131137
default:
132138
debugLog(r.debugLevel > 10, fmt.Sprintf("recvUnicastIGMP(%s) localIP:%s loops:%d unexpected igmp.Type", interf, localIP, loops))
133139
r.pC.WithLabelValues("recvUnicastIGMP", "unexpectedIgmpType", "error").Inc()

0 commit comments

Comments
 (0)