goIGMP

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 4, 2024 License: MIT Imports: 16 Imported by: 0

README

goIGMP

go IGMP toys

This is a little go library to allow handling of IGMP messages for different scenarios.

It was mostly designed to allow proxing IGMP messages into a docker bridge network to containers. There is a special unicast response mode which allows crafting specific IGMP responses in the case you do not want to jsut let the kernel respond. Essentailly, this allows you to control which IGMP responses come out of the docker network.

Interfaces "outside" and "inside"

The interface names are named outside and inside a little like an old Cisco PIX.

Potentially "upstream" and "downstream" would have been better names.

When there are x2 outside interfaces, the second interface is named "alternative" or "alt".

Proxy from outside to inside

   ProxyOutToIn                true
   ProxyInToOut                false
   UnicastProxyInToOut         true
   QueryNotify                 false
   MembershipReportFromNetwork false
   MembershipReportToNetworkCh false
   UnicastMembershipResponse   false
proxy_mode_special

Two (2) outside interfaces

Allow for x2 outside interfaces, with a channel to allow an application to signal which outside interface to use.

   ProxyOutToIn                true
   ProxyInToOut                false
   UnicastProxyInToOut         true
   QueryNotify                 false
   MembershipReportFromNetwork false
   MembershipReportToNetworkCh false
   UnicastMembershipResponse   false
proxy_mode_special_two_outside

Full Proxy Mode

   outName                     enp1s0
   altName                     gre0
   inName                      dockerbr
   ProxyOutToIn                true
   ProxyInToOut                true
   UnicastProxyInToOut         true
   QueryNotify                 false
   MembershipReportFromNetwork false
   MembershipReportToNetworkCh false
   UnicastMembershipResponse   false
proxy_full

Client mode

Client mode setups up channels

  • QueryNotifyCh struct{}
  • MembershipReportToNetworkCh []membershipItem
  • MembershipReportFromNetworkCh []membershipItem
type membershipItem struct {
   Source       netip.Addr
   Group        netip.Addr
}
   outName                     enp1s0
   inName                      dockerbr
   ProxyOutToIn                false
   ProxyInToOut                false
   UnicastProxyInToOut         false
   QueryNotify                 true
   MembershipReportFromNetwork true
   MembershipReportToNetworkCh true
   UnicastMembershipResponse   true
igmp_client_mode

This is an example of using the proxy from outside to inside, and then having a special application controlling the IGMP responses that leave the docker network.

deployment_scenario_example

Code to:

  • send IGMP membership reports
  • recieve IGMP membership queries

IGMP version support

The code essenially just copies the entire payload, but was tested against IGMPv3.

IGMPv2 sends the join on the multicast group in question, so this code doesn't really do that. It could be extended to support this easily enough I suppose.

IGMPv3

Internet Group Management Protocol, Version 3 https://www.rfc-editor.org/rfc/rfc3376

Message Formats

https://www.rfc-editor.org/rfc/rfc3376#section-4

IGMP messages are encapsulated in IPv4 datagrams, with an IP protocol
number of 2.  Every IGMP message described in this document is sent
with an IP Time-to-Live of 1, IP Precedence of Internetwork Control
(e.g., Type of Service 0xc0), and carries an IP Router Alert option
[RFC-2113] in its IP header.
  • IP protocol = 2
  • TTL = 1
  • IP Precedence = 0xc0
  • Router alert

Router Alert

Router alert: https://www.rfc-editor.org/rfc/rfc2113

   The Router Alert option has the following format:

                 +--------+--------+--------+--------+
                 |10010100|00000100|  2 octet value  |
                 +--------+--------+--------+--------+

   Type:
     Copied flag:  1 (all fragments must carry the option)
     Option class: 0 (control)
     Option number: 20 (decimal)

   Length: 4

   Value:  A two octet code with the following values:
     0 - Router shall examine packet
     1-65535 - Reserved
