DOBON.NET DOBON.NETプログラミング掲示板過去ログ

グローバルIPアドレスの取得について

環境/言語:[windows2000pro、C#、.NET Framework1.1]
分類:[.NET]

こんにちは。
最近、UDPを使ったチャットプログラムを作ろうかと思っているのですが、
プライベートIPアドレスは、

String localHostName = Dns.GetHostName();
IPAddress pAddr = Dns.Resolve(localHostName).AddressList[0];

という風にすることで取得できたのですが、
グローバルIPアドレスの取得方法がわかりません。
おそらくルータなどを通さずに接続すれば、取得できるかもしれませんが、
それだとちょっと使い勝手が悪そうなので・・・
どなたかわかる人がいらしたら、教えてくださいm(__)m
こんにちは中です。

UPnPをキーワードにして調べると幸せに慣れるかも。
でもたぶん、ネットワークの知識がかなり必要です。
かなり高い壁ですよ。(^^
がんばってね。

------------------------------------------------------
中博俊 MSMVP Visual Studio C# Since 2004/04-2005/03, MCP
http://naka.wankuma.com/
http://naka.wankuma.com/blog/
naka@wankuma.com
俺は取得したアドレスリストに対して、グローバルIPアドレスかどうかを判断する関数を組んで、
ゴリゴリ書いてしまった…しまった(orz

ゴリゴリ書いたのを載せて置きます。

Public Function isGlobalAddress(ByVal DotAddress As String) As Boolean

Dim i As Long
Dim v As Variant
Dim ipa(1 To 4) As Byte

If Not ((DotAddress Like "*.*.*.*") And Not (DotAddress Like "*.*.*.*.*")) Then
isGlobalAddress = False
Exit Function
End If

i = 1
For Each v In Split(DotAddress, ".")
ipa(i) = CByte(v)
i = i + 1
Next

Select Case ipa(1)
'Private Class A(10.0.0.0 - 10.255.255.255)
Case 10
Exit Function

'Private Class B(172.16.0.0 - 172.31.255.255)
Case 172
If ipa(2) >= 16 And ipa(2) <= 31 Then
Exit Function
End If

'Private Class C(192.168.0.0 - 192.168.255.255)
Case 192
If ipa(2) = 168 Then
Exit Function
End If
End Select

isGlobalAddress = True

End Function

ビットマスクとか使っていないので、小汚い…(orz
※VB6用
と書くのを忘れていました。(ororororz
169.*がないですねー。
■No9675に返信(中博俊さんの記事)
> 169.*がないですねー。
自分で調べた限りでは上の三つのクラスがプライベートIPアドレスとして認識していたのですが、
169.*はドコに資料がありますか?

※gooってみた結果
http://search.goo.ne.jp/web.jsp?TAB=&MT=%A5%D7%A5%E9%A5%A4%A5%D9%A1%BC%A5%C8IP%A5%A2%A5%C9%A5%EC%A5%B9
取得したアドレスリストから…っていうことでしたので、
アドレスリストを見てみたんですが、ひとつしか取得できていませんでした。
VB6.0だと複数のアドレスが取得できる方法があるのでしょうか?
よければその辺も教えていただけますか?
■No9677に返信(アイアムサムさんの記事)
> 取得したアドレスリストから…っていうことでしたので、
> アドレスリストを見てみたんですが、ひとつしか取得できていませんでした。
> VB6.0だと複数のアドレスが取得できる方法があるのでしょうか?
> よければその辺も教えていただけますか?
.NETはよく判らないからちょとヘルプ見ながら考えてみた。
Winsockを単純にラップしているなら、
GetHostName()でホスト名を取得→
 GetHostByName()でIPHostEntryクラスのインスタンスを取得→
  [IPHostEntry].AddressListとかいうメンバが、ローカルホストに
  関連付けられたアドレスをリストしているので、それを見てみる。→
   AddressListの各元はIPAddressとかいうクラス。
   で、IPv4のがありそう…か?
   んー…プライベート/グローバルIPアドレスの区別はIPv4でのことだからなぁ…
   しかたないので、「旧バージョン用」って書いてある(少し危険…)
   [IPAddress].Addressプロパティを見てみる。

で、(INET⇔(?)IPv4の)IPアドレスが取れたので、ゴリゴリ解析して、
グローバルかプライベートなのかを判断する。


※AddressListに一つしかIPアドレスが割り当てられていないときがあるけど、
 …なんでだったけ?(orz
※…激しく意味のないレスの予感w;
いい記事発見

http://www.atmarkit.co.jp/fpc/pctips/019disableapipa2k/disableapipa2k.html
■No9679に返信(中 博俊さんの記事)
> いい記事発見
>
>http://www.atmarkit.co.jp/fpc/pctips/019disableapipa2k/disableapipa2k.html
…マジですかぃ(orz
なんだか見てはいけない一端を見つけてしまってぅっw;
…んー…これはもー、IPv4が32Bit空間なのがいけないということで…(ぇ

ハァ…どーすっかなー…面倒だなぁー…いいや…もうぃぃゃ。
標準化なんてチラン(or-----z

※そういえばLoopBackも抜けている悪寒…
 …アレは…アレは、privateってゆーことで…ダメ?(ぇ
 というわけで、そのほかの発見。
 http://www.itbook.info/study/p62.html

※IPアドレス嫌いにな(ry
そうですね。127.0.0.1も。

ということで、こういうローカルかどうかを調べるかってのを実装するのであればIPv4とか、DHCPの仕様書は確認しましょうね。(^^
■No9684に返信(中博俊さんの記事)
> そうですね。127.0.0.1も。
>
> ということで、こういうローカルかどうかを調べるかってのを実装するのであればIPv4とか、DHCPの仕様書は確認しましょうね。(^^
助言ありがとうございますw;
…というかもうお金が(orz…学割効くかなぁ;(ぇ
んー…適当に作るとやっぱり危険ですねぇ、
でもあきらめてもいられないので、応急処置として関数にコードを追加しました;

※危険です、使わないでください。(ぇ
Public Function isGlobalAddress(ByVal DotAddress As String) As Boolean

Dim i As Long
Dim v As Variant
Dim ipa(1 To 4) As Byte

If Not ((DotAddress Like "*.*.*.*") And Not (DotAddress Like "*.*.*.*.*")) Then
isGlobalAddress = False
Exit Function
End If

i = 1
For Each v In Split(DotAddress, ".")
ipa(i) = CByte(v)
i = i + 1
Next

Select Case ipa(1)
'Private Class A(10.0.0.0 - 10.255.255.255)
Case 10
Exit Function

'Private Class B(172.16.0.0 - 172.31.255.255)
Case 172
If 16 <= ipa(2) And ipa(2) <= 31 Then
Exit Function
End If

'Private Class C(192.168.0.0 - 192.168.255.255)
Case 192
If ipa(2) = 168 Then
Exit Function
End If

'LoopBack (127.0.0.0 - 127.255.255.255)
Case 127
Exit Function

'LinkLocal(169.254.1.0 - 169.254.254.255)
Case 169
If ipa(2) = 254 Then
If 1 <= ipa(3) And ipa(3) <= 254 Then
Exit Function
End If
End If
End Select

isGlobalAddress = True

End Function

※LinkLocalについて追記。
 http://www.itbook.info/study/p62.html
 を参照していただくと、
 「実は(APIAPで)自動で割り振られるのはIPアドレスの
  みのでデフォルトゲートウェイは設定されません。
  そのためそのままではルータを越えた通信は出来ないのです。」(前後省略、一部追加)
 という一文を見つけることが出来ます。
 …設定によってはLinkLocal範囲のアドレスを使ってインターネット接続できるかもしれないので、
 LinkLocalを一概にprivateとして判断するのは結構ダメかもしれませんw;
 適宜、関数を変えるなり、見切りをつけて他の方法をやってください(or----z

※@当初の質問者の議題から大幅に外れてしまったことを反省しております。
 ごめんなさい;;
>助言ありがとうございますw;
>…というかもうお金が(orz…学割効くかなぁ;(ぇ

プライベート網のアドレス割当(RFC1918)
http://www.nic.ad.jp/ja/translation/rfc/1918.html

特別に使用するIPv4アドレス(RFC3330)
http://www5d.biglobe.ne.jp/~stssk/rfc3330j.html

意外と探すのに時間がかかってしまった。orz
■No9689に返信(中博俊さんの記事)
> >助言ありがとうございますw;
> >…というかもうお金が(orz…学割効くかなぁ;(ぇ
>
> プライベート網のアドレス割当(RFC1918)
> http://www.nic.ad.jp/ja/translation/rfc/1918.html
>
> 特別に使用するIPv4アドレス(RFC3330)
> http://www5d.biglobe.ne.jp/~stssk/rfc3330j.html
>
> 意外と探すのに時間がかかってしまった。orz
中博俊さん、検索&リンク情報ありがとうございました。
リンク先に目を通してみました結果、
IPアドレスをグローバル/プライベートに大別するのは結構弊害があるようなので…
なので、isGlobalAddress()関数としては最後に提示したのを破棄して、最初に定義したものを結果として残すことにしますw;
どもこちらでは初めまして.
GDN/J で以前似たような質問がありましたね.
御参考までに.

http://www.gdncom.jp/general/bbs/ShowPost.aspx?PostID=15807

DOBON.NET | プログラミング道 | プログラミング掲示板