OSX: Check if the default interface is physical or virtual - macos

Is there way on OSX to see if the default interface is an actual physical interface or if it is a virtual interface like when it is connected to a VPN?
Essentially, I am trying to figure out an interface property that can tell if the default interface is virtual or physical. We can read interface properties from scutil system configuration utility framework.

It sounds like you are defining a virtual interface as a VPN connection, OK. However the concept of default interface depends on the specific address you are trying to communicate to, meaning the default interface may be different when communicating to google.com or abc.com or yourcompany.com
In the Mac OS X terminal you can run the route command against something meaningful, for this example i will use abc.com:
route get abc.com | grep interface
For me, using wifi it reports:
interface: en0
Then when connected to VPN over wifi it reports:
interface: ppp0
Note that in this test I was using the VPN option 'send all traffic over vpn connection' but when i turn this off it reports interface: en0 because abc.com is not defined as a remote network for my VPN. This is why it is important to use a meaningful address for this test.

Related

How to get the underlying network interface used by a VPN connection in Windows

The closest thing to a solution I've found is using Get-NetConnectionProfile to return all active interfaces, which works fine when there's only an active physical interface and the VPN itself. However, this would not work if the user's machine has 2 active physical interfaces (e.g Wi-Fi + Ethernet) along with the VPN.
Ideally, I'd like a solution that works similarly to "ifconfig -v" in MacOS, which tells you the effective interface for a virtual interface:
Unfortunately it seems there is no sure-fire way to get the underlying physical adapter for a VPN using a Windows API. Short of involving a packet sniffer such as Wireshark, the best solution I found involves parsing the output of two PowerShell commands: Get-NetAdapter and Get-NetRoute.
With the information from these commands, I can know which interfaces are virtual and which ones are physical, and I can rank the physical interfaces by 3 different criteria (in case of tie, we move on to the next criteria):
Sorting the physical interfaces by the interface metric + the route metric to the default gateway (0.0.0.0).
Wired connections over wireless ones (PhysicalMediaType=802.3).
Prioritizing faster adapters.
With this logic all the VPNs I tested appear to reflect the expected network interface, although some VPNs let you force traffic through a particular physical adapter in which case obviously this all goes out the window.
First,
You can install wireshark or some other traffic monitoring tool and capture the relevant packets (filtering using openvVPN protocol or port etc.)
Second,
As far as I know there is no hard linking between the virtual network interface and the regular (ethernet, WIFI etc.) interface, at least not in OpenVPN (there are diffrent VPN protocols). The openVPN packets will be routed to the remote server using you OS routing table.
This way if your ethernet interface is your primary default gateway, and it gets unplugged, your VPN service will be able to recover, since it will have a route to your remote VPN-server address using your WIFI interface.

My MAC is connected to both Ethernet and Wifi at time,how can i detect from which network is getting acessed

My MAC is connected to Ethernet and Wifi at a time. Both are different networks. I wanted to know from which interface my system is accessing internet. I want a command to check this. By giving
traceroute google.com , i can get default route, as i know ip addresses of both networks. But the case is how can i detect this in remote machines whose ip addresses are unknown
when i give
ifconfig
I see en0 and en1 are assigned with two diff ips and are active. Even from this i am unable to differentiate.
I achieved this by following below procedure
1) networksetup -listnetworkserviceorder , by using this we will network service order of MAC, along with interface to which it is connected
2) route get default | grep interface gives the currently using interface.
By checking current interface with service order, we can know from which interface our mac is accessing internet

Finding MacAddress from IP Address in a platform independent way

