mirror of
https://github.com/soypat/lneto.git
synced 2026-08-19 22:24:03 +00:00
huge improvements to stack example
This commit is contained in:
+16
-6
@@ -17,7 +17,6 @@ func main() {
|
|||||||
rng := rand.New(rand.NewSource(1))
|
rng := rand.New(rand.NewSource(1))
|
||||||
var gen ltesto.PacketGen
|
var gen ltesto.PacketGen
|
||||||
gen.RandomizeAddrs(rng)
|
gen.RandomizeAddrs(rng)
|
||||||
|
|
||||||
slogger := logger{slog.Default()}
|
slogger := logger{slog.Default()}
|
||||||
lStack := LinkStack{
|
lStack := LinkStack{
|
||||||
logger: slogger,
|
logger: slogger,
|
||||||
@@ -49,18 +48,29 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
iss := tcp.Value(100)
|
||||||
err = pStack.tcb.Open(tcp.Value(rng.Int()), 256, tcp.StateListen)
|
err = pStack.tcb.Open(iss, 256, tcp.StateListen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
seg := tcp.Segment{
|
||||||
|
SEQ: 300,
|
||||||
|
ACK: iss,
|
||||||
|
DATALEN: 0,
|
||||||
|
WND: 256,
|
||||||
|
Flags: tcp.FlagSYN,
|
||||||
|
}
|
||||||
buf := make([]byte, lStack.mtu)
|
buf := make([]byte, lStack.mtu)
|
||||||
packet := gen.AppendRandomIPv4TCPPacket(buf[:0], rng)
|
packet := gen.AppendRandomIPv4TCPPacket(buf[:0], rng, seg)
|
||||||
err = lStack.RecvEth(packet)
|
err = lStack.RecvEth(packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
n, err := lStack.HandleEth(buf)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(n, err)
|
||||||
|
}
|
||||||
|
log.Println("success receiving packet")
|
||||||
}
|
}
|
||||||
|
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
@@ -334,7 +344,7 @@ func (ts *TCPStack) Handle(ipFrame []byte, tcpOff int) (n int, err error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
// TCP packet written.
|
// TCP packet written.
|
||||||
tfrm, _ := lneto.NewTCPFrame(ipFrame[tcpOff:])
|
tfrm, _ := lneto.NewTCPFrame(ipFrame[tcpOff : tcpOff+n])
|
||||||
ts.validator.ResetErr()
|
ts.validator.ResetErr()
|
||||||
tfrm.ValidateSize(&ts.validator) // Perform basic validation.
|
tfrm.ValidateSize(&ts.validator) // Perform basic validation.
|
||||||
if err = ts.validator.Err(); err != nil {
|
if err = ts.validator.Err(); err != nil {
|
||||||
|
|||||||
@@ -610,7 +610,7 @@ func (tfrm TCPFrame) CalculateIPv4CRC(ifrm IPv4Frame) uint16 {
|
|||||||
ifrm.crcWriteTCPPseudo(&crc)
|
ifrm.crcWriteTCPPseudo(&crc)
|
||||||
expectLen := int(ifrm.TotalLength()) - ifrm.HeaderLength()
|
expectLen := int(ifrm.TotalLength()) - ifrm.HeaderLength()
|
||||||
if expectLen != len(tfrm.buf) {
|
if expectLen != len(tfrm.buf) {
|
||||||
println("unexpected TCP buffer length mismatches IPv4 header total length", expectLen, len(tfrm.buf))
|
println("unexpected TCP buffer length mismatches IPv4 header total length", len(tfrm.buf), expectLen)
|
||||||
}
|
}
|
||||||
tfrm.crcWrite(&crc)
|
tfrm.crcWrite(&crc)
|
||||||
return crc.Sum16()
|
return crc.Sum16()
|
||||||
@@ -622,7 +622,7 @@ func (tfrm TCPFrame) CalculateIPv6CRC(ifrm IPv6Frame) uint16 {
|
|||||||
ifrm.crcWritePseudo(&crc)
|
ifrm.crcWritePseudo(&crc)
|
||||||
expectLen := int(ifrm.PayloadLength())
|
expectLen := int(ifrm.PayloadLength())
|
||||||
if expectLen != len(tfrm.buf) {
|
if expectLen != len(tfrm.buf) {
|
||||||
println("unexpected TCP buffer length mismatches IPv4 header total length", expectLen, len(tfrm.buf))
|
println("unexpected TCP buffer length mismatches IPv4 header total length", len(tfrm.buf), expectLen)
|
||||||
}
|
}
|
||||||
tfrm.crcWrite(&crc)
|
tfrm.crcWrite(&crc)
|
||||||
return crc.Sum16()
|
return crc.Sum16()
|
||||||
|
|||||||
+19
-14
@@ -2,6 +2,7 @@ package ltesto
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"github.com/soypat/lneto"
|
"github.com/soypat/lneto"
|
||||||
@@ -34,13 +35,17 @@ func (gen *PacketGen) RandomizeAddrs(rng *rand.Rand) {
|
|||||||
gen.DstTCP = uint16(ports >> 16)
|
gen.DstTCP = uint16(ports >> 16)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gen *PacketGen) AppendRandomIPv4TCPPacket(dst []byte, rng *rand.Rand) []byte {
|
func (gen *PacketGen) AppendRandomIPv4TCPPacket(dst []byte, rng *rand.Rand, seg tcp.Segment) []byte {
|
||||||
|
if seg.WND > math.MaxUint16 {
|
||||||
|
panic("TCP segment window overflow")
|
||||||
|
} else if seg.DATALEN > 2048 {
|
||||||
|
panic("too long datalen")
|
||||||
|
}
|
||||||
ri := rng.Int()
|
ri := rng.Int()
|
||||||
var (
|
var (
|
||||||
isVLAN = ri&(1<<0) != 0
|
isVLAN = ri&(1<<0) != 0
|
||||||
hasIPOpt = ri&(1<<1) != 0
|
hasIPOpt = ri&(1<<1) != 0
|
||||||
hasTCPOpt = ri&(1<<2) != 0
|
hasTCPOpt = ri&(1<<2) != 0
|
||||||
hasPayload = ri&(1<<3) != 0
|
|
||||||
)
|
)
|
||||||
var etherType lneto.EtherType = lneto.EtherTypeIPv4
|
var etherType lneto.EtherType = lneto.EtherTypeIPv4
|
||||||
var ipOpts []byte
|
var ipOpts []byte
|
||||||
@@ -56,14 +61,11 @@ func (gen *PacketGen) AppendRandomIPv4TCPPacket(dst []byte, rng *rand.Rand) []by
|
|||||||
if hasTCPOpt {
|
if hasTCPOpt {
|
||||||
tcpOpts = []byte{byte(tcp.OptSACKPermitted), 0, 1, 0}
|
tcpOpts = []byte{byte(tcp.OptSACKPermitted), 0, 1, 0}
|
||||||
}
|
}
|
||||||
var payloadLen int
|
|
||||||
if hasPayload {
|
|
||||||
payloadLen = (ri >> 16) % 1024
|
|
||||||
}
|
|
||||||
ipOptWLen := sizeWord(len(ipOpts))
|
ipOptWLen := sizeWord(len(ipOpts))
|
||||||
tcpOptWlen := sizeWord(len(tcpOpts))
|
tcpOptWlen := sizeWord(len(tcpOpts))
|
||||||
off := len(dst)
|
off := len(dst)
|
||||||
dst = append(dst, make([]byte, ethsize+sizeHeaderIPv4+4*int(ipOptWLen)+sizeHeaderTCP+4*int(tcpOptWlen)+payloadLen)...)
|
dst = append(dst, make([]byte, ethsize+sizeHeaderIPv4+4*int(ipOptWLen)+sizeHeaderTCP+4*int(tcpOptWlen)+int(seg.DATALEN))...)
|
||||||
efrm, err := lneto.NewEthFrame(dst[off:])
|
efrm, err := lneto.NewEthFrame(dst[off:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -99,11 +101,11 @@ func (gen *PacketGen) AppendRandomIPv4TCPPacket(dst []byte, rng *rand.Rand) []by
|
|||||||
}
|
}
|
||||||
tfrm.SetSourcePort(gen.SrcTCP)
|
tfrm.SetSourcePort(gen.SrcTCP)
|
||||||
tfrm.SetDestinationPort(gen.DstTCP)
|
tfrm.SetDestinationPort(gen.DstTCP)
|
||||||
tfrm.SetSeq(tcp.Value(rng.Uint32()))
|
tfrm.SetSeq(seg.SEQ)
|
||||||
tfrm.SetAck(tcp.Value(rng.Uint32()))
|
tfrm.SetAck(seg.ACK)
|
||||||
wlen := sizeWord(sizeHeaderTCP + len(tcpOpts))
|
wlen := sizeWord(sizeHeaderTCP + len(tcpOpts))
|
||||||
tfrm.SetOffsetAndFlags(wlen, tcp.Flags(rng.Uint32()))
|
tfrm.SetOffsetAndFlags(wlen, seg.Flags)
|
||||||
tfrm.SetWindowSize(uint16(rng.Uint32()))
|
tfrm.SetWindowSize(uint16(seg.WND))
|
||||||
urgPtr := uint16(rng.Uint32())
|
urgPtr := uint16(rng.Uint32())
|
||||||
tfrm.SetUrgentPtr(urgPtr)
|
tfrm.SetUrgentPtr(urgPtr)
|
||||||
tcpPayload := tfrm.Payload()
|
tcpPayload := tfrm.Payload()
|
||||||
@@ -111,6 +113,9 @@ func (gen *PacketGen) AppendRandomIPv4TCPPacket(dst []byte, rng *rand.Rand) []by
|
|||||||
if len(tcpPayload) > 0 {
|
if len(tcpPayload) > 0 {
|
||||||
rng.Read(tcpPayload)
|
rng.Read(tcpPayload)
|
||||||
firstPayloadByte = tcpPayload[0]
|
firstPayloadByte = tcpPayload[0]
|
||||||
|
if len(tcpPayload) != int(seg.DATALEN) {
|
||||||
|
panic("incorrect payload length calculation")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Set Variable section of data.
|
// Set Variable section of data.
|
||||||
copy(ifrm.Options(), ipOpts)
|
copy(ifrm.Options(), ipOpts)
|
||||||
|
|||||||
Reference in New Issue
Block a user