~ubuntu-branches/ubuntu/hoary/s390-tools/hoary

« back to all changes in this revision

Viewing changes to qetharp/qetharp26.c

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2004-06-27 18:45:15 UTC
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20040627184515-q7lnvli1j94gr6dv
Tags: upstream-1.3.1
ImportĀ upstreamĀ versionĀ 1.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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>
 
6
 * 
 
7
 * Bugreports.to..: <Linux390@de.ibm.com>
 
8
 * (C) IBM Corporation 2001,2004
 
9
 *
 
10
 */
 
11
 
 
12
#include <stdio.h>
 
13
#include <stdlib.h>
 
14
#include <signal.h>
 
15
#include <string.h>
 
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>
 
21
#include <netdb.h>
 
22
#include <errno.h>
 
23
#include <unistd.h>
 
24
#include <getopt.h>
 
25
#include "qetharp26.h"
 
26
 
 
27
/*****************************************************
 
28
 *            Function implementation                *
 
29
 *****************************************************/
 
30
 
 
31
static inline void
 
32
qeth_hex_dump(unsigned char *buf, int len)
 
33
{
 
34
        int i;
 
35
        
 
36
        for (i = 0; i < len; i++) {
 
37
                if (i && !(i % 16))
 
38
                        printf("\n");
 
39
                printf("%02x ", *(buf + i));
 
40
        }
 
41
        printf("\n");
 
42
}
 
43
 
 
44
static void
 
45
show_header() 
 
46
{
 
47
        printf("%-40.40s%-20.20s%-10.10s%-10.10s\n", 
 
48
               "Address","HWaddress","HWType","Iface");
 
49
}
 
50
 
 
51
static
 
52
void show_entry5(__u8 ipaddr_type, __u8 *ip,
 
53
                 struct option_info *opin)
 
54
{
 
55
        char tmpbuff[32];
 
56
        struct in_addr inadr;
 
57
        struct hostent *machine=NULL;
 
58
 
 
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);
 
65
                        else
 
66
                                machine = gethostbyname(tmpbuff);
 
67
                }
 
68
                if (opin->compact_output==OPTION_INFO_COMPACT_OUTPUT) {
 
69
                        printf("%s\n",tmpbuff);
 
70
                } else {
 
71
                        if (machine)
 
72
                                printf("%-40.40s",machine->h_name);
 
73
                        else
 
74
                                printf("%-40.40s",tmpbuff);
 
75
                        printf("%-20.20s%-10.10s%-10.10s\n",
 
76
                               "","hiper",opin->dev_name);
 
77
                }
 
78
        }
 
79
}
 
80
 
 
81
static int
 
82
get_arp_from_hipersockets(struct qeth_arp_query_user_data *udata,
 
83
                          struct option_info *opin) 
 
84
{
 
85
        struct qeth_arp_qi_entry5 *entry;
 
86
        struct qeth_arp_qi_entry5_short *entry_s;
 
87
        int i;
 
88
 
 
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);
 
94
                }
 
95
        } else {
 
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);
 
100
                }
 
101
        }
 
102
        return 0;
 
103
}
 
104
 
 
105
static
 
106
void show_entry7(__u8 ipaddr_type, __u8 *ip, __u8 *mac,
 
107
                 unsigned short flags, struct option_info *opin)
 
108
{
 
109
        char tmpbuff[32];
 
110
        struct in_addr inadr;
 
111
        struct hostent *machine=NULL;
 
112
 
 
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);
 
119
                        else
 
120
                                machine = gethostbyname(tmpbuff);
 
121
                }
 
122
                if (opin->compact_output==OPTION_INFO_COMPACT_OUTPUT) {
 
123
                        printf("%s\n",tmpbuff);
 
124
                } else {
 
125
                        if (machine)
 
126
                                printf("%-40.40s",machine->h_name);
 
127
                        else
 
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",
 
132
                               tmpbuff,
 
133
                               (flags==OSACARD_FLAGS)? "ether":
 
134
                               (flags==OSA_TR_FLAGS)? "tr":"n/a",
 
135
                               opin->dev_name);
 
136
                }
 
137
        }
 
138
}
 
139
 
 
140
static int
 
141
get_arp_from_osacard(struct qeth_arp_query_user_data *udata,
 
142
                     unsigned short flags, struct option_info *opin) 
 
143
{
 
144
        struct qeth_arp_qi_entry7 *entry;
 
145
        struct qeth_arp_qi_entry7_short *entry_s;
 
146
        int i;
 
147
 
 
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);
 
154
                }
 
155
        } else {
 
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);
 
