OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [userland/] [route/] [arp.c] - Blame information for rev 745

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 745 simons
/*
2
 * arp                This file contains an implementation of the command
3
 *              that maintains the kernel's ARP cache.  It is derived
4
 *              from Berkeley UNIX arp(8), but cleaner and with sup-
5
 *              port for devices other than Ethernet.
6
 *
7
 * NET-TOOLS    A collection of programs that form the base set of the
8
 *              NET-3 Networking Distribution for the LINUX operating
9
 *              system.
10
 *
11
 * Version:     $Id: arp.c,v 1.1 2002-03-17 19:58:52 simons Exp $
12
 *
13
 * Maintainer:  Bernd 'eckes' Eckenfels, <net-tools@lina.inka.de>
14
 *
15
 * Author:      Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
16
 *
17
 * Changes:
18
 *              (based on work from Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>)
19
 *              Alan Cox        :       modified for NET3
20
 *              Andrew Tridgell :       proxy arp netmasks
21
 *              Bernd Eckenfels :       -n option
22
 *              Bernd Eckenfels :       Use only /proc for display
23
 *       {1.60} Bernd Eckenfels :       new arpcode (-i) for 1.3.42 but works
24
 *                                      with 1.2.x, too
25
 *       {1.61} Bernd Eckenfels :       more verbose messages
26
 *       {1.62} Bernd Eckenfels :       check -t for hw adresses and try to
27
 *                                      explain EINVAL (jeff)
28
 *970125 {1.63} Bernd Eckenfels :       -a print hardwarename instead of tiltle
29
 *970201 {1.64} Bernd Eckenfels :       net-features.h support
30
 *970203 {1.65} Bernd Eckenfels :       "#define" in "#if",
31
 *                                      -H|-A additional to -t|-p
32
 *970214 {1.66} Bernd Eckenfels :       Fix optarg required for -H and -A
33
 *970412 {1.67} Bernd Eckenfels :       device=""; is default
34
 *970514 {1.68} Bernd Eckenfels :       -N and -D
35
 *970517 {1.69} Bernd Eckenfels :       usage() fixed
36
 *970622 {1.70} Bernd Eckenfels :       arp -d priv
37
 *970106 {1.80} Bernd Eckenfels :       new syntax without -D and with "dev <If>",
38
 *                                      ATF_MAGIC, ATF_DONTPUB support.
39
 *                                      Typo fix (Debian Bug#5728 Giuliano Procida)
40
 *970803 {1.81} Bernd Eckenfels :       removed junk comment line 1
41
 *970925 {1.82} Bernd Eckenfels :       include fix for libc6
42
 *980213 (1.83) Phil Blundell:          set ATF_COM on new entries
43
 *980629 (1.84) Arnaldo Carvalho de Melo: gettext instead of catgets
44
 *990101 {1.85} Bernd Eckenfels         fixed usage and return codes
45
 *990105 (1.86) Phil Blundell:          don't ignore EINVAL in arp_set
46
 *
47
 *              This program is free software; you can redistribute it
48
 *              and/or  modify it under  the terms of  the GNU General
49
 *              Public  License as  published  by  the  Free  Software
50
 *              Foundation;  either  version 2 of the License, or  (at
51
 *              your option) any later version.
52
 */
53
#include <sys/types.h>
54
#include <sys/socket.h>
55
#include <sys/ioctl.h>
56
#include <net/if.h>
57
/* #include <linux/netdevice.h> */
58
/* #include <linux/if_arp.h>    */
59
#include <net/if_arp.h>
60
#include <stdlib.h>
61
#include <stdio.h>
62
#include <errno.h>
63
#include <ctype.h>
64
#include <fcntl.h>
65
#include <string.h>
66
#include <getopt.h>
67
#include <unistd.h>
68
#include "net-support.h"
69
#include "pathnames.h"
70
#include "version.h"
71
#include "config.h"
72
#include "intl.h"
73
#include "util.h"
74
 
75
#define DFLT_AF "inet"
76
#define DFLT_HW "ether"
77
 
78
#define FEATURE_ARP
79
#include "lib/net-features.h"
80
 
81
char *Release = RELEASE, *Version = "arp 1.85 (1999-01-05)";
82
 
