質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.98%

SNMPのOidを16進数にしてbyte配列に格納したい

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 2,114

panda12

score 9

前提・実現したいこと

C#でSNMPTrapをライブラリを使わずにパケットを直に
送信したいと考えています。

作成している最中にOidのパケット変換で躓いてしまったので質問をさせて頂きます。

1.3.6.1.4.1.311.21.20
のOidを
0x2B 0x06 0x01 0x04 0x01 0x82 0x37 0x15 0x14
の形にしてバイト配列に16進数で格納したいと考えています。

ネットで調べた所10進数→16進数の変換にbitConverterクラスを使う方法が
あることがわかり下記のソースコードのように試してみましたが上手く
変換されませんでした。

初歩的な質問で申し訳ありませんが
Oidを16進数に変換しbyte配列に保存する方法を教えていただきたいです。

発生している問題・エラーメッセージ

16進数に変換されない

該当のソースコード

namespace SNMPTrap
{
    class Program
    {

        static void Main(string[] args)
        {
            string remoteHost = "127.0.0.1";
            int remotePort = 162;
            UdpClient udp = new UdpClient();

            byte[] Oid = ConvertToOid("1.3.6.1.4.1.311.21.20");
            udp.Send(Oid, Oid.Length, remoteHost,remotePort);
        }

        public static byte[] ConvertToOid(string str)
        {
            string[] splitData = str.Split('.');
            byte[] data = new byte[splitData.Length];
            byte[] buf = new byte[1];
            for (int j = 0; j < splitData.Length; j++)
            {
                buf = BitConverter.GetBytes(Convert.ToInt16(splitData[j]));
                data[j] = buf[0];
            }
            return data;
        }

    }

}

試したこと

文字列を'.'で区切り
C#のbitCOnverter.GetBytes()を使い16進数のバイト変換を試みました。

補足情報(言語/FW/ツール等のバージョンなど)

C# framework4.6 visualstudio2013 

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

SNMPのOIDは、ASN.1バイナリ変換規則により変換されます。
ASN.1 バイナリ変換規則 (BER, CER, DER) - OBJECT IDENTIFIER

  • 1~2オクテットは、規定の手順によりバイナリ変換を行います。
    1オクテットの値に40を掛けて、2オクテットの値と足し合わせ、バイナリ化します。
  • 3オクテット以降は、7ビットごとにデータを分割し、符号ビットを先頭に付与して8ビットにします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/04 20:36

    変換規則大変勉強になりました。
    適切な回答ありがとうございます。

    キャンセル

+1

1.3.6.1.4.1.311.21.20
のOidを
0x2B 0x06 0x01 0x04 0x01 0x82 0x37 0x15 0x14
の形にしてバイト配列に16進数で格納したいと考えています。

とありますが、10進数文字列を整数に変換し、byte配列に格納するでよろしいでしょうか。
上記Oidの場合、311は2バイト必要ですので、各々2バイト単位に変換する必要があると考えます。

311 -> 0x0137
1.3.6.1.4.1.311.21.20 ->
0x00 0x01 0x00 0x03 0x00 0x06 0x00 0x01 0x00 0x04 0x00 0x01 0x01 0x37 0x00 0x15 0x00 0x14

2バイト単位で処理するように、修正してみました。
出力は以下となります。
"00-01-00-03-00-06-00-01-00-04-00-01-01-37-00-15-00-14"

       static void Main(string[] args)
        {

            byte[] Oid = ConvertToOid("1.3.6.1.4.1.311.21.20");

            // 変換後のOidを16進数で表示
            Console.WriteLine(BitConverter.ToString(Oid));
        }

        public static byte[] ConvertToOid(string str)
        {
            string[] splitData = str.Split('.');
            List<byte> bytes = new List<byte>();

            for (int j = 0; j < splitData.Length; j++)
            {
                byte[] buf = BitConverter.GetBytes(Convert.ToInt16(splitData[j]));
                bytes.Add(buf[1]);          // 整数に変換後の上位バイト
                bytes.Add(buf[0]);          // 整数に変換後の下位バイト
            }
            return bytes.ToArray();
        }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/04 20:38

    >10進数文字列を整数に変換し、byte配列に格納するでよろしいでしょうか。
    はい、10進数→16進数の変換については相違ありません。

    大変わかりやすいソースコードをありがとうございます。
    ester41様の回答と照らし合わせて自己解決できました。

    キャンセル

0

SNMPのOidの仕様は知らないのですが、

1.3.6.1.4.1.311.21.20
のOidを
0x2B 0x06 0x01 0x04 0x01 0x82 0x37 0x15 0x14
の形にしてバイト配列に16進数で格納したいと考えています。

とすると、最初の 1,3 -> 0x2B 部分と、311 -> 0x82,0x37 部分がよくわかりません。  
先頭部分や、2byteを超える場合の変換に特殊な仕様はありませんでしょうか?  

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/04 20:41

    回答ありがとうございます。
    mituha様のおっしゃる通りASN.1という変換規則による変換処理だったようです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.98%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る