summaryrefslogtreecommitdiffhomepage
path: root/disco/pcap.go
blob: 71035424868e84c96acf27f2a2c30b44916d1d35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause

package disco

import (
	"bytes"
	"encoding/binary"
	"net/netip"

	"tailscale.com/tailcfg"
	"tailscale.com/types/key"
)

// ToPCAPFrame marshals the bytes for a pcap record that describe a disco frame.
//
// Warning: Alloc garbage. Acceptable while capturing.
func ToPCAPFrame(src netip.AddrPort, derpNodeSrc key.NodePublic, payload []byte) []byte {
	var (
		b    bytes.Buffer
		flag uint8
	)
	b.Grow(128) // Most disco frames will probably be smaller than this.

	if src.Addr() == tailcfg.DerpMagicIPAddr {
		flag |= 0x01
	}
	b.WriteByte(flag) // 1b: flag

	derpSrc := derpNodeSrc.Raw32()
	b.Write(derpSrc[:])                                       // 32b: derp public key
	binary.Write(&b, binary.LittleEndian, uint16(src.Port())) // 2b: port
	addr, _ := src.Addr().MarshalBinary()
	binary.Write(&b, binary.LittleEndian, uint16(len(addr)))    // 2b: len(addr)
	b.Write(addr)                                               // Xb: addr
	binary.Write(&b, binary.LittleEndian, uint16(len(payload))) // 2b: len(payload)
	b.Write(payload)                                            // Xb: payload

	return b.Bytes()
}