@@ -131,11 +131,10 @@ func ipInput(inputdev *netDevice, packet []byte) {
131
131
srcAddr : byteToUint32 (packet [12 :16 ]),
132
132
destAddr : byteToUint32 (packet [16 :20 ]),
133
133
}
134
+ // fmt.Printf("Input dev name is %s, ip addr is %s\n", inputdev.name, printIPAddr(inputdev.ipdev.address))
134
135
fmt .Printf ("Received IP packet type %d from %s to %s\n " , ipheader .protocol ,
135
136
printIPAddr (ipheader .srcAddr ), printIPAddr (ipheader .destAddr ))
136
137
137
- // fmt.Printf("ip header is %+v\n", ipheader)
138
- // fmt.Printf("input net dev is %s, %d\n", inputdev.name, inputdev.ipdev.address)
139
138
// IPバージョンが4でなければドロップ
140
139
// Todo: IPv6の実装
141
140
if ipheader .version != 4 {
@@ -153,11 +152,55 @@ func ipInput(inputdev *netDevice, packet []byte) {
153
152
return
154
153
}
155
154
156
- // 宛先アドレスがブロードキャストアドレスか自分のIPアドレスの場合
155
+ // 宛先アドレスがブロードキャストアドレスか受信したNICインターフェイスのIPアドレスの場合
157
156
if ipheader .destAddr == IP_ADDRESS_LIMITED_BROADCAST || inputdev .ipdev .address == ipheader .destAddr {
158
157
// 自分宛の通信として処理
159
158
ipInputToOurs (inputdev , ipheader , packet [20 :])
160
159
}
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
+ }
161
204
}
162
205
163
206
/*
@@ -171,7 +214,8 @@ func ipInputToOurs(inputdev *netDevice, ipheader ipHeader, packet []byte) {
171
214
fmt .Println ("ICMP received!" )
172
215
icmpInput (inputdev , ipheader .srcAddr , ipheader .destAddr , packet )
173
216
case IP_PROTOCOL_NUM_UDP :
174
- return
217
+ fmt .Printf ("udp received : %x\n " , packet )
218
+ //return
175
219
case IP_PROTOCOL_NUM_TCP :
176
220
return
177
221
default :
@@ -185,10 +229,10 @@ IPパケットを直接イーサネットでホストに送信
185
229
*/
186
230
func ipPacketOutputToHost (dev * netDevice , destAddr uint32 , packet []byte ) {
187
231
// ARPテーブルの検索
188
- destMacAddr := searchArpTableEntry (destAddr )
232
+ destMacAddr , _ := searchArpTableEntry (destAddr )
189
233
if destMacAddr == [6 ]uint8 {0 , 0 , 0 , 0 , 0 , 0 } {
190
234
// 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 ))
192
236
// ARPリクエストを送信
193
237
sendArpRequest (dev , destAddr )
194
238
} else {
@@ -200,13 +244,14 @@ func ipPacketOutputToHost(dev *netDevice, destAddr uint32, packet []byte) {
200
244
/*
201
245
IPパケットをNextHopに送信
202
246
*/
203
- func ipPacketOutputToNetxhop (dev * netDevice , nextHop uint32 , packet []byte ) {
247
+ func ipPacketOutputToNetxhop (nextHop uint32 , packet []byte ) {
204
248
// ARPテーブルの検索
205
- destMacAddr := searchArpTableEntry (nextHop )
249
+ destMacAddr , dev := searchArpTableEntry (nextHop )
206
250
if destMacAddr == [6 ]uint8 {0 , 0 , 0 , 0 , 0 , 0 } {
207
251
fmt .Printf ("Trying ip output to next hop, but no arp record to %s\n " , printIPAddr (nextHop ))
208
252
// ルーティングテーブルのルックアップ
209
253
routeToNexthop := iproute .radixTreeSearch (nextHop )
254
+ //fmt.Printf("next hop route is from %s\n", routeToNexthop.netdev.name)
210
255
if routeToNexthop == (ipRouteEntry {}) || routeToNexthop .iptype != connected {
211
256
// next hopへの到達性が無かったら
212
257
fmt .Printf ("Next hop %s is not reachable\n " , printIPAddr (nextHop ))
@@ -235,7 +280,7 @@ func ipPacketOutput(outputdev *netDevice, routeTree radixTreeNode, destAddr, src
235
280
ipPacketOutputToHost (outputdev , destAddr , packet )
236
281
} else if route .iptype == network {
237
282
// 直接つながっていないネットワークなら
238
- ipPacketOutputToNetxhop (outputdev , destAddr , packet )
283
+ ipPacketOutputToNetxhop (destAddr , packet )
239
284
}
240
285
}
241
286
@@ -271,7 +316,7 @@ func ipPacketEncapsulateOutput(inputdev *netDevice, destAddr, srcAddr uint32, pa
271
316
272
317
// ルートテーブルを検索して送信先IPのMACアドレスがなければ、
273
318
// ARPリクエストを生成して送信して結果を受信してから、ethernetからパケットを送る
274
- destMacAddr := searchArpTableEntry (destAddr )
319
+ destMacAddr , _ := searchArpTableEntry (destAddr )
275
320
if destMacAddr != [6 ]uint8 {0 , 0 , 0 , 0 , 0 , 0 } {
276
321
// ルートテーブルに送信するIPアドレスのMACアドレスがあれば送信
277
322
ethernetOutput (inputdev , destMacAddr , ipPacket , ETHER_TYPE_IP )
0 commit comments