iphlpapi.dll and sendarp
-
hi. I new to C# and would like to know how i send an ARP packet to a computer using sendarp from iphlpapi.dll. I saw this code somewhere on the web, and its what i need. but i have little idea how to use it: [DllImport("iphlpapi.dll", ExactSpelling = true)] public static extern int SendARP(int DestIP, int SrcIP, [Out] byte[] pMacAddr, ref int PhyAddrLen); I can see that a function is being build. Can i just use it by doing this: Int32 IP = Convert.ToDecimal(192.168.0.1); SendARP(IP,0,0,IP.Length) or how do i do it ?
-
hi. I new to C# and would like to know how i send an ARP packet to a computer using sendarp from iphlpapi.dll. I saw this code somewhere on the web, and its what i need. but i have little idea how to use it: [DllImport("iphlpapi.dll", ExactSpelling = true)] public static extern int SendARP(int DestIP, int SrcIP, [Out] byte[] pMacAddr, ref int PhyAddrLen); I can see that a function is being build. Can i just use it by doing this: Int32 IP = Convert.ToDecimal(192.168.0.1); SendARP(IP,0,0,IP.Length) or how do i do it ?
Mmm, no, that won't work.. You can't create integer IP's from just using Convert.ToDecimal(). That would be too simple. Also, you can't pass in a 0 for the 3rd parameter, it's a byte[] that's returned out as your data that you receive from the ARP I think (I haven't done any research, I'm just letting you know basic things that are wrong.) What this all means is that you need to: a) Declare a byte[] to use for the 3rd parameter. I'd reccomend using one that's got a decent length, like 256...declared as so: byte[] buffer = new byte[256]; (Note: You might not even need to declare a length, since you have that ref integer parameter that seems to tell you how much data you got out of the function - I'd try both ways) b) for the 4th parameter, you need to declare an integer before calling the function, then pass that integer in as a ref parameter...that variable will hold the length of the actual output from the function (how much data it filled in the buffer) c) you need IP's as integers...fortunately for you, I've written code that does that. :)
public static int StringIPToInt(string IPString) { string[] _splitString = IPString.Split(new char[]{'.'}); int _retVal = 0; if (_splitString.Length < 4) throw new ArgumentException("Please pass in a valid IP in dotted-quad notation!","IPString"); else { _retVal += (int)(int.Parse(_splitString[3]) * Math.Pow(256,0)); _retVal += (int)(int.Parse(_splitString[2]) * Math.Pow(256,1)); _retVal += (int)(int.Parse(_splitString[1]) * Math.Pow(256,2)); _retVal += (int)(int.Parse(_splitString[0]) * Math.Pow(256,3)); } _retVal = (int) (((_retVal & 0x000000ff) << 24) + ((_retVal & 0x0000ff00) << 8) + ((_retVal & 0x00ff0000) >> 8) + ((_retVal & 0xff000000) >> 24)); return _retVal; }
I won't go into detail except that all the compound addition you see is parsing the dotted-quad notation and creating an integer value to represent it (dotted-quad just stores the 32 bits of an IP address as four octets, so it's easy to go back to a 32bit integer). The last bit of code with all the bitshifting and binary AND's flips the endianness of the output integer so that you have the correct value. So, a call like this may be appropriate:
byte[] outputData; int dataLength = 0; SendARP(StringIPToLong("192.168.1.101"),StringIPToLong("127.0.0.1"),outputData,ref dataLength);
I would then use BitConverter.ToString() or something similar to get
-
Mmm, no, that won't work.. You can't create integer IP's from just using Convert.ToDecimal(). That would be too simple. Also, you can't pass in a 0 for the 3rd parameter, it's a byte[] that's returned out as your data that you receive from the ARP I think (I haven't done any research, I'm just letting you know basic things that are wrong.) What this all means is that you need to: a) Declare a byte[] to use for the 3rd parameter. I'd reccomend using one that's got a decent length, like 256...declared as so: byte[] buffer = new byte[256]; (Note: You might not even need to declare a length, since you have that ref integer parameter that seems to tell you how much data you got out of the function - I'd try both ways) b) for the 4th parameter, you need to declare an integer before calling the function, then pass that integer in as a ref parameter...that variable will hold the length of the actual output from the function (how much data it filled in the buffer) c) you need IP's as integers...fortunately for you, I've written code that does that. :)
public static int StringIPToInt(string IPString) { string[] _splitString = IPString.Split(new char[]{'.'}); int _retVal = 0; if (_splitString.Length < 4) throw new ArgumentException("Please pass in a valid IP in dotted-quad notation!","IPString"); else { _retVal += (int)(int.Parse(_splitString[3]) * Math.Pow(256,0)); _retVal += (int)(int.Parse(_splitString[2]) * Math.Pow(256,1)); _retVal += (int)(int.Parse(_splitString[1]) * Math.Pow(256,2)); _retVal += (int)(int.Parse(_splitString[0]) * Math.Pow(256,3)); } _retVal = (int) (((_retVal & 0x000000ff) << 24) + ((_retVal & 0x0000ff00) << 8) + ((_retVal & 0x00ff0000) >> 8) + ((_retVal & 0xff000000) >> 24)); return _retVal; }
I won't go into detail except that all the compound addition you see is parsing the dotted-quad notation and creating an integer value to represent it (dotted-quad just stores the 32 bits of an IP address as four octets, so it's easy to go back to a 32bit integer). The last bit of code with all the bitshifting and binary AND's flips the endianness of the output integer so that you have the correct value. So, a call like this may be appropriate:
byte[] outputData; int dataLength = 0; SendARP(StringIPToLong("192.168.1.101"),StringIPToLong("127.0.0.1"),outputData,ref dataLength);
I would then use BitConverter.ToString() or something similar to get
Thanks for the fast reply. I think i have figured the SendARP() out now, but i still can't give it the IP destination in integer. i tried with the code you provieded me, like this:
public partial class _Default : System.Web.UI.Page { [DllImport("iphlpapi.dll", ExactSpelling = true)] public static extern int SendARP(int DestIP, int SrcIP, [Out] byte[] pMacAddr, ref int PhyAddrLen); protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) { byte[] outputData = new byte[6]; int dataLength = outputData.Length; SendARP(StringIPToLong("192.168.1.101"), StringIPToLong("127.0.0.1"), outputData, ref dataLength); Label1.Text = "MAC:" + BitConverter.ToString(outputData, 0, 6); } public static int StringIPToInt(string IPString) { string[] _splitString = IPString.Split(new char[] { '.' }); int _retVal = 0; if (_splitString.Length < 4) throw new ArgumentException("Please pass in a valid IP in dotted-quad notation!", "IPString"); else { _retVal += (int)(int.Parse(_splitString[3]) * Math.Pow(256, 0)); _retVal += (int)(int.Parse(_splitString[2]) * Math.Pow(256, 1)); _retVal += (int)(int.Parse(_splitString[1]) * Math.Pow(256, 2)); _retVal += (int)(int.Parse(_splitString[0]) * Math.Pow(256, 3)); } _retVal = (int)(((_retVal & 0x000000ff) << 24) + ((_retVal & 0x0000ff00) << 8) + ((_retVal & 0x00ff0000) >> 8) + ((_retVal & 0xff000000) >> 24)); return _retVal; }
The error i get is: Default.aspx.cs(24): error CS0103: The name 'StringIPToLong' does not exist in the current context That sound like it can't find the StingIPToLong function in the current codeblock, but the function is declared "public" so i thought that it worked in all codeblocks. -
Thanks for the fast reply. I think i have figured the SendARP() out now, but i still can't give it the IP destination in integer. i tried with the code you provieded me, like this:
public partial class _Default : System.Web.UI.Page { [DllImport("iphlpapi.dll", ExactSpelling = true)] public static extern int SendARP(int DestIP, int SrcIP, [Out] byte[] pMacAddr, ref int PhyAddrLen); protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) { byte[] outputData = new byte[6]; int dataLength = outputData.Length; SendARP(StringIPToLong("192.168.1.101"), StringIPToLong("127.0.0.1"), outputData, ref dataLength); Label1.Text = "MAC:" + BitConverter.ToString(outputData, 0, 6); } public static int StringIPToInt(string IPString) { string[] _splitString = IPString.Split(new char[] { '.' }); int _retVal = 0; if (_splitString.Length < 4) throw new ArgumentException("Please pass in a valid IP in dotted-quad notation!", "IPString"); else { _retVal += (int)(int.Parse(_splitString[3]) * Math.Pow(256, 0)); _retVal += (int)(int.Parse(_splitString[2]) * Math.Pow(256, 1)); _retVal += (int)(int.Parse(_splitString[1]) * Math.Pow(256, 2)); _retVal += (int)(int.Parse(_splitString[0]) * Math.Pow(256, 3)); } _retVal = (int)(((_retVal & 0x000000ff) << 24) + ((_retVal & 0x0000ff00) << 8) + ((_retVal & 0x00ff0000) >> 8) + ((_retVal & 0xff000000) >> 24)); return _retVal; }
The error i get is: Default.aspx.cs(24): error CS0103: The name 'StringIPToLong' does not exist in the current context That sound like it can't find the StingIPToLong function in the current codeblock, but the function is declared "public" so i thought that it worked in all codeblocks.GentooBoxX wrote: That sound like it can't find the StingIPToLong function in the current codeblock, but the function is declared "public" Look at your code. You renamed the function to "StingIPToInt" but are calling "StringIPToLong" Absolute faith corrupts as absolutely as absolute power Eric Hoffer All that is necessary for the triumph of evil is that good men do nothing. Edmund Burke
-
GentooBoxX wrote: That sound like it can't find the StingIPToLong function in the current codeblock, but the function is declared "public" Look at your code. You renamed the function to "StingIPToInt" but are calling "StringIPToLong" Absolute faith corrupts as absolutely as absolute power Eric Hoffer All that is necessary for the triumph of evil is that good men do nothing. Edmund Burke
-
I actually renamed the function when I was typing the comment (so as to simplify for you - I represented an IP as a long variable instead of an int in my app). :) Did it help you with what you needed?
-
hi. I new to C# and would like to know how i send an ARP packet to a computer using sendarp from iphlpapi.dll. I saw this code somewhere on the web, and its what i need. but i have little idea how to use it: [DllImport("iphlpapi.dll", ExactSpelling = true)] public static extern int SendARP(int DestIP, int SrcIP, [Out] byte[] pMacAddr, ref int PhyAddrLen); I can see that a function is being build. Can i just use it by doing this: Int32 IP = Convert.ToDecimal(192.168.0.1); SendARP(IP,0,0,IP.Length) or how do i do it ?