More Fixes and optimization
This commit is contained in:
parent
ce659c31d8
commit
d3a5059aa2
@ -32,7 +32,9 @@ func readConfig(dest string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer func(file *os.File) {
|
||||||
|
_ = file.Close()
|
||||||
|
}(file)
|
||||||
|
|
||||||
scanner := bufio.NewScanner(file)
|
scanner := bufio.NewScanner(file)
|
||||||
|
|
||||||
|
3
main.go
3
main.go
@ -17,7 +17,7 @@ func WaitForSignal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println("PNDPD Version 0.9 - Kioubit 2021")
|
fmt.Println("PNDPD Version 1.0 - Kioubit 2021")
|
||||||
|
|
||||||
if len(os.Args) <= 2 {
|
if len(os.Args) <= 2 {
|
||||||
printUsage()
|
printUsage()
|
||||||
@ -31,7 +31,6 @@ func main() {
|
|||||||
r.Start()
|
r.Start()
|
||||||
} else {
|
} else {
|
||||||
r = pndp.NewResponder(os.Args[2], nil, "")
|
r = pndp.NewResponder(os.Args[2], nil, "")
|
||||||
fmt.Println("WARNING: You should use a whitelist unless you know what you are doing")
|
|
||||||
r.Start()
|
r.Start()
|
||||||
}
|
}
|
||||||
WaitForSignal()
|
WaitForSignal()
|
||||||
|
@ -15,6 +15,7 @@ type ndpRequest struct {
|
|||||||
mac []byte
|
mac []byte
|
||||||
receivedIfaceMac []byte
|
receivedIfaceMac []byte
|
||||||
sourceIface string
|
sourceIface string
|
||||||
|
rawPacket []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type ndpQuestion struct {
|
type ndpQuestion struct {
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
package pndp
|
package pndp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var emptyIpv6 = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
var emptyIpv6 = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
var allNodesIpv6 = []byte{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
|
|
||||||
|
|
||||||
type payload interface {
|
type payload interface {
|
||||||
constructPacket() ([]byte, int)
|
constructPacket() ([]byte, int)
|
||||||
@ -115,6 +115,11 @@ func (p *ndpPayload) constructPacket() ([]byte, int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func calculateChecksum(h *ipv6Header, payload []byte) uint16 {
|
func calculateChecksum(h *ipv6Header, payload []byte) uint16 {
|
||||||
|
if payload == nil {
|
||||||
|
return 0x0000
|
||||||
|
} else if len(payload) == 0 {
|
||||||
|
return 0x0000
|
||||||
|
}
|
||||||
sumPseudoHeader := checksumAddition(h.srcIP) + checksumAddition(h.dstIP) + checksumAddition([]byte{0x00, h.protocol}) + checksumAddition(h.payloadLen)
|
sumPseudoHeader := checksumAddition(h.srcIP) + checksumAddition(h.dstIP) + checksumAddition([]byte{0x00, h.protocol}) + checksumAddition(h.payloadLen)
|
||||||
sumPayload := checksumAddition(payload)
|
sumPayload := checksumAddition(payload)
|
||||||
sumTotal := sumPayload + sumPseudoHeader
|
sumTotal := sumPayload + sumPseudoHeader
|
||||||
@ -128,7 +133,7 @@ func checksumAddition(b []byte) uint32 {
|
|||||||
var sum uint32 = 0
|
var sum uint32 = 0
|
||||||
for i := 0; i < len(b); i++ {
|
for i := 0; i < len(b); i++ {
|
||||||
if i%2 == 0 {
|
if i%2 == 0 {
|
||||||
if len(b) <= i-1 {
|
if len(b)-1 == i {
|
||||||
sum += uint32(uint16(b[i])<<8 | uint16(0x0))
|
sum += uint32(uint16(b[i])<<8 | uint16(0x0))
|
||||||
} else {
|
} else {
|
||||||
sum += uint32(uint16(b[i])<<8 | uint16(b[i+1]))
|
sum += uint32(uint16(b[i])<<8 | uint16(b[i+1]))
|
||||||
@ -138,7 +143,41 @@ func checksumAddition(b []byte) uint32 {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkPacketChecksum(scrip, dstip, payload []byte) bool {
|
||||||
|
v6, err := newIpv6Header(scrip, dstip)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
packetsum := make([]byte, 2)
|
||||||
|
copy(packetsum, payload[2:4])
|
||||||
|
|
||||||
|
bPayloadLen := make([]byte, 2)
|
||||||
|
binary.BigEndian.PutUint16(bPayloadLen, uint16(len(payload)))
|
||||||
|
v6.payloadLen = bPayloadLen
|
||||||
|
|
||||||
|
payload[2] = 0x0
|
||||||
|
payload[3] = 0x0
|
||||||
|
|
||||||
|
bChecksum := make([]byte, 2)
|
||||||
|
binary.BigEndian.PutUint16(bChecksum, calculateChecksum(v6, payload))
|
||||||
|
if bytes.Equal(packetsum, bChecksum) {
|
||||||
|
if GlobalDebug {
|
||||||
|
fmt.Println("Verified received packet checksum")
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
if GlobalDebug {
|
||||||
|
fmt.Println("Received packet checksum validation failed")
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func isIpv6(ip string) bool {
|
func isIpv6(ip string) bool {
|
||||||
rip := net.ParseIP(ip)
|
rip := net.ParseIP(ip)
|
||||||
return rip != nil && strings.Contains(ip, ":")
|
if rip.To16() == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ type ProxyObj struct {
|
|||||||
// With the optional autosenseInterface argument, the whitelist is configured based on the addresses assigned to the interface specified. This works even if the IP addresses change frequently.
|
// With the optional autosenseInterface argument, the whitelist is configured based on the addresses assigned to the interface specified. This works even if the IP addresses change frequently.
|
||||||
// Start() must be called on the object to actually start responding
|
// Start() must be called on the object to actually start responding
|
||||||
func NewResponder(iface string, filter []*net.IPNet, autosenseInterface string) *ResponderObj {
|
func NewResponder(iface string, filter []*net.IPNet, autosenseInterface string) *ResponderObj {
|
||||||
|
fmt.Println("WARNING: You should use a whitelist for the responder unless you really know what you are doing")
|
||||||
var s sync.WaitGroup
|
var s sync.WaitGroup
|
||||||
return &ResponderObj{
|
return &ResponderObj{
|
||||||
stopChan: make(chan struct{}),
|
stopChan: make(chan struct{}),
|
||||||
@ -61,7 +62,7 @@ func (obj *ResponderObj) start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Stop a running Responder instance
|
//Stop a running Responder instance
|
||||||
// Returns false on success
|
// Returns false on error
|
||||||
func (obj *ResponderObj) Stop() bool {
|
func (obj *ResponderObj) Stop() bool {
|
||||||
close(obj.stopChan)
|
close(obj.stopChan)
|
||||||
fmt.Println("Shutting down responder instance..")
|
fmt.Println("Shutting down responder instance..")
|
||||||
|
@ -2,7 +2,6 @@ package pndp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/bpf"
|
"golang.org/x/net/bpf"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
@ -46,6 +45,7 @@ func htons16(v uint16) uint16 { return v<<8 | v>>8 }
|
|||||||
func listen(iface string, responder chan *ndpRequest, requestType ndpType, stopWG *sync.WaitGroup, stopChan chan struct{}) {
|
func listen(iface string, responder chan *ndpRequest, requestType ndpType, stopWG *sync.WaitGroup, stopChan chan struct{}) {
|
||||||
stopWG.Add(1)
|
stopWG.Add(1)
|
||||||
defer stopWG.Done()
|
defer stopWG.Done()
|
||||||
|
|
||||||
niface, err := net.InterfaceByName(iface)
|
niface, err := net.InterfaceByName(iface)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err.Error())
|
panic(err.Error())
|
||||||
@ -61,7 +61,7 @@ func listen(iface string, responder chan *ndpRequest, requestType ndpType, stopW
|
|||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
<-stopChan
|
<-stopChan
|
||||||
syscall.Close(fd)
|
_ = syscall.Close(fd)
|
||||||
stopWG.Done() // syscall.read does not release when the file descriptor is closed
|
stopWG.Done() // syscall.read does not release when the file descriptor is closed
|
||||||
}()
|
}()
|
||||||
if GlobalDebug {
|
if GlobalDebug {
|
||||||
@ -99,9 +99,9 @@ func listen(iface string, responder chan *ndpRequest, requestType ndpType, stopW
|
|||||||
bpf.LoadAbsolute{Off: 54, Size: 1},
|
bpf.LoadAbsolute{Off: 54, Size: 1},
|
||||||
// Jump to the drop packet instruction if Type is not Neighbor Solicitation / Advertisement.
|
// Jump to the drop packet instruction if Type is not Neighbor Solicitation / Advertisement.
|
||||||
bpf.JumpIf{Cond: bpf.JumpNotEqual, Val: protocolNo, SkipTrue: 1},
|
bpf.JumpIf{Cond: bpf.JumpNotEqual, Val: protocolNo, SkipTrue: 1},
|
||||||
// Verdict is "send up to 4k of the packet to userspace."buf
|
// Verdict is: send up to 4096 bytes of the packet to userspace.
|
||||||
bpf.RetConstant{Val: 4096},
|
bpf.RetConstant{Val: 4096},
|
||||||
// Verdict is "ignore packet."
|
// Verdict is: "ignore packet."
|
||||||
bpf.RetConstant{Val: 0},
|
bpf.RetConstant{Val: 0},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +118,6 @@ func listen(iface string, responder chan *ndpRequest, requestType ndpType, stopW
|
|||||||
}
|
}
|
||||||
if numRead < 86 {
|
if numRead < 86 {
|
||||||
if GlobalDebug {
|
if GlobalDebug {
|
||||||
|
|
||||||
fmt.Println("Dropping packet since it does not meet the minimum length requirement")
|
fmt.Println("Dropping packet since it does not meet the minimum length requirement")
|
||||||
fmt.Printf("% X\n", buf[:numRead])
|
fmt.Printf("% X\n", buf[:numRead])
|
||||||
}
|
}
|
||||||
@ -128,72 +127,39 @@ func listen(iface string, responder chan *ndpRequest, requestType ndpType, stopW
|
|||||||
fmt.Println("Got packet on", iface, "of type", requestType)
|
fmt.Println("Got packet on", iface, "of type", requestType)
|
||||||
fmt.Printf("% X\n", buf[:numRead])
|
fmt.Printf("% X\n", buf[:numRead])
|
||||||
|
|
||||||
fmt.Println("Source MAC ETHER")
|
fmt.Println("Source mac on ethernet layer:")
|
||||||
fmt.Printf("% X\n", buf[:numRead][6:12])
|
fmt.Printf("% X\n", buf[6:12])
|
||||||
fmt.Println("Source IP:")
|
fmt.Println("Source IP:")
|
||||||
fmt.Printf("% X\n", buf[:numRead][22:38])
|
fmt.Printf("% X\n", buf[22:38])
|
||||||
fmt.Println("Destination IP:")
|
fmt.Println("Destination IP:")
|
||||||
fmt.Printf("% X\n", buf[:numRead][38:54])
|
fmt.Printf("% X\n", buf[38:54])
|
||||||
fmt.Println("Requested IP:")
|
fmt.Println("Requested IP:")
|
||||||
fmt.Printf("% X\n", buf[:numRead][62:78])
|
fmt.Printf("% X\n", buf[62:78])
|
||||||
fmt.Println("Source MAC")
|
if requestType == ndp_ADV {
|
||||||
fmt.Printf("% X\n", buf[:numRead][80:86])
|
fmt.Println("NDP Flags")
|
||||||
|
fmt.Printf("% X\n", buf[58])
|
||||||
|
}
|
||||||
|
fmt.Println("NDP MAC:")
|
||||||
|
fmt.Printf("% X\n", buf[80:86])
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
if bytes.Equal(buf[:numRead][6:12], niface.HardwareAddr) {
|
if bytes.Equal(buf[6:12], niface.HardwareAddr) {
|
||||||
if GlobalDebug {
|
if GlobalDebug {
|
||||||
fmt.Println("Dropping packet from ourselves")
|
fmt.Println("Dropping packet from ourselves")
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !checkPacketChecksum(buf[:numRead][22:38], buf[:numRead][38:54], buf[:numRead][54:numRead]) {
|
|
||||||
if GlobalDebug {
|
|
||||||
fmt.Println("Dropping packet because of invalid checksum")
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
responder <- &ndpRequest{
|
responder <- &ndpRequest{
|
||||||
requestType: requestType,
|
requestType: requestType,
|
||||||
srcIP: buf[:numRead][22:38],
|
srcIP: buf[22:38],
|
||||||
dstIP: buf[:numRead][38:54],
|
dstIP: buf[38:54],
|
||||||
answeringForIP: buf[:numRead][62:78],
|
answeringForIP: buf[62:78],
|
||||||
mac: buf[:numRead][80:86],
|
mac: buf[80:86],
|
||||||
receivedIfaceMac: niface.HardwareAddr,
|
receivedIfaceMac: niface.HardwareAddr,
|
||||||
sourceIface: iface,
|
sourceIface: iface,
|
||||||
|
rawPacket: buf[:numRead],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkPacketChecksum(scrip, dstip, payload []byte) bool {
|
|
||||||
v6, err := newIpv6Header(scrip, dstip)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
packetsum := make([]byte, 2)
|
|
||||||
copy(packetsum, payload[2:4])
|
|
||||||
|
|
||||||
bPayloadLen := make([]byte, 2)
|
|
||||||
binary.BigEndian.PutUint16(bPayloadLen, uint16(len(payload)))
|
|
||||||
v6.payloadLen = bPayloadLen
|
|
||||||
|
|
||||||
payload[2] = 0x0
|
|
||||||
payload[3] = 0x0
|
|
||||||
|
|
||||||
bChecksum := make([]byte, 2)
|
|
||||||
binary.BigEndian.PutUint16(bChecksum, calculateChecksum(v6, payload))
|
|
||||||
if bytes.Equal(packetsum, bChecksum) {
|
|
||||||
if GlobalDebug {
|
|
||||||
fmt.Println("Verified received packet checksum")
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
if GlobalDebug {
|
|
||||||
fmt.Println("Received packet checksum validation failed")
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -9,62 +9,107 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func respond(iface string, requests chan *ndpRequest, respondType ndpType, ndpQuestionChan chan *ndpQuestion, filter []*net.IPNet, autoSense string, stopWG *sync.WaitGroup, stopChan chan struct{}) {
|
func respond(iface string, requests chan *ndpRequest, respondType ndpType, ndpQuestionChan chan *ndpQuestion, filter []*net.IPNet, autoSense string, stopWG *sync.WaitGroup, stopChan chan struct{}) {
|
||||||
var ndpQuestionsList = make([]*ndpQuestion, 0, 100)
|
var ndpQuestionsList = make([]*ndpQuestion, 0, 40)
|
||||||
stopWG.Add(1)
|
stopWG.Add(1)
|
||||||
defer stopWG.Done()
|
defer stopWG.Done()
|
||||||
fd, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_RAW, syscall.IPPROTO_RAW)
|
fd, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_RAW, syscall.IPPROTO_RAW)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
defer syscall.Close(fd)
|
defer func(fd int) {
|
||||||
|
_ = syscall.Close(fd)
|
||||||
|
}(fd)
|
||||||
err = syscall.BindToDevice(fd, iface)
|
err = syscall.BindToDevice(fd, iface)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
niface, err := net.InterfaceByName(iface)
|
nIface, err := net.InterfaceByName(iface)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err.Error())
|
panic(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = emptyIpv6
|
var result = emptyIpv6
|
||||||
ifaceaddrs, err := niface.Addrs()
|
ifaceaddrs, err := nIface.Addrs()
|
||||||
|
|
||||||
for _, n := range ifaceaddrs {
|
for _, n := range ifaceaddrs {
|
||||||
tip, _, err := net.ParseCIDR(n.String())
|
tip, _, err := net.ParseCIDR(n.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
var haveUla = false
|
||||||
if isIpv6(tip.String()) {
|
if isIpv6(tip.String()) {
|
||||||
if tip.IsGlobalUnicast() {
|
if tip.IsGlobalUnicast() {
|
||||||
|
haveUla = true
|
||||||
result = tip
|
result = tip
|
||||||
_, tnet, _ := net.ParseCIDR("fc00::/7")
|
_, tnet, _ := net.ParseCIDR("fc00::/7")
|
||||||
if !tnet.Contains(tip) {
|
if !tnet.Contains(tip) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
} else if tip.IsLinkLocalUnicast() && !haveUla {
|
||||||
|
result = tip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
var n *ndpRequest
|
var n *ndpRequest
|
||||||
if ndpQuestionChan == nil && respondType == ndp_ADV {
|
if (ndpQuestionChan == nil && respondType == ndp_ADV) || (ndpQuestionChan != nil && respondType == ndp_SOL) {
|
||||||
select {
|
select {
|
||||||
case <-stopChan:
|
case <-stopChan:
|
||||||
return
|
return
|
||||||
case n = <-requests:
|
case n = <-requests:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// THis is if ndpQuestionChan != nil && respondType == ndp_ADV
|
||||||
select {
|
select {
|
||||||
case <-stopChan:
|
case <-stopChan:
|
||||||
return
|
return
|
||||||
case q := <-ndpQuestionChan:
|
case q := <-ndpQuestionChan:
|
||||||
ndpQuestionsList = append(ndpQuestionsList, q)
|
ndpQuestionsList = append(ndpQuestionsList, q)
|
||||||
|
ndpQuestionsList = cleanupQuestionList(ndpQuestionsList)
|
||||||
continue
|
continue
|
||||||
case n = <-requests:
|
case n = <-requests:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _, LinkLocalSpace, _ = net.ParseCIDR("fe80::/10")
|
||||||
|
if LinkLocalSpace.Contains(n.answeringForIP) {
|
||||||
|
if GlobalDebug {
|
||||||
|
fmt.Println("Dropping packet asking for a link-local IP")
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if n.requestType == ndp_ADV {
|
||||||
|
if (n.rawPacket[78] != 0x02) || (n.rawPacket[79] != 0x01) {
|
||||||
|
if GlobalDebug {
|
||||||
|
fmt.Println("Dropping Advertisement packet without target Source address set")
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if n.rawPacket[58] == 0x0 {
|
||||||
|
if GlobalDebug {
|
||||||
|
fmt.Println("Dropping Advertisement packet without any NDP flags set")
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (n.rawPacket[78] != 0x01) || (n.rawPacket[79] != 0x01) {
|
||||||
|
if GlobalDebug {
|
||||||
|
fmt.Println("Dropping Solicitation packet without Source address set")
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !checkPacketChecksum(n.srcIP, n.dstIP, n.rawPacket[54:]) {
|
||||||
|
if GlobalDebug {
|
||||||
|
fmt.Println("Dropping packet because of invalid checksum")
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if autoSense != "" {
|
if autoSense != "" {
|
||||||
autoiface, err := net.InterfaceByName(autoSense)
|
autoiface, err := net.InterfaceByName(autoSense)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -72,8 +117,8 @@ func respond(iface string, requests chan *ndpRequest, respondType ndpType, ndpQu
|
|||||||
}
|
}
|
||||||
autoifaceaddrs, err := autoiface.Addrs()
|
autoifaceaddrs, err := autoiface.Addrs()
|
||||||
|
|
||||||
for _, n := range autoifaceaddrs {
|
for _, l := range autoifaceaddrs {
|
||||||
_, anet, err := net.ParseCIDR(n.String())
|
_, anet, err := net.ParseCIDR(l.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -104,7 +149,7 @@ func respond(iface string, requests chan *ndpRequest, respondType ndpType, ndpQu
|
|||||||
}
|
}
|
||||||
|
|
||||||
if n.sourceIface == iface {
|
if n.sourceIface == iface {
|
||||||
pkt(fd, result, n.srcIP, n.answeringForIP, niface.HardwareAddr, respondType)
|
pkt(fd, result, n.srcIP, n.answeringForIP, nIface.HardwareAddr, respondType)
|
||||||
} else {
|
} else {
|
||||||
if respondType == ndp_ADV {
|
if respondType == ndp_ADV {
|
||||||
success := false
|
success := false
|
||||||
@ -121,7 +166,7 @@ func respond(iface string, requests chan *ndpRequest, respondType ndpType, ndpQu
|
|||||||
askedBy: n.srcIP,
|
askedBy: n.srcIP,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pkt(fd, result, n.dstIP, n.answeringForIP, niface.HardwareAddr, respondType)
|
pkt(fd, result, n.dstIP, n.answeringForIP, nIface.HardwareAddr, respondType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,7 +222,7 @@ forloop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getAddressFromQuestionList(targetIP []byte, ndpQuestionsList []*ndpQuestion) ([]byte, bool) {
|
func getAddressFromQuestionList(targetIP []byte, ndpQuestionsList []*ndpQuestion) ([]byte, bool) {
|
||||||
for i, _ := range ndpQuestionsList {
|
for i := range ndpQuestionsList {
|
||||||
if bytes.Equal((*ndpQuestionsList[i]).targetIP, targetIP) {
|
if bytes.Equal((*ndpQuestionsList[i]).targetIP, targetIP) {
|
||||||
result := (*ndpQuestionsList[i]).askedBy
|
result := (*ndpQuestionsList[i]).askedBy
|
||||||
ndpQuestionsList = removeFromQuestionList(ndpQuestionsList, i)
|
ndpQuestionsList = removeFromQuestionList(ndpQuestionsList, i)
|
||||||
@ -190,3 +235,10 @@ func removeFromQuestionList(s []*ndpQuestion, i int) []*ndpQuestion {
|
|||||||
s[i] = s[len(s)-1]
|
s[i] = s[len(s)-1]
|
||||||
return s[:len(s)-1]
|
return s[:len(s)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cleanupQuestionList(s []*ndpQuestion) []*ndpQuestion {
|
||||||
|
for len(s) >= 40 {
|
||||||
|
s = removeFromQuestionList(s, 0)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
18
pndpd.service
Normal file
18
pndpd.service
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Proxy NDP Daemon
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network.target network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5s
|
||||||
|
ExecStart=/usr/bin/pndpd config /etc/pndpd/pndpd.conf
|
||||||
|
|
||||||
|
DynamicUser=yes
|
||||||
|
AmbientCapabilities=CAP_NET_RAW
|
||||||
|
CapabilityBoundingSet=
|
||||||
|
ProtectHome=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
Loading…
x
Reference in New Issue
Block a user