83
int opt_n = 0;                   /* do not resolve addresses     */
84
int opt_N = 0;                   /* use symbolic names           */
85
int opt_v = 0;                   /* debugging output flag        */
86
int opt_D = 0;                   /* HW-address is devicename     */
87
int opt_e = 0;                   /* 0=BSD output, 1=new linux    */
88
int opt_a = 0;                   /* all entries, substring match */
89
struct aftype *ap;              /* current address family       */
90
struct hwtype *hw;              /* current hardware type        */
91
int sockfd = 0;                  /* active socket descriptor     */
92
int hw_set = 0;                  /* flag if hw-type was set (-H) */
93
char device[16] = "";           /* current device               */
94
static void usage(void);
95
 
96
/* Delete an entry from the ARP cache. */
97
static int arp_del(char **args)
98
{
99
    char host[128];
100
    struct arpreq req;
101
    struct sockaddr sa;
102
    int flags = 0;
103
    int err;
104
 
105
    memset((char *) &req, 0, sizeof(req));
106
 
107
    /* Resolve the host name. */
108
    if (*args == NULL) {
109
        fprintf(stderr, _("arp: need host name\n"));
110
        return (-1);
111
    }
112
    safe_strncpy(host, *args, (sizeof host));
113
    if (ap->input(0, host, &sa) < 0) {
114
        ap->herror(host);
115
        return (-1);
116
    }
117
    /* If a host has more than one address, use the correct one! */
118
    memcpy((char *) &req.arp_pa, (char *) &sa, sizeof(struct sockaddr));
119
 
120
    if (hw_set)
121
        req.arp_ha.sa_family = hw->type;
122
 
123
    req.arp_flags = ATF_PERM;
124
    args++;
125
    while (*args != NULL) {
126
        if (opt_v)
127
            fprintf(stderr, "args=%s\n", *args);
128
        if (!strcmp(*args, "pub")) {
129
            flags |= 1;
130
            args++;
131
            continue;
132
        }
133
        if (!strcmp(*args, "priv")) {
134
            flags |= 2;
135
            args++;
136
            continue;
137
        }
138
        if (!strcmp(*args, "temp")) {
139
            req.arp_flags &= ~ATF_PERM;
140
            args++;
141
            continue;
142
        }
143
        if (!strcmp(*args, "trail")) {
144
            req.arp_flags |= ATF_USETRAILERS;
145
            args++;
146
            continue;
147
        }
148
        if (!strcmp(*args, "dontpub")) {
149
#ifdef HAVE_ATF_DONTPUB
150
            req.arp_flags |= ATF_DONTPUB;
151
#else
152
            ENOSUPP("arp", "ATF_DONTPUB");
153
#endif
154
            args++;
155
            continue;
156
        }
157
        if (!strcmp(*args, "auto")) {
158
#ifdef HAVE_ATF_MAGIC
159
            req.arp_flags |= ATF_MAGIC;
160
#else
161
            ENOSUPP("arp", "ATF_MAGIC");
162
#endif
163
            args++;
164
            continue;
165
        }
166
        if (!strcmp(*args, "dev")) {
167
            if (*++args == NULL)
168
                usage();
169
            safe_strncpy(device, *args, sizeof(device));
170
            args++;
171
            continue;
172
        }
173
        if (!strcmp(*args, "netmask")) {
174
            if (*++args == NULL)
175
                usage();
176
            if (strcmp(*args, "255.255.255.255") != 0) {
177
                strcpy(host, *args);
178
                if (ap->input(0, host, &sa) < 0) {
179
                    ap->herror(host);
180
                    return (-1);
181
                }
182
                memcpy((char *) &req.arp_netmask, (char *) &sa,
183
                       sizeof(struct sockaddr));
184
                req.arp_flags |= ATF_NETMASK;
185
            }
186
            args++;
187
            continue;
188
        }
189
        usage();
190
    }
191
    if (flags == 0)
192
        flags = 3;
193
 
194
    strcpy(req.arp_dev, device);
195
 
196
    err = -1;
197
 
198
    /* Call the kernel. */
199
    if (flags & 2) {
200
        if (opt_v)
201
            fprintf(stderr, "arp: SIOCDARP(nopub)\n");
202
        if ((err = ioctl(sockfd, SIOCDARP, &req) < 0)) {
203
            if (errno == ENXIO) {
204
                if (flags & 1)
205
                    goto nopub;
206
                printf(_("No ARP entry for %s\n"), host);
207
                return (-1);
208
            }
209
            perror("SIOCDARP(priv)");
210
            return (-1);
211
        }
212
    }
213
    if ((flags & 1) && (err)) {
214
      nopub:
215
        req.arp_flags |= ATF_PUBL;
216
        if (opt_v)
217
            fprintf(stderr, "arp: SIOCDARP(pub)\n");
218
        if (ioctl(sockfd, SIOCDARP, &req) < 0) {
219
            if (errno == ENXIO) {
220
                printf(_("No ARP entry for %s\n"), host);
221
                return (-1);
222
            }
223
            perror("SIOCDARP(pub)");
224
            return (-1);
225
        }
226
    }
227
    return (0);
228
}
229
 
