From: deraadt@newt.cuc.ab.ca (Theo de Raadt)
Subject: Re: Sun Generic Broadcasting
Organization: little lizard city
Date: Thu, 5 Nov 1992 21:47:40 GMT

[Distribution changed from "usa" to "world". Unix is the same in Europe, isn't it??]

In article <1004@math.math.mv.dupont.com> mc@math.math.mv.dupont.com (Matt Cunningham-Software Development) writes:
> I am trying to find the proper broadcast IP address to send a packet (BOOTP 
> packet to be specific - but the packet type is not important) to so that
> everyone on the network will receive it.
[deleted descriptions of numerous attempts to make it work...]

The bind() call will take INADDR_ANY to indicate that it will take a
connect from any address. It's more difficult when you send packets
out -- you must indicate _exactly_ where you want to send to. A
unix machine may have multiple interfaces, with multiple addresses.
You need to specify the broadcast address for the particular network
you are interested in. If you wish to send on all the attached networks,
you need to do multiple send()'s.

The program below will list the broadcast addresses for all of the
networks that your machine is directly connected to. It will skip
LOOPBACK and POINTTOPOINT links, simply because those do not have a
broadcast address. For your problem, just sendto() each address that
is discovered by this routine below..

Note that on some machines you'll need to enable broadcasting before
packets will actually make it onto the wire. You don't need this on
Suns, but it does now hurt. Other machines (ie. SGI) DO need it.

        if( (sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
                perror("socket");
                return -1;
        }
	i = 1;
        setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &i, sizeof(i));

On some operating system (Ultrix?) only root processes can broadcast,
what a crock.

Hope this helps you.
 <tdr.

----------------------------------------------------------------------
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/signal.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <dirent.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>

main()
{
	struct ifconf ifc;
	struct ifreq ifreq, *ifr;
	struct sockaddr_in *sin;
	struct in_addr in;
	struct net *n;
	int i, sock;
	char inbuf[1024];

	if( (sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
		perror("socket");
		return -1;
	}

	ifc.ifc_len = sizeof inbuf;
	ifc.ifc_buf = inbuf;
	if( ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
		close(sock);
		perror("ioctl");
		return -1;
	}
	ifr = ifc.ifc_req;
	for(i=ifc.ifc_len/sizeof(struct ifreq); i>0; i--, ifr++) {
		ifreq = *ifr;
		if( ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
			perror("ioctl");
			continue;
		}
		if( (ifreq.ifr_flags & IFF_BROADCAST) &&
		    (ifreq.ifr_flags & IFF_UP) &&
		    ifr->ifr_addr.sa_family == AF_INET) {
			sin = (struct sockaddr_in *)&ifr->ifr_addr;
			if( ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0 ) {
				in = inet_makeaddr(inet_netof(sin->sin_addr.s_addr),
					(int)INADDR_ANY);
			} else { 
				in = ((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr;
			}
			printf("address %s\n", inet_ntoa(in));
		}
	}
	close(sock);
}
----------------------------------------------------------------------
--

This space not left unintentionally unblank.		deraadt@newt.cuc.ab.ca
Newsgroups: comp.protocols.tcp-ip