]>
Commit | Line | Data |
---|---|---|
df92424c MT |
1 | diff -up iputils-s20071127/arping.c.infiniband iputils-s20071127/arping.c |
2 | --- iputils-s20071127/arping.c.infiniband 2007-11-27 01:57:27.000000000 +0100 | |
3 | +++ iputils-s20071127/arping.c 2008-08-08 10:05:04.000000000 +0200 | |
4 | @@ -50,14 +50,26 @@ int unicasting; | |
5 | int s; | |
6 | int broadcast_only; | |
7 | ||
8 | -struct sockaddr_ll me; | |
9 | -struct sockaddr_ll he; | |
10 | +/* | |
11 | + * Make these two structs have padding at the end so the overly long Infiniband | |
12 | + * hardware addresses can have the remainder of their address tacked onto | |
13 | + * the end of the struct without overlapping anything. | |
14 | + */ | |
15 | +struct sockaddr_ll me[2]; | |
16 | +struct sockaddr_ll he[2]; | |
17 | ||
18 | struct timeval start, last; | |
19 | ||
20 | int sent, brd_sent; | |
21 | int received, brd_recv, req_recv; | |
22 | ||
23 | +#define SYSFS_MNT_PATH "/sys" | |
24 | +#define SYSFS_CLASS "class" | |
25 | +#define SYSFS_NET "net" | |
26 | +#define SYSFS_BROADCAST "broadcast" | |
27 | +#define SYSFS_PATH_ENV "SYSFS_PATH" | |
28 | +#define SYSFS_PATH_LEN 256 | |
29 | + | |
30 | #define MS_TDIFF(tv1,tv2) ( ((tv1).tv_sec-(tv2).tv_sec)*1000 + \ | |
31 | ((tv1).tv_usec-(tv2).tv_usec)/1000 ) | |
32 | ||
33 | @@ -124,7 +136,8 @@ int send_pack(int s, struct in_addr src, | |
34 | p+=4; | |
35 | ||
36 | gettimeofday(&now, NULL); | |
37 | - err = sendto(s, buf, p-buf, 0, (struct sockaddr*)HE, sizeof(*HE)); | |
38 | + err = sendto(s, buf, p-buf, 0, (struct sockaddr*)HE, (ah->ar_hln > 8) ? | |
39 | + sizeof(*HE) + ah->ar_hln - 8 : sizeof(*HE)); | |
40 | if (err == p-buf) { | |
41 | last = now; | |
42 | sent++; | |
43 | @@ -172,7 +185,7 @@ void catcher(void) | |
44 | finish(); | |
45 | ||
46 | if (last.tv_sec==0 || MS_TDIFF(tv,last) > 500) { | |
47 | - send_pack(s, src, dst, &me, &he); | |
48 | + send_pack(s, src, dst, &me[0], &he[0]); | |
49 | if (count == 0 && unsolicited) | |
50 | finish(); | |
51 | } | |
52 | @@ -219,7 +232,7 @@ int recv_pack(unsigned char *buf, int le | |
53 | return 0; | |
54 | if (ah->ar_pln != 4) | |
55 | return 0; | |
56 | - if (ah->ar_hln != me.sll_halen) | |
57 | + if (ah->ar_hln != me[0].sll_halen) | |
58 | return 0; | |
59 | if (len < sizeof(*ah) + 2*(4 + ah->ar_hln)) | |
60 | return 0; | |
61 | @@ -230,7 +243,7 @@ int recv_pack(unsigned char *buf, int le | |
62 | return 0; | |
63 | if (src.s_addr != dst_ip.s_addr) | |
64 | return 0; | |
65 | - if (memcmp(p+ah->ar_hln+4, &me.sll_addr, ah->ar_hln)) | |
66 | + if (memcmp(p+ah->ar_hln+4, &me[0].sll_addr, ah->ar_hln)) | |
67 | return 0; | |
68 | } else { | |
69 | /* DAD packet was: | |
70 | @@ -248,7 +261,7 @@ int recv_pack(unsigned char *buf, int le | |
71 | */ | |
72 | if (src_ip.s_addr != dst.s_addr) | |
73 | return 0; | |
74 | - if (memcmp(p, &me.sll_addr, me.sll_halen) == 0) | |
75 | + if (memcmp(p, &me[0].sll_addr, me[0].sll_halen) == 0) | |
76 | return 0; | |
77 | if (src.s_addr && src.s_addr != dst_ip.s_addr) | |
78 | return 0; | |
79 | @@ -264,7 +277,7 @@ int recv_pack(unsigned char *buf, int le | |
80 | printf("for %s ", inet_ntoa(dst_ip)); | |
81 | s_printed = 1; | |
82 | } | |
83 | - if (memcmp(p+ah->ar_hln+4, me.sll_addr, ah->ar_hln)) { | |
84 | + if (memcmp(p+ah->ar_hln+4, me[0].sll_addr, ah->ar_hln)) { | |
85 | if (!s_printed) | |
86 | printf("for "); | |
87 | printf("["); | |
88 | @@ -290,12 +303,69 @@ int recv_pack(unsigned char *buf, int le | |
89 | if (quit_on_reply) | |
90 | finish(); | |
91 | if(!broadcast_only) { | |
92 | - memcpy(he.sll_addr, p, me.sll_halen); | |
93 | + memcpy(he[0].sll_addr, p, me[0].sll_halen); | |
94 | unicasting=1; | |
95 | } | |
96 | return 1; | |
97 | } | |
98 | ||
99 | +int get_sysfs_mnt_path(char *mnt_path, size_t len) | |
100 | +{ | |
101 | + const char *sysfs_path_env; | |
102 | + int pth_len=0; | |
103 | + | |
104 | + if (len == 0 || mnt_path == NULL) | |
105 | + return -1; | |
106 | + | |
107 | + /* possible overrride of real mount path */ | |
108 | + sysfs_path_env = getenv(SYSFS_PATH_ENV); | |
109 | + memset(mnt_path, 0, len); | |
110 | + strncpy(mnt_path, | |
111 | + sysfs_path_env != NULL ? sysfs_path_env : SYSFS_MNT_PATH, | |
112 | + len-1); | |
113 | + | |
114 | + if ((pth_len = strlen(mnt_path)) > 0 && mnt_path[pth_len-1] == '/') | |
115 | + mnt_path[pth_len-1] = '\0'; | |
116 | + | |
117 | + return 0; | |
118 | +} | |
119 | + | |
120 | +int make_sysfs_broadcast_path(char *broadcast_path, size_t len) | |
121 | +{ | |
122 | + char mnt_path[SYSFS_PATH_LEN]; | |
123 | + | |
124 | + if (get_sysfs_mnt_path(mnt_path, len) != 0) | |
125 | + return -1; | |
126 | + | |
127 | + snprintf(broadcast_path, len, | |
128 | + "%s/" SYSFS_CLASS "/" SYSFS_NET "/%s/" SYSFS_BROADCAST, | |
129 | + mnt_path, device); | |
130 | + | |
131 | + return 0; | |
132 | +} | |
133 | + | |
134 | +char * read_sysfs_broadcast(char *brdcast_path) | |
135 | +{ | |
136 | + int fd; | |
137 | + int len_to_read; | |
138 | + char *brdcast = NULL; | |
139 | + | |
140 | + if ((fd = open(brdcast_path, O_RDONLY)) > -1) { | |
141 | + len_to_read = lseek(fd, 0L, SEEK_END); | |
142 | + if ((brdcast = malloc(len_to_read+1)) != NULL) { | |
143 | + lseek(fd, 0L, SEEK_SET); | |
144 | + memset(brdcast, 0, len_to_read+1); | |
145 | + if (read(fd, brdcast, len_to_read) == -1) { | |
146 | + free(brdcast); | |
147 | + brdcast = NULL; | |
148 | + } | |
149 | + } | |
150 | + close(fd); | |
151 | + } | |
152 | + | |
153 | + return brdcast; | |
154 | +} | |
155 | + | |
156 | int | |
157 | main(int argc, char **argv) | |
158 | { | |
159 | @@ -459,9 +529,9 @@ main(int argc, char **argv) | |
160 | close(probe_fd); | |
161 | }; | |
162 | ||
163 | - me.sll_family = AF_PACKET; | |
164 | - me.sll_ifindex = ifindex; | |
165 | - me.sll_protocol = htons(ETH_P_ARP); | |
166 | + me[0].sll_family = AF_PACKET; | |
167 | + me[0].sll_ifindex = ifindex; | |
168 | + me[0].sll_protocol = htons(ETH_P_ARP); | |
169 | if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { | |
170 | perror("bind"); | |
171 | exit(2); | |
172 | @@ -474,14 +544,33 @@ main(int argc, char **argv) | |
173 | exit(2); | |
174 | } | |
175 | } | |
176 | - if (me.sll_halen == 0) { | |
177 | + if (me[0].sll_halen == 0) { | |
178 | if (!quiet) | |
179 | printf("Interface \"%s\" is not ARPable (no ll address)\n", device); | |
180 | exit(dad?0:2); | |
181 | } | |
182 | + he[0] = me[0]; | |
183 | + he[1] = me[1]; | |
184 | + { | |
185 | + char brdcast_path[SYSFS_PATH_LEN]; | |
186 | + char *brdcast_val; | |
187 | + char *next_ch; | |
188 | + | |
189 | + if (make_sysfs_broadcast_path(brdcast_path, sizeof brdcast_path) != 0) { | |
190 | + perror("sysfs attribute broadcast"); | |
191 | + exit(2); | |
192 | + } | |
193 | + | |
194 | + if ((brdcast_val = read_sysfs_broadcast(brdcast_path)) == NULL) { | |
195 | + perror("sysfs read broadcast value"); | |
196 | + exit(2); | |
197 | + } | |
198 | + for (ch=0; ch<he[0].sll_halen; ch++) { | |
199 | + he[0].sll_addr[ch] = strtol(brdcast_val + (ch*3), &next_ch, 16); | |
200 | + } | |
201 | ||
202 | - he = me; | |
203 | - memset(he.sll_addr, -1, he.sll_halen); | |
204 | + free(brdcast_val); | |
205 | + } | |
206 | ||
207 | if (!quiet) { | |
208 | printf("ARPING %s ", inet_ntoa(dst)); | |
209 | @@ -501,12 +590,12 @@ main(int argc, char **argv) | |
210 | while(1) { | |
211 | sigset_t sset, osset; | |
212 | unsigned char packet[4096]; | |
213 | - struct sockaddr_ll from; | |
214 | + struct sockaddr_ll from[2]; | |
215 | socklen_t alen = sizeof(from); | |
216 | int cc; | |
217 | ||
218 | if ((cc = recvfrom(s, packet, sizeof(packet), 0, | |
219 | - (struct sockaddr *)&from, &alen)) < 0) { | |
220 | + (struct sockaddr *)&from[0], &alen)) < 0) { | |
221 | perror("arping: recvfrom"); | |
222 | continue; | |
223 | } | |
224 | @@ -514,7 +603,7 @@ main(int argc, char **argv) | |
225 | sigaddset(&sset, SIGALRM); | |
226 | sigaddset(&sset, SIGINT); | |
227 | sigprocmask(SIG_BLOCK, &sset, &osset); | |
228 | - recv_pack(packet, cc, &from); | |
229 | + recv_pack(packet, cc, &from[0]); | |
230 | sigprocmask(SIG_SETMASK, &osset, NULL); | |
231 | } | |
232 | } | |
233 | diff -up iputils-s20071127/Makefile.infiniband iputils-s20071127/Makefile | |
234 | --- iputils-s20071127/Makefile.infiniband 2008-08-08 09:17:35.000000000 +0200 | |
235 | +++ iputils-s20071127/Makefile 2008-08-08 10:02:10.000000000 +0200 | |
236 | @@ -37,6 +37,8 @@ rdisc_srv: rdisc_srv.o | |
237 | rdisc_srv.o: rdisc.c | |
238 | $(CC) $(CFLAGS) -DRDISC_SERVER -o rdisc_srv.o rdisc.c | |
239 | ||
240 | +arping: arping.o | |
241 | + $(CC) $(LDFLAGS) arping.o $(LOADLIBES) $(LDLIBS) -o arping | |
242 | ||
243 | check-kernel: | |
244 | ifeq ($(KERNEL_INCLUDE),) |