161
                }
 
162
        }
 
163
        return 0;
 
164
}
 
165
 
 
166
static int
 
167
qetharp_purge(struct option_info *opin)
 
168
{
 
169
        int sd;
 
170
        struct ifreq ifr;
 
171
 
 
172
        if (!opin->dev_name) {
 
173
                printf("\nError: no interface specified!\n");
 
174
                return -1;
 
175
        }
 
176
                
 
177
        if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 
178
                perror("Socket failed: %m\n");
 
179
                return -1;
 
180
        }
 
181
        strcpy(ifr.ifr_name, opin->dev_name);
 
182
        if (ioctl(sd, SIOC_QETH_ARP_FLUSH_CACHE, &ifr) < 0) {
 
183
                close(sd);
 
184
                perror("\nUnsuccessful");
 
185
                return -1;
 
186
        }
 
187
 
 
188
        return 0;
 
189
}
 
190
 
 
191
static int
 
192
qetharp_add(struct option_info *opin)
 
193
{
 
194
        int sd;
 
195
        struct ifreq ifr;
 
196
        struct qeth_arp_cache_entry arp_entry;
 
197
        unsigned int i1,i2,i3,i4,i5,i6,r;
 
198
 
 
199
        memset(&arp_entry, 0, sizeof(struct qeth_arp_cache_entry));
 
200
        if (!opin->dev_name) {
 
201
                printf("\nError: no interface specified!\n");
 
202
                return -1;
 
203
        }
 
204
        if (!opin->ip_addr) {
 
205
                printf("\nError: no ip address specified!\n");
 
206
                return -1;
 
207
        }
 
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");
 
211
                return -1;
 
212
        }
 
213
        arp_entry.ipaddr[0]=i1;
 
214
        arp_entry.ipaddr[1]=i2;
 
215
        arp_entry.ipaddr[2]=i3;
 
216
        arp_entry.ipaddr[3]=i4;
 
217
        
 
218
        if (!opin->mac_addr) {
 
219
                printf("\nError: no MAC address specified!\n");
 
220
                return -1;
 
221
        }
 
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");
 
226
                return -1;
 
227
        }
 
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;
 
234
 
 
235
        if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 
236
                perror("Socket failed: %m\n");
 
237
                return -1;
 
238
        }
 
239
        strcpy(ifr.ifr_name, opin->dev_name);
 
240
        ifr.ifr_ifru.ifru_data = (void*)&arp_entry;
 
241
 
 
242
        if (ioctl(sd, SIOC_QETH_ARP_ADD_ENTRY, &ifr) < 0) {
 
243
                close(sd);
 
244
                perror("\nUnsuccessful");
 
245
                return -1;
 
246
        }
 
247
 
 
248
        return 0;
 
249
}
 
250
 
 
251
static int
 
252
qetharp_delete(struct option_info *opin)
 
253
{
 
254
        int sd;
 
255
        struct ifreq ifr;
 
256
        struct qeth_arp_cache_entry arp_entry;
 
257
        unsigned int i1,i2,i3,i4,r;
 
258
 
 
259
        memset(&arp_entry,0,sizeof(struct qeth_arp_cache_entry));
 
260
        if (!opin->dev_name) {
 
261
                printf("\nError: no interface specified!\n");
 
262
                return -1;
 
263
        }
 
264
        if (!opin->ip_addr) {
 
265
                printf("\nError: no ip address specified!\n");
 
266
                return -1;
 
267
        }
 
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");
 
271
                return -1;
 
272
        }
 
273
        arp_entry.ipaddr[0]=i1;
 
274
        arp_entry.ipaddr[1]=i2;
 
275
        arp_entry.ipaddr[2]=i3;
 
276
        arp_entry.ipaddr[3]=i4;
 
277
        
 
278
        if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 
279
                perror("Socket failed: %m\n");
 
280
                return -1;
 
281
        }
 
282
        strcpy(ifr.ifr_name, opin->dev_name);
 
283
        ifr.ifr_ifru.ifru_data = (void*)&arp_entry;
 
284
 
 
285
        if (ioctl(sd, SIOC_QETH_ARP_REMOVE_ENTRY, &ifr) < 0) {
 
286
                close(sd);
 
287
                perror("\nUnsuccessful");
 
288
                return -1;
 
289
        }
 
290
 
 
291
        return 0;
 
292
}
 
293
 
 
294
static int
 
295
qetharp_query(struct option_info *opin)
 
