見出し画像

TWSNMP開発日誌:モバイル版のDNS検索、MACアドレス検索、ポート番号検索、MIBツリー表示機能ができた

今朝は5時から開発開始です。昨日は、2番目に近い温泉に行ったので10時間近くぐっすり寝ました。お盆休みなのでモバイル版の開発も進みます。
一昨日からモバイル版にネットワークに関連した情報を検索する機能を作っています。
1つ目はDNS検索機能です。

入力したホスト名かIPアドレスをDNSで検索して情報を表示します。
ホスト名ならIPv4やIPv6のアドレスをなどのDNSレコードを検索でます。
ローカルのDNSサーバーとGoogleのDNSサーバーへ問い合わせを行います。
Googleのサーバーへの問い合わせはDNS Over HTTPS

で行います。基本的に同じ値になると思いますが、違っていたら怪しいことが起こっているかもしれません。テスト中に、www.twise.co.jpを検索していましたが、おかしなアドレスが検索されました。どうもiOSシミュレータの入力補正機能が働いてtwiseがtwiceになってしまっていました。別のサイトのアドレスを検索していました。自動補正が働かないように変更しました。
IPアドレスを入力すると、いわいる逆引きでホスト名を検索します。

2つ目は、MACアドレスからベンダー名を検索する機能です。

3つ目は、ポート番号からサービス名を調べる機能です。

4つ目がMIBツリーの表示です。

ツリー構造のデータを扱うプログラムは、かなり頭を使うので、
脳トレになります。ぐっすり寝て頭がスッキリした今朝から作り始めました。TWSNMP FCで作ったGO言語のソースコードをdartに移植しました。比較的簡単に移植できます。dartのほうがclassが使えるため書きやすい気もします。
元のGO言語のソースコードは

var (
	mibTreeMAP  = map[string]*MIBTreeEnt{}
	mibTreeRoot *MIBTreeEnt
)

func addToMibTree(oid, name, poid string) {
	n := &MIBTreeEnt{Name: name, OID: oid, Children: []*MIBTreeEnt{}}
	if poid == "" {
		mibTreeRoot = n
	} else {
		p, ok := mibTreeMAP[poid]
		if !ok {
			log.Printf("no parent name=%s oid=%s poid=%s", name, oid, poid)
			return
		}
		p.Children = append(p.Children, n)
	}
	mibTreeMAP[oid] = n
}

func makeMibTreeList() {
	oids := []string{}
	minLen := len(".1.3.6.1")
	for _, n := range MIBDB.GetNameList() {
		oid := MIBDB.NameToOID(n)
		if len(oid) <= minLen {
			continue
		}
		oids = append(oids, oid)
	}
	sort.Slice(oids, func(i, j int) bool {
		a := strings.Split(oids[i], ".")
		b := strings.Split(oids[j], ".")
		for k := 0; k < len(a) && k < len(b); k++ {
			l, _ := strconv.Atoi(a[k])
			m, _ := strconv.Atoi(b[k])
			if l == m {
				continue
			}
			if l < m {
				return true
			}
			return false
		}
		return len(a) < len(b)
	})
	addToMibTree(".1.3.6.1", "iso.org.dod.internet", "")
	for _, oid := range oids {
		name := MIBDB.OIDToName(oid)
		if name == "" {
			continue
		}
		lastDot := strings.LastIndex(oid, ".")
		if lastDot < 0 {
			continue
		}
		poid := oid[:lastDot]
		addToMibTree(oid, name, poid)
	}
	if mibTreeRoot != nil {
		MIBTree = append(MIBTree, mibTreeRoot.Children...)
	}
}

移植したdartのソースコードは、

  void _addToMibTree(String name, String oid, String poid) {
    final n = TreeNode(content: Text("$name($oid)"), children: []);
    if (poid == "") {
      _mibTreeRoot = n;
    } else {
      final p = _mibTreeMap[poid];
      if (p == null) {
        return;
      }
      p.children?.add(n);
    }
    _mibTreeMap[oid] = n;
  }

  void _loadMIBDB() async {
    final mibfile = await rootBundle.loadString('assets/conf/mib.txt');
    _mibdb = MIBDB(mibfile);
    if (_mibdb == null) {
      return;
    }
    // Make MIB Tree
    _mibNames = _mibdb!.getAllNames();
    final List<String> oids = [];
    var minLen = "1.3.6.1".length;
    for (var n in _mibNames) {
      var oid = _mibdb!.nameToOid(n);
      if (oid.length < minLen) {
        continue;
      }
      oids.add(oid);
    }
    oids.sort((a, b) {
      final aa = a.split(".");
      final ba = b.split(".");
      for (var i = 0; i < aa.length && i < ba.length; i++) {
        var l = int.parse(aa[i]);
        var m = int.parse(ba[i]);
        if (l == m) {
          continue;
        }
        return l < m ? -1 : 1;
      }
      return aa.length.compareTo(ba.length);
    });
    _addToMibTree("iso.org.dod.internet", "1.3.6.1", "");
    for (var oid in oids) {
      var n = _mibdb!.oidToName(oid);
      if (n == "") {
        continue;
      }
      final oida = oid.split(".");
      if (oida.length < 2) {
        continue;
      }
      oida.removeLast();
      _addToMibTree(n, oid, oida.join("."));
    }
  }

のような感じです。OIDの順番に並べて親子関係をつけているという感じです。
ツリーの表示自体は

を使いました。いい感じにできました。

モバイル版の改善は一通りできたのでリリースしてもよいのですが、リリースのための作業を思い出すのは頭のスッキリした朝のほうがよいので、明日からにします。
今日も本業がお休みなのでTWSNMP FCの問題を考えようと思います。

明日に続く

開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。