10010100 = 0x94
00000100 = 0x04
Type Number (hex)   Message Name
-----------------   ------------
	  0x11          Membership Query
	  0x22          Version 3 Membership Report

IGMPv2

https://www.rfc-editor.org/rfc/rfc2236

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      Type     | Max Resp Time |           Checksum            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Group Address                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4.1. Membership Query Message
0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Type = 0x11  | Max Resp Code |           Checksum            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Group Address                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Resv  |S| QRV |     QQIC      |     Number of Sources (N)     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Source Address [1]                      |
+-                                                             -+
|                       Source Address [2]                      |
+-                              .                              -+
.                               .                               .
.                               .                               .
+-                                                             -+
|                       Source Address [N]                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4.2. Version 3 Membership Report Message
0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Type = 0x22  |    Reserved   |           Checksum            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Reserved            |  Number of Group Records (M)  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
.                                                               .
.                        Group Record [1]                       .
.                                                               .
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
.                                                               .
.                        Group Record [2]                       .
.                                                               .
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               .                               |
.                               .                               .
|                               .                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
.                                                               .
.                        Group Record [M]                       .
.                                                               .
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

where each Group Record has the following internal format:

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Record Type  |  Aux Data Len |     Number of Sources (N)     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Multicast Address                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Source Address [1]                      |
+-                                                             -+
|                       Source Address [2]                      |
+-                                                             -+
.                               .                               .
.                               .                               .
.                               .                               .
+-                                                             -+
|                       Source Address [N]                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
.                                                               .
.                         Auxiliary Data                        .
.                                                               .
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

GoPacket

https://github.com/google/gopacket/

https://github.com/google/gopacket/blob/master/layers/igmp.go https://github.com/google/gopacket/blob/master/layers/igmp_test.go

IGMP Query https://github.com/google/gopacket/blob/master/layers/igmp.go#L78

IGMP Membership Report https://github.com/google/gopacket/blob/master/layers/igmp.go#L162

See also https://github.com/jmylchreest/igmpqd https://github.com/individuwill/mcast/

Documentation

Index

Constants

View Source
const (

	// IN  = "inside"
	// OUT = "outside"
	OUT       side = 1
	IN        side = 2
	ALTOUT    side = 3
	OUTSTR         = "outside"
	ALTOUTSTR      = "altOutside"
	INSTR          = "inside"

	OutOrAltKey int = 1

	TTL        ttlType = 1
	GRATUITOUS ttlType = 2
	QUERY      ttlType = 3

	IGMPHostsQuad = "224.0.0.22"

	IGMPHosts destIP = 22  // 224.0.0.22
	QueryHost destIP = 666 // In this case we use the query source IP

)
View Source
const (
	IGMPv2SizeCst     = 8
	IGMPv3BaseSizeCst = 24
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	InIntName                    string
	OutIntName                   string
	AltOutIntName                string
	UnicastDst                   string
	ProxyOutToIn                 bool
	ProxyInToOut                 bool
	UnicastProxyInToOut          bool
	QueryNotify                  bool
	MembershipReportsFromNetwork bool
	MembershipReportsToNetwork   bool
	UnicastMembershipReports     bool
	SocketReadDeadLine           time.Duration
	ChannelSize                  int
	Gratuitous                   time.Duration
	QueryTime                    time.Duration
	HackPayloadFilename          string
	DebugLevel                   int
	Testing                      TestingOptions
}

func (Config) String

func (c Config) String() string

type IGMP

type IGMP struct {
	layers.BaseLayer
	Type                    layers.IGMPType
	MaxResponseTime         time.Duration
	Checksum                uint16
	GroupAddress            net.IP
	SupressRouterProcessing bool
	RobustnessValue         uint8
	IntervalTime            time.Duration
	SourceAddresses         []net.IP
	NumberOfGroupRecords    uint16
	NumberOfSources         uint16
	GroupRecords            []IGMPv3GroupRecord
	Version                 uint8 // IGMP protocol version
}

