broadcast oddity
Daniel Braniss
danny at cs.huji.ac.il
Tue Jul 19 07:40:14 UTC 2011
Hi Eygene,
> Daniel, good day.
>
> Mon, Jul 18, 2011 at 05:04:27PM +0300, Daniel Braniss wrote:
> > this code behaves correctly when run from a diskless host which
> > booted via PXE, but fails on a host that was booted from disk.
> > hint: the non working sends a packet with a non ethernet broadcast
> > address and an ip address of 255.255.255.255,
>
> And that non-broadcast ethernet address is the MAC of your
> default router?
yes.
>
> > the working version sets the ethernet address to 0xffffffff and the
> > ip to the network broadcast address.
>
> What's your routing table (netstat -rn) for the PXE-booted host?
it's ok, same in both cases. it's picked up via DHCP, in the diskless
case by the boot/loader in the second via dhcpclient.
>
> > what am I doing wrong?
> >=20
> > danny
> > PS: what is the correct way to obtain the network broadcast address?
>
> You nailed it: you should send packets to the network's broadcast,
> not to the 0xffffffff.
>
but I'm at the user/ip level!, have no way to set mac/ethernet address.
still, the question is why it works in one case, and failes in the other.
> And in order to find the broadcast address for the interface (or
> network at that interface), you should use getifaddrs(), like in the
> attached example. It is very quick and dirty one and it has some
> limitations (e.g., it takes the first broadcast address from the
> interface), but it should be a good starting point.
thanks,
danny
> Eygene Ryabinkin ,,,^..^,,,
> [ Life's unfair - but root password helps! | codelabs.ru ]
> [ 82FE 06BC D497 C0DE 49EC 4FF0 16AF 9EAE 8152 ECFB | freebsd.org ]
>
> --UeXZ3FjlYZvuln/G
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: attachment; filename="bcast.c"
>
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <net/if.h>
> #include <ifaddrs.h>
> #include <stdlib.h>
> #include <string.h>
> #include <time.h>
> #include <stdio.h>
>
> void
> bcast(in_addr_t addr)
> {
> int so, on;
> char msg[BUFSIZ];
> struct timespec t2;
> struct sockaddr_in soin;
>
> if((so = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
> perror("socket");
> exit(-1);
> }
> on = 1;
> if(setsockopt(so, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on))) {
> perror("setsockopt");
> exit(-1);
> }
>
> bzero(&soin, sizeof(struct sockaddr_in));
> soin.sin_len = sizeof(struct sockaddr_in);
> soin.sin_family = AF_INET;
> soin.sin_addr.s_addr = addr;
> soin.sin_port = htons(12345);
> while(1) {
> clock_gettime(CLOCK_REALTIME, &t2);
> sprintf(msg, "0x%016x", t2.tv_sec);
> if(sendto(so, msg, strlen(msg)+1,
> 0, (struct sockaddr *)&soin, sizeof(struct sockaddr)) < 0) {
> perror("sendto");
> break;
> }
> sleep(10);
> }
> }
>
> main(int argc, char *argv[])
> {
> struct ifaddrs *ifap, *ifa, *our_if;
> struct sockaddr_in *sin;
>
> if (argc < 2)
> errx(1, "No arguments");
> if (getifaddrs(&ifap) != 0)
> perror("getifaddrs");
> our_if = NULL;
> for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
> if (strcmp(argv[1], ifa->ifa_name) == 0) {
> sin = (struct sockaddr_in *)ifa->ifa_broadaddr;
> if (!(ifa->ifa_flags & IFF_BROADCAST) ||
> sin == NULL ||
> sin->sin_addr.s_addr == 0)
> continue;
> our_if = ifa;
> break;
> }
> }
> if (!our_if)
> errx(1, "Can't find broadcast-able interface '%s'", argv[1]);
> bcast(sin->sin_addr.s_addr);
> freeifaddrs(ifap);
> }
>
> --UeXZ3FjlYZvuln/G--
>
> --McpcKDxJRrEJVmOH
> Content-Type: application/pgp-signature
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.11 (Darwin)
>
> iF0EAREIAAYFAk4kmE8ACgkQFq+eroFS7PvE+QD/ZL0cpFaKvLA+ZWWFH/QlA5Xb
> hqKEG+XY90zdya2/twEA9R3xcK8wwRtOiLf7Tb9SHviukeMsrxwufSWhdapJfj0=
> =Iujs
> -----END PGP SIGNATURE-----
>
> --McpcKDxJRrEJVmOH--
More information about the freebsd-hackers
mailing list