1

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?
  • 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 2 '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 2 '15 at 22:19
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.

  • 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 2 '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

  • ipcalc only shifts the problem from finding out the broadcast address, to finding out IP address and prefix/mask – Nils Toedtmann Jun 2 '15 at 13:52
  • I agree, then you could use ipcalc -b "$(ip a show eth0 | awk '/inet/{print substr($2,6)}')". – 7y7 Jun 2 '15 at 17:00
  • Well then i'd rather parse is straight out with ip a show eth0 | awk '/inet/{print $4}, wouldn't I? – Nils Toedtmann Jun 2 '15 at 22:14
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.

  • 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 2 '15 at 14:33
-1

awk is your friend.

ip a s dev $DEV | awk '/inet / {print $4}'
  • 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 1 '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 1 '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 8:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.