vppn/peer/ifreader2.go
2025-02-10 19:11:30 +01:00

79 lines
1.3 KiB
Go

package peer
import (
"io"
"log"
)
type IFReader struct {
iface io.Reader
connWriter interface {
WriteData(ip byte, pkt []byte)
}
}
func NewIFReader(
iface io.Reader,
connWriter interface {
WriteData(ip byte, pkt []byte)
},
) *IFReader {
return &IFReader{iface, connWriter}
}
func (r *IFReader) Run() {
packet := newBuf()
for {
r.handleNextPacket(packet)
}
}
func (r *IFReader) handleNextPacket(packet []byte) {
packet = r.readNextPacket(packet)
if remoteIP, ok := r.parsePacket(packet); ok {
r.connWriter.WriteData(remoteIP, packet)
}
}
func (r *IFReader) readNextPacket(buf []byte) []byte {
n, err := r.iface.Read(buf[:cap(buf)])
if err != nil {
log.Fatalf("Failed to read from interface: %v", err)
}
return buf[:n]
}
func (r *IFReader) parsePacket(buf []byte) (byte, bool) {
n := len(buf)
if n == 0 {
return 0, false
}
version := buf[0] >> 4
switch version {
case 4:
if n < 20 {
r.logf("Short IPv4 packet: %d", len(buf))
return 0, false
}
return buf[19], true
case 6:
if len(buf) < 40 {
r.logf("Short IPv6 packet: %d", len(buf))
return 0, false
}
return buf[39], true
default:
r.logf("Invalid IP packet version: %v", version)
return 0, false
}
}
func (*IFReader) logf(s string, args ...any) {
log.Printf("[IFReader] "+s, args...)
}