ARPテーブルの削除 (C#)(F#)
iphlpapi.dllのDeleteIpNetEntry()を使用してARPテーブルの削除が可能です。
下記のサンプルは、現在のARPテーブルを取得して、その情報を削除しています。(コマンドのラインから「arp -d」とした場合と同じ)
static(静的)なテーブルを削除したくない場合などは、MIB_IPNETROWのTypeで条件判断が可能です。
※ARPテーブル取得についてはhttp://d.hatena.ne.jp/spw0022/20111108/1320700838を参照してください。
using System; using System.Runtime.InteropServices; namespace Example { class Program { [DllImport("iphlpapi.dll")] extern static int GetIpNetTable(IntPtr pTcpTable, ref int pdwSize, bool bOrder); [DllImport("iphlpapi.dll")] extern static int DeleteIpNetEntry(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; } static void Main(string[] args) { int size = 0; GetIpNetTable(IntPtr.Zero, ref size, true);//必要サイズの取得 var p = Marshal.AllocHGlobal(size);//メモリ割当て if (GetIpNetTable(p, ref size, true) == 0) {//データの取得 var ptr = IntPtr.Add(p, 4);//MIB_IPNETTABLE.dwNumEntries(データ数)以降へのポインタ for (int i = 0; i < Marshal.ReadInt32(p); i++) { var n = (MIB_IPNETROW)Marshal.PtrToStructure(ptr, typeof(MIB_IPNETROW)); if(0==DeleteIpNetEntry(ptr)){ Console.WriteLine(string.Format("Interface:{0} {1,-15}を削除しました", n.Index,ipstr(n.Addr))); } ptr = IntPtr.Add(ptr, Marshal.SizeOf(typeof(MIB_IPNETROW)));//次のデータ } Marshal.FreeHGlobal(p); //メモリ開放 } Console.WriteLine(); Console.WriteLine("何かのキーを押してください。"); Console.ReadKey(); } private static string ipstr(int addr) { var b = BitConverter.GetBytes(addr); return string.Format("{0}.{1}.{2}.{3}", b[0], b[1], b[2], b[3]); } } }
F#サンプル
今回は、C#のサンプルとの統一性はあまり考えないで、F#らしさが少しでも出せればと、色々教えてい頂いた事を見よう見まねで頑張って書いてみました。
「突っ込み」大歓迎です。どうぞ宜しくお願いします~。
#nowarn "9" "51" open System open System.Runtime.InteropServices [<DllImport("iphlpapi.dll")>] extern int GetIpNetTable(IntPtr pTcpTable, int *pdwSize, bool bOrder) [<DllImport("iphlpapi.dll")>] extern int DeleteIpNetEntry(IntPtr pArpEntry) [<Struct; StructLayout(LayoutKind.Sequential)>] type MIB_IPNETROW = val Index:int val PhysAddrLen:int [<MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)>] val PhysAddr:byte [] val Addr:int val Type:int let ipstr(addr:int)= let b = BitConverter.GetBytes(addr) sprintf "%d.%d.%d.%d" b.[0] b.[1] b.[2] b.[3] let mutable size = 0 GetIpNetTable(IntPtr.Zero, &&size, true) |> ignore //必要サイズの取得 let p = Marshal.AllocHGlobal(size)//メモリ割当て if GetIpNetTable(p, &&size, true) = 0 then //ARPテーブルの取得 let step = Marshal.SizeOf(typeof<MIB_IPNETROW>) let num = Marshal.ReadInt32(p) [0..num-1]//データ数 |> List.map(fun n ->IntPtr.Add(p,4 + n * step ))//ポインタ取得 |> Seq.iter(fun ptr -> let n = Marshal.PtrToStructure(ptr, typeof<MIB_IPNETROW>) :?> MIB_IPNETROW //構造体への変換 if DeleteIpNetEntry(ptr)=0 then //ARPテーブルの削除 printfn "Interface:%d %sを削除しました" n.Index (ipstr(n.Addr))) Marshal.FreeHGlobal(p); //メモリ開放 printfn "何かのキーを押してください。" Console.ReadKey() |> ignore