概要

  • 指定した IPv4 ゾーンに対して MAC アドレスを収集するコマンドラインツール。
  • IP アドレスを指定しなかった場合は、自身のホストアドレスを元に収集する。
  • ファイアウォール等で ping 応答を返さない端末についても収集する。
  • 電源が落ちている端末については収集出来ない。
  • 要 .NET Framework 4.0

実行ファイルのみ

  • &ref(): File not found: "scanNetArp_bin.zip" at page "CSharp/scanNetArp";

ソース

  • &ref(): File not found: "scanNetArp.zip" at page "CSharp/scanNetArp";
    すべてを展開すべてを収束
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    -
    -
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    -
    |
    |
    |
    |
    |
    |
    |
    |
    !
    |
    |
    |
    |
    |
    |
    |
    |
    |
    -
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    !
    |
    |
    |
    |
    -
    |
    |
    |
    |
    |
    !
    |
    |
    |
    |
    |
    |
    -
    |
    |
    |
    -
    |
    |
    |
    |
    |
    |
    |
    |
    |
    -
    |
    |
    !
    |
    |
    !
    |
    |
    |
    !
    |
    |
    |
    |
    |
    |
    -
    |
    -
    -
    |
    |
    !
    |
    -
    |
    !
    |
    |
    |
    |
    |
    |
    |
    |
    !
    |
    !
    |
    -
    |
    -
    -
    |
    -
    |
    !
    -
    |
    |
    |
    |
    |
    -
    |
    -
    |
    |
    !
    !
    |
    !
    |
    |
    -
    |
    |
    !
    !
    !
    !
    
    /**
         @file Program.cs
     
        @mainpage scan Net Arp
        - 指定した IPv4 ゾーンに対して MAC アドレスを収集するコマンドラインツール。
        - IP アドレスを指定しなかった場合は、自身のホストアドレスを元に収集する。
        - ファイアウォール等で ping 応答を返さない端末についても収集する。
        - 電源が落ちている端末については収集出来ない。
        - 要 .NET Framework 4.0
     
        - ARPによるMACアドレスの取得 @ SIN\@SAPPOROWORKSの覚書<br/>
          http://d.hatena.ne.jp/spw0022/20111024/1319575443
     
        - マルチスレッド @ ++C++;// 未確認飛行 C<br/>
          http://ufcpp.net/study/csharp/sp_thread.html
    */
     
    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.Runtime.InteropServices;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
     
    namespace TakeAsh.scanNetArp {
        class Program {
     
            /// <summary>
            /// SendARP function<br/>
            /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa366358.aspx
            /// </summary>
            /// <param name="dstIp">The destination IPv4 address</param>
            /// <param name="srcIp">he source IPv4 address of the sender</param>
            /// <param name="mac">A pointer to an array of ULONG variables</param>
            /// <param name="macLen">a pointer to a ULONG value 
            /// that specifies the maximum buffer size, in bytes</param>
            /// <returns>
            /// - If the function succeeds, the return value is NO_ERROR.
            /// - If the function fails, the return value is one of the following error codes.
            /// </returns>
            [DllImport("IPHlpApi.dll", ExactSpelling = true)]
            private static extern uint SendARP(uint dstIp, uint srcIp, Byte[] mac, ref uint macLen);
     
            /// <summary>
            /// ステータスコードとシンボルの対応 (WinError.h)
            /// </summary>
            static Dictionary<uint, string> StatusCode = new Dictionary<uint, string>(){
                { 0,    "NO_ERROR" },
                { 67,   "ERROR_BAD_NET_NAME" },
                { 111,  "ERROR_BUFFER_OVERFLOW" },
                { 31,   "ERROR_GEN_FAILURE" },
                { 87,   "ERROR_INVALID_PARAMETER" },
                { 1784, "ERROR_INVALID_USER_BUFFER" },
                { 1168, "ERROR_NOT_FOUND" },
                { 50,   "ERROR_NOT_SUPPORTED" },
            };
     
            /// <summary>
            /// IP アドレス最大値
            /// </summary>
            const int ipMax = 254;
     
            /// <summary>
            /// ARP問い合わせ結果を格納するためのクラス
            /// </summary>
            class ARPresult {
     
                /// <summary>
                /// IPアドレス
                /// </summary>
                public string ip;
     
                /// <summary>
                /// MACアドレス
                /// </summary>
                public Byte[] mac;
     
                /// <summary>
                /// MACアドレスのバイト数
                /// </summary>
                public uint macLen;
     
                /// <summary>
                /// ARP問い合わせ結果
                /// </summary>
                public uint status;
            }
     
            /// <summary>
            /// ヘルプメッセージの表示および終了
            /// </summary>
            static void showHelpMessage() {
                Console.WriteLine(
                    "usage: scanNetArp [aa.bb.cc.dd]\n" +
                    "listup MAC addresses in zone aa.bb.cc.xx or localnet."
                );
                Environment.Exit(-1);
            }
     
            /// <summary>
            /// ARP 情報の収集を行う
            /// </summary>
            /// <param name="zone">対象ゾーン</param>
            /// <returns>収集結果の配列</returns>
            static ARPresult[] getArpTable(IPAddress zone) {
                ARPresult[] results = new ARPresult[ipMax];
                Byte[] zoneByte = zone.GetAddressBytes();
     
                Parallel.For(0, ipMax, ip => {
                    ARPresult result = new ARPresult();
                    result.ip = string.Format("{0}.{1}.{2}.{3}",
                        zoneByte[0], zoneByte[1], zoneByte[2], ip + 1);
                    result.mac = new Byte[sizeof(uint) * 2];
                    result.macLen = (uint)result.mac.Length;
                    IPAddress dst = IPAddress.Parse(result.ip);
                    Console.Error.WriteLine(string.Format("Request:{0}", dst.ToString()));
                    Byte[] addrByte = dst.GetAddressBytes();
                    uint addr = 0;
                    for(int i = addrByte.Length - 1; i >= 0; --i) {
                        addr <<= 8;
                        addr |= addrByte[i];
                    }
                    result.status = SendARP(addr, 0, result.mac, ref result.macLen);
                    results[ip] = result;
                });
                Console.Error.WriteLine();
     
                return results;
            }
     
            /// <summary>
            /// ARP 情報の表示<br/>
            /// 収集ステータスが NO_ERROR だったもののみを表示する。
            /// </summary>
            /// <param name="results">ARP 情報テーブル</param>
            static void printArpTable(ARPresult[] results) {
                Console.WriteLine("IPAddr\tMACAddr");
                for(int ip = 0; ip < ipMax; ++ip) {
                    if(results[ip].status != 0) {
                        // NO_ERROR でなければスキップする
                        continue;
                    }
                    string macStr = "";
                    for(uint i = 0; i < results[ip].macLen; ++i) {
                        macStr += string.Format("{0:x2}:", results[ip].mac[i]);
                    }
                    /*
                        uint statusCode = results[ip].status;
                        var status = StatusCode.ContainsKey( statusCode )
                            ? StatusCode[statusCode]
                            : statusCode.ToString();
                    */
                    Console.WriteLine(string.Format("{0}\t{1}",
                        results[ip].ip, macStr.TrimEnd(':')));
                }
                Console.WriteLine();
            }
     
            static void Main(string[] args) {
                IPAddress[] addrList = new IPAddress[] { new IPAddress(0) };
                if(args.Length > 0) {
                    if(!IPAddress.TryParse(args[0], out addrList[0])) {
                        showHelpMessage();
                    } else {
                        Console.WriteLine("IPAddr:\t" + addrList[0].ToString());
                    }
                } else {
                    string hostName = Dns.GetHostName();
                    Console.WriteLine("Host:\t" + hostName);
                    IPAddress[] addrV4V6List = Dns.GetHostAddresses(hostName);
                    List<IPAddress> addrV4List = new List<IPAddress>();
                    Regex regIPv4 = new Regex(@"^\d+\.\d+\.\d+\.\d+$");
                    for(int i = 0; i < addrV4V6List.Length; ++i) {
                        string addrStr = addrV4V6List[i].ToString();
                        if(regIPv4.IsMatch(addrStr)) {
                            addrV4List.Add(addrV4V6List[i]);
                            Console.WriteLine("IPAddr:\t" + addrStr);
                        }
                    }
                    addrList = addrV4List.ToArray();
                }
                Console.WriteLine("Date:\t" + DateTime.Now.ToString("G") + "\r\n");
     
                foreach(IPAddress address in addrList) {
                    ARPresult[] results = getArpTable(address);
                    printArpTable(results);
                }
            }
        }
    }

リロード   新規 下位ページ作成 編集 凍結 差分 添付 コピー 名前変更   ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: Wed, 12 Feb 2014 16:16:29 JST (1651d)