2

I need to determine the IPv4 broadcast address of a device (if any) with a shell script. If there are several, pick one (e.g. first as ordered by /sbin/ip).

I have a solution, but i do not like it because it makes assumptions about the output format of /sbin/ip, and i don't know how stable that output format is across systems.

DEV=eth0
BROADCAST=`ip address show $DEV | grep 'inet .* brd ' | head -1 | sed -e 's/^.* brd \([0-9\.]*\) .*$/\1/'`
echo $BROADCAST

Isn't there something in /proc/ or /sys/ that i can simply cat? Why not?

I need the solution to work reliably, at least across the Debian/Ubuntu Linux family.


Edit: This is NOT a question about sed/awk/grep magic. The question is:

  • Can i expect ip (of ifconfig for that matter) across architectures and Linux flavours to have the same output format, such that i can reliably parse e.g. an interface's IPv4 broadcast address from it?
  • If not: is there another way to output an interface's IPv4 broadcast address in an more predictable manner?
  • Why is there no /proc/sys/net/ipv4/conf/eth0/{address,mask,broadcast} that i can simply cat?
Nils Toedtmann
  • 3,202
  • 5
  • 25
  • 36
  • Why does it have to be a shell script? Why couldn't you write it in a language where you can actually make use of ioctl calls? – kasperd Jun 02 '15 at 21:00
  • In the end it's gonna be a script to be plonked in Debian's /etc/network/if-up.d/. Its aim is to establish some iptables DNAT rules per interface that depend on the interface's broadcast address. But right, the bit that finds the broadcast address doesn't have to be bash. Thing is, i am more on the Ops side of DevOps. – Nils Toedtmann Jun 02 '15 at 22:19

4 Answers4

6

Can i expect ip (of ifconfig for that matter) across architectures and Linux flavours to have the same output format, such that i can reliably parse

I wouldn't. Though ifconfig is dead and so shouldn't change to much, there have been minor changes applied by distros to keep this deprecated tool somewhat functional since many people don't seem to want to learn how to make the switch. The output of ip really isnt' great for parsing IMO.

If not: is there another way to output an interface's IPv4 broadcast address in an more predictable manner?

If I were you I would probably look at installing and using a tool like facter to do the work for you. I don't think it gives you the broadcast address directly, but it should be trivial to take the address/netmask and perform the math to get the broadcast address.

Why is there no /proc/sys/net/...

iproute2 connects to the the kernel via the NETLINK socket. Ifconfig uses the ioctl method which is deprecated. If you want to get the correct information without scraping the output of some user-space program or installing something, then you'll need to use one of those API.

If you want you can do something like strace ip addr show or strace ifconfig to see the output of exactly what those tools are doing to retrieve the values.

I don't know the history of why, but that isn't a question for this site. This is the way it is. If you want 'why' go talk to the kernel devs.

Zoredache
  • 128,755
  • 40
  • 271
  • 413
  • 1
    Interesting answer, thank you. The problem with facter though is (a) that it requires ruby (one of my target platforms are embedded devices). And (b) that it doesn't query NETLINK but also just parses the output of `ifconfig -a` - i can do that myself. – Nils Toedtmann Jun 02 '15 at 14:28
1

For Redhat, the broadcast IP Address is automatically calculated using ipcalc - AFAIK there're no configuration files that contain it. It might also help: Red Hat Docs - Interface Configuration Files

7y7
  • 108
  • 4
0

Have you considered routing data. This script should return the broadcast address of the Internet interface:

ipcalc $(route | awk '$2 ~ /\*/ {print $1 "/" $3}') | \
    awk '/^Broadcast/ {print $2}'

Or this one using ip route may return multiple addresses.

for x in $(ip route show | awk '/^[1-9]/ {print $1}'); do 
    ipcalc $x | awk '/^Broadcast/ {print $2}'; 
done

ipcalc may not be installed by default.

BillThor
  • 27,354
  • 3
  • 35
  • 69
  • Nice one. Leaves the question whether the output formats of `route` or `ip route` are any more stable than those of `ifconfig` or `ip addr`. – Nils Toedtmann Jun 02 '15 at 14:33
-1

awk is your friend.

ip a s dev $DEV | awk '/inet / {print $4}'
Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
  • 1
    You make the same kind of assumptions ("broadcast address always in column 4") about the output format of `ip`. I am looking for a solution that avoids that. – Nils Toedtmann Jun 01 '15 at 18:33
  • @NilsToedtmann Of course I make assumptions. You can't do this at all without making assumptions! Anyway, the format hasn't really changed in a decade or more, so it probably won't. That's my assumption. – Michael Hampton Jun 01 '15 at 21:08
  • add 'grep brd', so that if the device has no broadcast address, the result is empty: `ip addr show dev $DEV|grep brd|awk '/inet / {print $4}'` – Francois Aug 12 '15 at 08:05