I have this snippet in Java:
final InetAddress address = InetAddress.getLocalHost();
final NetworkInterface ni = NetworkInterface.getByInetAddress(address);
key = new String(ni.getHardwareAddress());
"key", on my PC returns:
▲╔UiÎ
What would be the equivalent to get the same output in VB.Net? I have tried getting 'MAC Address' and 'Physical Address' but they do not compare to the output in Java at all?
I can't help you with the VB, but maybe I can clear a few things up.
In my experience, InetAddress.getLocalHost() is useless. It gives different results depending on the OS, on the Java version, on the brand of router you're connecting to, on the phase of the moon, etc. Stay away from it. If you want the loopback IP address, just hard-code it: 127.0.0.1. If you want the addresses of the network interfaces on your machine, call NetworkInterface.getInterfaces() and iterate through them.
The MAC address is the unique ID of an ethernet interface. Normally, you don't have to worry about it at all, unless you're doing something weird with the network hardware. It's got nothing to do with IP addresses.
Lastly: if you're looking to determine the IP address that others can use to connect to you, just be aware that it's not so simple. A computer may have multiple network interfaces - how do you know which one to pick? And if you're behind a router (as most machines are these days) then the computer is assigned a "local" address, which is completely useless to anyone outside the local network.
Related
I tried getting Public IP address from HttpServletRequest object using
httpServletRequest.getRemoteAddress();
which returns simple public ip address e.g. 123.21.21.12 but what I need is 132.21.21.12/8.
I have checked this How to get client's IP address using javascript only? but all of these provide simple ip addresses not with CIDR bits.
Thank you.
As others stated in the comments to your question, there is no way to extract subnet mask information just from the IP address alone, and there is no reliable way to get this information from the server. Firstly, you are communicating with a single IP address and not the whole subnet, so the correct CIDR is, as others said, /32. Secondly, network mask is network layer information and the way IP routing works doesn't require any other information to be provided other than a destination IP address.
It is important to know what exactly are trying to accomplish and are using this information for. Do you need this just to fulfill some format requirements or you really need the subnet mask. Anyway, if we're talking about ordinary web client/server I could see two different scenarios:
1) You need exact information about client network configuration
Even if you would be able to programmatically obtain such data, I'm not sure how useful it would be. Because of the shortage of IPv4 addresses and the way ISPs allocate addresses to customers most of the clients are behind their home router which does NAT or in some cases behind carrier grade NAT. Having bunch of clients that all have the same 192.168.1.2/24 address would be a bit pointless.
2) You need the public information (used for global routing) to group customers or something related to that.
This means getting the public IP address (the one you get with httpServletRequest.getRemoteAddress();). There's no way to obtain the exact subnet with 100% accuracy but you can get the route object from a RIR (Regional Internet Registry) database that delegated the scope that IP belongs to. LIRs (organizations that got the address block) have the obligation to update this database with various information and one of those is creating these route objects. For that you can use Whois protocol which is really simple and easily implemented. Basically you just need to open TCP connection to a port 43, send a command that contain the IP address you need the info on and parse the output.
For your example (123.21.21.12) the route object would look like:
~ # whois -T route 123.21.21.12
% [whois.apnic.net]
% Whois data copyright terms http://www.apnic.net/db/dbcopyright.html
% Information related to '123.21.16.0/20AS45899'
route: 123.21.16.0/20
descr: VietNam Post and Telecom Corporation (VNPT)
descr: VNPT-AS-AP
country: VN
origin: AS45899
remarks: mailto: noc#vnn.vn
notify: hm-changed#vnnic.net.vn
mnt-by: MAINT-VN-VNPT
changed: hm-changed#vnnic.net.vn 20100810
source: APNIC
% This query was served by the APNIC Whois Service version 1.69.1-APNICv1r0 (UNDEFINED)
We can see that that IP address belongs to a AS45899 (VNPT) and that the route object is 123.21.16.0/20, which gives you the CIDR you wanted.
And if we query that IP address from a router that has a full BGP table:
# show bgp ipv4 unicast 123.21.21.12
BGP routing table entry for 123.21.16.0/20, version 71369881
Paths: (3 available, best #1, table default)
we do see that indeed the Whois database is updated and that IP belongs to 123.21.16.0/20 route.
Keep in mind that this /20 could be aggregated route, but that's the best you can get. That's the routing information that's globally available and used by routers around the world to route traffic. How that /20 prefix is used inside the ISP network is up to their internal organization and policies and you can't check that. You also shouldn't get routes smaller than /24 this way.
I want to know in advance what network interface will be used for a given IP address X.
I could do that by browsing the result of java.net.NetworkInterface.getNetworkInterfaces() and checking X against the IP address and subnet mask of each InterfaceAddress returned by getInterfaceAddresses(), but it doesn’t seem like a lot of fun and I could end up with a different result from the one chosen by the IP stack if several choices are valid.
Why do I need that?
I need to know the IP address which can be used to reach me from the peer having the IP address X.
There's an answer here that I feel solves your problem.
But to expand on it a bit, the following code prints out the IP address of the interface you would use to route an IP packet from your host to the IP x.x.x.x.
DatagramSocket s = new DatagramSocket();
s.connect(InetAddress.getByAddress(new byte[]{x,x,x,x}), 0);
NetworkInterface n = NetworkInterface.getByInetAddress(s.getLocalAddress());
InetAddress yourInterfaceIP = n.getInetAddresses().nextElement();
System.out.println(yourInterfaceIP.getHostAddress());
Setting up a UDP datagram socket doesn't send anything. It just simply checks permissions and routing between the two end points. The IP you specify doesn't need to be reachable either for this to work.
This uses the routing present on the host your running this on. Obviously it doesn't use the routing on the remote host. So really, it returns what it considers a reachable interface from the perspective of X.
This obviously won't work behind a proxy, for which you'll need to use a whats-my-ip type service to look up what your proxy address is.
I need to get the actual (not the gateway) ip address of my computer but all the solutions I have tried are returning the gateway IP address. For instance, all suggestions from this link Get the client IP address using PHP return the gateway address. Is there a way I can get the actual ip address (public) of my computer - either in php or java?
From the comments, it sounds like you want to create a unique identifier for each computer accessing the server. There is no one piece of information that you can get that will act as such an identifier, here's why:
IP Address
The IP address that you can see is the public address, not the private address of a device behind a NAT'd router.
MAC Address
The MAC address of each network card in each computer is unique, but that information is not available outside of the LAN segment.
You may be able to use a combination of pieces of information (like the IP address and user agent) to make an educated guess that a given request is coming from a unique user, but this would be a guess.. there's no way to be certain of it.
Use $_SERVER['REMOTE_ADDR'] to get the user's public address, and then $_SERVER['USER_AGENT'] to get their user agent. If the combination of these two are unique, then there's a good chance that the request is coming from a unique user.
Another way to do this would be to set a cookie that has a distant future expiration date, or a session ID. But this all depends on how long you need to keep track of the user, if you need to keep track of them after they've closed their browser and then later returned, etc. The only full-proof way is to create an account where they authenticate on your site.
java's InetAddress class might be useful.
InetAddress IP=InetAddress.getLocalHost();
System.out.println("IP is := "+IP.getHostAddress());
Output: IP is := 10.100.95.228
I'm trying to determine the name of a PPTP VPN interface in android so I can list it as a bind-able interface in my application. Since there is no VPN API to do that in Android -- I figured I could use straight Java to find it.
When I do your standard Java to get the list of interfaces, ie.
ArrayList<NetworkInterface> allInterfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
I see a few interesting things:
When phone is on 802.11X Wifi
tiwlan0 (the wifi interface)
ppp0 (the VPN)
When the phone is on Verizon Only
ppp0 (the VPN, usually)
ppp1 (the VZ network, usually)
So - I need a way to eliminate the VZ interface. You can get NetworkInfo objects from the Android API like this:
ConnectivityManager conMan = (ConnectivityManager)this.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] infoList = conMan.getAllNetworkInfo();
There are a few problems with that method:
The VPN doesn't show up
The names/fields in the network info objects don't correspond to anything in the Java NetworkInterface object
The way I see it there's a few ways to eliminate the VZ interface from the all interfaces list:
Do it by name (ie. if Android gave me a list that had "ppp1" in it I could eliminate ppp1, since the Android list does not ever contain the VPN)
Do it by IP (ie. if I could figure out the VZ IP address, I could eliminate the interface with that IP using Java's NetworkInterface object.)
Unfortunately, it doesn't look like either of those options are possible since the names don't match up and I can't figure out how to get the VZ IP from the Android OS.
So -- has anyone else tried something similar? Is there some way to ask the android OS what interfaces have IP addresses?
Thanks in advance -- all help is appreciated.
Dan
PS. I'm trying to avoid forcing the user to input a valid IP range (or specific IP) to bind to.
EDIT: One possible option here is to do a JNI system calll with the android native kit. Read the directory listing of /dev/ and grep for ppp*. Assume the earliest one is the 3G/4g connection and the latter one is the VPN.
Found out this is not possible using the current API (10). Bug Report/Feature Request:
http://code.google.com/p/android/issues/detail?id=15082
I want to get all the usernames or IPaddresses from the LAN using java.
Can anyone suggest me how to approach?
Thank you.
This is a slightly strange question. What is your purpose, what do you want to do with the information? A list of user names is quite different from a list of IP addresses, it's hard to understand why either is acceptable.
Also, consider that just because an IP address "exists" on a LAN, that doesn't say anything about the type of host that has the IP address. It might not have a "user" associated with it, for instance.
For a list of IPs, try finding the subnetwork mask, and pinging the broadcast address.