230
/* Get the hardware address to a specified interface name */
231
static int arp_getdevhw(char *ifname, struct sockaddr *sa, struct hwtype *hw)
232
{
233
    struct ifreq ifr;
234
    struct hwtype *xhw;
235
 
236
    strcpy(ifr.ifr_name, ifname);
237
    if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) {
238
        fprintf(stderr, _("arp: cant get HW-Address for `%s': %s.\n"), ifname, strerror(errno));
239
        return (-1);
240
    }
241
    if (hw && (ifr.ifr_hwaddr.sa_family != hw->type)) {
242
        fprintf(stderr, _("arp: protocol type mismatch.\n"));
243
        return (-1);
244
    }
245
    memcpy((char *) sa, (char *) &(ifr.ifr_hwaddr), sizeof(struct sockaddr));
246
 
247
    if (opt_v) {
248
        if (!(xhw = get_hwntype(ifr.ifr_hwaddr.sa_family)) || (xhw->sprint == 0)) {
249
            xhw = get_hwntype(-1);
250
        }
251
        fprintf(stderr, _("arp: device `%s' has HW address %s `%s'.\n"), ifname, xhw->name, xhw->sprint(&ifr.ifr_hwaddr));
252
    }
253
    return (0);
254
}
255
 
256
/* Set an entry in the ARP cache. */
257
static int arp_set(char **args)
258
{
259
    char host[128];
260
    struct arpreq req;
261
    struct sockaddr sa;
262
    int flags;
263
 
264
    memset((char *) &req, 0, sizeof(req));
265
 
266
    /* Resolve the host name. */
267
    if (*args == NULL) {
268
        fprintf(stderr, _("arp: need host name\n"));
269
        return (-1);
270
    }
271
    safe_strncpy(host, *args++, (sizeof host));
272
    if (ap->input(0, host, &sa) < 0) {
273
        ap->herror(host);
274
        return (-1);
275
    }
276
    /* If a host has more than one address, use the correct one! */
277
    memcpy((char *) &req.arp_pa, (char *) &sa, sizeof(struct sockaddr));
278
 
279
    /* Fetch the hardware address. */
280
    if (*args == NULL) {
281
        fprintf(stderr, _("arp: need hardware address\n"));
282
        return (-1);
283
    }
284
    if (opt_D) {
285
        if (arp_getdevhw(*args++, &req.arp_ha, hw_set ? hw : NULL) < 0)
286
            return (-1);
287
    } else {
288
        if (hw->input(*args++, &req.arp_ha) < 0) {
289
            fprintf(stderr, _("arp: invalid hardware address\n"));
290
            return (-1);
291
        }
292
    }
293
 
294
    /* Check out any modifiers. */
295
    flags = ATF_PERM | ATF_COM;
296
    while (*args != NULL) {
297
        if (!strcmp(*args, "temp")) {
298
            flags &= ~ATF_PERM;
299
            args++;
300
            continue;
301
        }
302
        if (!strcmp(*args, "pub")) {
303
            flags |= ATF_PUBL;
304
            args++;
305
            continue;
306
        }
307
        if (!strcmp(*args, "priv")) {
308
            flags &= ~ATF_PUBL;
309
            args++;
310
            continue;
311
        }
312
        if (!strcmp(*args, "trail")) {
313
            flags |= ATF_USETRAILERS;
314
            args++;
315
            continue;
316
        }
317
        if (!strcmp(*args, "dontpub")) {
318
#ifdef HAVE_ATF_DONTPUB
319
            flags |= ATF_DONTPUB;
320
#else
321
            ENOSUPP("arp", "ATF_DONTPUB");
322
#endif
323
            args++;
324
            continue;
325
        }
326
        if (!strcmp(*args, "auto")) {
327
#ifdef HAVE_ATF_MAGIC
328
            flags |= ATF_MAGIC;
329
#else
330
            ENOSUPP("arp", "ATF_MAGIC");
331
#endif
332
            args++;
333
            continue;
334
        }
335
        if (!strcmp(*args, "dev")) {
336
            if (*++args == NULL)
337
                usage();
338
            safe_strncpy(device, *args, sizeof(device));
339
            args++;
340
            continue;
341
        }
342
        if (!strcmp(*args, "netmask")) {
343
            if (*++args == NULL)
344
                usage();
345
            if (strcmp(*args, "255.255.255.255") != 0) {
346
                strcpy(host, *args);
347
                if (ap->input(0, host, &sa) < 0) {
348
                    ap->herror(host);
349
                    return (-1);
350
                }
351
                memcpy((char *) &req.arp_netmask, (char *) &sa,
352
                       sizeof(struct sockaddr));
353
                flags |= ATF_NETMASK;
354
            }
355
            args++;
356
            continue;
357
        }
358
        usage();
359
    }
360
 
361
    /* Fill in the remainder of the request. */
362
    req.arp_flags = flags;
363
 
364
    strcpy(req.arp_dev, device);
365
 
366
    /* Call the kernel. */
367
    if (opt_v)
368
        fprintf(stderr, "arp: SIOCSARP()\n");
369
    if (ioctl(sockfd, SIOCSARP, &req) < 0) {
370
        perror("SIOCSARP");
371
        return (-1);
372
    }
373
    return (0);
374
}
375
 