func (*IGMP) LayerContents

func (i *IGMP) LayerContents() []byte

func (*IGMP) LayerPayload

func (i *IGMP) LayerPayload() []byte

func (*IGMP) LayerType

func (i *IGMP) LayerType() gopacket.LayerType

func (*IGMP) SerializeTo

func (igmp *IGMP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error

SerializeTo writes the serialized form of this layer into the SerializationBuffer, implementing gopacket.SerializableLayer. See the docs for gopacket.SerializableLayer for more info.

func (*IGMP) SerializeToIGMPv2

func (igmp *IGMP) SerializeToIGMPv2(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error

SerializeToIGMPv2 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Max Resp Time | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Group Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

func (*IGMP) SerializeToIGMPv3

func (igmp *IGMP) SerializeToIGMPv3(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error

SerializeToIGMPv3 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type = 0x11 | Max Resp Code | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Group Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Resv |S| QRV | QQIC | Number of Sources (N) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Address [1] | +- -+ | Source Address [2] | +- . -+ . . . . . . +- -+ | Source Address [N] | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

type IGMPReporter

type IGMPReporter struct {
	IntName    map[side]string
	IntOutName *sync.Map
	Interfaces []side

	AltOutExists      bool
	OutsideInterfaces map[side]bool

	TimerDuration map[ttlType]time.Duration

	NetIF      map[side]*net.Interface
	NetIFIndex map[int]side
	NetIP      map[side]net.IP
	NetAddr    map[side]netip.Addr

	ContMsg map[side]*ipv4.ControlMessage

	QueryNotifyCh                 chan struct{}
	MembershipReportFromNetworkCh chan []MembershipItem
	MembershipReportToNetworkCh   chan []MembershipItem
	OutInterfaceSelectorCh        chan side

	WG *sync.WaitGroup
	// contains filtered or unexported fields
}

func NewIGMPReporter

func NewIGMPReporter(conf Config) *IGMPReporter

NewIGMPReporter

func (IGMPReporter) Run

func (r IGMPReporter) Run(ctx context.Context)

func (IGMPReporter) RunSelfQuery

func (r IGMPReporter) RunSelfQuery()

type IGMPv3GroupRecord

type IGMPv3GroupRecord struct {
	Type             IGMPv3GroupRecordType
	AuxDataLen       uint8 // this should always be 0 as per IGMPv3 spec.
	NumberOfSources  uint16
	MulticastAddress net.IP
	SourceAddresses  []net.IP
	AuxData          uint32 // NOT USED
}

IGMPv3GroupRecord stores individual group records for a V3 Membership Report message.

type IGMPv3GroupRecordType

type IGMPv3GroupRecordType uint8
const (
	IGMPIsIn  IGMPv3GroupRecordType = 0x01 // Type MODE_IS_INCLUDE, source addresses x
	IGMPIsEx  IGMPv3GroupRecordType = 0x02 // Type MODE_IS_EXCLUDE, source addresses x
	IGMPToIn  IGMPv3GroupRecordType = 0x03 // Type CHANGE_TO_INCLUDE_MODE, source addresses x
	IGMPToEx  IGMPv3GroupRecordType = 0x04 // Type CHANGE_TO_EXCLUDE_MODE, source addresses x
	IGMPAllow IGMPv3GroupRecordType = 0x05 // Type ALLOW_NEW_SOURCES, source addresses x
	IGMPBlock IGMPv3GroupRecordType = 0x06 // Type BLOCK_OLD_SOURCES, source addresses x
)

func (IGMPv3GroupRecordType) String

func (i IGMPv3GroupRecordType) String() string

type MembershipItem added in v1.0.0

type MembershipItem struct {
	Sources []netip.Addr
	Group   netip.Addr
}

type TestingOptions

type TestingOptions struct {
	MulticastLoopback       bool
	ConnectQueryToReport    bool
	MembershipReportsReader bool
}

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL