-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathip_states.go
86 lines (75 loc) · 2.32 KB
/
ip_states.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package netfilter
import (
"fmt"
"github.com/aschepis/netfilter/ip"
"github.com/aschepis/netfilter/tcp"
)
func stateValidateHeader(filter *Filter) stateFn {
// read the minimum number of bytes to validate the ip header
numBytes := ip.MIN_HEADER_LENGTH
header := ip.NewHeader(filter.stream.Next(numBytes))
// validate the ip haeder
if header.ValidChecksum {
filter.iphdr = header
// see if there is more ip header to read.
restOfHdr := int(header.HeaderLen()) - numBytes
if restOfHdr == 0 {
return stateReadPacket
} else {
return readStateFn(restOfHdr, consumeStreamStateFn(restOfHdr, stateReadPacket))
}
}
// ip header was invalid.. return nil.
// TODO: real error handling (e.g. find next ethernet frame)
return nil
// remainingBytes := math.MaxInt(0, int(header.TotalLen)-filter.stream.Len())
// fmt.Printf("invalid ip header. skipping %v bytes.. is this right?\n", remainingBytes)
// if remainingBytes == 0 {
// return skipLinkLayerStateFn()
// }
// return skipStateFn(remainingBytes, skipLinkLayerStateFn())
}
func stateReadPacket(filter *Filter) stateFn {
toRead := filter.iphdr.DataLen() - filter.stream.Len()
if toRead > 0 {
return readStateFn(filter.iphdr.DataLen(), stateHandlePacket)
}
return stateHandlePacket
}
func stateHandlePacket(filter *Filter) stateFn {
len := int(filter.iphdr.DataLen())
packetData := filter.stream.Next(len)
fmt.Println("IP Protocol:", filter.iphdr.Protocol)
switch filter.iphdr.Protocol {
case ip.PROTO_TCP:
tcpHdr := tcp.NewHeader(packetData)
fmt.Println("TCP")
fmt.Println("\tSrc:", tcpHdr.SrcPort)
fmt.Println("\tDst:", tcpHdr.DstPort)
case ip.PROTO_UDP:
fmt.Println("\tUDP")
}
return stateIPPacketComplete
}
func stateIPPacketComplete(filter *Filter) stateFn {
toSkip := LINK_LAYER_LEN - filter.stream.Len()
if toSkip > 0 {
fmt.Println("need to skip:", toSkip)
ipHeaderToRead := ip.MIN_HEADER_LENGTH - toSkip
var next stateFn
if ipHeaderToRead > 0 {
next = readStateFn(ipHeaderToRead, stateValidateHeader)
} else {
next = stateValidateHeader
}
return skipStateFn(toSkip, next)
}
ipHeaderToRead := ip.MIN_HEADER_LENGTH - filter.stream.Len()
var next stateFn
if ipHeaderToRead > 0 {
next = readStateFn(ipHeaderToRead, stateValidateHeader)
} else {
next = consumeStreamStateFn(LINK_LAYER_LEN, stateValidateHeader)
}
return next
}