Pndpd/responder.go

109 lines
2.0 KiB
Go
Raw Normal View History

2021-12-20 14:53:42 -05:00
package main
import (
2021-12-21 06:00:28 -05:00
"bytes"
"fmt"
2021-12-20 16:46:26 -05:00
"net"
2021-12-20 14:53:42 -05:00
"syscall"
)
2021-12-21 06:00:28 -05:00
var globalFd int
2021-12-20 14:53:42 -05:00
2021-12-21 06:14:56 -05:00
func respond(iface string, requests chan *NDRequest, respondType NDPType, filter []*net.IPNet) {
2021-12-22 06:04:00 -05:00
defer stopWg.Done()
2021-12-21 06:00:28 -05:00
fd, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_RAW, syscall.IPPROTO_RAW)
if err != nil {
panic(err)
}
defer syscall.Close(globalFd)
globalFd = fd
err = syscall.BindToDevice(fd, iface)
if err != nil {
panic(err)
}
2021-12-20 14:53:42 -05:00
2021-12-20 16:46:26 -05:00
niface, err := net.InterfaceByName(iface)
if err != nil {
panic(err.Error())
}
2021-12-21 06:00:28 -05:00
var result = emptyIpv6
ifaceaddrs, err := niface.Addrs()
for _, n := range ifaceaddrs {
tip, _, err := net.ParseCIDR(n.String())
if err != nil {
break
}
if IsIPv6(tip.String()) {
if tip.IsGlobalUnicast() {
result = tip
_, tnet, _ := net.ParseCIDR("fc00::/7")
if !tnet.Contains(tip) {
break
}
}
}
}
2021-12-20 14:53:42 -05:00
for {
2021-12-22 06:04:00 -05:00
var n *NDRequest
select {
case <-stop:
return
case n = <-requests:
}
2021-12-21 06:14:56 -05:00
if filter != nil {
ok := false
for _, i := range filter {
if i.Contains(n.answeringForIP) {
fmt.Println("filter allowed IP", n.answeringForIP)
ok = true
break
}
}
if !ok {
continue
}
}
2021-12-21 06:00:28 -05:00
if n.sourceIface == iface {
pkt(result, n.srcIP, n.answeringForIP, niface.HardwareAddr, respondType)
} else {
if !bytes.Equal(n.mac, n.receivedIfaceMac) {
pkt(n.srcIP, n.dstIP, n.answeringForIP, niface.HardwareAddr, respondType)
}
}
2021-12-20 14:53:42 -05:00
}
}
2021-12-21 06:00:28 -05:00
func pkt(ownIP []byte, dstIP []byte, tgtip []byte, mac []byte, respondType NDPType) {
v6, err := newIpv6Header(ownIP, dstIP)
if err != nil {
return
}
NDPa, err := newNdpPacket(tgtip, mac, respondType)
if err != nil {
return
}
2021-12-20 14:53:42 -05:00
v6.addPayload(NDPa)
response := v6.constructPacket()
var t [16]byte
2021-12-21 06:00:28 -05:00
copy(t[:], dstIP)
2021-12-20 16:46:26 -05:00
2021-12-20 14:53:42 -05:00
d := syscall.SockaddrInet6{
Port: 0,
Addr: t,
}
2021-12-21 06:42:30 -05:00
if GlobalDebug {
fmt.Println("Sending packet of type", respondType, "to")
fmt.Printf("% X\n", t)
}
2021-12-21 06:00:28 -05:00
err = syscall.Sendto(globalFd, response, 0, &d)
2021-12-21 06:14:56 -05:00
if err != nil {
fmt.Println(err.Error())
}
2021-12-20 14:53:42 -05:00
}