...

論文 - 大阪工業大学

by user

on
Category: Documents
7

views

Report

Comments

Transcript

論文 - 大阪工業大学
学士論文
アドホックネットワークにおける
セキュリティについての考察
大阪工業大学
情報科学部 情報ネットワーク学科
N11-101
山添 優紀
目次
第 1 章 はじめに 1.1
1.2
研究の背景・・・・・・・・・・・・・・・・・・・・・・・・・1 研究の目的・・・・・・・・・・・・・・・・・・・・・・・・・2 第 2 章 研究の概要 2.1 2.2 2.2.1 2.2.2 2.2.3 2.3 2.4 2.5 2.6 2.7 2.8 アドホックネットワークとは・・・・・・・・・・・・・・・・・3 ルーティングプロトコルについて・・・・・・・・・・・・・・・4 リアクティブ型・・・・・・・・・・・・・・・・・・・・・・・4 プロアクティブ型・・・・・・・・・・・・・・・・・・・・・・4 ハイブリット型・・・・・・・・・・・・・・・・・・・・・・・5 マルチホップ通信・・・・・・・・・・・・・・・・・・・・・・5 AODV・・・・・・・・・・・・・・・・・・・・・・・・・・・・5 DSDV・・・・・・・・・・・・・・・・・・・・・・・・・・・・6 RREQ メッセージ・・・・・・・・・・・・・・・・・・・・・・・8 RREP メッセージ・・・・・・・・・・・・・・・・・・・・・・10 RERR メッセージ・・・・・・・・・・・・・・・・・・・・・・11 第 3 章 OLSR 3.1 3.2 3.2.1 3.2.2 3.3 3.4 3.5 3.6 3.7 3.7.1 3.8 3.9 OLSR・・・・・・・・・・・・・・・・・・・・・・・・・・・・14 HELLO メッセージ・・・・・・・・・・・・・・・・・・・・・・16 ローカルリンク情報・・・・・・・・・・・・・・・・・・・・・16 MPR 集合・・・・・・・・・・・・・・・・・・・・・・・・・・17 TC メッセージ・・・・・・・・・・・・・・・・・・・・・・・18 OLSRv2・・・・・・・・・・・・・・・・・・・・・・・・・・・18 fish eye 機能・・・・・・・・・・・・・・・・・・・・・・・18 OLSRv2 の HELLO メッセージ・・・・・・・・・・・・・・・・・19 TLV・・・・・・・・・・・・・・・・・・・・・・・・・・・・20 TLV の機能・・・・・・・・・・・・・・・・・・・・・・・・・20 ルーティングテーブル・・・・・・・・・・・・・・・・・・・・21 route コマンド・・・・・・・・・・・・・・・・・・・・・・・21 第 4 章 システム提案 4.1 4.2 4.3 4.3.1 4.4 4.5 4.6 IETF・・・・・・・・・・・・・・・・・・・・・・・・・・・・22 RFC・・・・・・・・・・・・・・・・・・・・・・・・・・・・22 HELLO メッセージの傍受・・・・・・・・・・・・・・・・・・・23 プロミスキャスモード・・・・・・・・・・・・・・・・・・・・23 OLSR_Analizer の仕様・・・・・・・・・・・・・・・・・・・・24 OLSR_Analizer の表記・・・・・・・・・・・・・・・・・・・・29 OLSR_Analizer による偽 HELLO 作成・・・・・・・・・・・・・・29 第 5 章 動作実験 5.1 検証環境・・・・・・・・・・・・・・・・・・・・・・・・・・30 5.2 システムを動作させるための準備・・・・・・・・・・・・・・・30 5.2.1. OLSRv2 の起動手順・・・・・・・・・・・・・・・・・・・・・30 5.2.2 隣接端末の確認・・・・・・・・・・・・・・・・・・・・・・・34 5.3 OLSR_Analizer の起動・・・・・・・・・・・・・・・・・・・・36 5.4 起動画面解説・・・・・・・・・・・・・・・・・・・・・・・・39 第 6 章 結論 ・謝辞
・参考文献
・ 付録
第 1 章 はじめに 1.1 研究の背景 近年、携帯電話、スマートフォン、などのモバイル端末の普及と共に、無線
LAN 通信技術が社会に浸透してきている。この中で無線基地局を必要とせず、端
末のみで無線ネットワークを構築できるモバイルアドホックネットワークは、
「端末間の無線通信によりネットワークを構成できることから、配線コストや
機器設置コストが問題となる環境や歴史的建造物など機器設置の制約が大きい
環境に適している。また、大規模災害時など社会情報基盤が停止した際の緊急
通信手段としても期待が持たれている。[1]」そういった意味でユビキタス社会
では重要な技術である。しかし一方で、無線通信では受信可能な範囲であれば
誰でも情報を共有することになるといった欠点もある。 アドホックネットワークにはいくつかネットワークを構築するための手法が
考案されている。その中でも、もっとも主流である OLSR というプロトコルでは、
ネットワークを構築するためにデータ通信の有無に関わらず、定期的に隣接情
報をフラッディングしている。そのフラッディングしているパケットには特に
セキュリティはなく、不正端末による盗聴及び傍受、データ改ざん、またはセ
キュリティ攻撃の可能性がある。そのため、情報の安全性が厳しく懸念されて
いる昨今セキュリティに対する考慮が不十分であると考える。 1
1.2 研究の目的 前述を踏まえて本研究の目的は、アドホックネットワークを構築するプロト
コルとしてもっとも主流である OLSR を用いて、セキュリティ攻撃により、通信
されているデータを傍受、ネットワークそのものを破壊できることを検証した。 前述のようにアドホックネットワークは無線基地局を必要とせず、直接通信可
能な範囲の端末同士でネットワークを構築できる。さらに、直接通信のできな
い遠方の端末には、中継端末を用いることにより中継端末を介して通信が可能
になる。OLSR では、直接通信の出来る範囲の端末を把握するため制御メッセー
ジを定期的にフラッディングしている。制御メッセージには、各端末が自身の
IP アドレスをブロードキャストし直接通信可能な端末に対して存在を示す
HELLO メッセージと各端末自身の隣接情報をフラッディングすることによりネ
ットワーク全体を把握する役割を持つ TC メッセージがある。 本研究では、正常にフラッディングしネットワークを構築している環境に 1
台の不正端末をネットワークに参加させ、上記の制御メッセージを盗聴し、ど
んな端末がネットワークを構築しているのか把握する。その後、得られた隣接
端末情報より、偽 HELLO をネットワークに流し、ネットワーク内のルーティン
グテーブルを混乱させる。これにより、どのようにネットワークに影響が出る
のか検証することが出来る。今回そのためのツールを開発した。 2
第 2 章 研究の概要
2.1 アドホックネットワークとは アドホックネットワークとは無線LANのようなアクセスポイントや通信キ
ャリアの提供する基地局を必要とせず、直接電波が届く端末同士で構成された
ネットワークである。アドホック(Ad-Hoc)とはラテン語で「特定の目的のため
の」や「限定目的の」などといった意味のラテン語の語句である。アドホック
ネットワークの始まりは 1980 年頃の米国の軍事技術の1つとして戦場でのネッ
トワークを構築する目的で研究された。その後 1997 年にはインターネットの技
術標準化を行う組織である IETF に MANET(Mobile Adhoc Network)WG が設立さ
れ、アドホックネットワークのルーティング技術の標準化が開始された。アド
ホックネットワークでは、広くコンピュータ等の 無線接続に用いられている IEEE 802.11x、Bluetooth などの技術を用いながら 多数の端末をアクセスポイ
ントの介在なしに相互に接続する形態いわゆるマルチホップ通信を取っている。
このため、アドホックネットワークでは通信キャリアの用意したネットワーク
やアクセスポイントが不要となり、簡易なネットワークの構築が可能となる。 アドホックネットワークには端末が移動しトポロジーが変化することを考慮
した様々なルーティングプロトコルが提案されている。またそのルーティング
プロトコルには経路生成のタイミングの観点から大きくプロアクティブ型とリ
アクティブ型に分類される。その他に、これらを組み合わせたハイブリット型
も存在する。[2] 直接通信可能
図 2.1 マルチホップ通信
3
2.2 ルーティングプロトコルについて 以下でハイブリット型、リアクティブ型の説明をする。 2.2.1 リアクティブ型 リアクティブ型ルーティングプロトコルでは、パケットを送信する際に経路
探索する方式であり、ある端末が実際に通信を始める際、通信経路が必要にな
るため、その時初めてプロトコルが動作し、周りのノードの存在を確かめるべ
く電波を発信させ経路表を作成する。経路表が作成されると、通信が開始され
る。具体的には、通信を開始する端末は近隣の端末に相手のアドレスを入れた
問い合わせパケットをブロードキャストする。近隣の端末は自分がそのアドレ
スでなければ、更に隣の端末に同じ問い合わせを行う。これを繰り返し最終的
に目的の端末に届き、返信パケットが帰ってくることでルートが確定する。[3] このプロトコルのメリットは、通信をする時のみ経路を探索するので、電力
消費が少ないことである。よって災害や緊急時など電力資源が限られている時
など有効になる。デメリットはルーティングテーブルの更新が著しい環境に適
さないこと。 リアクティブ型ルーティングプロトコルの代表的なものに「AODV」
「DSR」
「IERP」
「DSDV」などがある。 2.2.2 プロアクティブ型 プロアクティブ型ルーティングでは、パケットの有無に関わらず定期的に経
路を探索する方式である。簡潔な言い方をすると、あらかじめ経路表を作成し
ておくプロトコルである。よって、通信の要求が起こるとすぐに通信を開始で
きる。[3] 定期的に経路情報を交換しているこの方式では、すでに構築されているネッ
トワークに新規参加したり、トポロジーになんらかの変化があった端末は、自
らネットワークに新規参加または変化したことをフラッディングすることによ
りネットワーク再構築することが容易にできる。隣接端末情報を常に交換し各
端末がそれを元に経路情報(ルーティングテーブル)を更新している。通信をす
る際は、このあらかじめ作成されたルーティングテーブルを元に送信する。[3] プロアクティブ型ルーティングプロトコルの代表的なものとしては「OLSR」
「TBRPF」「LANMAR」「FSR」「IARP」がある。 4
2.2.3 ハイブリット型 ハイブリット型ルーティングプロトコルは、上記2つのルーティングプロト
コルを組み合わせたルーティングプロトコルである。詳しくは、テーブル駆動
方式とオンデマンド方式を組み合わせたもので、各端末の近くにある端末につ
いてはプロアクティブ型のように経路表を作成し、ルーティングに関してはテ
ーブル駆動方式で行う。遠くにある端末に関してはオンデマンド方式を使って
ルーティングを行う。[4] ハイブリット型ルーティングプロトコルの代表的なものに「ZHLS」がある。 2.3 マルチホップ通信 マルチホップ通信とは、通信のパケットをバケツリレーのような要領で目的
の端末まで伝える方式である。無線電波に対する障害物を回りこむような中継
経路の設定によって、電波の不感地帯を解消することもできる。[5] 2.4 AODV AODV(Ad-Hoc On-Demand Distance Vector Routing) ルーティングプロトコル
の略称であり、Reactive 型のプロトコルである。AODV は、DSDV アルゴリズム
を元に構築されている。このアルゴリズムが完全な経路のリストを維持管理す
るのに対し、AODV はオンデマンドに経路を作成する。よって、必要なブロード
キャストの数を概ね最小化するような改良を加えている。選択した経路上にな
い端末が経路情報を管理せず、ルーティングテーブルの交換にも参加しない。
送信元端末は、ある宛先端末にメッセージを送信するときに有効な既存の経路
が存在しなかったら、パスディスカバリ(経路探索)プロセスを開始して他の
端末の位置を把握する。そして、端末は隣接する端末に向けて RREQ(Routing Request:経路要求)パケットをブロードキャストする。隣接端末はさらに、自
身の隣接する端末に RREQ パケットを転送していく。宛先もしくは宛先への十分
に新しい経路を持つ中継端末が発見されるまで、繰り返す。 制御メッセージとしては RREQ(Route REQuest),RREP(Route REPly),RERR(RouteERRor),RREP-ACK(RouteREPly ACKnowledgment) の 4 種類の
メッセージが使われ、各メッセージは UDP の 654 番ポートへ向けて送信される。
DSR プロトコルは送信元ノードのみが経路情報を持っていたが、AODV では各ノ
ードが次にどこに送ればよいかという情報を持っている。従って、パケットに
は転送されるべき経路が記録されていない。新しい送信先への経路が必要にな
ったとき、その経路を見つけるために、「RREQ メッセージ」がブロードキャス
トされる。やがて目的の端末へ RREQ メッセージが届くと、送信先ノードは「RREP メッセージ」を送信元へ向けてユニキャストで送り返す。このやり取りによっ
5
て、中間に位置するノードの経路表上には、送信元と送信先への双方向の経路
ができあがっているので、それ以降はその経路表を使ってデータの送受信がで
きるようになる。しかし、これでは経路をまだ知らないノードが通信を始めよ
うとするたびに、ネットワーク中 RREQ メッセージがブロードキャストされてし
まうことになる。そこで、もし中間ノードが新しい経路を保持していれば、送
信先の代わりに RREP メッセージを返すようになっている。この処理によって、
無駄なメッセージのブロードキャストができるだけ抑えられる。
「シーケンス番
号」はさまざまなプロトコルで用いられている番号である。一般的にはパケッ
トのヘッダに書き込まれ、送信するたびに毎回値を増やすなどして、新旧を見
分けるためによく使われている。AODV においてはこの番号がより積極的に利用
されており、各ノードは固有のシーケンス番号を管理している。通常、経路表
の各送信先に対するエントリー(各送信先に対するさまざまな情報の集まり)
として、送信先ノード IP アドレス、ホップ数、次ホップ(ネットワークインタ
ーフェイス)、有効期間があるぐらいだが、AODV ではそれに加えて、送信先シ
ーケンス番号や、そのシーケンス番号の有効性もが含まれている。特にマルチ
ホップ無線ネットワークでは、ノードの移動が激しくなると実際のノードの位
置関係を追従できなくなり、パケットがぐるぐると周回するという厄介な現象
が起こる。これらの情報を駆使することで、そのような現象をできるだけ起こ
さないようにしている。 ノードの移動や電波的な問題、電源 OFF などで経路が切断されたときに「RERR メッセージ」を送信する時に利用される。AODV で管理されている経路表の各エ
ントリーは、その経路が頻繁に利用されていると「アクティブ」な状態になっ
ている。しかし利用されなくなって一定時間(3 秒が推奨されている)が経過
すると「無効状態」となる。これは完全に経路が削除された状態ではなく、後
からその経路を探索するときに、再び経路情報が有効に利用される。さらに、
無効状態のまま一定時間が経つと(15 秒後が推奨されている)、そのエントリ
ーは完全に経路表から削除される。[2] 2.5 DSDV DSDV(Destination Sequenced Distance Vector)ルーティングプロトコルは、
Bellman-Ford ルーティングアルゴリズムをもとにした、リアクティブ型ルーテ
ィングプロトコルである。この方式では、モバイルアドホックネットワーク内
のルータ間でルーティング情報がループしないように改良が加えられている。
モバイルネットワーク中の各ノードは、同一ネットワーク内の到達可能なすべ
ての宛先とその宛先までのホップ数(無線ホップ数)を記録しルーティングテ
ーブルを管理している。したがって、送信者トードが経路を必要とするかしな
6
いかに関わらず、常に利用可能なルーティング情報が準備されている。シーケ
ンス番号は、経路が新しいか古いかをホストが判断するのに使用し、ルーティ
ングテーブルの更新情報はテーブルの整合性を維持するためにネットワーク全
体に定期的に送信される。したがって、ネットワーク中に多くの制御トラフィ
ック生成が起き、ネットワーク資源の利用効率を低下させてしまう。この問題
を軽減するために、DSDV は 2 種類のルーティング情報更新用パケットを使用す
る。1 つ目は、フルダンプ(Full Dump)で、これは利用可能なすべてのルーテ
ィング情報を格納しており、ネットワークプロトコルデータユニット(NPDU)
を複数要求することができる。もう一つは、フルダンプより小さな差分
(Incremental)で、こちらは最後に行ったフルダンプ移項の更新情報のみを送
信するときに用いる。新しいルーティング情報をブロードキャストする時、宛
先ノードのアドレス、宛先までのホップ数、そしてそのブロードキャストの新
しい一意なシーケンス番号とともに、宛先についての情報を受信した時のシー
ケンス番号を格納する。最も新しいシーケンス番号を持つ経路が常に使用され
る。2 つの経路更新情報が同じシーケンス番号を持つ場合、ホップ数の少ない
経路を選択する。[2] 7
2.6 RREQ メッセージ AODV において、各端末はある送信先への経路が要求されたとき、まず自分の
経路表をチェックする。その経路表に目的の端末への経路が存在していない場
合は、経路を探索するために RREQ メッセージを新たにフラッディングする。 RREQ メッセージのヘッダは、図 2.2 のようになっている。 タイプ(8)
J R G F U 予約済み(11)
ホップ数
(8)
RREQ ID (32)
送信先 IP アドレス (32)
送信先シーケンス番号 (32)
送信元 IP アドレス (32)
送信元シーケンス番号 (32)
図 2.2 RREQ メッセージヘッダ
「タイプ」には必ず「1」が入る。それにより RREQ メッセージであることを識
別する。
「ホップ数」は送信元から何回中継されたかを表わすフィールド値であ
る。初期値は 0 が設定される。次の行のフィールド値「RREQ ID」には、自身が
最後に送信した RREQ メッセージの RREQ ID に“1” 加えた値となる。「送信先
IP アドレス」は送信先の IP アドレスが設定される。「送信先シーケンス番号」
は、送信先端末について最後に得たシーケンス番号であり、経路表の中から検
索する。もし経路表の中にエントリーが存在せず、シーケンス番号がわからな
い場合、「U」(Unknown sequencenumber)フラグが立つ。「送信元 IP アドレス」
には各端末自身の IP アドレス、「送信元シーケンス番号」には各端末自身のシ
ーケンス番号が設定されるが、ノードは RREQ メッセージを作成する直前に自分
自身の送信元シーケンス番号を増加させる。この番号はもし経路が存在すれば
RREP メッセージに乗っていずれ返ってくることになる番号である。何らかの障
害でやむを得ず複数回 RREQ メッセージを送らなければならなかった場合、後で
複数回、RREP メッセージを受信する可能性があるが、どのメッセージが最新な
のかはこの番号を見ることによって判断することができる。このようにして作
成された RREQ メッセージをネットワークにフラッディングする。その際、目的
の端末が近くにいるかもしれない可能性を考慮し、「expanding ringserch」と
いう技術を使用する。これは、まずは再転送するホップ数を制限する。それで
目的端末が見つからなければ徐々にホップ数を増やしていき、探索する範囲を
広げていくという方法である。最初のホップ数や、増加していく量、RREP メッ
8
セージを待つ時間などについては詳しい規定がある メッセージを受け取ったノードは、すぐにそのメッセージの送信元への経路表
のエントリーがあるかどうかを調べ、もしなければ直ちに作成することになっ
ている。そして経路表のエントリーの送信先シーケンス番号は、そのメッセー
ジに含まれている情報から決定される。もしわからない場合は、シーケンス番
号が無効であるという情報を記録する。このような処理によって、経路表が徐々
に作成されているのである。実はこの処理は RREQ メッセージだけではなく、す
べての AODV のメッセージに対して行なわれる処理である。その処理後に、以下
の条件によりそれぞれ処理が行なわれる。 1. 重複して同じ RREQ メッセージが送信されないようにする 2. RREQ メッセージの送信元への経路表のエントリーをさらに更新する 3. ホップ数が制限以内であれば(TTL が 1 より大きければ)、ホップ数を増加
させるなどの RREQ メッセージの更新処理をして、自分の周辺ノードにブロ
ードキャストする 上記のような処理が行なわれ、経路表の作成とメッセージの転送をする。これ
を繰り返されることによって、RREQ メッセージをネットワーク上に広げる。RREQ
メッセージの処理イメージを図 2.3 に示す。この図の端末 S と端末 T が、それ
ぞれ送信元と送信先(目的端末)である。 図 2.3 RREQ メッセージのフラッディング[15] 9
2.7 RREP メッセージ 上記 2.6 で述べた RREQ メッセージが目的端末まで届くと、送信先端末はその
返事として、送信元へ向けて RREP メッセージを送信する。RREP メッセージヘ
ッダ図 2.4 に示すフォーマットになっている。タイプには「2」が入る。 タイプ(8)
R A
予約済み
(11)
Prefix(5)
ホップ数
(8)
送信先 IP アドレス (32)
送信先シーケンス番号(32)
送信元 IP アドレス(32)
送信元シーケンス番号(32)
図 2.4 RREP メッセージへッダ
RREP メッセージを作成する前に、送信先ノードは自身のシーケンス番号が
RREQ メッセージに書かれている送信先シーケンス番号よりも小さい場合、端末
自身のシーケンス番号を送信先シーケンス番号で書き換える。そして、その値
を RREP メッセージの送信先シーケンス番号に書き込む。ホップ数は 0 とする。
送信先 IP アドレスと送信元 IP アドレスには、RREQ メッセージに書かれてい
たものをコピーする。よって、名前だけ見ると逆になるが、このメッセージは
送信元 IP アドレスへ向かって送信される。RREP メッセージは、送信先端末だ
けではなく、中継端末であっても送り返すことができる。ただし、その端末に
RREQ メッセージに指定されている送信先へのアクティブな経路があり、有効な
送信先シーケンス番号が RREQ メッセージの送信先シーケンス番号以上であり、
かつ RREQ メッセージの D フラグ(Destination only ag)によって中間ノード
による返答が禁止されていない場合に限る。以上の条件を満たすときに限り、
中間ノードは送信元ノードに対して RREP メッセージを送信する。そのメッセー
ジのホップ数や送信先シーケンス番号は、そのノードの経路 表のエントリーからコピーしてくる。そうすることで、送信先ノードから RREP
メッセージが送信されてきたのと同じ状況を作り出すことができる。この処理
によって、経路が十分新しい場合には、無駄なメッセージの行き交いを少なく
することが可能となる。RREP メッセージは送信元と送信先の中間に位置するノ
ードらによって送信元へ送り返されるが、このときの経路は RREQ メッセージの
転送時に作られたものが用いられる。さらにその転送処理を行なうたびに、メ
ッセージの内容に従って送信先への経路表が作成・更新される。この処理によ
って、双方向の経路が完成する。このイメージを図で表したのが図 2.5 である。 10
図 2.5 RREP メッセージの返信[15-図 4] RREP メッセージを送信する端末は、経路表の送信元ノードへのエントリー内
の precursor リストに前ホップの IP アドレスが、送信先ノードへのエントリー
内の precursor リストに次ホップの IP アドレスがそれぞれ追加される。これら
のリストの端末は、次に説明する RERR メッセージを送信するために利用される。
[2] 2.8 RERR メッセージ AODV プロトコルは、リンクに障害が起こったかどうかを、DSR プロトコルと
ほぼ同様の手法を用いて検知する。リンクが失われたことを検知した場合、そ
の時点で経路表に存在している経路を無効化し(完全に消去するわけではない)、
その障害によって影響を受ける送信先をリストアップする。さらに、その影響
を受ける可能性がある隣接ノードを決定し、そのような隣接ノードへの適切な
RERR メッセージの送信を行なう。RERR メッセージヘッダは、図 2.6 の通りであ
る。タイプには「3」が入る。 11
タイプ(8)
N
予約済み
送信先数
(15)
(8)
不達送信先 IP アドレス(32)
不達送信先シーケンス番号(32)
不達送信元 IP アドレス(32)
不達送信元シーケンス番号(32)
:
図 2.6 RERR メッセージヘッダ 「不達送信先 IP アドレス」と「不達送信先シーケンス番号」は 1 つの組にな
っている。これは複数組連ねることができ、その個数を「送信先数」フィール
ドで示すようになっている。RRER メッセージはリンク障害を検知した場合だけ
ではなく、アクティブな経路がないノードへのデータパケットを受信した時や、
アクティブな経路に関する RERR メッセージを受け取った時にも作成される。リ
ンク障害を検知した場合には、そのリンクを利用する送信先のすべてを不達送
信先としてリストアップする。経路がない送信先へのパケットを受信した場合
は、単純にその送信先を不達送信先とする。アクティブな経路に対する RERR メ
ッセージを受信した場合は、その RERR メッセージを送信したノードを次ホップ
とするようなすべての経路の送信先を不達送信先としてリストアップする。そ
れから、そのリストの各不達送信先について経路表を検索し、precursor リス
トが空でないものを RERR メッセージの不達送信先として登録していく。このよ
うして作られた RERR メッセージは隣接ノードへブロードキャストされるが、も
しそのメッセージが 1 つの隣接ノードでしか必要でないとわかった場合は、ユ
ニキャストで送信される。なお、各不達送信先に対応する経路表のエントリー
はすべて無効状態になり、送信先シーケンス番号は増やされるか、または受信
した RERR からコピーされる。全体的な視点からこの処理を大まかにみると、
RERR メッセージは、リンク障害によって影響を受けるような送信元のノードへ
向かって広がっていくイメージになる(図 2.5)。すると RERR メッセージを受
信した各ノードは対応する経路が無効になるので、次に送信するときには再度
経路探索が行なわれるようになるのである。 12
図 2.7 RERR メッセージの伝播[15-図 6] もしアクティブな経路上でリンク障害が起こったら、障害を検知したノード
は、送信先がある程度近い場合に限り、その経路の修復を自分で行なうことが
できる。やり方は簡単で、そのノードが送信先のシーケンス番号を増やした RREQ メッセージをフラッディングするだけである。ただし RREQ メッセージの広がる
範囲は、パケットの送信元まで届かないように計算されて調整される。 ノードは RREQ メッセージの処理と同じように RREP メッセージを待つのだが、
その間、送信元から送られてくるデータパケットは破棄せずに溜め込んでいく。
そして RREP メッセージが届いて経路が再作成されたら、その経路に向かって溜
め込んできたパケットを送信する。もちろん、RREP メッセージが決められた期
間内に受信できなければ、RERR メッセージを送信して前述のエラー処理を行な
わなければならない。以上のようにして、リンクに障害が発生した場合でも、
経路の修復が自動的に行なわれる。 13
第 3 章 OLSR この章では今回の検証に使用するプロトコルである OLSR について記述する。 本研究では、私が所属しているユビキタスネットワークシステム研究室で用い
られている「OLSR」と呼ばれるルーティングプロトコルを使用した。 3.1 OLSR OLSR(Optimized Link State Routing) プロトコルは、プロアクティブ型ルー
ティングプロトコルである。このプロトコルでは、経路は通信を行う前に確立
されており、いつも直ちに通信を開始することができる。 OLSR プロトコルの主な特徴は、フラッディングを効率良く行うことである。
フラッディングとは、端末一機から同一パケットをネットワーク全ての端末へ
配信する、いわゆる一斉配信である。この方式では、端末の密集地が高ければ
高いほど効率的なフラッディングが行なえる。まず一般的なネットワークでフ
ラッディングを行なう場合は次のようなアルゴリズムが用いられる。送信元端
末は、自分に繋がるすべてのノードにパケットを送信する。一度送信したパケ
ットを再び受信した場合はそのパケットを破棄する多少の最適化方法は存在す
る。すべてのノードは必ず 1 回、送信処理を行なうルーティングプロトコルな
どによって生成される制御情報を載せたパケットは、ネットワークに参加して
いる全ノードに対して配信される場合が多い。OLSR プロトコルでは、フラッデ
ィングをマルチホップ無線ネットワークで効果的に実行するために、「MPR
(multipoint relay)集合」というノードを選択することにより、制御オーバ
ーヘッドの削減を図る。(図 3.1) 図 3.1 はマルチホップ無線ネットワーク上において、一般的なフラッディン
グを行った場合にパケットが移動する様子を矢印で表わす。図 3.1 の一番上の
端末は5本の矢印が出ている。パケットを受信したノード(今回の図では丸で囲
った5つの端末)はすべて、直ちにそのパケットを再送信する。この5つのノー
ドが電波を送信すると、残り7つのノードに電波が届き、それらはそのパケッ
トを受信する。しかし、同じ端末が何度も同じパケットを受信している。ここ
で OLSR の特徴である MPR 集合を行うことにより、効率よくパケットを送信する
ことができる。 OLSR では、すべてのノードがネットワークのトポロジーを把握する。この情
報も MPR 集合によってフラッディングされている。各ノードでは、そのように
して得たトポロジーを基にして経路を計算し、経路表(ルーティングテーブル)
を作成する。実際に行なわれるノード間の通信は、このルーティングテーブル
に従って行う。 14
図 3.1 MPR 集合処理前[16-図 1] 図 3.2 MRP 集合処理後 OLSR でやりとりされるパケットやメッセージは図 3.5 に示すフォーマット
で送受信される。パケットは UDP(User Datagram Protocol)のポート番号 698 番を使用し通信が行われる。OLSR のパケットは「パケットヘッダ」と複数の「メ
ッセージヘッダ」から成り立っている。パケットヘッダは、
「パケット長」と「パ
ケットシーケンス番号」で構成されている。パケット長はパケットのバイト数、
パケットシーケンス番号は新しいパケットが生成されるたびに“1” 加えた値
である。シーケンス番号は、どのパケットが新しいかを区別するために用いら
れている。メッセージヘッダは、
「メッセージタイプ」、
「有効時間」、
「メッセー
ジサイズ」、
「発信元アドレス」、
「TTL」、
「ホップ数」、
「メッセージシーケンス番
号」、「メッセージ本体」によって構成されている。メッセージタイプは、メッ
セージ本体に書かれているメッセージの種類を表し、0 から 127 である。有効
時間とは、受信後にこのメッセージを管理していなければならない時間であり、
仮数部と指数部で構成されている。メッセージサイズでは、メッセージの長さ、
発信元アドレスはこのメッセージを生成したノードをアドレスを表している。
15
TTL では、このメッセージが転送される最大ホップ数が指定されており、転送
されるときに必ず“1” 減少する。このフィールドが 1 か 0 の場合は転送され
ない。ホップ数は、このメッセージの生成元カラのホップ数であり、最初は 0 に
設定され、転送されるたびにメッセージが重複しないため値を“1”追加する。
制御メッセージには HELLO メッセージ、TC メッセージ、MID メッセージ、HINA メ
ッセージの 4 種類存在する。[2][6] *トポロジー:(どのノードがどのノードとどのように繋がっているかの情報) 3.2 HELLO メッセージ HELLO メッセージは、各端末が持つ情報「ローカルリンク情報」の配信を定
期的に(デフォルトでは 2 秒に 1 回)送信するメッセージである。HELLO メッセー
ジを受信することで隣接端末情報を把握することができる。HELLO メッセージを
送受信することで、自分の周囲にどんな端末がいるのか把握する。OLSR ではル
ーティングテーブルを作成するために、突き詰めると通信を行う上で最も重要
なメッセージである。 各端末が保持するデータのことをローカルリンク情報と言い、HELLO メッセー
ジが配信しているローカルリンク情報は、以下の 5 つで構成される。 ・リンク集合 ・隣接ノード集合 ・2 ホップ隣接ノードとそれらのノードへのリンク集号 ・MPR 集合 ・MPR セレクタ集合 3.2.1 ローカルリンク情報 リンク集合とは、直接電波が届く端末(隣接端末)の集合へのリンクのことで
ある。各リンクは 2HOP のアドレスと有効時間によって表現されている。有効時
間は、そのリンクが単方向なのか双方向なのかを表すためにも利用されている。
隣接ノード集合とは、各端末のノードの再送信への積極度(Will-ingness)な
どによって構成されている。 隣接ノード集合のさらに先に存在するノード集合、MPR として選択された隣
16
接ノードの集合の場合、もし自身が MPR として選択されている場合には自分を
MPR として選択しているノードの集合(MPR セレクタ集合)などの情報が、ロ
ーカルリンク情報として各ノードに存在している。HELLO メッセージは、初期
の段階では自分の存在をアピールするために、自分の IP アドレスを HELLO メッ
セージとして隣接ノードへ向けてブロードキャストする。これをすべてのノー
ドが行い、各ノードは自分の周りにどんなアドレスを持ったノード(隣接端末情
報)がいるのかを把握する。この段階では、各端末の隣接関係が双方向かどうか
は不明で、送信元から自分のノードへのリンクがあるということしかわからな
い。構築されたローカルリンク情報の殆どは、再び HELLO メッセージによって
定期的に送り続けられる。これを繰り返すことで、各リンクが双方であるのか、
隣接ノードの先にはどんなノードがあるのかが徐々に明らかになってくる。こ
れらの情報もローカルリンク情報として蓄えられていく。 さらに、MPR に関する情報もこの HELLO メッセージで定期的に送信されてい
く。 3.2.2 MPR 集合 MPR 集合とは、OLSR プロトコルが動いているネットワーク上でフラッディン
グを行う際、パケットの再送信を責任をもって行うノードの集まりのことであ
る。これはネットワーク上の各ノードによって、隣接ノード集合の中から選ば
れている。各ノードは、
Willingness という 0 から 7 の範囲の値を持っており、
この値が高ければ高いほど、MPR 集合として選ばれやすくなる。この値は HELLO メッセージによって送信されるので、周辺に存在するノードは、 どのノードがどれだけ再送信に対して積極的であるかを把握する。0 の場合は
MPR として選ばれず、7 の場合には積極的に選ばれる。通常の値は 3 である。
Willingness は値に名前が付けられている。以下表 3.1 表 3.1: Willingness の定数と値 定数名 値
WILL_NEVER 0
WILL_LOW 1
WILL_DEFAULT
3
WILL_HIGH
5
WILL_ALWAYS
7
17
3.3 TC メッセージ 上記で述べた HELLO メッセージにより、各端末は隣接端末情報を保持できた。
しかし、経路表(ルーティングテーブル)はまだ作成されていない。OLSR プロト
コルでは、HELLO メッセージとは別に、TC(Topology Control)メッセージ(デ
フォルトで 5 秒に 1 回)フラッディングすることにより、HELLO メッセージが届
かない範囲(隣接端末、すなわち再送信は行なわれない)に隣接情報を伝える事
が出来る。すなわち、TC メッセージはネットワーク全体へ各端末の隣接情報を
フラッディングするメッセージである。各ノードはそのトポロジー情報を基に
して実際の通信経路を計算し、経路表を構築する。
「トポロジーといっても、実
際に存在するすべてのリンクから構成されるトポロジーではなく、基本的には
各ノードの MPR セレクタ集合から構築されるトポロジーであるため、管理する
リンク数は実際のリンク数よりも非常に少ない。ここでも MPR の思想がうまく
生かされているわけである。[2]」TC メッセージは MPR として選択されている
すべてのノードが定期的に発信する。各ノードはそのトポロジーを用いて最短
路を計算し、それに基づいて経路表を作成する。 3.4 OLSRv2 OLSRv2 は 2014 年 4 月に IETF により公開された新たなプロトコルであり、
OLSRv1 を元に考案されたプロアクティブ型経路制御プロトコルである。OLSRv2 と OLSRv1 は、さほど機能の仕様の変更はない。すなわちハローメッセージに
隣接ノードの情報を含めることにより各ノードが2ホップ先までのノードを把
握する隣接ノードの中から MPR(multipoint relay)と呼ばれるノードを選択
する方式、各 MPR が自身の部分トポロジー情報(MPR セレクタと MPR 間のリ
ンク情報を MPR フラッディングと呼ばれる方法によりネットワーク全体へ効率 的に配布する方式などは共通である。しかし、OLSRv2 にはいくつかの改良機能
が追加されている。
「例えば、より早くリンク切断を検知することでパケット損
失を削減できるリンク切断通知機能,経路制御メッセージのサイズを削減でき
るアドレスのサイズ圧縮機能,遠距離ノードへのメッセージ送信周期を大きく
することによりメッセージを削減できるフィッシュアイ(fish eye)機能など
が挙げられる.[7]」 3.5 fish eye 機能 TC メッセージの保持時間をメッセージの生成元からのホップ数に依存して
与えることが可 能である.これにより,遠距離のノードへはメッセージの送信
周期を大きくすることにより, メッセージ数を削減することが可能となる.こ
18
の方法はフィッシュアイと呼ばれる.[9] 3.6 OLSRv2 の HELLO メッセージ 本研究でも最も深く扱うパケットフォーマットに大きな違いがある。従来の
OLSR のパケットフォーマットはフィールドの値が固定であり、とても見やすい
仕様になっている図 3.5 図 3.3 OLSR のパケットフォーマット
OLSR では複数メッセージを格納する固有のパケットフォーマットおよび機能
ごとの固有メッセージフォーマットを使用している。それに対し、OLSRv2 では
本論文冒頭部で述べたような他のルーティングプロトコルとの一般生を持たせ
るために制御メッセージパケットのフィールドの値が固定ではなく、図 3.4 の
ような、「TLV」を用いて書かれている。OLSRv2 のパケットフォーマットは主に
パケットヘッダ、メッセージヘッダ、アドレスブロックと大きく別れており、
長さが固定ではなく以下に記載するような TLV が詰まったような構造になって
いる。 図 3.4 OLSRv2 のパケットフォーマット 19
3.7 TLV TLV とは TYPE,LENGTH,VALUE の総称であり、情報の種類(type)・長さ(length)・
値(value)をセットにして表現するフォーマットである。Type と length は固定
長(通常、1~4 バイト)である。value(値)のフィールドは可変長である。各
フィールドは以下を表す。[8]。 ・TYPE 情報の種類に対応した数値または文字
・LENGTH 次に示す value フィールドのサイズ(数値)
・VALUE 可変長のデータであり、情報の大きさの実際の数値
3.7.1 TLV の種類 例として今回扱う TLV の種類とその値の意味について記載する。 OLSRv2 のメッセージ TLV の例として、VALIDITY-TIME と INTERVAL-TIME がある。
VALIDITY-TIME はメッセージの受信後、そのメッセージの内容が有効とされる時
間であり、その value には与えられた保持時間を表わす値が入る。保持時間の
値は通常、メッセージ周期の 3 倍程度に設定される。HELLO メッセージの
VALIDITY-TIME の value をメッセージの生成元からのホップ数に依存して与えら
れる。これによって遠距離のノードへはメッセージの送信周期を大きくするこ
とにより、メッセージ数を削減することが可能になる。[2]このような方法のこ
とをフィッシュアイと呼ぶ。HELLO メッセージにおいて MPR という type の TLV を追加することにより、各端末自身が MPR として選択したことを相手隣接
ノードに通知する。これにより、相 手ノードは自身の MPR セレクタを知るこ
とができ、MPR セレクタセットを生成する。OLSR ではトポロジーセットのみを
トポロジー情報ベースと呼んでいたが、OLSRv2 では広告隣接セット、付属ネッ
トワークセット、ANSN 履歴セット、ルーティングセット(経路表)も含めてト
ポロジー情報ベースと呼んでいる。
「トポロジーセットは終点ノードのインタフ
ェースアドレスとその終点へ至る最 終ホップのノードのインタフェースアド
レスの対応を示すものである。広告隣接セットは MANET 全体に広告すべき対称
隣接ノードのインタフェースアドレス(MPR セレクタを必ず含む)の集合であ
り、ANSN(advertised neighbor set sequence number)という値を保持する。
広告隣接セットが更新されると ANSN の値を増やす。付属ネットワークセットは
他の MANET ノードに付属するネットワークのネットワークアドレスとそこへ
至るゲートウェイとなる MANET インタフェースの対応を示すものである。ここ
で付属ネットワークとはノードの MANET インターフェース以外のインターフェ
ースを経由してつながるネットワークのことである。ノードに付属ネットワー
クが追加・削除された場合も ANSN の値を増やす。[6]」アドレスブロックと
20
TLV を使用する汎用的なメッセージフォーマットの利用により、OLSR で使用さ
れていた MANET 外部へのインタフェースを広告する HNA メッセージは、OLSRv2 では TC メッセージに統合されている。OLSR のマルチインタフェースアドレスを
広告する MID メッセージは OLSRv2 では HELLO と TC メッセージに統合されてい
る。TLV では、HELLO メッセージや TC メッセージは複数の IP アドレスを運ぶ必
要がありメッセージサイズが増大する。しかし、TLV を用いることにより、アド
レスブロックのサイズ圧縮ができる。さらに以上のことより TLV を用いること
により、新たな情報を追加しやすくなっている。 3.8 ルーティングテーブル ルーティングテーブルとはルータや端末が保持するパケットの配送先に関す
る経路情報のことである。TCP/IP ネットワークでは、パケットを送ろうとする
とき、ルーティングテーブルを参照してパケットを送信する相手を判断する。 ある端末から他の端末へとパケットを送ろうとする場合、目的の端末がネット
ワーク内にない場合、端末内にあるルーティングテーブルを参照し、パケット
を中継させる端末を決定する。ルータなど多くの機器はダイナミックルーティ
ングによってルーティングテーブルを管理するが、特にルーティング処理を行
う必要のない端末はスタティックルーティングの一種である「デフォルトルー
ティング」を用いることが多い。[9] 3.9 route コマンド route コマンドとは、ルーティングテーブルの内容表示と設定を行うコマン
ドである。ルーティングテーブルには以下の意味がある。 • ルーティングテーブルの表示と確認
• ルーティングテーブルへの経路の追加、削除、変更
ルーティングテーブルの表示を行うためには以下のコマンドを実行する。
route[ -n][ -v][ -e— -ee][ -F][ -C][ -A アドレスファミリ名]
21
第 4 章 システム提案 本研究では、ネットワーク攻撃によりネットワークがどのような影響を受け
るのかを検証するために HELLO メッセージ、TC メッセージのパケットを盗み見
し、偽 HELLO メッセージを送信するツールを開発した。以下、今回作成したツ
ールを OLSR_Analizer と名付ける。今回開発した OLSR_Analizer のプログラム
の解説やプログラムのソースコード等は付録にて記載する。 今回 OLSR_Analizer を開発する上で IETF による RFC を参考にした。 4.1 IETF IETF とはインターネットで利用される技術の標準化を推進する組織である。
原則として誰でも個人の資格で参加できる。 通信プロトコルやデータ形式など、インターネットで情報を交換するのに必要
な技術標準の策定を行っており、メーリングリストや年 3 回の全体会議で各規
格の仕様の検討が行われている。議論の過程はすべて公開され、誰でも見るこ
とができる。 IETF で決定された規格は、各規格ごとに“RFC 2626”のような、通し番号が
付けられ、
「RFC」(Request For Comments)と呼ばれる文書にまとめられ、公開
される。 IETF は原則として、例えば、物理層の通信システムや、Web(WWW)関連の技術
については IEEE の標準他の標準化団体が対象としている技術分野になどは取り
扱わない。ちなみに Web は W3C(World Wide Web Consortium)の標準をそれぞれ
参照している。[11] 4.2 RFC RFC とは、インターネットに関する技術の標準を定める団体である IETF が正
式に発行する文書の事である。例えば、IP(RFC 791)、TCP(RFC 793)、HTTP(RFC 2616)、FTP(RFC 959 など)などインターネットで利用されるプロトコルや、その
他インターネットに関わるさまざまな技術の仕様を通し番号をつけて公開して
いる。IETF では定期的に技術の標準化動向を一覧できる RFC を発行している。 標準化動向をまとめた RFC の通し番号は 100 の倍数になる慣例がある。 毎年 4 月 1 日には数件の(よくできた)ジョーク RFC が発行されるのが通例で、
こちらは「伝書鳩プロトコル(RFC 1149 など)」
「コーヒーポット制御プロトコル
22
(RFC 2324)」などが著名。[12] 本研究で参考にした RFC は以下である。 ・RFC 6130 Neighborhood Discovery Protocol ・RFC 5444 Packet/Message Format ・RFC 7181 The Optimized Link State Routing Protocol Version 2 4.3 HELLO メッセージの傍受 OLSR によって構築されているネットワークではルーティングテーブルを構築するために各端
末が定期的に(デフォルトで 2 秒に 1 回)隣接端末情報を HELLO メッセージとしてフラッディン
グし交換しあっている。 HELLO メッセージは第 2 レイヤで通信されており、OLSR では Hello メッセージを受信した際
に、データリンク層(MAC 層)の無線リンクコントロール部にて、Hello メッセージの送信に使用された
IP パケット及び MAC フレームを解析して、その送信元の通信装置の IP アドレスと MAC アドレ
スを取得し、これらを対応付けたアドレスエントリを、ARP 情報管理・設定部を通じてネットワ
ーク層の ARP テーブルに設定(登録)する。[13] 次に、ARP(Address Resolution Protocol)について説明する。ARP は、
Ethernet(登録商標)環境において、IP アドレス(ネットワーク層の論理アドレス)から MAC アド
レス(データリンク層の物理アドレス)を得るために用いられるプロトコルである。レイヤー 3(L3)で
あるネットワーク層で処理される IP パケットのフォーマットを示してある。IP パケットは、送信元の
IP アドレスが格納される Source IP Address(F41)、宛先の IP アドレスが格納される
Destination IP Address(F42)、トランスポート層やアプリケーション層などの上位層のプロトコル
(例えば、OLSR)のデータが格納される TransPort Layer/Application Layer Protocol Data(F43)などの領域を有する。 以上のことより、HELLO メッセージは第 2 レイヤで**** であることに注目し、今回プロミスキャスモードを用いて、ネットワークに流れる制御メッセージを
傍受することにした。 4.3.1 プロミスキャスモード プロミスキャスモードとは、ネットワークカードの動作モードの一つで、ネ
ットワークを流れるすべてのパケットを受信して読み込むモード。別名、
「無差
別モード」と呼ばれる。 ネットワークカードは通常、宛先が自分になっているパケットのみを受信す
るよう設定されているが、ケーブルから別の宛先のパケットが届いても読み込
まずに破棄するようになっている。プロミスキャスモードに設定したカードで
23
は、宛先に関わらずすべての受信パケットを上位レイヤのソフトウェアに引き
渡すため、そのセグメントを流れるすべてのデータを監視することができる [14]。 4.4 OLSR_Analizer 仕様 ここで実際の OLSR_Analizer のプログラムの各部位や関数の役割などを説明
する。 まず、116 行目、図 4.1 より OLSR のパケットヘッダを習得し、TLV を解析す
る。 for(i=0;i<(int)u_len-sizeof(struct udphdr);){
if(i==0) printf("olsr data
: ");
else
printf("
");
for(j=0;j<4;j++){
printf("%2.2x ",p[i]);
i++;
if(i==(int)u_len-sizeof(struct udphdr)) break;
}
printf("¥n");
}
図 4.1 OLSR のパケットヘッダ習得解析部 143 行目、図 4.2 よりメッセージヘッダを解析する。 if(olsr_msg_hdr->type == 0x05) printf(" msg-type : HELLO¥n");
if(olsr_msg_hdr->type == 0x06) printf(" msg-type : TC¥n");
if((olsr_msg_hdr->flags & 0xf0) != 0xf0){
printf("Not msg_flags = 0xf0 packet!¥n");
continue;
}
if((olsr_msg_hdr->flags & 0x0f) != 0x03){
printf("Not IPv4 address!¥n");
continue;
}
msg_size = (int)ntohs(olsr_msg_hdr->size);
printf(" msg_size
: %d¥n",msg_size);
24
printf("
meg_orig_addr : %s¥n",inet_ntoa(olsr_msg_hdr->orig_addr));
printf(" msg_hop_limit : %d¥n",olsr_msg_hdr->hop_limit);
printf(" msg_hop_count : %d¥n",olsr_msg_hdr->hop_count);
printf("
msg_seq_num
: %d¥n",ntohs(olsr_msg_hdr->seq_num));
図 4.2 OSLR メッセージヘッダ解析 そして、165 行目、図 4.3 より各 TLV の解析をする処理を書いた。 p = p + MSG_HEADER_SIZE;
msg_size = msg_size - MSG_HEADER_SIZE;
p_short = (unsigned short *)p;
tlvs_length = *p_short;
tlvs_length = (unsigned int)ntohs(*p_short);
printf(" Message_tlvs¥n");
printf("
tlvs_length
: %d¥n",tlvs_length);
p = p + sizeof(short);
msg_size = msg_size-sizeof(short);
for(i=0;i<tlvs_length;){
printf("
tlv¥n");
ptlv = (struct tlv *)p;
if(ptlv->type == 4) printf("
tlv_type
:
MPR_WILLING¥n");
else if(ptlv->type == 35)
printf("
tlv_type
: VALIDITY_TIME¥n");
else if(ptlv->type == 30)
printf("
tlv_type
: INTERVAL_TIME¥n");
else if(ptlv->type == 6)
printf("
tlv_type
: CONT_SEQNUM¥n");
else
printf("
tlv_type
: %2.2x¥n",ptlv->type);
p = p + 1;
i++;
printf("
tlv_flags
if(ptlv->flags != 0x10){
25
: %2.2x¥n",ptlv->flags);
printf("It is Message TLV, but flags !=
0x10!¥n");
k=1;
}
p = p + 1;
i++;
printf("
p = p + 1;
i++;
printf("
length
: %d¥n",ptlv->l_v[0]);
value
:");
if (ptlv->l_v[0] == 2){
p_short = (unsigned short *)p;
printf(" %d¥n",ntohs(*p_short));
j=2;
}else {
for(j=0;j<ptlv->l_v[0];j++){
printf(" %2.2x",ptlv->l_v[j+1]);
}
printf("¥n");
}
p = p + j;
i = i+j;
}
msg_size = msg_size-tlvs_length;
for(;msg_size > 0;){
printf(" Address Block¥n");
num_addr = *p;
printf("
num_addr
: %d¥n",num_addr);
p = p+1;
msg_size = msg_size-1;
printf("
addr_flags
: %2.2x¥n",*p);
if (*p == 0x00){
p = p + 1;
msg_size = msg_size-1;
for(i=0;i<num_addr;i++){
26
IP_addr
IP_addr
p_int = (unsigned int *)p;
addr.s_addr = (in_addr_t) *p_int;
printf("
: %s¥n",inet_ntoa(addr));
p = p + 4;
}
msg_size = msg_size - 4*num_addr;
}
if (*p == 0x80){
p = p + 1;
msg_size = msg_size-1;
head_length = *p;
p = p + 1;
msg_size = msg_size-1;
for(i=0;i<head_length;i++){
ip_addr[i]=*p;
p = p + 1;
msg_size = msg_size-1;
}
for(i=0;i<num_addr;i++){
for(j=0;j<4-head_length;j++){
ip_addr[head_length+j]=*p;
p = p + 1;
msg_size = msg_size-1;
}
p_int = (unsigned int *) ip_addr;
addr.s_addr = (in_addr_t) *p_int;
printf("
: %s¥n",inet_ntoa(addr));
}
}
p_short = (unsigned short *)p;
tlvs_length = *p_short;
tlvs_length = (unsigned int)ntohs(*p_short);
printf("
tlvs_length
: %d¥n",tlvs_length);
27
tlv_type
tlv_type
tlv_type
tlv_flags
p = p + sizeof(short);
msg_size = msg_size-sizeof(short);
for(i=0,l=0;i<tlvs_length;){
printf("
tlv¥n");
ptlv = (struct tlv *)p;
if(ptlv->type == 1)
printf("
: ORIGINATOR¥n");
if(ptlv->type == 2)
printf("
: ROUTABLE¥n");
if(ptlv->type == 3)
printf("
: ROUTABLE_ORIG¥n");
l++;
printf("
: %2.2x¥n",ptlv->flags);
if(ptlv->flags != 0x10){
if(ptlv->flags != 0x14){
printf("can not analize addr
tlv!¥n");
k=1;
}
length
}
l++;
printf("
: %d¥n",ptlv->l_v[0]);
l++;
printf("
value
:");
for(;l < tlvs_length;l++){
printf(" %2.2x",ptlv->l_v[j+1]);
if (l>50){
k=1;
break;
}
}
printf("¥n");
p = p + l;
i = i+l;
28
}
msg_size = msg_size-tlvs_length;
}
}
図 4.3 TLV 解析 4.5 OLSR_Analizer の表記 前述 4.3 の考案により、HELL メッセージ、TC メッセージのパケットを傍受す
る。そして、OLSR_Analizer では傍受したパケットの中身を 16 進数表記でツー
ルを実行させた端末に表示させる。OLSRv2 ではパケットが前述のように TLV の
集合であり、フィールドの値が固定ではない。よって、端末にそのパケットが
何を表しているのか意味が分かるように表記させるためには TLV を解析し、フ
ィールド値 TYPE で宣言されているフラグによりそのパケットが何を表している
のか判定する必要がある。そのため IETF()の RFC()より TYPE のフラグ種類のパ
ターンをプログラムに書き込むことで、端末に表示する際にパケットのフィー
ルド値の TLV の一つ一つの意味まで分かるように表示させた。 4.6 OLSR_Analizer による偽 HELLO 作成 前述までで、ネットワーク内にどのような IP アドレスを持った端末が存在す
るのかを、プロミスキャスモードにより盗み見し、把握した。では次に前述 1.2
研究の目的で述べたように、ネットワークを混乱、破壊するようなセキュリテ
ィ攻撃を検証する。本来ならば、OLSR_Analizer に偽 HELLO を作成し、ネットワ
ークに流すことによりネットワークを混乱させることを検証する予定であった
が、学部生生活の中では達成するに至らなかった。そこで、本来実装するはず
であった偽 HELLO についての考察を述べ、今後の課題とする。 では、ここより、実装には至っていないが提案した方式を述べる。 まず、上記で述べたように、ネットワーク内にどのような端末が存在するの
か把握した。その後、その隣接端末情報を元にネットワークを混乱させるため
にセキュリティ攻撃を行う。そのために、OLSR_Analizer に「各端末がそれぞれ
に全ての端末が隣接である」と勘違いするような偽りの隣接情報の書かれた
HELLO メッセージを作成する機能を追加する。偽 HELLO を作成した後、ネットワ
ークに HELLO メッセージとしてブロードキャストすることにより、偽 HELLO メ
ッセージを受信した端末は全ての端末が隣接関係にあるという情報を元にルー
ティングテーブルを作成することになるため、ある端末から見ると本来、中継
端末であるはずの端末が直接通信できると勘違いするために本来中継端末であ
る端末には通信が届かないため、通信ができなくなる。図 4.4~4.5 29
宛先
端末
Next
Hop
A
A
B
B
D
D
E
E
F
B
G
B
表 4.4 正常なルーティングテーブル
宛先端
末
Next
Hop
A
A
B
B
D
D
E
E
F
F
G
G
図 4.5:理論上不正端末により書き換えられたルーティングテーブル 30
第 5 章 動作実験 この章では実際に OLSR_Analizer を起動させ、そのシステムについて述べる。 5.1 検証環境 今回、検証に使用した環境が以下である。 •
•
•
•
•
・
ノートパソコン 4 台
OS:Ubuntu 14.04
OLSR_Analizer 実装 PC:1 台
アドホックネットワークを構築する PC:3 台
アドホックネットワークのルーティングプロトコル:OLSRv2
ルーティングソフト:nuOLSRv2
5.2 システムを動作させるための準備 本研究を実証するための環境作りと手順を述べる。 5.2.1 OLSRv2 の起動手順 まずは、アドホックネットワークを構築するために OLSRv2 のプロトコルを使
用するために nuOLSRv2 起動させる。本研究で使用するルーティングソフトであ
る nuOLSRv2 は私の所属する研究室の共同 HDD にあるものを使用した。保存形式
は圧縮ファイルである zip だったため、まずは私の作業するパソコン及びディ
レクトリに保存する。その後解凍し、make コマンドによりコンパイルする。こ
の時、
「そのようなファイルは見当たりません」のようなコンパイルエラーが出
た場合の対処方法は以下である。 まず、nuOLSRv2 ファイルの一番上のディレクトリに保存されている
00ReedMe.txt の 6.2 nuOLSRv2 の記載事項に従う。 1. Change the current working directory to nuOLSRv2d/.
2. Copy config.mk.in to config.mk
3. Edit config.mk if you want to change compile options.
4. Type make
5. Copy nuOLSRv2d.conf.sample to nuOLSRv2d.conf
6. Edit nuOLSRv2d.conf
7. Type ./nuolsrv2d nuOLSRv2.conf
31
コンパイルが無事できたら、cd コマンドで/nuOLSRv2/nuOLSRv2d ディレクト
リに移動し、 最後に以下のような宣言の仕方で「./コマンド」を実施し、OLSRv2 を実行する。 #./nuolsrv2d nuOLSRv2d.conf
図 5.1 nuolsrv2d の起動コマンド
図 5.2 nuolsrv2d 起動画面 2
32
図 5.3 nuolsrv2d 起動画面 3
上記図 5.1~5.3 では 192.168.10.100 というアドレスの端末が HELLO メッセー
ゾをブロードキャストし、192.168.30.10.と 192.168.30.30 のアドレスの端末
が recv していることがわかる。 33
5.2.2 隣接端末の確認 OLSRv2 の HELLO メッセージ及び TC メッセージにより各端末がそれぞれの隣接
端末情報をフラッディングすることによりルーティングテーブルを作成し、ネ
ットワークを構築している。実際にどのようなルーティングテーブルができて
いるのか確認するには route コマンド使う。本実験での route コマンドを実行
した様子は以下である。 図 5.4 192.168.10.100 のルーティングテーブル PC3 台でアドホックネットワークを構築することに成功した。各端末のルーテ
ィングテーブルをまとめたものが以下である。今回ルーティングテーブルを説
明するにあたり IP アドレスと端末名を関連付けて見やすく説明する(図 5.5)。 そして、図 5.4 のルーティングテーブルを各端末ごとに見やすく抽象化する(図
5.6~5.9)。 以下の図を見てみると、PC4 のルーティングテーブルをみると、PC1 とは直接
つながっており、PC2 と PC3、とは PC1 を経由したマルチホップ通信をしている
ことがわかる。 端末名
IP アドレス
PC1
192.168.30.10
PC2
192.168.30.20
PC3
192.168.30.30
PC4
192.168.10.100
図 5.5 端末名とその IP アドレス
34
PC1
宛先端末
NextHop
PC2
PC2
PC3
PC3
PC4
PC4
図 5.6 PC1 のルーティングテーブル
PC2
宛先端末
NextHop
PC1
PC1
PC3
PC3
PC4
PC1
図 5.7 PC2 のルーティングテーブル
PC3
宛先端末
NextHop
PC1
PC1
PC2
PC2
PC4
PC1
図 5.8 PC3 のルーティングテーブル
PC4
宛先端末
NextHop
PC1
PC1
PC2
PC1
PC3
PC1
図 5.9 PC4 のルーティングテーブル
35
5.3 OLSR_Analizer の起動 OLSR_Analizer の起動手順は以下の順序通りである。 まず端末から OLSR_Analizer のプログラムが保存されているディレクトリに移
動する。移動の際は cd コマンドを使用する。 図 6 cd コマンド
次にコンパイルして、バイナリを作成する。コンパイルには gcc コマンドを使
用する。 図 7 gcc コマンド
バイナリが作成出来たことを確認出来たら実行コマンドを使い OLSR_Analizer
を起動させる。
36
図 8 OLSR_Analizer 起動画面 1
37
図 9 OLSR_Analizer 起動画面 2
38
5.4 起動画面解説 上記図 8,9 をみると、図 8 の上部に 16 進数で 4*14 で表記されている部分が
ある。ここは、とあるパケットの一つのデータであり、HELLIO メッセージの中
身本体である。この 16 進数はそれぞれ下記図 10 で表すように TLV の集まりで
構成されている。OLSR_Analizer では、この盗み見した 16 進数表記のデータを
前述で説明したように、TLV フラグなど解析して図 8,9 の 16 進数表記の下部よ
り、意味のわかりやすいように表記させた。 以下図 10 では、盗み見したパケット一つを例に挙げ、色分けをして、TLV の
意味を表記する。色分けされているフィールド一つ一つが TLV であり、意味は
以下図 10 の表の通りである。 今回図 10 で色の付いていない下 2 行については、RFC の解読ができていない
ため、TLV を解析できていない。よって、白い部分については今後解析する。 00
32
0a
58
10
10
10
00
0a
10
00
1e
10
05
c0
01
00
01
01
01
c0
00
01
c0
00
01
f3
a8
00
0c
03
58
64
a8
04
00
a8
04
01
00
1e
01
04
1e
23
01
1e
01
01
1e
02
05ならH ELO O メッセージである。
fとは2進数で1111となり、R FC よりorig-addがあることを表す。
R FC よりM S G -addrを表す=IP v4
メッセージサイズを表す。
この場合50バイトある。
自分のアドレスを表す。
ホップリミットを表す。
ホップカウントを表す。
これより下にTLV がある。この場合12バイトある=3つのTLV
1つ目のTLV 。TLV フラグ。この場合10なのでTLV が存在する、
2つ目のTLV 。1eはインターバルタイムを表す。この場合58
3つ目のTLV バリティティータイムを表す。この場合64
ここからaddr-blockを表す。
01とは一つのアドレスが入っていることを表す。
自身のアドレスを表す。この場合10進数表記で192.168.30.10
隣接のアドレスを表す。この場合192.168.30.30
図 10 パケット解析
39
6 結論 アドホックネットワークのセキュリティ対策の必要性を明らかにする事を目
的にアドホックネットワークのセキュリティ攻撃により OLSR を用いたネットワ
ークを構築するための HELLO、TC を盗み見るツールを開発、実施した。 その結果、今回傍受することが出来たが、パケット解析の点で、解析が不十分
なところもある。よって引き続き RFC の解読を行うと共に、偽物の HELLO を作
成して送信するプログラムが未完成のため、今後偽装して送信するプログラム
を追加し、ネットワークを壊せる事を確認する。 最後に、将来的には第三者による情報を傍受、セキュリティ攻撃によりネッ
トワークが危機に侵されないよう HELLO、TC のセキュリティを暗号化するなど、
検討していきたい。 謝辞 本研究を進めるにあたり、ご指導を頂いた卒業論文指導教員の松井 進教授
に感謝いたします。また、多くの知識や示唆を頂いた先生方や他研究室の皆々
様、並びに、二年間共に研究を頑張ってきたユビキタスネットワークシステム
研究室の皆様に感謝します。最後に、4 年間学生生活、研究を無事贈れたのはこ
こまで支えてくださった親のおかげであり、とても感謝いたします。 皆様、本当にありがとうございました。
40
参考文献
[1] マルチインターフェースアドホックネットワークにおけるチャンネル使用
状態を考慮した経路制御手法の提案と実装 <http://l252-17.is.oit.ac.jp/Close/pdf/AN2007-24.pdf> [2] アドホックネットワークにおけるネットワークトポロジーモニタリング システムの開発 東口義隆 3ページ目17行目 [3] ITpro コンピューティングの未来!「いつでもつながる」の到来(下) <http://itpro.nikkeibp.co.jp/members/NBY/techsquare/20050118/154884/> [4] ルーティングプロトコル <http://www.kawachi.zaq.ne.jp/dpdee706/routing.html#hybrid> [5] HITACHI 通信のバケツリレーでデータを届ける"マルチホップルーティング" <http://www.hitachi.co.jp/rd/portal/story/ami_wirelessnetwork
/02.html> [6] 第 6 回 OLSR(Optimized Link State Routing)プロトコル <http://internet.watch.impress.co.jp/www/column/wp2p/wp2p06.htm> [7] OLSRv2 wikipedea <http://en.wikipedia.org/wiki/Optimized_Link_State_Routing_Protocol#OL
SR_version_2> [8] Type-length-value <http://ja.wikipedia.org/wiki/Type-length-value> [9] 千葉大学大学院工学研究科 修士論文 アドホックネットワークにおける プロアクティブ型経路制御の適用限界
<http://www.qos.tu.chiba-u.jp/thesis/2009_m2_choyo_kou.pdf> 41
[10] ルーティングテーブル <http://e-words.jp/w/E383ABE383BCE38386E382A3E383B3E382B0E38386E38
3BCE38396E383AB.html> [11] IETF IT 用語辞典 <http://e-words.jp/w/IETF.html> [12] RFC IT 用語辞典 <http://e-words.jp/w/RFC.html> [13] 通信装置 <http://www.google.com/patents/WO2013073209A1?cl=ja> [14]プロミスキャスモード it 用語辞典 http://e-words.jp/w/E38397E383ADE3839FE382B9E382ADE383A3E382B9E383A2E3
83BCE38389.html [15] 第 7 回 AODV(Ad hoc On-Demand Distance Vector)プロトコル http://internet.watch.impress.co.jp/www/column/wp2p/wp2p07.htm [16] 第 6 回 OLSR(Optimized Link State Routing)プロトコル http://internet.watch.impress.co.jp/www/column/wp2p/wp2p06.htm 42
付録 OLSR_Analizer のプログラム
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <pthread.h>
#define OLSR_PORT 10693
#define PKT_HEADER_SIZE 1
#define MSG_HEADER_SIZE 12
//threadtuika
#define PORT 9876 //通信使用ポート番号
void sakamoto(void *);
int trash ;
//kokomade
//
struct ex_data {
int cnt;
char ip_addr[100][16];
} ex_data;
//
pthread_mutex_t mutex;
43
void enqueue(struct in_addr addr);
int main(int argc, char **argv)
{
int sock;
struct packet_mreq mreq;
//threadgomi
trash=0;
//gomi
sock = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));
if (sock < 0) {
perror("socket");
return -1;
}
memset(&mreq, 0, sizeof(mreq));
mreq.mr_type = PACKET_MR_PROMISC;
mreq.mr_ifindex = if_nametoindex("eth0");
if (setsockopt(sock, SOL_PACKET,
PACKET_ADD_MEMBERSHIP, (char *)&mreq,
sizeof(mreq)) != 0) {
perror("setsockopt");
return -1;
}
char buf[2048];
int n,i,j;
unsigned char *p;
struct iphdr *ip;
char s_addr[16], d_addr[16];
struct in_addr saddr, daddr;
char protocol[16];
struct udphdr *udp;
unsigned short sport, dport, u_len;
44
struct OLSR_MSG_hdr {
unsigned char
type;
unsigned char
flags;
unsigned short
size;
struct in_addr
orig_addr;
unsigned char
hop_limit;
unsigned char
hop_count;
unsigned short
seq_num;
}
*olsr_msg_hdr;
int msg_size;
unsigned int tlvs_length;
struct tlv {
unsigned char
type;
unsigned char
flags;
unsigned char
l_v[20];
}
*ptlv;
unsigned char num_addr;
unsigned char ip_addr[4];
struct in_addr addr;
unsigned char head_length;
unsigned short *p_short;
unsigned int *p_int;
int k,l;
//threadKoKokara
pthread_t saka;
pthread_create( &saka, NULL, (void *)sakamoto, &trash);
//koko
for(k=0;k==0;){
n = recv(sock, buf, sizeof(buf), 0);
if (n < 1) {
perror("recv");
return 1;
}
45
p = buf;
ip = (struct iphdr *)p;
saddr.s_addr = ip->saddr;
daddr.s_addr = ip->daddr;
strcpy(s_addr,inet_ntoa(saddr));
strcpy(d_addr,inet_ntoa(daddr));
//thread addresadd
//iplist kakikomutokoro //koko ifbunn tokakaku /* kakikomu bekika
check*/
// strcpy(ex_data.ip_addr[ex_data.cnt],s_addr);
//
ex_data.cnt++;
//ex_data.y=s_addr;
//
strcpy(protocol,"Others");
if (ip->protocol == 1) strcpy(protocol,"ICMP");
if (ip->protocol == 6) strcpy(protocol,"TCP");
if (ip->protocol == 17) strcpy(protocol,"UDP");
if (ip->protocol != 17) continue;
p = p + sizeof(struct iphdr);
udp = (struct udphdr *)p;
sport = ntohs(udp->uh_sport);
dport = ntohs(udp->uh_dport);
u_len = ntohs(udp->uh_ulen);
if (sport != OLSR_PORT) continue;
printf("¥n");
printf("IP version : %d¥n", ip->version);
printf("protocol
: %s¥n", protocol);
46
printf("source addr : %s¥n", s_addr);
printf("dest addr : %s¥n", d_addr);
printf("source port : %d¥n", sport);
printf("dest port
: %d¥n", dport);
printf("udp length : %d¥n", u_len);
p = p + sizeof(struct udphdr);
/*
OLSR Packet Analize
*/
for(i=0;i<(int)u_len-sizeof(struct udphdr);){
if(i==0) printf("olsr data
: ");
else
printf("
");
for(j=0;j<4;j++){
printf("%2.2x ",p[i]);
i++;
if(i==(int)u_len-sizeof(struct udphdr)) break;
}
printf("¥n");
}
//kokomade
if((p[0] & 0xf0) != 0x00){
printf("Not version 0 packet!¥n");
continue;
}
if((p[0] & 0x0f) != 0x00){
printf("Not pkt_flags = 0 packet!¥n");
continue;
}
p = p + PKT_HEADER_SIZE;
olsr_msg_hdr = (struct OLSR_MSG_hdr *)p;
47
/*
OLSR Message Analize
*/
if(olsr_msg_hdr->type == 0x05) printf("
if(olsr_msg_hdr->type == 0x06) printf("
msg-type : HELLO¥n");
msg-type : TC¥n");
if((olsr_msg_hdr->flags & 0xf0) != 0xf0){
printf("Not msg_flags = 0xf0 packet!¥n");
continue;
}
if((olsr_msg_hdr->flags & 0x0f) != 0x03){
printf("Not IPv4 address!¥n");
continue;
}
msg_size = (int)ntohs(olsr_msg_hdr->size);
printf(" msg_size
: %d¥n",msg_size);
printf(" meg_orig_addr : %s¥n",inet_ntoa(olsr_msg_hdr->orig_addr));
printf(" msg_hop_limit : %d¥n",olsr_msg_hdr->hop_limit);
printf(" msg_hop_count : %d¥n",olsr_msg_hdr->hop_count);
printf(" msg_seq_num
: %d¥n",ntohs(olsr_msg_hdr->seq_num));
/*
Message TLV Analize
*/
p = p + MSG_HEADER_SIZE;
msg_size = msg_size - MSG_HEADER_SIZE;
p_short = (unsigned short *)p;
tlvs_length = *p_short;
tlvs_length = (unsigned int)ntohs(*p_short);
printf(" Message_tlvs¥n");
printf("
tlvs_length
: %d¥n",tlvs_length);
p = p + sizeof(short);
msg_size = msg_size-sizeof(short);
for(i=0;i<tlvs_length;){
printf(" tlv¥n");
48
ptlv = (struct tlv *)p;
if(ptlv->type == 4)
printf("tlv_type : MPR_WILLING¥n");
else if(ptlv->type == 35)
printf("tlv_type :VALIDITY_TIME¥n");
else if(ptlv->type == 30)
printf("tlv_type :INTERVAL_TIME¥n");
else if(ptlv->type == 6)
printf("tlv_type:CONT_SEQNUM¥n");
else printf("
tlv_type
: %2.2x¥n",ptlv->type);
p = p + 1;
i++;
printf("tlv_flags : %2.2x¥n",ptlv->flags);
if(ptlv->flags != 0x10){
printf("It is Message TLV, but flags != 0x10!¥n");
k=1;
}
p = p + 1;
i++;
printf("length: %d¥n",ptlv->l_v[0]);
p = p + 1;
i++;
printf("value:");
//
if (ptlv->l_v[0] == 2){
p_short = (unsigned short *)p;
printf(" %d¥n",ntohs(*p_short));
j=2;
}else {
for(j=0;j<ptlv->l_v[0];j++){
printf(" %2.2x",ptlv->l_v[j+1]);
}
printf("¥n");
49
}
p = p + j;
i = i+j;
}
msg_size = msg_size-tlvs_length;
for(;msg_size > 0;){
printf(" Address Block¥n");
num_addr = *p;
printf("num_addr : %d¥n",num_addr);
p = p+1;
msg_size = msg_size-1;
printf("addr_flags: %2.2x¥n",*p);
if (*p == 0x00){
p = p + 1;
msg_size = msg_size-1;
for(i=0;i<num_addr;i++){
p_int = (unsigned int *)p;
addr.s_addr = (in_addr_t) *p_int;
printf("IP_addr : %s¥n",inet_ntoa(addr));
enqueue(addr);
p = p + 4;
}
msg_size = msg_size - 4*num_addr;
}
if (*p == 0x80){
p = p + 1;
msg_size = msg_size-1;
head_length = *p;
p = p + 1;
msg_size = msg_size-1;
for(i=0;i<head_length;i++){
ip_addr[i]=*p;
p = p + 1;
msg_size = msg_size-1;
}
for(i=0;i<num_addr;i++){
50
for(j=0;j<4-head_length;j++){
ip_addr[head_length+j]=*p;
p = p + 1;
msg_size = msg_size-1;
}
p_int = (unsigned int *) ip_addr;
addr.s_addr = (in_addr_t) *p_int;
printf("IP_addr : %s¥n",inet_ntoa(addr));
enqueue(addr);
}
}
p_short = (unsigned short *)p;
tlvs_length = *p_short;
tlvs_length = (unsigned int)ntohs(*p_short);
printf("tlvs_length : %d¥n",tlvs_length);
p = p + sizeof(short);
msg_size = msg_size-sizeof(short);
for(i=0,l=0;i<tlvs_length;){
printf("tlv¥n");
ptlv = (struct tlv *)p;
if(ptlv->type == 1)
printf("tlv_type : ORIGINATOR¥n");
if(ptlv->type == 2)
printf("tlv_type : ROUTABLE¥n");
if(ptlv->type == 3)
printf("tlv_type : ROUTABLE_ORIG¥n");
l++;
printf("tlv_flags : %2.2x¥n",ptlv->flags);
if(ptlv->flags != 0x10){
if(ptlv->flags != 0x14){
printf("can not analize addr tlv!¥n");
k=1;
}
}
51
l++;
printf("length : %d¥n",ptlv->l_v[0]);
l++;
printf("value :");
for(;l < tlvs_length;l++){
printf(" %2.2x",ptlv->l_v[j+1]);
if (l>50){
k=1;
break;
}
}
printf("¥n");
p = p + l;
i = i+l;
}
msg_size = msg_size-tlvs_length;
}
}
//threadclose
pthread_detach(saka);
//
return 0;
}
//threadsakamoto
void sakamoto(void *trash){
char snd_data[16];
struct sockaddr_in dstAddr;
int result;
int yes=1;
int dstSocket;
int i;
52
dstSocket = socket(AF_INET, SOCK_DGRAM, 0);
dstAddr.sin_family = AF_INET;
dstAddr.sin_port = htons(OLSR_PORT);
dstAddr.sin_addr.s_addr =
inet_addr("192.168.1.255");//konoatainanntokasuru
result = setsockopt(dstSocket,SOL_SOCKET, SO_BROADCAST, (char
*)&yes, sizeof(yes));
if (result == -1) {
printf("setsockopt error no = %d¥n",result);
return;
}
//nise hello tobasu
while(1){
printf("スレッド側¥n");
pthread_mutex_lock(&mutex);
for(i=0;i<ex_data.cnt;i++){
strcpy(snd_data,ex_data.ip_addr[ex_data.cnt]);
result = sendto(dstSocket, snd_data,
sizeof(snd_data), 0, (struct sockaddr *)&dstAddr, sizeof(dstAddr));
}
ex_data.cnt=0;
pthread_mutex_unlock(&mutex);
sleep(10);
}
}
void enqueue(struct in_addr addr)
{
char source_addr[16];
int cnt,match;
strcpy(source_addr,inet_ntoa(addr));
53
pthread_mutex_lock(&mutex);
for(match=0,cnt=0;cnt<ex_data.cnt;cnt++){
if(strcmp(ex_data.ip_addr[cnt],source_addr)==0){
match=1;
break;
}
}
if(match==0){
strcpy(ex_data.ip_addr[ex_data.cnt],source_addr);
ex_data.cnt++;
}
pthread_mutex_unlock(&mutex);
}
54
Fly UP