376
 
377
/* Process an EtherFile */
378
static int arp_file(char *name)
379
{
380
    char buff[1024];
381
    char *sp, *args[32];
382
    int linenr, argc;
383
    FILE *fp;
384
 
385
    if ((fp = fopen(name, "r")) == NULL) {
386
        fprintf(stderr, _("arp: cannot open etherfile %s !\n"), name);
387
        return (-1);
388
    }
389
    /* Read the lines in the file. */
390
    linenr = 0;
391
    while (fgets(buff, sizeof(buff), fp) != (char *) NULL) {
392
        linenr++;
393
        if (opt_v == 1)
394
            fprintf(stderr, ">> %s", buff);
395
        if ((sp = strchr(buff, '\n')) != (char *) NULL)
396
            *sp = '\0';
397
        if (buff[0] == '#' || buff[0] == '\0')
398
            continue;
399
 
400
        argc = getargs(buff, args);
401
        if (argc < 2) {
402
            fprintf(stderr, _("arp: format error on line %u of etherfile %s !\n"),
403
                    linenr, name);
404
            continue;
405
        }
406
        if (arp_set(args) != 0)
407
            fprintf(stderr, _("arp: cannot set entry on line %u of etherfile %s !\n"),
408
                    linenr, name);
409
    }
410
 
411
    (void) fclose(fp);
412
    return (0);
413
}
414
 
415
 
