-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathethernet.go
More file actions
86 lines (72 loc) · 2.54 KB
/
Copy pathethernet.go
File metadata and controls
86 lines (72 loc) · 2.54 KB
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 main
import (
"bytes"
"log"
)
const ETHER_TYPE_IP uint16 = 0x0800
const ETHER_TYPE_ARP uint16 = 0x0806
const ETHER_TYPE_IPV6 uint16 = 0x86dd
const ETHERNET_ADDRES_LEN = 6
var ETHERNET_ADDRESS_BROADCAST = [6]uint8{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
type ethernetHeader struct {
destAddr [6]uint8 // 宛先MACアドレス
srcAddr [6]uint8 // 送信元MACアドレス
etherType uint16 //イーサタイプ
}
func (ethHeader ethernetHeader) ToPacket() []byte {
var b bytes.Buffer
b.Write(macToByte(ethHeader.destAddr))
b.Write(macToByte(ethHeader.srcAddr))
b.Write(uint16ToByte(ethHeader.etherType))
return b.Bytes()
}
func setMacAddr(macAddrByte []byte) [6]uint8 {
var macaddrUint8 [6]uint8
copy(macaddrUint8[:], macAddrByte)
return macaddrUint8
}
func macToByte(macAddrByte [6]uint8) (b []byte) {
for _, v := range macAddrByte {
b = append(b, v)
}
return b
}
//イーサネットの受信処理
func ethernetInput(netdev *netDevice, packet []byte) {
//14バイト未満のヘッダをチェックする
if len(packet) < 14 {
return
}
//送られてきた通信をイーサネットのフレームとして解釈する
netdev.etheHeader.destAddr = setMacAddr(packet[0:6])
netdev.etheHeader.srcAddr = setMacAddr(packet[6:12])
netdev.etheHeader.etherType = byteToUint16(packet[12:14])
//自分のMACアドレス宛かブロードキャストの通信化を確認する
if netdev.macaddr != netdev.etheHeader.destAddr && netdev.etheHeader.destAddr != ETHERNET_ADDRESS_BROADCAST || netdev.etheHeader.srcAddr == [6]uint8{} {
//自分のMACアドレス宛かブロードキャストでなければreturnする
return
}
//イーサタイプの値から上位プロトコルを特定する
switch netdev.etheHeader.etherType {
case ETHER_TYPE_ARP:
arpInput(netdev, packet[14:])
case ETHER_TYPE_IP:
ipInput(netdev, packet[14:])
}
}
// イーサネットにカプセル化して送信
func ethernetOutput(netdev *netDevice, destaddr [6]uint8, packet []byte, ethType uint16) {
//イーサネットヘッダのパケットを作成
ethHeaderPacket := ethernetHeader{
destAddr: destaddr,
srcAddr: netdev.macaddr,
etherType: ethType,
}.ToPacket()
//イーサネットヘッダに送信するパケットをつなげる
ethHeaderPacket = append(ethHeaderPacket, packet...)
//ネットワークデバイスに送信する
err := netdev.netDeviceTransmit(ethHeaderPacket)
if err != nil {
log.Fatalf("netDeviceTransmit is err : %v", err)
}
}