This repository has been archived by the owner on Dec 27, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathethernet.go
81 lines (73 loc) · 1.55 KB
/
ethernet.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
package swtch
// The code below was taken from github.com/mdlayher/ethernet and adapted for embedded use
// All credit to mdlayher and the ethernet Authors
import (
"bytes"
"github.com/soypat/ether-swtch/grams"
)
// Ethernet state machine logic
// etherCtl controlled decoding/encoding of Ethernet
// frame. Yields more triggers to other functions which
// decode following frames
func etherCtl(c *TCPConn) Trigger {
_log("ethCtl")
if errTrig := etherIO(c); errTrig != nil {
return errTrig
}
switch c.Ethernet.EtherType() {
case grams.EtherTypeARP:
return arpIO
case grams.EtherTypeIPv4:
return ipv4Ctl
}
return triggerError(c, ErrUnknownEthProtocol)
}
// etherIO reads to or writes data from
// ethernet frame in Conn.
func etherIO(c *TCPConn) Trigger {
_log("ethIO")
var n int
var err error
f := &c.Ethernet
if !c.read {
// Marshal block.
n = 14
if f.IsVLAN() {
n = 16
}
n, err = c.conn.Write(f[:n])
_log("eth:send", f[:n])
c.n += n
if err != nil {
return triggerError(c, err)
}
return nil
}
// Unmarshalling logic.
n, err = c.packet.Read(f[0:14])
c.n += n
_log("eth:decoded", f[:n])
if err != nil {
return triggerError(c, err)
}
if f.IsVLAN() {
n, err = c.packet.Read(f[14:16])
c.n += n
if err != nil {
return triggerError(c, err)
}
}
return nil
}
// set Ethernet
func etherSet(c *TCPConn) Trigger {
_log("ethSet")
f := &c.Ethernet
Set := f.Set()
if !bytes.Equal(f.Source(), c.macAddr) {
Set.Destination(f.Source())
Set.Source(c.macAddr)
}
c.minPlen = 60 // not counting CRC length
return nil
}