I need to findout the mac address of the device from which my device gets TCP requests, I ll be getting the ip address of the device by tcp endpoint but i need to find out the mac address of the device.My application will be running on both windows and linux, so please suggest me a cross platform method to find the mac address.. Any boost libraries will help me doing the same??
Firstly, you can't find the MAC address for any network interface that is not on the same local area network. That information is not transmitted beyond the router.
There is a command line tool called arp that is available on Unix and also Windows that will list IP addresses and MAC addresses of interfaces that have been in communication with your PC. i.e.
arp -a
on Windows gives something like:
Interface: 9.175.198.236 --- 0x2
Internet Address Physical Address Type
9.175.198.129 00-1b-53-46-fa-7f dynamic
and on a Unix-alike looks like:
foo.bar.com (10.27.68.72) at 00:50:56:AE:00:0B [ether] on eth0
baz.bar.com (10.27.68.77) at 00:50:56:AE:00:10 [ether] on eth0
? (10.27.68.1) at 00:50:5A:1B:44:01 [ether] on eth0
You can try invoking it and parsing the output programmatically.
arp source code is available in the below link, take the piece of code that interests you! It is c code so it should work fine.
http://www.opensource.apple.com/source/network_cmds/network_cmds-328/arp.tproj/arp.c
First thing to note is that at TCP layer, you don't know the MAC addresses.
For your case, I guess you can do two things:
use arp or write a piece of code similar to arp which looks for MAC given the IP address.
The problem with this approach is that it won't work in cases when the source is in another network.
write your server in such a way that it requests for this information from the client sending TCP request. This can be done post TCP establishment. The client should also be able to look up the machine's MAC address for the given IP.

Find IP address of directly connected device

Is there a way to find out the IP address of a device that is directly connected to a specific ethernet interface? I.e. given one host, one wired ethernet connection and one second host connected to this wired connection, which layer or protocol below IP could be used to find this out.
I would also be comfortable with a Windows-only solution using some Windows-API function or callback.
(I know that the real way to do this would probably via DHCP, but this is about discovering a legacy device.)
Mmh ... there are many ways.
I answer another network discovery question, and I write a little getting started.
Some tcpip stacks reply to icmp broadcasts.
So you can try a PING to your network broadcast address.
For example, you have ip 192.168.1.1 and subnet 255.255.255.0
ping 192.168.1.255
stop the ping after 5 seconds
watch the devices replies : arp -a
Note : on step 3. you get the lists of the MAC-to-IP cached entries, so there are also the hosts in your subnet you exchange data to in the last minutes, even if they don't reply to icmp_get.
Note (2) : now I am on linux. I am not sure, but it can be windows doesn't reply to icm_get via broadcast.
Is it the only one device attached to your pc ?
Is it a router or another simple pc ?
To use DHCP, you'd have to run a DHCP server on the primary and a client on the secondary; the primary could then query the server to find out what address it handed out. Probably overkill.
I can't help you with Windows directly. On Unix, the "arp" command will tell you what IP addresses are known to be attached to the local ethernet segment. Windows will have this same information (since it's a core part of the IP/Ethernet interface) but I don't know how you get at it.
Of course, the networking stack will only know about the other host if it has previously seen traffic from it. You may have to first send a broadcast packet on the interface to elicit some sort of response and thus populate the local ARP table.
Windows 7 has the arp command within it.
arp -a should show you the static and dynamic type interfaces connected to your system.
Your Best Approach is to install Wireshark, reboot the device wait for the TCP/UDP stream , broadcasts will announce the IP address for both Ethernet ports
This is especially useful when the device connected does not have DHCP Client enabled, then you can go from there.
You can also get information from directly connected networking devices, such as network switches with LDWin, a portable and free Windows program published on github:
http://www.sysadmit.com/2016/11/windows-como-saber-la-ip-del-switch-al-que-estoy-conectado.html
LDWin supports the following methods of link discovery: CDP (Cisco Discovery Protocol) and LLDP (Link Layer Discovery Protocol).
You can obtain the model, management IP, VLAN identifier, Port identifier, firmware version, etc.

Virtual network interface in Mac OS X

