TWSNMP開発日誌:モバイル版に自分のIPアドレスを調べる機能を追加したい
今朝も5時から開発開始です。
夜中に、ふとモバイル版で自分のIPアドレスを表示する機能を追加したくなりました。スマホについているデバイスのIPだけでなくインターネットで通信している時の自分IPアドレスも知りたいのです。今週、本業で悩まされている問題が影響しているのかもしれません。寝ながら考えていたらSTUNサーバーを利用するアイデアを思いつきました。起きた時も覚えていたいので早速調べました。
が参考になりました。ありがたいことです。
ソースコードもありましたがRustでした。でもパケットキャプチャーのファイルもあったのでこちらのほうが参考になりました。
テストプログラムを作ってみました。
STUNのパケットを作る部分は、
List<int> _makeSTUNPkt(bool change) {
final now = DateTime.now();
List<int> r = [];
r.add(0x00); // Bind Request
r.add(0x01);
r.add(0x00); // Length
r.add(0x08);
// TID
for (var i = 0; i < 16; i++) {
r.add(i * now.microsecond);
}
r.add(0x00); // Attr Type = Change
r.add(0x03);
r.add(0x00); // Attr Len =4
r.add(0x04);
r.add(0x00); // Attr
r.add(0x00);
r.add(0x00); // Attr
if (change) {
r.add(0x04);
} else {
r.add(0x00);
}
return r;
}
これをUDP送信します。こんなソースコードです。
void _testSTUN() async {
var strun = await UDP.bind(Endpoint.any());
// receiving\listening
strun.asStream(timeout: const Duration(seconds: 120)).listen((datagram) {
print(datagram!.data);
strun.close();
});
// stun1.l.google.com:19302
var dataLength = await strun.send(_makeSTUNPkt(false), Endpoint.unicast(InternetAddress("74.125.197.127"), port: const Port(19302)));
print('$dataLength bytes sent.');
送信したパケットを WireSharkで見ると
応答も帰ってきました。デコードすれば自分のインターネット上のIPアドレスがわかります。
デバイスのIPアドレスは、
for (var interface in await NetworkInterface.list()) {
print('== Interface: ${interface.name} ==');
for (var addr in interface.addresses) {
print('${addr.address} ${addr.host} ${addr.isLoopback} ${addr.rawAddress} ${addr.type.name}');
}
}
のようなソースコードでよさそうですが Androidではだめとか書いてあるサイトがあるので、もう少し調べる必要がありそうです。
でも、今朝は時間切れです。
明日に続く
開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。