Don't check for unnecessary flags, fix potential bottleneck

This commit is contained in:
Kioubit 2021-12-28 12:48:52 -05:00
parent b7c5e6afba
commit 1da76a4547
4 changed files with 23 additions and 45 deletions

View File

@ -13,7 +13,7 @@ type ndpRequest struct {
answeringForIP []byte answeringForIP []byte
dstIP []byte dstIP []byte
sourceIface string sourceIface string
rawPacket []byte payload []byte
} }
type ndpQuestion struct { type ndpQuestion struct {

View File

@ -75,8 +75,8 @@ 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 4096 bytes of the packet to userspace. // Verdict is: send up to 86 bytes of the packet to userspace.
bpf.RetConstant{Val: 4096}, bpf.RetConstant{Val: 86},
// Verdict is: "ignore packet." // Verdict is: "ignore packet."
bpf.RetConstant{Val: 0}, bpf.RetConstant{Val: 0},
} }
@ -87,12 +87,12 @@ func listen(iface string, responder chan *ndpRequest, requestType ndpType, stopW
} }
for { for {
buf := make([]byte, 4096) buf := make([]byte, 86)
numRead, err := syscall.Read(fd, buf) numRead, err := syscall.Read(fd, buf)
if err != nil { if err != nil {
panic(err) panic(err)
} }
if numRead < 86 { if numRead < 78 {
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])
@ -115,8 +115,6 @@ func listen(iface string, responder chan *ndpRequest, requestType ndpType, stopW
fmt.Println("NDP Flags") fmt.Println("NDP Flags")
fmt.Printf("% X\n", buf[58]) fmt.Printf("% X\n", buf[58])
} }
fmt.Println("NDP MAC:")
fmt.Printf("% X\n", buf[80:86])
fmt.Println() fmt.Println()
} }
@ -127,13 +125,22 @@ func listen(iface string, responder chan *ndpRequest, requestType ndpType, stopW
continue continue
} }
if requestType == ndp_ADV {
if buf[58] == 0x0 {
if GlobalDebug {
fmt.Println("Dropping Advertisement packet without any NDP flags set")
}
continue
}
}
responder <- &ndpRequest{ responder <- &ndpRequest{
requestType: requestType, requestType: requestType,
srcIP: buf[22:38], srcIP: buf[22:38],
dstIP: buf[38:54], dstIP: buf[38:54],
answeringForIP: buf[62:78], answeringForIP: buf[62:78],
payload: buf[54:],
sourceIface: iface, sourceIface: iface,
rawPacket: buf[:numRead],
} }
} }
} }

View File

@ -135,7 +135,7 @@ func checksumAddition(b []byte) uint32 {
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)-1 == i { if len(b)-1 == i {
sum += uint32(uint16(b[i])<<8 | uint16(0x0)) sum += uint32(uint16(b[i])<<8 | uint16(0x00))
} else { } else {
sum += uint32(uint16(b[i])<<8 | uint16(b[i+1])) sum += uint32(uint16(b[i])<<8 | uint16(b[i+1]))
} }

View File

@ -84,36 +84,11 @@ func respond(iface string, requests chan *ndpRequest, respondType ndpType, ndpQu
continue continue
} }
if req.requestType == ndp_ADV {
if (req.rawPacket[78] != 0x02) || (req.rawPacket[79] != 0x01) {
if GlobalDebug {
fmt.Println("Dropping Advertisement packet without target Source address set")
}
continue
}
if req.rawPacket[58] == 0x0 {
if GlobalDebug {
fmt.Println("Dropping Advertisement packet without any NDP flags set")
}
continue
}
} else {
if (req.rawPacket[78] != 0x01) || (req.rawPacket[79] != 0x01) {
if GlobalDebug {
fmt.Println("Dropping Solicitation packet without Source address set")
}
continue
}
}
v6Header, err := newIpv6Header(req.srcIP, req.dstIP) v6Header, err := newIpv6Header(req.srcIP, req.dstIP)
if err != nil { if err != nil {
continue continue
} }
if !checkPacketChecksum(v6Header, req.rawPacket[54:]) { if !checkPacketChecksum(v6Header, req.payload) {
if GlobalDebug {
fmt.Println("Dropping packet because of invalid checksum")
}
continue continue
} }
@ -216,23 +191,19 @@ func getAddressFromQuestionListRetry(targetIP []byte, ndpQuestionChan chan *ndpQ
return result, true return result, true
} }
hasBuffered := true
gotBuffered := false gotBuffered := false
for hasBuffered {
select { select {
case q := <-ndpQuestionChan: case q := <-ndpQuestionChan:
ndpQuestionsList = append(ndpQuestionsList, q) ndpQuestionsList = append(ndpQuestionsList, q)
gotBuffered = true gotBuffered = true
default: default:
hasBuffered = false
}
} }
if gotBuffered { if gotBuffered {
result, success = getAddressFromQuestionList(targetIP, ndpQuestionsList) result, success = getAddressFromQuestionList(targetIP, ndpQuestionsList)
} }
return result, success return nil, false
} }
func getAddressFromQuestionList(targetIP []byte, ndpQuestionsList []*ndpQuestion) ([]byte, bool) { func getAddressFromQuestionList(targetIP []byte, ndpQuestionsList []*ndpQuestion) ([]byte, bool) {