diff -up iputils-s20070202/Makefile.infiniband iputils-s20070202/Makefile --- iputils-s20070202/Makefile.infiniband 2008-02-18 16:47:39.000000000 +0100 +++ iputils-s20070202/Makefile 2008-02-18 16:47:39.000000000 +0100 @@ -37,6 +37,8 @@ rdisc_srv: rdisc_srv.o rdisc_srv.o: rdisc.c $(CC) $(CFLAGS) -DRDISC_SERVER -o rdisc_srv.o rdisc.c +arping: arping.o + $(CC) $(LDFLAGS) arping.o $(LOADLIBES) $(LDLIBS) -lsysfs -o arping check-kernel: ifeq ($(KERNEL_INCLUDE),) diff -up iputils-s20070202/arping.c.infiniband iputils-s20070202/arping.c --- iputils-s20070202/arping.c.infiniband 2008-02-18 16:47:39.000000000 +0100 +++ iputils-s20070202/arping.c 2008-02-18 16:50:44.000000000 +0100 @@ -31,6 +31,7 @@ #include #include #include +#include #include "SNAPSHOT.h" @@ -50,8 +51,13 @@ int unicasting; int s; int broadcast_only; -struct sockaddr_ll me; -struct sockaddr_ll he; +/* + * Make these two structs have padding at the end so the overly long Infiniband + * hardware addresses can have the remainder of their address tacked onto + * the end of the struct without overlapping anything. + */ +struct sockaddr_ll me[2]; +struct sockaddr_ll he[2]; struct timeval start, last; @@ -124,7 +130,8 @@ int send_pack(int s, struct in_addr src, p+=4; gettimeofday(&now, NULL); - err = sendto(s, buf, p-buf, 0, (struct sockaddr*)HE, sizeof(*HE)); + err = sendto(s, buf, p-buf, 0, (struct sockaddr*)HE, (ah->ar_hln > 8) ? + sizeof(*HE) + ah->ar_hln - 8 : sizeof(*HE)); if (err == p-buf) { last = now; sent++; @@ -172,7 +179,7 @@ void catcher(void) finish(); if (last.tv_sec==0 || MS_TDIFF(tv,last) > 500) { - send_pack(s, src, dst, &me, &he); + send_pack(s, src, dst, &me[0], &he[0]); if (count == 0 && unsolicited) finish(); } @@ -219,7 +226,7 @@ int recv_pack(unsigned char *buf, int le return 0; if (ah->ar_pln != 4) return 0; - if (ah->ar_hln != me.sll_halen) + if (ah->ar_hln != me[0].sll_halen) return 0; if (len < sizeof(*ah) + 2*(4 + ah->ar_hln)) return 0; @@ -230,7 +237,7 @@ int recv_pack(unsigned char *buf, int le return 0; if (src.s_addr != dst_ip.s_addr) return 0; - if (memcmp(p+ah->ar_hln+4, &me.sll_addr, ah->ar_hln)) + if (memcmp(p+ah->ar_hln+4, &me[0].sll_addr, ah->ar_hln)) return 0; } else { /* DAD packet was: @@ -248,7 +255,7 @@ int recv_pack(unsigned char *buf, int le */ if (src_ip.s_addr != dst.s_addr) return 0; - if (memcmp(p, &me.sll_addr, me.sll_halen) == 0) + if (memcmp(p, &me[0].sll_addr, me[0].sll_halen) == 0) return 0; if (src.s_addr && src.s_addr != dst_ip.s_addr) return 0; @@ -264,7 +271,7 @@ int recv_pack(unsigned char *buf, int le printf("for %s ", inet_ntoa(dst_ip)); s_printed = 1; } - if (memcmp(p+ah->ar_hln+4, me.sll_addr, ah->ar_hln)) { + if (memcmp(p+ah->ar_hln+4, me[0].sll_addr, ah->ar_hln)) { if (!s_printed) printf("for "); printf("["); @@ -290,7 +297,7 @@ int recv_pack(unsigned char *buf, int le if (quit_on_reply) finish(); if(!broadcast_only) { - memcpy(he.sll_addr, p, me.sll_halen); + memcpy(he[0].sll_addr, p, me[0].sll_halen); unicasting=1; } return 1; @@ -459,9 +466,9 @@ main(int argc, char **argv) close(probe_fd); }; - me.sll_family = AF_PACKET; - me.sll_ifindex = ifindex; - me.sll_protocol = htons(ETH_P_ARP); + me[0].sll_family = AF_PACKET; + me[0].sll_ifindex = ifindex; + me[0].sll_protocol = htons(ETH_P_ARP); if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { perror("bind"); exit(2); @@ -474,14 +481,37 @@ main(int argc, char **argv) exit(2); } } - if (me.sll_halen == 0) { + if (me[0].sll_halen == 0) { if (!quiet) printf("Interface \"%s\" is not ARPable (no ll address)\n", device); exit(dad?0:2); } - - he = me; - memset(he.sll_addr, -1, he.sll_halen); + he[0] = me[0]; + he[1] = me[1]; + { + struct sysfs_class_device *dev; + struct sysfs_attribute *brdcast; + char *next_ch; + + dev = sysfs_open_class_device("net", device); + if (!dev) { + perror("sysfs class device"); + exit(2); + } + brdcast = sysfs_get_classdev_attr(dev, "broadcast"); + if (!brdcast) { + perror("sysfs attribute broadcast"); + exit(2); + } + if (sysfs_read_attribute(brdcast)) { + perror("sysfs read brdcast"); + exit(2); + } + for (ch=0; chvalue + (ch*3), + &next_ch, 16); + } + } if (!quiet) { printf("ARPING %s ", inet_ntoa(dst)); @@ -501,7 +531,7 @@ main(int argc, char **argv) while(1) { sigset_t sset, osset; unsigned char packet[4096]; - struct sockaddr_ll from; + struct sockaddr_ll from[2]; socklen_t alen = sizeof(from); int cc; @@ -514,7 +544,7 @@ main(int argc, char **argv) sigaddset(&sset, SIGALRM); sigaddset(&sset, SIGINT); sigprocmask(SIG_BLOCK, &sset, &osset); - recv_pack(packet, cc, &from); + recv_pack(packet, cc, &from[0]); sigprocmask(SIG_SETMASK, &osset, NULL); } }