2
* File...........: qetharp26.c
3
* Author(s)......: Thomas Spatzier <tspat@de.ibm.com>
4
* (adaptations to 2.6 kernel)
5
* originally written by: Frank Pavlic <pavlic@de.ibm.com>
7
* Bugreports.to..: <Linux390@de.ibm.com>
8
* (C) IBM Corporation 2001,2004
16
#include <sys/types.h>
17
#include <sys/socket.h>
18
#include <sys/ioctl.h>
19
#include <netinet/in.h>
20
#include <arpa/inet.h>
25
#include "qetharp26.h"
27
/*****************************************************
28
* Function implementation *
29
*****************************************************/
32
qeth_hex_dump(unsigned char *buf, int len)
36
for (i = 0; i < len; i++) {
39
printf("%02x ", *(buf + i));
47
printf("%-40.40s%-20.20s%-10.10s%-10.10s\n",
48
"Address","HWaddress","HWType","Iface");
52
void show_entry5(__u8 ipaddr_type, __u8 *ip,
53
struct option_info *opin)
57
struct hostent *machine=NULL;
59
if (ipaddr_type == IP_VERSION_4) {
60
sprintf(tmpbuff,"%d.%d.%d.%d",ip[0],ip[1],ip[2],ip[3]);
61
if (!opin->host_resolution) {
62
if (inet_aton(tmpbuff,&inadr))
63
machine = gethostbyaddr((char *)
64
&inadr,sizeof(inadr),AF_INET);
66
machine = gethostbyname(tmpbuff);
68
if (opin->compact_output==OPTION_INFO_COMPACT_OUTPUT) {
69
printf("%s\n",tmpbuff);
72
printf("%-40.40s",machine->h_name);
74
printf("%-40.40s",tmpbuff);
75
printf("%-20.20s%-10.10s%-10.10s\n",
76
"","hiper",opin->dev_name);
82
get_arp_from_hipersockets(struct qeth_arp_query_user_data *udata,
83
struct option_info *opin)
85
struct qeth_arp_qi_entry5 *entry;
86
struct qeth_arp_qi_entry5_short *entry_s;
89
if (udata->mask_bits & QETH_QARP_STRIP_ENTRIES) {
90
for (i = 0; i < udata->u.no_entries; i++) {
91
entry_s = (struct qeth_arp_qi_entry5_short *)
92
(((char *)udata) + 6 + i * sizeof(*entry_s));
93
show_entry5(entry_s->ipaddr_type, entry_s->ipaddr,opin);
96
for (i = 0; i < udata->u.no_entries; i++) {
97
entry = (struct qeth_arp_qi_entry5 *)
98
(((char *)udata) + 6 + i * sizeof(*entry));
99
show_entry5(entry->ipaddr_type, entry->ipaddr, opin);
106
void show_entry7(__u8 ipaddr_type, __u8 *ip, __u8 *mac,
107
unsigned short flags, struct option_info *opin)
110
struct in_addr inadr;
111
struct hostent *machine=NULL;
113
if (ipaddr_type == IP_VERSION_4) {
114
sprintf(tmpbuff,"%d.%d.%d.%d",ip[0],ip[1],ip[2],ip[3]);
115
if (!opin->host_resolution) {
116
if (inet_aton(tmpbuff,&inadr))
117
machine = gethostbyaddr((char *)
118
&inadr,sizeof(inadr),AF_INET);
120
machine = gethostbyname(tmpbuff);
122
if (opin->compact_output==OPTION_INFO_COMPACT_OUTPUT) {
123
printf("%s\n",tmpbuff);
126
printf("%-40.40s",machine->h_name);
128
printf("%-40.40s",tmpbuff);
129
sprintf(tmpbuff,"%02x:%02x:%02x:%02x:%02x:%02x",
130
mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
131
printf("%-20.20s%-10.10s%-10.10s\n",
133
(flags==OSACARD_FLAGS)? "ether":
134
(flags==OSA_TR_FLAGS)? "tr":"n/a",
141
get_arp_from_osacard(struct qeth_arp_query_user_data *udata,
142
unsigned short flags, struct option_info *opin)
144
struct qeth_arp_qi_entry7 *entry;
145
struct qeth_arp_qi_entry7_short *entry_s;
148
if (udata->mask_bits & QETH_QARP_STRIP_ENTRIES) {
149
for (i = 0; i < udata->u.no_entries; i++){
150
entry_s = (struct qeth_arp_qi_entry7_short *)
151
(((char *)udata) + 6 + i * sizeof(*entry_s));
152
show_entry7(entry_s->ipaddr_type, entry_s->ipaddr,
153
entry_s->macaddr, flags, opin);
156
for (i = 0; i < udata->u.no_entries; i++){
157
entry = (struct qeth_arp_qi_entry7 *)
158
(((char *)udata) + 6 + i * sizeof(*entry));
159
show_entry7(entry->ipaddr_type, entry->ipaddr,
160
entry->macaddr, flags, opin);
167
qetharp_purge(struct option_info *opin)
172
if (!opin->dev_name) {
173
printf("\nError: no interface specified!\n");
177
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
178
perror("Socket failed: %m\n");
181
strcpy(ifr.ifr_name, opin->dev_name);
182
if (ioctl(sd, SIOC_QETH_ARP_FLUSH_CACHE, &ifr) < 0) {
184
perror("\nUnsuccessful");
192
qetharp_add(struct option_info *opin)
196
struct qeth_arp_cache_entry arp_entry;
197
unsigned int i1,i2,i3,i4,i5,i6,r;
199
memset(&arp_entry, 0, sizeof(struct qeth_arp_cache_entry));
200
if (!opin->dev_name) {
201
printf("\nError: no interface specified!\n");
204
if (!opin->ip_addr) {
205
printf("\nError: no ip address specified!\n");
208
r=sscanf(opin->ip_addr,"%u.%u.%u.%u",&i1,&i2,&i3,&i4);
209
if ( (r!=4) || (i1>255) || (i2>255) || (i3>255) || (i4>255) ) {
210
printf("\nError: invalid ip address specified!\n");
213
arp_entry.ipaddr[0]=i1;
214
arp_entry.ipaddr[1]=i2;
215
arp_entry.ipaddr[2]=i3;
216
arp_entry.ipaddr[3]=i4;
218
if (!opin->mac_addr) {
219
printf("\nError: no MAC address specified!\n");
222
r=sscanf(opin->mac_addr,"%x:%x:%x:%x:%x:%x",&i1,&i2,&i3,&i4,&i5,&i6);
223
if ( (r!=6) || (i1>255) || (i2>255) || (i3>255) ||
224
(i4>255) || (i5>255) || (i6>255) ) {
225
printf("\nError: invalid MAC address specified!\n");
228
arp_entry.macaddr[0]=i1;
229
arp_entry.macaddr[1]=i2;
230
arp_entry.macaddr[2]=i3;
231
arp_entry.macaddr[3]=i4;
232
arp_entry.macaddr[4]=i5;
233
arp_entry.macaddr[5]=i6;
235
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
236
perror("Socket failed: %m\n");
239
strcpy(ifr.ifr_name, opin->dev_name);
240
ifr.ifr_ifru.ifru_data = (void*)&arp_entry;
242
if (ioctl(sd, SIOC_QETH_ARP_ADD_ENTRY, &ifr) < 0) {
244
perror("\nUnsuccessful");
252
qetharp_delete(struct option_info *opin)
256
struct qeth_arp_cache_entry arp_entry;
257
unsigned int i1,i2,i3,i4,r;
259
memset(&arp_entry,0,sizeof(struct qeth_arp_cache_entry));
260
if (!opin->dev_name) {
261
printf("\nError: no interface specified!\n");
264
if (!opin->ip_addr) {
265
printf("\nError: no ip address specified!\n");
268
r=sscanf(opin->ip_addr,"%u.%u.%u.%u",&i1,&i2,&i3,&i4);
269
if ( (r!=4) || (i1>255) || (i2>255) || (i3>255) || (i4>255) ) {
270
printf("\nError: invalid ip address specified!\n");
273
arp_entry.ipaddr[0]=i1;
274
arp_entry.ipaddr[1]=i2;
275
arp_entry.ipaddr[2]=i3;
276
arp_entry.ipaddr[3]=i4;
278
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
279
perror("Socket failed: %m\n");
282
strcpy(ifr.ifr_name, opin->dev_name);
283
ifr.ifr_ifru.ifru_data = (void*)&arp_entry;
285
if (ioctl(sd, SIOC_QETH_ARP_REMOVE_ENTRY, &ifr) < 0) {
287
perror("\nUnsuccessful");
295
qetharp_query(struct option_info *opin)
299
struct qeth_arp_query_user_data *udata;
301
unsigned short mask_bits;
303
if (!opin->dev_name) {
304
printf("\nError: no interface specified!\n");
308
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
309
perror("Socket failed: %m\n");
312
strcpy(ifr.ifr_name, opin->dev_name);
313
memsize = QETH_QARP_USER_DATA_SIZE;
314
udata = malloc(QETH_QARP_USER_DATA_SIZE);
315
memcpy(&udata->u.data_len, &memsize, sizeof(int));
316
udata->mask_bits = QETH_QARP_STRIP_ENTRIES;
317
ifr.ifr_ifru.ifru_data = (char *) udata;
318
if (ioctl(sd, SIOC_QETH_ARP_QUERY_INFO, &ifr) < 0) {
320
perror("\nUnsuccessful");
323
if (opin->compact_output!=OPTION_INFO_COMPACT_OUTPUT) {
326
mask_bits = udata->mask_bits & QETH_QARP_REQUEST_MASK;
327
if (mask_bits == HIPERSOCKET_FLAGS)
328
result = get_arp_from_hipersockets(udata, opin);
329
else if (mask_bits == OSACARD_FLAGS)
330
result = get_arp_from_osacard(udata, mask_bits, opin);
331
else if (mask_bits == OSA_TR_FLAGS)
332
result = get_arp_from_osacard(udata, mask_bits, opin);
334
perror("\nReceived entries with invalid format");
345
printf("qetharp [-[nc]q interface]|[-p interface]|\n" \
346
"\t\t[-a interface -i ip-addr -m MAC-addr]|\n" \
347
"\t\t[-d interface -i ip-addr] [-h] [-v ]\n\n");
349
"\tq: prints ARP entries found on the card\n" \
350
"\tn: in conjunction with the -q option it shows\n" \
351
"\t\tnumerical addresses instead of trying to\n" \
352
"\t\tresolve IP addresses to host names.\n" \
353
"\tc: in conjuction with the -q option it shows\n" \
354
"\t\tonly numerical addresses without any\n" \
355
"\t\tother information.\n" \
356
"\tp: flushes the ARP table of the card\n" \
357
"\ta: add static ARP entry\n" \
358
"\td: delete static ARP entry\n" \
359
"\tv: prints version information\n"
360
"\th: prints this usage information\n");
364
qetharp_parse_info(struct option_info *opin)
366
if ((opin->purge_flag+opin->query_flag+
367
opin->add_flag+opin->delete_flag)!=1) {
368
printf("\nOnly use one of the options '-a', " \
369
"'-d', '-p' and 'q' at a time.\n");
372
if (opin->purge_flag &&
373
(opin->query_flag || opin->host_resolution)) {
374
printf("\nError in using '-p' option:\n" \
375
"\tYou can not use '-p' option in conjunction with " \
379
if (opin->purge_flag) {
380
return qetharp_purge(opin);
382
if ((opin->host_resolution) &&
383
!(opin->query_flag)) {
384
printf("\nError in using '-n' option:\n" \
385
"\t'-q' option missing!\n");
388
if (opin->query_flag) {
389
return qetharp_query(opin);
391
if (opin->add_flag) {
392
if ((!opin->ip_flag)||(!opin->mac_flag)) {
393
printf("\nError in using '-a' option:\n" \
394
"\t'-i' or '-m' option missing!\n");
397
return qetharp_add(opin);
399
if (opin->delete_flag) {
400
if (!opin->ip_flag) {
401
printf("\nError in using '-d' option:\n" \
402
"\t'-i' option missing!\n");
405
return qetharp_delete(opin);
411
int main(int argc, char **argv)
415
struct option_info info;
421
memset(&info, 0, sizeof(info));
424
c = getopt_long(argc, argv,QETHARP_GETOPT_STRING,
425
qetharp_options,&index);
437
printf("\nqetharp version 0.02\n");
440
info.dev_name = optarg;
441
info.query_flag = OPTION_INFO_QUERY;
444
info.host_resolution = OPTION_INFO_HOST_RESOLUTION;
447
info.dev_name = optarg;
448
info.purge_flag = OPTION_INFO_PURGE;
451
info.compact_output = OPTION_INFO_COMPACT_OUTPUT;
454
info.dev_name = optarg;
455
info.add_flag = OPTION_INFO_ADD;
458
info.dev_name = optarg;
459
info.delete_flag = OPTION_INFO_DELETE;
462
info.ip_addr = optarg;
463
info.ip_flag = OPTION_INFO_IP;
466
info.mac_addr = optarg;
467
info.mac_flag = OPTION_INFO_MAC;
474
result = qetharp_parse_info(&info);