416
/* Print the contents of an ARP request block. */
417
static void arp_disp_2(char *name, int type, int arp_flags, char *hwa, char *mask, char *dev)
418
{
419
    static int title = 0;
420
    struct hwtype *xhw;
421
    char flags[10];
422
 
423
    xhw = get_hwntype(type);
424
    if (xhw == NULL)
425
        xhw = get_hwtype(DFLT_HW);
426
 
427
    if (title++ == 0) {
428
        printf(_("Address\t\t\tHWtype\tHWaddress\t    Flags Mask\t\t  Iface\n"));
429
    }
430
    /* Setup the flags. */
431
    flags[0] = '\0';
432
    if (arp_flags & ATF_COM)
433
        strcat(flags, "C");
434
    if (arp_flags & ATF_PERM)
435
        strcat(flags, "M");
436
    if (arp_flags & ATF_PUBL)
437
        strcat(flags, "P");
438
#ifdef HAVE_ATF_MAGIC
439
    if (arp_flags & ATF_MAGIC)
440
        strcat(flags, "A");
441
#endif
442
#ifdef HAVE_ATF_DONTPUB
443
    if (arp_flags & ATF_DONTPUB)
444
        strcat(flags, "!");
445
#endif
446
    if (arp_flags & ATF_USETRAILERS)
447
        strcat(flags, "T");
448
 
449
    if (!(arp_flags & ATF_NETMASK))
450
        mask = "";
451
 
452
    printf("%-23.23s\t", name);
453
 
454
    if (!(arp_flags & ATF_COM)) {
455
        if (arp_flags & ATF_PUBL)
456
            printf("%-8.8s%-20.20s", "*", "*");
457
        else
458
            printf("%-8.8s%-20.20s", "", _("(incomplete)"));
459
    } else {
460
        printf("%-8.8s%-20.20s", xhw->name, hwa);
461
    }
462
 
463
    printf("%-6.6s%-15.15s %s\n", flags, mask, dev);
464
}
465
 
466
/* Print the contents of an ARP request block. */
467
static void arp_disp(char *name, char *ip, int type, int arp_flags, char *hwa, char *mask, char *dev)
468
{
469
    struct hwtype *xhw;
470
 
471
    xhw = get_hwntype(type);
472
    if (xhw == NULL)
473
        xhw = get_hwtype(DFLT_HW);
474
 
475
    printf(_("%s (%s) at "), name, ip);
476
 
477
    if (!(arp_flags & ATF_COM)) {
478
        if (arp_flags & ATF_PUBL)
479
            printf("* ");
480
        else
481
            printf(_("<incomplete> "));
482
    } else {
483
        printf("%s [%s] ", hwa, xhw->name);
484
    }
485
 
486
    if (arp_flags & ATF_NETMASK)
487
        printf(_("netmask %s "), mask);
488
 
489
    if (arp_flags & ATF_PERM)
490
        printf("PERM ");
491
    if (arp_flags & ATF_PUBL)
492
        printf("PUP ");
493
#ifdef HAVE_ATF_MAGIC
494
    if (arp_flags & ATF_MAGIC)
495
        printf("AUTO ");
496
#endif
497
#ifdef HAVE_ATF_DONTPUB
498
    if (arp_flags & ATF_DONTPUB)
499
        printf("DONTPUB ");
500
#endif
501
    if (arp_flags & ATF_USETRAILERS)
502
        printf("TRAIL ");
503
 
504
    printf(_("on %s\n"), dev);
505
}
506
 
507
 
508
/* Display the contents of the ARP cache in the kernel. */
509
static int arp_show(char *name)
510
{
511
    char host[100];
512
    struct sockaddr sa;
513
    char ip[100];
514
    char hwa[100];
515
    char mask[100];
516
    char line[200];
517
    char dev[100];
518
    int type, flags;
519
    FILE *fp;
520
    char *hostname;
521
    int num, entries = 0, showed = 0;
522
 
523
    host[0] = '\0';
524
 
525
    if (name != NULL) {
526
        /* Resolve the host name. */
527
        safe_strncpy(host, name, (sizeof host));
528
        if (ap->input(0, host, &sa) < 0) {
529
            ap->herror(host);
530
            return (-1);
531
        }
532
        strcpy(host, ap->sprint(&sa, 1));
533
    }
534
    /* Open the PROCps kernel table. */
535
    if ((fp = fopen(_PATH_PROCNET_ARP, "r")) == NULL) {
536
        perror(_PATH_PROCNET_ARP);
537
        return (-1);
538
    }
539
    /* Bypass header -- read until newline */
540
    if (fgets(line, sizeof(line), fp) != (char *) NULL) {
541
        strcpy(mask, "-");
542
        strcpy(dev, "-");
543
        /* Read the ARP cache entries. */
544
        for (; fgets(line, sizeof(line), fp);) {
545
            num = sscanf(line, "%s 0x%x 0x%x %100s %100s %100s\n",
546
                         ip, &type, &flags, hwa, mask, dev);
547
            if (num < 4)
548
                break;
549
 
550
            entries++;
551
            /* if the user specified hw-type differs, skip it */
552
            if (hw_set && (type != hw->type))
553
                continue;
554
 
555
            /* if the user specified address differs, skip it */
556
            if (host[0] && strcmp(ip, host))
557
                continue;
558
 
559
            /* if the user specified device differs, skip it */
560
            if (device[0] && strcmp(dev, device))
561
                continue;
562
 
563
            showed++;
564
            /* This IS ugly but it works -be */
565
            if (opt_n)
566
                hostname = "?";
567
            else {
568
                if (ap->input(0, ip, &sa) < 0)
569
                    hostname = ip;
570
                else
571
                    hostname = ap->sprint(&sa, opt_n | 0x8000);
572
                if (strcmp(hostname, ip) == 0)
573
                    hostname = "?";
574
            }
575
 
576
            if (opt_e)
577
                arp_disp_2(hostname[0] == '?' ? ip : hostname, type, flags, hwa, mask, dev);
578
            else
579
                arp_disp(hostname, ip, type, flags, hwa, mask, dev);
580
        }
581
    }
582
    if (opt_v)
583
        printf(_("Entries: %d\tSkipped: %d\tFound: %d\n"), entries, entries - showed, showed);
584
 
585
    if (!showed) {
586
        if (host[0] && !opt_a)
587
            printf(_("%s (%s) -- no entry\n"), name, host);
588
        else if (hw_set || host[0] || device[0]) {
589
            printf(_("arp: in %d entries no match found.\n"), entries);
590
        }
591
    }
592
    (void) fclose(fp);
593
    return (0);
594
}
595
 
