-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathntpalias.go
More file actions
98 lines (92 loc) · 3.28 KB
/
ntpalias.go
File metadata and controls
98 lines (92 loc) · 3.28 KB
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package twinklenet
import (
"context"
"fmt"
"log"
"net"
"net/netip"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
func NTPAliasActionFunc(ctx context.Context, pckin, pckout chan gopacket.Packet, logch chan TwinkleLog) {
for p := range pckin {
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}
if orgntp := p.Layer(layers.LayerTypeNTP); orgntp != nil {
//do not check the format of incoming packet
//response to query and status
if orgudp := p.Layer(layers.LayerTypeUDP); orgudp != nil {
//only support NTP over UDP
log.Println("receive ntp request")
orgudpl, _ := orgudp.(*layers.UDP)
sip, _ := netip.AddrFromSlice(p.NetworkLayer().NetworkFlow().Src().Raw())
dip, _ := netip.AddrFromSlice(p.NetworkLayer().NetworkFlow().Dst().Raw())
logch <- TwinkleLog{Time: p.Metadata().Timestamp, SrcAddrPort: netip.AddrPortFrom(sip, uint16(orgudpl.SrcPort)), DstAddrPort: netip.AddrPortFrom(dip, uint16(orgudpl.DstPort)), Msg: fmt.Sprintf("ntp request")}
udp := &layers.UDP{
SrcPort: orgudpl.DstPort,
DstPort: orgudpl.SrcPort,
}
orgethl, _ := p.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
eth := &layers.Ethernet{
DstMAC: orgethl.SrcMAC,
SrcMAC: net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
}
ntp := &layers.NTP{
LeapIndicator: 3,
Version: 4,
Stratum: 0,
Mode: 4,
ReferenceID: layers.NTPReferenceID(0x44454e59), //DENY
}
if ip6 := p.Layer(layers.LayerTypeIPv6); ip6 != nil {
eth.EthernetType = layers.EthernetTypeIPv6
//use ipv6
ip := &layers.IPv6{
Version: 6,
SrcIP: p.NetworkLayer().NetworkFlow().Dst().Raw(),
DstIP: p.NetworkLayer().NetworkFlow().Src().Raw(),
HopLimit: uint8(TW_ResponseTTL),
FlowLabel: setv6flowid(p),
NextHeader: layers.IPProtocolUDP,
}
if err := udp.SetNetworkLayerForChecksum(ip); err != nil {
log.Println("udp checksum error", err)
return
}
if err := gopacket.SerializeLayers(buf, opts, eth, ip, udp, ntp); err == nil {
outpck := gopacket.NewPacket(buf.Bytes(), layers.LayerTypeEthernet, gopacket.NoCopy)
log.Println("send v6 ntp DENY response")
pckout <- outpck
} else {
log.Println("serialize packet error", err)
}
} else if ip4 := p.Layer(layers.LayerTypeIPv4); ip4 != nil {
eth.EthernetType = layers.EthernetTypeIPv4
//use ipv4
ip := &layers.IPv4{
Version: 4,
SrcIP: p.NetworkLayer().NetworkFlow().Dst().Raw(),
DstIP: p.NetworkLayer().NetworkFlow().Src().Raw(),
TTL: uint8(TW_ResponseTTL),
Id: uint16(ipidcounter.Add(1)),
Protocol: layers.IPProtocolUDP,
}
if err := udp.SetNetworkLayerForChecksum(ip); err != nil {
log.Println("udp checksum error", err)
return
}
if err := gopacket.SerializeLayers(buf, opts, eth, ip, udp, ntp); err == nil {
outpck := gopacket.NewPacket(buf.Bytes(), layers.LayerTypeEthernet, gopacket.NoCopy)
log.Println("send v4 ntp DENY response")
pckout <- outpck
} else {
log.Println("serialize packet error", err)
}
}
}
}
}
}
func NTPAliasHashFunc(p gopacket.Packet) string {
return ""
}