Skip to content

Commit 4e9f26e

Browse files
committed
update
1 parent 51265e8 commit 4e9f26e

File tree

4 files changed

+70
-16
lines changed

4 files changed

+70
-16
lines changed

arp.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,15 @@ func addArpTableEntry(netdev *netDevice, ipaddr uint32, macaddr [6]uint8) {
134134
/*
135135
ARPテーブルの検索
136136
*/
137-
func searchArpTableEntry(ipaddr uint32) [6]uint8 {
137+
func searchArpTableEntry(ipaddr uint32) ([6]uint8, *netDevice) {
138138
if len(ArpTableEntryList) != 0 {
139139
for _, arpTable := range ArpTableEntryList {
140140
if arpTable.ipAddr == ipaddr {
141-
return arpTable.macAddr
141+
return arpTable.macAddr, arpTable.netdev
142142
}
143143
}
144144
}
145-
return [6]uint8{}
145+
return [6]uint8{}, nil
146146
}
147147

148148
/*

chapter2.go

+10-3
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,19 @@ import (
1010
// Global変数でルーティングテーブルを宣言
1111
var iproute radixTreeNode
1212

13-
func runChapter2() {
14-
var netDeviceList []netDevice
13+
// Global変数で宣言
14+
var netDeviceList []netDevice
1515

16-
events := make([]syscall.EpollEvent, 10)
16+
func runChapter2() {
17+
// 直接接続ではないhost2へのルーティングを登録する
18+
routeEntryTohost2 := ipRouteEntry{
19+
iptype: network,
20+
nexthop: 0xc0a80002,
21+
}
22+
iproute.radixTreeAdd(0xc0a80202&0xffffff00, 24, routeEntryTohost2)
1723

1824
// epoll作成
25+
events := make([]syscall.EpollEvent, 10)
1926
epfd, err := syscall.EpollCreate1(0)
2027
if err != nil {
2128
log.Fatalf("epoll create err : %s", err)

ip.go

+55-10
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,10 @@ func ipInput(inputdev *netDevice, packet []byte) {
131131
srcAddr: byteToUint32(packet[12:16]),
132132
destAddr: byteToUint32(packet[16:20]),
133133
}
134+
// fmt.Printf("Input dev name is %s, ip addr is %s\n", inputdev.name, printIPAddr(inputdev.ipdev.address))
134135
fmt.Printf("Received IP packet type %d from %s to %s\n", ipheader.protocol,
135136
printIPAddr(ipheader.srcAddr), printIPAddr(ipheader.destAddr))
136137

137-
// fmt.Printf("ip header is %+v\n", ipheader)
138-
// fmt.Printf("input net dev is %s, %d\n", inputdev.name, inputdev.ipdev.address)
139138
// IPバージョンが4でなければドロップ
140139
// Todo: IPv6の実装
141140
if ipheader.version != 4 {
@@ -153,11 +152,55 @@ func ipInput(inputdev *netDevice, packet []byte) {
153152
return
154153
}
155154

156-
// 宛先アドレスがブロードキャストアドレスか自分のIPアドレスの場合
155+
// 宛先アドレスがブロードキャストアドレスか受信したNICインターフェイスのIPアドレスの場合
157156
if ipheader.destAddr == IP_ADDRESS_LIMITED_BROADCAST || inputdev.ipdev.address == ipheader.destAddr {
158157
// 自分宛の通信として処理
159158
ipInputToOurs(inputdev, ipheader, packet[20:])
160159
}
160+
161+
// 宛先IPアドレスをルータが持ってるか調べる
162+
// つまり宛先IPが他のNICインターフェイスについてるIPアドレスだったら自分宛てのものとして処理する
163+
for _, dev := range netDeviceList {
164+
// 宛先IPアドレスがルータの持っているIPアドレス or ディレクティッド・ブロードキャストアドレスの時の処理
165+
if dev.ipdev.address == ipheader.destAddr || dev.ipdev.broadcast == ipheader.destAddr {
166+
// 自分宛の通信として処理
167+
ipInputToOurs(inputdev, ipheader, packet[20:])
168+
}
169+
}
170+
171+
// 宛先IPアドレスがルータの持っているIPアドレスでない場合はフォワーディングを行う
172+
route := iproute.radixTreeSearch(ipheader.destAddr) // ルーティングテーブルをルックアップ
173+
if route == (ipRouteEntry{}) {
174+
// 宛先までの経路がなかったらパケットを破棄
175+
fmt.Printf("このIPへの経路がありません : %s\n", printIPAddr(ipheader.destAddr))
176+
return
177+
}
178+
179+
// TTLが1以下ならドロップ
180+
if ipheader.ttl <= 1 {
181+
// Todo: send_icmp_time_exceeded関数を作成
182+
return
183+
}
184+
185+
// TTLを1へらす
186+
ipheader.ttl -= 1
187+
188+
// IPヘッダチェックサムの再計算
189+
ipheader.headerChecksum = 0
190+
ipheader.headerChecksum = byteToUint16(calcChecksum(ipheader.ToPacket()))
191+
192+
// my_buf構造にコピー
193+
forwardPacket := ipheader.ToPacket()
194+
forwardPacket = append(forwardPacket, packet[20:]...)
195+
196+
if route.iptype == connected { // 直接接続ネットワークの経路なら
197+
// hostに直接送信
198+
fmt.Printf("forward packet to %s, from %s\n", printIPAddr(ipheader.destAddr), route.netdev.name)
199+
ipPacketOutputToHost(route.netdev, ipheader.destAddr, forwardPacket)
200+
} else { // 直接接続ネットワークの経路ではなかったら
201+
fmt.Printf("next hop is %s\n", printIPAddr(route.nexthop))
202+
ipPacketOutputToNetxhop(route.nexthop, forwardPacket)
203+
}
161204
}
162205

163206
/*
@@ -171,7 +214,8 @@ func ipInputToOurs(inputdev *netDevice, ipheader ipHeader, packet []byte) {
171214
fmt.Println("ICMP received!")
172215
icmpInput(inputdev, ipheader.srcAddr, ipheader.destAddr, packet)
173216
case IP_PROTOCOL_NUM_UDP:
174-
return
217+
fmt.Printf("udp received : %x\n", packet)
218+
//return
175219
case IP_PROTOCOL_NUM_TCP:
176220
return
177221
default:
@@ -185,10 +229,10 @@ IPパケットを直接イーサネットでホストに送信
185229
*/
186230
func ipPacketOutputToHost(dev *netDevice, destAddr uint32, packet []byte) {
187231
// ARPテーブルの検索
188-
destMacAddr := searchArpTableEntry(destAddr)
232+
destMacAddr, _ := searchArpTableEntry(destAddr)
189233
if destMacAddr == [6]uint8{0, 0, 0, 0, 0, 0} {
190234
// ARPエントリが無かったら
191-
fmt.Printf("Trying ip output to host, but no arp record to %s\\n", printIPAddr(destAddr))
235+
fmt.Printf("Trying ip output to host, but no arp record to %s\n", printIPAddr(destAddr))
192236
// ARPリクエストを送信
193237
sendArpRequest(dev, destAddr)
194238
} else {
@@ -200,13 +244,14 @@ func ipPacketOutputToHost(dev *netDevice, destAddr uint32, packet []byte) {
200244
/*
201245
IPパケットをNextHopに送信
202246
*/
203-
func ipPacketOutputToNetxhop(dev *netDevice, nextHop uint32, packet []byte) {
247+
func ipPacketOutputToNetxhop(nextHop uint32, packet []byte) {
204248
// ARPテーブルの検索
205-
destMacAddr := searchArpTableEntry(nextHop)
249+
destMacAddr, dev := searchArpTableEntry(nextHop)
206250
if destMacAddr == [6]uint8{0, 0, 0, 0, 0, 0} {
207251
fmt.Printf("Trying ip output to next hop, but no arp record to %s\n", printIPAddr(nextHop))
208252
// ルーティングテーブルのルックアップ
209253
routeToNexthop := iproute.radixTreeSearch(nextHop)
254+
//fmt.Printf("next hop route is from %s\n", routeToNexthop.netdev.name)
210255
if routeToNexthop == (ipRouteEntry{}) || routeToNexthop.iptype != connected {
211256
// next hopへの到達性が無かったら
212257
fmt.Printf("Next hop %s is not reachable\n", printIPAddr(nextHop))
@@ -235,7 +280,7 @@ func ipPacketOutput(outputdev *netDevice, routeTree radixTreeNode, destAddr, src
235280
ipPacketOutputToHost(outputdev, destAddr, packet)
236281
} else if route.iptype == network {
237282
// 直接つながっていないネットワークなら
238-
ipPacketOutputToNetxhop(outputdev, destAddr, packet)
283+
ipPacketOutputToNetxhop(destAddr, packet)
239284
}
240285
}
241286

@@ -271,7 +316,7 @@ func ipPacketEncapsulateOutput(inputdev *netDevice, destAddr, srcAddr uint32, pa
271316

272317
// ルートテーブルを検索して送信先IPのMACアドレスがなければ、
273318
// ARPリクエストを生成して送信して結果を受信してから、ethernetからパケットを送る
274-
destMacAddr := searchArpTableEntry(destAddr)
319+
destMacAddr, _ := searchArpTableEntry(destAddr)
275320
if destMacAddr != [6]uint8{0, 0, 0, 0, 0, 0} {
276321
// ルートテーブルに送信するIPアドレスのMACアドレスがあれば送信
277322
ethernetOutput(inputdev, destMacAddr, ipPacket, ETHER_TYPE_IP)

netns-scripts/chapter4-2-netns.sh

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ ip netns exec router1 ip link set router1-router2 up
4343
ip netns exec router1 ethtool -K router1-router2 rx off tx off
4444
ip netns exec router1 ip link set router1-router3 up
4545
ip netns exec router1 ethtool -K router1-router3 rx off tx off
46+
# router1のipv4フォワードを無効にする
47+
ip netns exec router1 sysctl -w net.ipv4.ip_forward=0
4648

4749
# goでip設定するの面倒くさいので追加
4850
ip netns exec router1 ip addr add 192.168.1.1/24 dev router1-host1

0 commit comments

Comments
 (0)