I'm programming in C# and i want to detect a cell phone(Name, IP address, RSSI, ...) in Wireless Network (Wi-Fi) to calculate after that the distance between my computer and the cell phone
Actually, I'm able to detect computers name connected to the same network with :
using System.DirectoryServices;
...
List<String> _ComputerNames = new List<String>();
String _ComputerSchema = "Computer";
DirectoryEntry _WinNTDirectoryEntries = new DirectoryEntry("WinNT:");
foreach (DirectoryEntry _AvailDomains in _WinNTDirectoryEntries.Children)
{
foreach (DirectoryEntry _PCNameEntry in _AvailDomains.Children)
{
if (_PCNameEntry.SchemaClassName.ToLower().Contains(_ComputerSchema.ToLower()))
{
_ComputerNames.Add(_PCNameEntry.Name);
}
}
}
But I cannot find my cell phone that is connect to the same wi-fi network.
How can I resolve this problem ?
Thanks!
I dont think ActiveDirectory is going to work too well for you here, your likely going to need to work more closely with the access point itself to fetch the RSSI values. Unless there is a particular domain knowledge you have about all phones being part of an ActiveDirectory its like Jean said: you only get MAC address, possibly IP address and the RSSI value.
If you are only interested in distance you will likely need to test out a range of distances with a particular device and use the RSSI-distance list you to guestimate the distance of a new device based on the RSSI value for it.
A problem you will encounter is you might have X RSSI Value for one device, and 2X RSSI Value for another device and they could very well be the exact same distance. Although if you are only interested in phones I would expect the fluctuation to be less severe.
A more accurate way to do this would be to have multiple Access Points setup and triangulate the device's position with a bit of math, the plus side of this is also giving you distance as well as direction, amounting to location
Unless I am mistaken, only the Wi-Fi access point itself will have access to the full list of devices. Even then, it doesn't know what type each device is. It knows the MAC address of each device, and it may know the IP it was allocated (assuming it is also a DHCP server), but beyond that the device could be anything from a laptop to a television.
If you are a network administrator, then I can see how this might be useful - if you have a policy where only certain devices are intended to connect to the network, then it makes sense to hunt down "rogue" devices. Otherwise, I can't see any good reason to try and help you any further.
If you know what ip address the phone has then you can try and ping the device.
bool isIpReachable(string ipAddress)
{
Ping pingSender = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 120;
try
{
PingReply reply = pingSender.Send(ipAddress, timeout, buffer, options);
return reply.Status == IPStatus.Success;
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
return false;
}
Related
We're trying to obtain all ip addresses and hostnames of machines on local network, we have a display box(BrightSign box) which is connected to local network and we want to have all information about that box. We can find ip address of it, but cannot get host name. So we can't determine which ip adresses is assigned to that box. (We can learn the ip address of the box by using its own program; but we want to detect automatically)
here the code we use in c#
`
public void scan(string subnet)
{
Ping myping;
PingReply reply;
IPAddress addr;
IPHostEntry host;
for (int i = 1; i < 255; i++)
{
string subnetn = "." + i.ToString();
myping = new Ping();
//string data = "aa";
//byte[] buffer = Encoding.ASCII.GetBytes(data);
//PingOptions optionss = new PingOptions(64, true);
int timeout = 1000;
reply = myping.Send(subnet + subnetn);
if (reply.Status == IPStatus.Success)
{
try {
addr = IPAddress.Parse(subnet+subnetn);
host = Dns.GetHostEntry(addr);
txtHosts.AppendText(subnet + subnetn + host.HostName.ToString()+"\n");
}
catch {
}
}
}
}`
if we use this code, system can detect all ip but not host names belongs to telephone and the box i mentioned.
Briefly, we need to have all machine name and ip addresses on local network.
So, do you guys have any idea what's the problem and what can we do to solve this issue. We made some research and tried some ways. We tried to send ping the ip address which we cannot take the hostname and we realized that if ttl of machine is set to 64, we cannot take the hostname, but if its ttl is 128, we can manage to learn the hostname, i also adjusted ping settings to test this challenge, but i still have problem.
I am looking forward to hearing your response.
Thank you all.
Machine name could be DNS or NETBIOS or something else. I recommend you check out NMAP and see what it can do. If you want to emulate that, you can ask about a specific requirement. For example, getting a DNS name means querying the DNS server, a computer wont reply with a name just from an ICMP ping. If the computer security settings allow it, you can do a netbios query, or use WMI, or if you are in a domain, query the domain server.
I don't know what brightsign is, but there is no law that says a device must have a DNS name, some appliances just use IP address and thats it. Also there's no law that says a device must respond to ping or any other protocol.
Anyone know if it can recover the ( hostname/machine name ) with a local IP address ? I know that the resolution reverse 'hostname -> ip' works perfectly with DeviceNetworkInformation.ResolveHostNameAsync (endpoint, OnNameResolved, null).
Is it possible to do the same thing but in reverse? Given the IP of a Local Machine and retrieve its hostname? A thousand thanks
Here is my code , but it's doesn't work the host is always called "192.168.1.5" like the ip . And it's should return "computer0001"
DeviceNetworkInformation.ResolveHostNameAsync("192.168.1.5", OnNameResolved, null);
private void OnNameResolved(NameResolutionResult result)
{
IPEndPoint[] endpoints = result.IPEndPoints;
if (endpoints != null)
{
if (endpoints.Length > 0)
{
//Host always return ip adress and not the machine name
host = endpoints[0].ToString();
}
}
}
Not sure if there is specific API on Windows Phone for that purpose.
I suggest you looking into similar question 'DNS lookup from custom DNS server in c#'.
If you're okay with going only WP8, then you should study this part of MSDN - Supported Win32 APIs for Windows Phone 8.
For example, getpeername function might return you information you're looking for. Or you might create new HostName object passing IP address there and trying to read DisplayName, CanonicalName or RawName properties of it.
Make sure you test with both emulator and real device as WP8 emulator has a little bit complex network configuration.
Would be great if you can update us if you have any success with the task.
string myHost = System.Net.Dns.GetHostName();
string myIP =
System.Net.Dns.GetHostByName(myHost).AddressList[0].ToString();
MessageBox.Show(myIP);
TextReader read = new StreamReader(//Text file with network address);
var ip = read.ReadLine();
read.Close();
if (ip == //Need help with this part)
MessageBox.Show("You are on the network");
else
MessageBox.Show("You are not on the network");
I can get my computers address but I need to compare it to a network address and if it falls under that network address to show that it is.
If your program crashes when your IP is invalid, you can change it over to a try catch that checks for that exception (run it and crash it to find the exception). This is how I validated the IP in my multiplayer with Lidgren.
Though this is probably not the best way, it works.
One simple way to see if an ip is in a range is to convert the ip and the start and end of the range to longs (a function can be written for the conversion to a long from an IP address). Then see if the ip is between the two numbers.
For example:
IP to check: 172.17.1.25 -- Converted to long --> 172017001025
Range:
Start - 172.0.0.0 -- Converted to long --> 172000000000
End - 172.255.255.255 -- Converted to long --> 172255255255
Now just check if the ip is between the start and end values.
I recommend the IPNetwork utility that can be found on codeplex. It is pretty flexible and powerful. It will allow you to do a lot of things, and determining the network for a given ip address is one of them.
http://ipnetwork.codeplex.com/
The code should look like :
var ipnetwork = IPNetwork.Parse(ip);
if (ipnetwork.Contains(myIp)) {
// do some work...
I have a situation where I ping a range of IPs in the network. Then, I try to connect to the successful pings.
My aim is to connect to specific equipment that has a specific MAC prefix. For example, when I ping a range of 100 IPs, I might get 20 replies. These replies include computers, printers, and possibly the hardware I am trying to connect.
Currently what happens is that when I try to connect to anything other than the hardware I would like (i.e computer, printer) I get a timeout connection.
This is fine, however, it is not efficient. I would like to filter out the successful ping list by using the MAC address, however, I have not yet been able to find a solution that allows me to seek a MAC address prior to connecting the hardware.
I have looked through most the MAC questions on here, but none fit my needs.
Any ideas??
I was able to find the solution here: http://pinvoke.net/default.aspx/iphlpapi/SendARP.html
The following method returns the MAC
internal static string GetMAC(string ip)
{
IPAddress dst = IPAddress.Parse(ip); // the destination IP address Note:Can Someone give the code to get the IP address of the server
byte[] macAddr = new byte[6];
uint macAddrLen = (uint)macAddr.Length;
if (SendARP((int)dst.Address, 0, macAddr, ref macAddrLen) != 0)
throw new InvalidOperationException("SendARP failed.");
string[] str = new string[(int)macAddrLen];
for (int i = 0; i < macAddrLen; i++)
str[i] = macAddr[i].ToString("x2");
return string.Join(":", str);
//Console.WriteLine(string.Join(":", str));
}
I'm trying to send a WOL package on all interfaces in order to wake up the gateway(which is the DHCP server, so the machine won't have an IP yet).
And it seems that I can only bind sockets to IP and port pairs...
So the question is: How can a create a socket(or something else) that is bound to a NIC that has no IP?
(Any languge is ok. c# is prefered)
#ctacke: I know that WOL is done by MAC address... My problem is that windows only sends UDP broadcasts on the NIC what Windows considers to be the primary NIC (which is not even the NIC with the default route on my Vista machine). And I can not seems to find a way to bind a socket to an interface which has no IP address. (like DHCP clients do this)
#Arnout: Why not? The clients know the MAC address of the gateway. I just want a send a WOL packet like a DHCP client does initially...(DHCP discover packets claim to come from 0.0.0.0) I don't mind if I have to construct the whole packet byte by byte...
It seems that I have found a solution. One can use winpcap to inject packets to any interface.
And there is good wrapper for .net: http://www.tamirgal.com/home/dev.aspx?Item=SharpPcap
(I would have prefered a solution which requires no extra libraries to be installed...)
UPDATE: Here is what I came up for sending a WOL packet on all interfaces:
//You need SharpPcap for this to work
private void WakeFunction(string MAC_ADDRESS)
{
/* Retrieve the device list */
Tamir.IPLib.PcapDeviceList devices = Tamir.IPLib.SharpPcap.GetAllDevices();
/*If no device exists, print error */
if (devices.Count < 1)
{
Console.WriteLine("No device found on this machine");
return;
}
foreach (NetworkDevice device in devices)
{
//Open the device
device.PcapOpen();
//A magic packet is a broadcast frame containing anywhere within its payload: 6 bytes of ones
//(resulting in hexadecimal FF FF FF FF FF FF), followed by sixteen repetitions
byte[] bytes = new byte[120];
int counter = 0;
for (int y = 0; y < 6; y++)
bytes[counter++] = 0xFF;
//now repeat MAC 16 times
for (int y = 0; y < 16; y++)
{
int i = 0;
for (int z = 0; z < 6; z++)
{
bytes[counter++] =
byte.Parse(MAC_ADDRESS.Substring(i, 2),
NumberStyles.HexNumber);
i += 2;
}
}
byte[] etherheader = new byte[54];//If you say so...
var myPacket = new Tamir.IPLib.Packets.UDPPacket(EthernetFields_Fields.ETH_HEADER_LEN, etherheader);
//Ethernet
myPacket.DestinationHwAddress = "FFFFFFFFFFFFF";//it's buggy if you don't have lots of "F"s... (I don't really understand it...)
try { myPacket.SourceHwAddress = device.MacAddress; }
catch { myPacket.SourceHwAddress = "0ABCDEF"; }//whatever
myPacket.EthernetProtocol = EthernetProtocols_Fields.IP;
//IP
myPacket.DestinationAddress = "255.255.255.255";
try { myPacket.SourceAddress = device.IpAddress; }
catch { myPacket.SourceAddress = "0.0.0.0"; }
myPacket.IPProtocol = IPProtocols_Fields.UDP;
myPacket.TimeToLive = 50;
myPacket.Id = 100;
myPacket.Version = 4;
myPacket.IPTotalLength = bytes.Length - EthernetFields_Fields.ETH_HEADER_LEN; //Set the correct IP length
myPacket.IPHeaderLength = IPFields_Fields.IP_HEADER_LEN;
//UDP
myPacket.SourcePort = 9;
myPacket.DestinationPort = 9;
myPacket.UDPLength = UDPFields_Fields.UDP_HEADER_LEN;
myPacket.UDPData = bytes;
myPacket.ComputeIPChecksum();
myPacket.ComputeUDPChecksum();
try
{
//Send the packet out the network device
device.PcapSendPacket(myPacket);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
device.PcapClose();
}
}
WOL is a very flexible protocol that can be implemented in multiple different ways.
The most common are:
Sending a WOL as the payload of an ethernet packet.
Sending a WOL as the payload of a UDP packet (for routing across the net).
Once it lands on the local network it's passes to all the hosts on the network using the broadcast MAC address.
For an Ethernet packet the structure is:
Destination MAC: FF:FF:FF:FF:FF:FF (Broadcast)
A Magic Packet Payload
For a UDP packet the structure is:
Destination MAC: FF:FF:FF:FF:FF:FF (Broadcast)
UDP Port: 9
A Magic Packet Payload
The Magic Payload consists of:
The Synchronization Stream: FFFFFFFFFFFF (that's 6 pairs or 6 bytes of FF)
16 copies of the MAC of the computer you're signaling to WOL
An optional passphrase of 0, 4, or 6 bytes.
To receive WOL packets from the internet (through a firewall/router):
Configure router port 9 to forward to IP 255.255.255.255 (Broadcast IP)
Set the destination IP: The external IP of the router
Note: This can only be achieved using the UDP example because Ethernet packets lack the IP layer necessary for the packet to be routed through the internet. IE, Ethernet packets are the local-network-only option. The issue with sending WOL packets over UDP is security because you have to set the router to enable IP broadcasting (255.255.255.255). Enabling broadcasting over IP is usually considered a bad idea because of the added risk of internal attack within the network (Ping flooding, cache spoofing, etc...).
For more info on the protocol including a sample capture see this site.
If you want a quick-and-dirty command line tool that generates WOL packets (and you're running on a debian, linux mint, or Ubuntu) you can install a tool that already does this.
Just install using the command line with:
sudo apt-get install wakeonlan
Update:
Here's a working example that generates a WakeOnLan packet using the current version of SharpPcap.
using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using PacketDotNet;
using SharpPcap;
namespace SharpPcap.Test.Example9
{
public class DumpTCP
{
public static void Main(string[] args)
{
// Print SharpPcap version
string ver = SharpPcap.Version.VersionString;
Console.WriteLine("SharpPcap {0}, Example9.SendPacket.cs\n", ver);
// Retrieve the device list
var devices = CaptureDeviceList.Instance;
// If no devices were found print an error
if(devices.Count < 1)
{
Console.WriteLine("No devices were found on this machine");
return;
}
Console.WriteLine("The following devices are available on this machine:");
Console.WriteLine("----------------------------------------------------");
Console.WriteLine();
int i = 0;
// Print out the available devices
foreach(var dev in devices)
{
Console.WriteLine("{0}) {1}",i,dev.Description);
i++;
}
Console.WriteLine();
Console.Write("-- Please choose a device to send a packet on: ");
i = int.Parse( Console.ReadLine() );
var device = devices[i];
Console.Write("What MAC address are you sending the WOL packet to: ");
string response = Console.ReadLine().ToLower().Replace(":", "-");
//Open the device
device.Open();
EthernetPacket ethernet = new EthernetPacket(PhysicalAddress.Parse(
"ff-ff-ff-ff-ff-ff"), PhysicalAddress.Parse("ff-ff-ff-ff-ff-ff"),
EthernetPacketType.WakeOnLan);
ethernet.PayloadPacket = new WakeOnLanPacket(
PhysicalAddress.Parse(response));
byte[] bytes = ethernet.BytesHighPerformance.Bytes;
try
{
//Send the packet out the network device
device.SendPacket(bytes);
Console.WriteLine("-- Packet sent successfuly.");
}
catch(Exception e)
{
Console.WriteLine("-- "+ e.Message );
}
//Close the pcap device
device.Close();
Console.WriteLine("-- Device closed.");
Console.Write("Hit 'Enter' to exit...");
Console.ReadLine();
}
}
}
Note: This is a fully functional Wake-On-Lan packet sending console application built on the Example09 that can be found in the SharpPcap source.
The libraries used in this example that can't be found in the .NET framework are:
using PacketDotNet;
This library (.dll) comes packaged with SharpPcap. It is responsible for all of the packet construction and parsing within SharpPcap. This is where the WakeOnLan class resides.
Note: The packet construction/parsing code was originally bundled within SharpPcap.dll. It was migrated to its own lib because SharpPcap is meant to be a wrapper for winpcap. Many of its users deal with designing protocols and/or handling raw networking packets.
using SharpPcap;
SharpPcap contains all of the winpcap(windows)/libpcap(*nix) wrapper code. It's needed to select the interface and send the actual packets across the wire.
WOL is done by MAC, not IP. Here's an example.
.NET operates as a virtual machine (the CLR), so it abstracts away much of the underlying real machine. For example, it only provides interfaces for TCP and UDP networking, which is much higher in the network protocol stack that what you are discussing. You might be able to find a third-party component that provides access to a lower-level interface, but I would not count on it (I have looked in the past for .NET and Java).
For access to that low in the network protocol stack, you probably will need to code in C to the relevant OS system calls. You may find this easiest in Python, and you may find this functionality already implemented in Python's or third-party libraries. For example, I suggest taking a look at the Twisted networking libraries. That was one of the reasons that I switched to Python for much of my work.
Best wishes.