596
static void version(void)
597
{
598
    fprintf(stderr, "%s\n%s\n%s\n", Release, Version, Features);
599
    exit(E_VERSION);
600
}
601
 
602
static void usage(void)
603
{
604
    fprintf(stderr, _("Usage:\n  arp [-vn]  [<HW>] [-i <if>] [-a] [<hostname>]             <-Display ARP cache\n"));
605
    fprintf(stderr, _("  arp [-v]          [-i <if>] -d  <hostname> [pub][nopub]    <-Delete ARP entry\n"));
606
    fprintf(stderr, _("  arp [-vnD] [<HW>] [-i <if>] -f  <filename>              <-Add entry from file\n"));
607
    fprintf(stderr, _("  arp [-v]   [<HW>] [-i <if>] -s  <hostname> <hwaddr> [temp][nopub] <-Add entry\n"));
608
    fprintf(stderr, _("  arp [-v]   [<HW>] [-i <if>] -s  <hostname> <hwaddr> [netmask <nm>] pub  <-''-\n"));
609
    fprintf(stderr, _("  arp [-v]   [<HW>] [-i <if>] -Ds <hostname> <if> [netmask <nm>] pub      <-''-\n\n"));
610
 
611
    fprintf(stderr, _("        -a                       display (all) hosts in alternative (BSD) style\n"));
612
    fprintf(stderr, _("        -s, --set                set a new ARP entry\n"));
613
    fprintf(stderr, _("        -d, --delete             delete a specified entry\n"));
614
    fprintf(stderr, _("        -v, --verbose            be verbose\n"));
615
    fprintf(stderr, _("        -n, --numeric            dont resolve names\n"));
616
    fprintf(stderr, _("        -i, --device             specify network interface (e.g. eth0)\n"));
617
    fprintf(stderr, _("        -D, --use-device         read <hwaddr> from given device\n"));
618
    fprintf(stderr, _("        -f, --file               read new entries from file\n\n"));
619
 
620
    fprintf(stderr, _("  <HW>=Use '-H <hw>' to specify hardware address type. Default: %s\n"), DFLT_HW);
621
    fprintf(stderr, _("  List of possible hardware types (which support ARP):\n"));
622
    print_hwlist(1); /* 1 = ARPable */
623
    exit(E_USAGE);
624
}
625
 
