identifying current LAN ip address from terminal
|
|
OP
Joined: Aug 2009
|
MAC:~ virtual1 $ ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
options=3<RXCSUM,TXCSUM>
inet6 ::1 prefixlen 128
inet 127.0.0.1 netmask 0xff000000
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
nd6 options=1<PERFORMNUD>
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 78:31:c1:d4:d8:16
inet6 fe80::7a31:c1ff:fed4:d816%en0 prefixlen 64 scopeid 0x4
inet 10.15.0.208 netmask 0xffff0000 broadcast 10.15.255.255
nd6 options=1<PERFORMNUD>
media: autoselect
status: active
en1: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
options=60<TSO4,TSO6>
ether 72:00:02:e6:f9:80
media: autoselect <full-duplex>
status: inactive
en2: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
options=60<TSO4,TSO6>
ether 72:00:02:e6:f9:81
media: autoselect <full-duplex>
status: inactive
bridge0: flags=8822<BROADCAST,SMART,SIMPLEX,MULTICAST> mtu 1500
options=63<RXCSUM,TXCSUM,TSO4,TSO6>
ether 7a:31:c1:4d:9b:00
Configuration:
id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
ipfilter disabled flags 0x2
member: en1 flags=3<LEARNING,DISCOVER>
ifmaxaddr 0 port 5 priority 0 path cost 0
member: en2 flags=3<LEARNING,DISCOVER>
ifmaxaddr 0 port 6 priority 0 path cost 0
media: <unknown type>
status: inactive
p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304
ether 0a:31:c1:d4:d8:16
media: autoselect
status: inactive
utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1380
inet6 fe80::e1a1:3f66:87bd:db95%utun0 prefixlen 64 scopeid 0xa
inet6 fd58:e0cd:efe3:3d3c:e1a1:3f66:87bd:db95 prefixlen 64
nd6 options=1<PERFORMNUD>
en4: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=10b<RXCSUM,TXCSUM,VLAN_HWTAGGING,AV>
ether a8:20:66:28:87:0b
inet6 fe80::aa20:66ff:fe28:870b%en4 prefixlen 64 scopeid 0x7
inet 10.3.24.143 netmask 0xffff0000 broadcast 10.3.255.255
nd6 options=1<PERFORMNUD>
media: autoselect (1000baseT <full-duplex>)
status: active ok that's pretty useful, but let me narrow it down en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 78:31:c1:d4:d8:16
inet6 fe80::7a31:c1ff:fed4:d816%en0 prefixlen 64 scopeid 0x4
inet 10.15.0.208 netmask 0xffff0000 broadcast 10.15.255.255
nd6 options=1<PERFORMNUD>
media: autoselect
status: active
en4: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=10b<RXCSUM,TXCSUM,VLAN_HWTAGGING,AV>
ether a8:20:66:28:87:0b
inet6 fe80::aa20:66ff:fe28:870b%en4 prefixlen 64 scopeid 0x7
inet 10.3.24.143 netmask 0xffff0000 broadcast 10.3.255.255
nd6 options=1<PERFORMNUD>
media: autoselect (1000baseT <full-duplex>)
status: active Close. Now... one is my airport, and one is my ethernet. Which one is my primary (listed at the top in the Network prefs) - i.e. where my traffic is going out on? In this specific case, en4 is actually my primary, I'm using a TB/Enet adapter on the retina. en0 is the wifi, which is placed below ethernet in my list. So how do I tell my script to figure out which one is primary? (en4 in this case) Note that wifi is turned on, which is why status is "active". Wifi will sometimes be active when ethernet is the primary, so "active" isn't sufficient to identify primary. I cannot rely on any consistency with the adapter name ("enXXX") I need to know which is primary. Any suggestions? I'm not limited to ifconfig and I can explore, I just need to know what to query. systemsetup doesn't have it...
I work for the Department of Redundancy Department
|
|
Re: identifying current LAN ip address from terminal
|
|
Joined: Aug 2009
|
Your "primary" interface is the one with the default gateway on it. You can get the default gateway with netstat -r | grep defaultConceptually, there could be a different default gateway for IPv4 and IPv6. They could be on different networks. On my machine there is only one, for IPv4. You can restrict the output from netstat to a specific family using the -f flag. Once you have an IP address for the default gateway, examine the inet/inet6 entries in the output from ifconfig to find the one whose IP address matches that of the default gateway, modulo the netmask/prefixlen. If I were doing it, I'd use Perl for the script, to get easy access to both pattern matching and bit manipulation in one package. Oh, what the heck...
#!/usr/bin/env perl
use strict;
use warnings;
sub scan_ip {
if ($_[0] =~ /^\s*(\d+)\.(\d+)\.(\d+)\.(\d+)\s*$/) {
return (($1 & 255) << 24) | (($2 & 255) << 16) | (($3 & 255) << 8) | ($4 & 255); }
else {
return 0; }
}
sub fmt_ip {
my $ip = shift;
return sprintf("%d.%d.%d.%d",
($ip >> 24) & 255, ($ip >> 16) & 255, ($ip >> 8) & 255, $ip & 255);
}
my $gw = 0;
my $ip = 0;
open *NS, "/usr/sbin/netstat -rf inet|" or die;
while (<NS>) {
if (m/^default\s+([\d\.]+)/) {
$gw = scan_ip($1);
last; }}
close *NS;
die "couldn't find default gateway" if $gw == 0;
# printf "Default gateway is %s\n", fmt_ip($gw);
open *IF, "/sbin/ifconfig|" or die;
while (<IF>) {
next unless m/^\s+inet\s+([\d\.]+)\s+netmask\s+0x([0-9a-fA-F]{8})\s/;
my $this_nm = hex($2);
my $this_ip = scan_ip($1);
if (($this_ip & $this_nm) == ($gw & $this_nm)) {
$ip = $this_ip;
last; }}
close *IF;
die "couldn't find primary IP address" if $ip == 0;
printf "Primary IP address is %s\n", fmt_ip($ip);
That's only for IPv4. IPv6 is left as an exercise for the student.
|
|
Re: identifying current LAN ip address from terminal
|
|
OP
Joined: Aug 2009
|
for whatever reason, netstat -r takes a very long time to run. it dumps a good deal of information, then burps out one more line every 10-15 seconds or so.
I work for the Department of Redundancy Department
|
|
Re: identifying current LAN ip address from terminal
|
|
Joined: Aug 2009
|
for whatever reason, netstat -r takes a very long time to run. it dumps a good deal of information, then burps out one more line every 10-15 seconds or so. Really? Sounds like you're adding extra flags, like maybe the -w flag to produce more data at intervals. Or you added flags that ask for additional information. Or you left out the -r, which makes it produce just the additional information, unasked. Check to see if you've made it into an alias/function by entering type netstatIf so, you can call the bare unaliased command by either invoking it as command netstat or better yet using it's full path. (You should be in the habit of using full paths in scripts anyway. A script that relies on $PATH is fragile, and scripts that run as root or invoke root processes should never be fragile. Besides, the purpose of $PATH is to save keystrokes in an interactive shell. Saving keystrokes is not a high priority when composing a script.) On my machine: $ type netstat
netstat is hashed (/usr/sbin/netstat)
$ time /usr/sbin/netstat -rf inet
Routing tables
Internet:
Destination Gateway Flags Refs Use Netif Expire
default 192.168.0.1 UGSc 19 0 en0
127 localhost UCS 0 0 lo0
localhost localhost UH 3 2789 lo0
169.254 link#4 UCS 0 0 en0
192.168.0 link#4 UCS 4 0 en0
192.168.0.1/32 link#4 UCS 1 0 en0
192.168.0.1 0:1b:63:f2:27:19 UHLWIir 25 275890 en0 359
192.168.0.15/32 link#4 UCS 1 0 en0
192.168.0.15 c8:2a:14:3c:44:54 UHLWI 0 1 lo0
192.168.0.132 0:26:ab:2b:4b:d3 UHLWI 0 0 en0 1200
192.168.0.133 d0:4f:7e:57:6:5 UHLWIi 2 6 en0 1184
192.168.0.134 70:3e:ac:cc:a7:f1 UHLWIi 252 1686 en0 360
192.168.0.255 ff:ff:ff:ff:ff:ff UHLWbI 0 54 en0
real 0m0.026s
user 0m0.002s
sys 0m0.005s
Actually, looking at that output I now notice the Netif column, which spares you the trouble of searching for the right interface.
/usr/sbin/netstat -rf inet |
while read NS_dest NS_gate NS_flags NS_refs NS_use NS_if NS_exp; do
if [[ "$NS_dest" = default ]]; then
/sbin/ifconfig $NS_if inet |
while read IF_if IF_ip IF_rest; do
if [[ "$IF_if" = inet ]]; then echo $IF_ip; fi
done
break
fi
done
|
|
Re: identifying current LAN ip address from terminal
|
|
Joined: Aug 2009
|
Shorter version:
ifconfig $(netstat -rf inet | awk '{if ($1 == "default") print $6}') inet | awk '{if ($1 == "inet") print $2}'
or $PATH-independently:
/sbin/ifconfig $(/usr/sbin/netstat -rf inet | /usr/bin/awk '{if ($1 == "default") print $6}') inet | /usr/bin/awk '{if ($1 == "inet") print $2}'
|
|
|
|