-
Notifications
You must be signed in to change notification settings - Fork 2
/
chapter1.go
86 lines (79 loc) · 2.24 KB
/
chapter1.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 main
import (
"fmt"
"log"
"net"
"syscall"
)
func runChapter1() {
var netDeviceList []netDevice
events := make([]syscall.EpollEvent, 10)
// epoll作成
epfd, err := syscall.EpollCreate1(0)
if err != nil {
log.Fatalf("epoll create err : %s", err)
}
// ネットワークインターフェイスの情報を取得
interfaces, _ := net.Interfaces()
for _, netif := range interfaces {
// 無視するインターフェイスか確認
if !isIgnoreInterfaces(netif.Name) {
// socketをオープン
sock, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, int(htons(syscall.ETH_P_ALL)))
if err != nil {
log.Fatalf("create socket err : %s", err)
}
// socketにインターフェイスをbindする
addr := syscall.SockaddrLinklayer{
Protocol: htons(syscall.ETH_P_ALL),
Ifindex: netif.Index,
}
err = syscall.Bind(sock, &addr)
if err != nil {
log.Fatalf("bind err : %s", err)
}
fmt.Printf("Created device %s socket %d adddress %s\n",
netif.Name, sock, netif.HardwareAddr.String())
// socketをepollの監視対象として登録
err = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, sock, &syscall.EpollEvent{
Events: syscall.EPOLLIN,
Fd: int32(sock),
})
if err != nil {
log.Fatalf("epoll ctrl err : %s", err)
}
// ノンブロッキングに設定
//err = syscall.SetNonblock(sock, true)
//if err != nil {
// log.Fatalf("set non block is err : %s", err)
//}
// netDevice構造体を作成
// net_deviceの連結リストに連結させる
netDeviceList = append(netDeviceList, netDevice{
name: netif.Name,
macaddr: setMacAddr(netif.HardwareAddr),
socket: sock,
sockaddr: addr,
})
}
}
for {
// epoll_waitでパケットの受信を待つ
nfds, err := syscall.EpollWait(epfd, events, -1)
if err != nil {
log.Fatalf("epoll wait err : %s", err)
}
for i := 0; i < nfds; i++ {
// デバイスから通信を受信
for _, netdev := range netDeviceList {
// イベントがあったソケットとマッチしたらパケットを読み込む処理を実行
if events[i].Fd == int32(netdev.socket) {
err = netdev.netDevicePoll("ch1")
if err != nil {
log.Fatal(err)
}
}
}
}
}
}