626
int main(int argc, char **argv)
627
{
628
    int i, lop, what;
629
#ifdef EMBED
630
#define getopt_long(a,b,c,d,e)  getopt(a,b,c)
631
#else
632
    struct option longopts[] =
633
    {
634
        {"verbose", 0, 0, 'v'},
635
        {"version", 0, 0, 'V'},
636
        {"all", 0, 0, 'a'},
637
        {"delete", 0, 0, 'd'},
638
        {"file", 0, 0, 'f'},
639
        {"numeric", 0, 0, 'n'},
640
        {"set", 0, 0, 's'},
641
        {"protocol", 1, 0, 'A'},
642
        {"hw-type", 1, 0, 'H'},
643
        {"device", 0, 0, 'i'},
644
        {"help", 0, 0, 'h'},
645
        {"use-device", 0, 0, 'D'},
646
        {"symbolic", 0, 0, 'N'},
647
        {NULL, 0, 0, 0}
648
    };
649
#endif
650
 
651
#if I18N
652
    bindtextdomain("net-tools", "/usr/share/locale");
653
    textdomain("net-tools");
654
#endif
655
 
656
    /* Initialize variables... */
657
    if ((hw = get_hwtype(DFLT_HW)) == NULL) {
658
        fprintf(stderr, _("%s: hardware type not supported!\n"), DFLT_HW);
659
        return (-1);
660
    }
661
    if ((ap = get_aftype(DFLT_AF)) == NULL) {
662
        fprintf(stderr, _("%s: address family not supported!\n"), DFLT_AF);
663
        return (-1);
664
    }
665
    what = 0;
666
 
667
    /* Fetch the command-line arguments. */
668
    /* opterr = 0; */
669
    while ((i = getopt_long(argc, argv, "A:H:adfp:nsei:t:vh?DNV", longopts, &lop)) != EOF)
670
        switch (i) {
671
        case 'a':
672
            what = 1;
673
            opt_a = 1;
674
            break;
675
        case 'f':
676
            what = 2;
677
            break;
678
        case 'd':
679
            what = 3;
680
            break;
681
        case 's':
682
            what = 4;
683
            break;
684
 
685
 
686
        case 'e':
687
            opt_e = 1;
688
            break;
689
        case 'n':
690
            opt_n = FLAG_NUM;
691
            break;
692
        case 'D':
693
            opt_D = 1;
694
            break;
695
        case 'N':
696
            opt_N = FLAG_SYM;
697
            fprintf(stderr, _("arp: -N not yet supported.\n"));
698
            break;
699
        case 'v':
700
            opt_v = 1;
701
            break;
702
 
703
        case 'A':
704
        case 'p':
705
            ap = get_aftype(optarg);
706
            if (ap == NULL) {
707
                fprintf(stderr, _("arp: %s: unknown address family.\n"),
708
                        optarg);
709
                exit(-1);
710
            }
711
            break;
712
        case 'H':
713
        case 't':
714
            hw = get_hwtype(optarg);
715
            if (hw == NULL) {
716
                fprintf(stderr, _("arp: %s: unknown hardware type.\n"),
717
                        optarg);
718
                exit(-1);
719
            }
720
            hw_set = 1;
721
            break;
722
        case 'i':
723
            safe_strncpy(device, optarg, sizeof(device));
724
            break;
725
 
726
        case 'V':
727
            version();
728
        case '?':
729
        case 'h':
730
        default:
731
            usage();
732
        }
733
 
734
    if (ap->af != AF_INET) {
735
        fprintf(stderr, _("arp: %s: kernel only supports 'inet'.\n"),
736
                ap->name);
737
        exit(-1);
738
    }
739
    if (hw->alen <= 0) {
740
        fprintf(stderr, _("arp: %s: hardware type without ARP support.\n"),
741
                hw->name);
742
        exit(-1);
743
    }
744
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
745
        perror("socket");
746
        exit(-1);
747
    }
748
    /* Now see what we have to do here... */
749
    switch (what) {
750
    case 0:
751
        opt_e = 1;
752
        what = arp_show(argv[optind]);
753
        break;
754
 
755
    case 1:                     /* show an ARP entry in the cache */
756
        what = arp_show(argv[optind]);
757
        break;
758
 
759
    case 2:                     /* process an EtherFile */
760
        what = arp_file(argv[optind]);
761
        break;
762
 
763
    case 3:                     /* delete an ARP entry from the cache */
764
        what = arp_del(&argv[optind]);
765
        break;
766
 
767
    case 4:                     /* set an ARP entry in the cache */
768
        what = arp_set(&argv[optind]);
769
        break;
770
 
771
    default:
772
        usage();
773
    }
774
 
775
    exit(what);
776
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.