ARPテーブルの追加 (C#)(F#)
iphlpapi.dllの CreateIpNetEntry()でARP追加することができます。追加した、ARPテーブルは、コマンドラインで「arp -a」とする事で確認できます。
CreateIpNetEntry()は、追加情報がすでに存在するときエラーとなるので、サンプルを実行する場合は、「arp -d」でARPテーブルをクリアしながら試してみてください。
なお、 MIB_IPNETROWのIndexは、環境に応じて、インターフェースのインデックス番号を適切に設定する必要があります。
C#サンプル
using System; using System.Runtime.InteropServices; using System.Net; namespace Example { class Program { [DllImport("Iphlpapi.dll")] extern static int CreateIpNetEntry(IntPtr pArpEntry); [StructLayout(LayoutKind.Sequential)] public struct MIB_IPNETROW { public int Index; public int PhysAddrLen; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte [] PhysAddr; public int Addr; public int Type; } enum MIB_IPNET_TYPE{ OTHER=1,//その他 INVALID=2,//無効 DYNAMIC=3,//動的 STATIC=4//静的 } static void Main(string[] args) { var pArpEntry = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MIB_IPNETROW))); var index = 15;//インターフェースのインデックス var ip = IPAddress.Parse("192.168.0.100");//IPアドレス var mac = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };//MACアドレス var p = pArpEntry;//作業用ポインタ Marshal.WriteInt32(p,index);//Index p = IntPtr.Add(p,4); Marshal.WriteInt32(p,6);//PhysAddrLen p = IntPtr.Add(p,4); Marshal.Copy(mac,0,p,6);//PhysAddr p = IntPtr.Add(p,8); Marshal.WriteInt32(p,(int)ip.Address);//Addr p = IntPtr.Add(p, 4); Marshal.WriteInt32(p, (int)MIB_IPNET_TYPE.STATIC);//Type p = IntPtr.Add(p, 4); var ret = CreateIpNetEntry(pArpEntry); if (ret == 0) { Console.WriteLine("Success"); } else { Console.WriteLine(string.Format("ERROR 0x{0:x}",ret)); } Marshal.FreeHGlobal(pArpEntry); Console.WriteLine("何かのキーを押してください。"); Console.ReadKey(); } } }
F#サンプル
open System open System.Runtime.InteropServices open System.Net [<DllImport("iphlpapi.dll")>] extern int CreateIpNetEntry(IntPtr pArpEntry); [<Struct; StructLayout(LayoutKind.Sequential)>] type MIB_IPNETROW = val Index:int val PhysAddrLen:int [<MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)>] val PhysAddr:byte [] val Addr:int val Type:int type MIB_IPNET_TYPE = |OTHER=1//その他 |INVALID=2//無効 |DYNAMIC=3//動的 |STATIC=4//静的 let pArpEntry = Marshal.AllocHGlobal(Marshal.SizeOf(typeof<MIB_IPNETROW>))//メモリ確保 let index = 15//インターフェースのインデックス let ip = IPAddress.Parse("192.168.0.100")//IPアドレス let mac = [|0x01uy; 0x02uy; 0x03uy; 0x04uy; 0x05uy; 0x06uy|] //MACアドレス let mutable p = pArpEntry//作業用ポインタ Marshal.WriteInt32(p,index)//Index p <- IntPtr.Add(p,4) Marshal.WriteInt32(p,6)//PhysAddrLen p <- IntPtr.Add(p,4) Marshal.Copy(mac,0,p,6)//PhysAddr p <- IntPtr.Add(p,8) Marshal.WriteInt32(p,(int)ip.Address);//Addr p <- IntPtr.Add(p, 4) Marshal.WriteInt32(p, (int)MIB_IPNET_TYPE.STATIC)//Type p <- IntPtr.Add(p, 4) let ret = CreateIpNetEntry(pArpEntry) if ret = 0 then printfn "Success" else printfn "ERROR 0x%x" ret Marshal.FreeHGlobal(pArpEntry)//メモリ開放 printfn "何かのキーを押してください。" Console.ReadKey() |> ignore