I know that you can make a virtual network interface in Windows (see here), and in Linux it is also pretty easy with ip-aliases, but does something similar exist for Mac OS X? I've been looking for loopback adapters, virtual interfaces and couldn't find a good solution.
You can create a new interface in the networking panel, based on an existing interface, but it will not act as a real fully functional interface (if the original interface is inactive, then the derived one is also inactive).
This scenario is needed when working in a completely disconnected situation. Even then, it makes sense to have networking capabilities when running servers in a VMWare installation. Those virtual machines can be reached by their IP address, but not by their DNS name, even if I run a DNS server in one of those virtual machines. By configuring an interface to use the virtual DNS server, I thought I could test some DNS scenario's. Unfortunately, no interface is resolving DNS names if none of them are inactive...
The loopback adapter is always up.
ifconfig lo0 alias 172.16.123.1 will add an alias IP 172.16.123.1 to the loopback adapter
ifconfig lo0 -alias 172.16.123.1 will remove it
Replying in particular to:
You can create a new interface in the networking panel, based on an existing interface, but it will not act as a real fully functional interface (if the original interface is inactive, then the derived one is also inactive).
This can be achieved using a Tun/Tap device as suggested by psv141, and manipulating the /Library/Preferences/SystemConfiguration/preferences.plist file to add a NetworkService based on either a tun or tap interface. Mac OS X will not allow the creation of a NetworkService based on a virtual network interface, but one can directly manipulate the preferences.plist file to add the NetworkService by hand. Basically you would open the preferences.plist file in Xcode (or edit the XML directly, but Xcode is likely to be more fool-proof), and copy the configuration from an existing Ethernet interface. The place to create the new NetworkService is under "NetworkServices", and if your Mac has an Ethernet device the NetworkService profile will also be under this property entry. The Ethernet entry can be copied pretty much verbatim, the only fields you would actually be changing are:
UUID
UserDefinedName
IPv4 configuration and set the interface to your tun or tap device (i.e. tun0 or tap0).
DNS server if needed.
Then you would also manipulate the particular Location you want this NetworkService for (remember Mac OS X can configure all network interfaces dependent on your "Location"). The default location UUID can be obtained in the root of the PropertyList as the key "CurrentSet". After figuring out which location (or set) you want, expand the Set property, and add entries under Global/IPv4/ServiceOrder with the UUID of the new NetworkService. Also under the Set property you need to expand the Service property and add the UUID here as a dictionary with one String entry with key __LINK__ and value as the UUID (use the other interfaces as an example).
After you have modified your preferences.plist file, just reboot, and the NetworkService will be available under SystemPreferences->Network. Note that we have mimicked an Ethernet device so Mac OS X layer of networking will note that "a cable is unplugged" and will not let you activate the interface through the GUI. However, since the underlying device is a tun/tap device and it has an IP address, the interface will become active and the proper routing will be added at the BSD level.
As a reference this is used to do special routing magic.
In case you got this far and are having trouble, you have to create the tun/tap device by opening one of the devices under /dev/. You can use any program to do this, but I'm a fan of good-old-fashioned C myself:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd = open("/dev/tun0", O_RDONLY);
if (fd < 0)
{
printf("Failed to open tun/tap device. Are you root? Are the drivers installed?\n");
return -1;
}
while (1)
{
sleep(100000);
}
return 0;
}
In regards to #bmasterswizzle's BRILLIANT answer - more specifically - to #DanRamos' question about how to force the new interface's link-state to "up".. I use this script, of whose origin I cannot recall, but which works fabulously (in coordination with #bmasterswizzles "Mona Lisa" of answers)...
#!/bin/zsh
[[ "$UID" -ne "0" ]] && echo "You must be root. Goodbye..." && exit 1
echo "starting"
exec 4<>/dev/tap0
ifconfig tap0 10.10.10.1 10.10.10.255
ifconfig tap0 up
ping -c1 10.10.10.1
echo "ending"
export PS1="tap interface>"
dd of=/dev/null <&4 & # continuously reads from buffer and dumps to null
I am NOT quite sure I understand the alteration to the prompt at the end, or...
dd of=/dev/null <&4 & # continuously reads from buffer and dumps to null
but WHATEVER. it works. link light🚦: green✅. loves it💚.
A few others seemed to hint at this, but the following demonstrates using ifconfig to create a vlan and test DNS on the virtual interface (using minidns) on OS X 10.9.5:
$ sw_vers -productVersion
10.9.5
$ sudo ifconfig vlan169 create && echo vlan169 created
vlan169 created
$ sudo ifconfig vlan169 inet 169.254.169.254 netmask 255.255.255.255 && echo vlan169 configured
vlan169 configured
$ sudo ./minidns.py 169.254.169.254 &
[1] 35125
$ miniDNS :: * 60 IN A 169.254.169.254
$ dig #169.254.169.254 +short test.host
Request: test.host. -> 169.254.169.254
Request: test.host. -> 169.254.169.254
169.254.169.254
$ sudo kill 35125
$
[1]+ Exit 143 sudo ./minidns.py 169.254.169.254
$ sudo ifconfig vlan169 destroy && echo vlan169 destroyed
vlan169 destroyed
It's possible to use TUN/TAP device.
http://tuntaposx.sourceforge.net/
if you are on a dev environment and want access some service already running on localhost/host machine. in docker for mac you have another option.use docker.for.mac.localhost instead of localhost in docker container.
docker.for.mac.host.internal should be used instead of docker.for.mac.localhost from Docker Community Edition 17.12.0-ce-mac46 2018-01-09.
this allows you to connect to service running on your on mac from within a docker container.please refer below links
understanding the docker.for.mac.localhost behavior
release notes
What do you mean by
"but it will not act as a real fully functional interface (if the original interface is inactive, then the derived one is also inactive"
?
I can make a new interface, base it on an already existing one, then disable the existing one and the new one still works. Making a second interface does however not create a real interface (when you check with ifconfig), it will just assign a second IP to the already existing one (however, this one can be DHCP while the first one is hard coded for example).
So did I understand you right, that you want to create an interface, not bound to any real interface? How would this interface then be used? E.g. if you disconnect all WLAN and pull all network cables, where would this interface send traffic to, if you send traffic to it? Maybe your question is a bit unclear, it might help a lot if rephrase it, so it's clear what you are actually trying to do with this "virtual interface" once you have it.
As you mentioned "alias IP" in your question, this would mean an alias interface. But an alias interface is always bound to a real interface. The difference is in Linux such an interface really IS an interface (e.g. an alias interface for eth0 could be eth1), while on Mac, no real interface is created, instead a virtual interface is created, that can configured and used independently, but it is still the same interface physically and thus no new named interface is generated (you just have two interfaces, that are both in fact en0, but both can be enabled/disabled and configured independently).
Take a look at this tutorial, it's for FreeBSD but also applies to OS X. http://people.freebsd.org/~arved/vlan/vlan_en.html
Go to Network Preferences.
At the bottom of the list of network adapters, click the + icons
Select the existing interface that you want to arp (say Ethernet 1), and give the Service Name that you want for the new port (say Ethernet 1.1) then press create.
Now you have the new virtual interface in the gui and can manage IP addresses etc it in the normal way.
ifconfig -a will confirm that you have multiple IPs on the interface, and these will still be there when you reboot.
Its a Mac. Don't fight it, do it the easy way.
i have resorted to running PFSense, a BSD based router/firewall to achieve this goal….
why? because OS X Server gets so FREAKY without a Static IP…
so after wrestling with it for DAYS to make NAT and DHCP and firewall and …
I'm trying this is parallels…
will let ya know how it goes...
ifconfig interfacename create will create a virtual interface,
Here's a good guide: https://web.archive.org/web/20160301104014/http://gerrydevstory.com/2012/08/20/how-to-create-virtual-network-interface-on-mac-os-x/
Basically you select a network adapter in the Networks pane of system preferences, then click the gear to "Duplicate Service". After the service is duplicated, you manually assign an IP in one of the private address ranges. Then ping it to make sure ;)

Resources