296
{
 
297
        int sd;
 
298
        struct ifreq ifr;
 
299
        struct qeth_arp_query_user_data *udata;
 
300
        int memsize,result;
 
301
        unsigned short mask_bits;
 
302
 
 
303
        if (!opin->dev_name) {
 
304
                printf("\nError: no interface specified!\n");
 
305
                return -1;
 
306
        }
 
307
                
 
308
        if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 
309
                perror("Socket failed: %m\n");
 
310
                return -1;
 
311
        }
 
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) {
 
319
                close(sd);
 
320
                perror("\nUnsuccessful");
 
321
                return -1;
 
322
        }
 
323
        if (opin->compact_output!=OPTION_INFO_COMPACT_OUTPUT) {
 
324
                show_header();
 
325
        }
 
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);
 
333
        else {
 
334
                perror("\nReceived entries with invalid format");
 
335
                return -1;
 
336
        }
 
337
        free(udata);
 
338
 
 
339
        return result;
 
340
}
 
341
 
 
342
static void
 
343
qetharp_usage(void)
 
344
{
 
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");
 
348
        printf("where:\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");
 
361
}
 
362
 
 
363
static int
 
364
qetharp_parse_info(struct option_info *opin)
 
365
{
 
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");
 
370
                return -1;      
 
371
        }
 
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 " \
 
376
                        "'-q' or '-n'.\n");
 
377
                return -1;
 
378
        }
 
379
        if (opin->purge_flag) {
 
380
                return qetharp_purge(opin);
 
381
        }
 
382
        if ((opin->host_resolution) && 
 
383
            !(opin->query_flag)) {
 
384
                printf("\nError in using '-n' option:\n" \
 
385
                       "\t'-q' option missing!\n");
 
386
                return -1;
 
387
        }
 
388
        if (opin->query_flag) {
 
389
                return qetharp_query(opin);
 
390
        }
 
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");
 
395
                        return -1;
 
396
                }
 
397
                return qetharp_add(opin);
 
398
        }
 
399
        if (opin->delete_flag) {
 
400
                if (!opin->ip_flag) {
 
401
                        printf("\nError in using '-d' option:\n" \
 
402
                               "\t'-i' option missing!\n");
 
403
                        return -1;
 
404
                }
 
405
                return qetharp_delete(opin);
 
406
        }
 
407
        return 0;
 
408
}
 
409
 
 
410
 
 
411
int main(int argc, char **argv) 
 
412
{
 
413
        
 
414
        int index,c,result;
 
415
        struct option_info info;
 
416
 
 
417
        opterr=0;
 
418
        result=0;
 
419
 
 
420
 
 
421
        memset(&info, 0, sizeof(info));
 
422
        while (1)
 
423
        {
 
424
                c = getopt_long(argc, argv,QETHARP_GETOPT_STRING,
 
425
                                qetharp_options,&index);
 
426
                
 
427
                if (c==-1)
 
428
                        break;
 
429
 
 
430
                switch (c) 
 
431
                {
 
432
                case '?':       
 
433
                case 'h':
 
434
                        qetharp_usage();
 
435
                        exit(0);
 
436
                case 'v':
 
437
                        printf("\nqetharp version 0.02\n");
 
438
                        exit(0);
 
439
                case 'q':
 
440
                        info.dev_name = optarg;
 
441
                        info.query_flag =  OPTION_INFO_QUERY;
 
442
                        break;
 
443
                case 'n':
 
444
                        info.host_resolution =  OPTION_INFO_HOST_RESOLUTION;
 
445
                        break;
 
446
                case 'p':
 
447
                        info.dev_name = optarg;
 
448
                        info.purge_flag = OPTION_INFO_PURGE;
 
449
                        break;
 
450
                case 'c':
 
451
                        info.compact_output = OPTION_INFO_COMPACT_OUTPUT;
 
452
                        break;
 
453
                case 'a':
 
454
                        info.dev_name = optarg;
 
455
                        info.add_flag = OPTION_INFO_ADD;
 
456
                        break;
 
457
                case 'd':
 
458
                        info.dev_name = optarg;
 
459
                        info.delete_flag = OPTION_INFO_DELETE;
 
460
                        break;
 
461
                case 'i':
 
462
                        info.ip_addr = optarg;
 
463
                        info.ip_flag = OPTION_INFO_IP;
 
464
                        break;
 
465
                case 'm':
 
466
                        info.mac_addr = optarg;
 
467
                        info.mac_flag = OPTION_INFO_MAC;
 
468
                        break;
 
469
                default:
 
470
                        qetharp_usage();
 
471
                        exit(0);
 
472
                }
 
473
        }
 
474
        result = qetharp_parse_info(&info);
 
475
        return result;
 
476
}
 
477