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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [userland/] [route/] [ifconfig.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
 * ifconfig   This file contains an implementation of the command
3
 *              that either displays or sets the characteristics of
4
 *              one or more of the system's networking interfaces.
5
 *
6
 * Version:     $Id: ifconfig.c,v 1.1 2002-03-17 19:58:52 simons Exp $
7
 *
8
 * Author:      Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
9
 *              and others.  Copyright 1993 MicroWalt Corporation
10
 *
11
 *              This program is free software; you can redistribute it
12
 *              and/or  modify it under  the terms of  the GNU General
13
 *              Public  License as  published  by  the  Free  Software
14
 *              Foundation;  either  version 2 of the License, or  (at
15
 *              your option) any later version.
16
 * {1.34} - 19980630 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
17
 *                     - gettext instead of catgets for i18n
18
 *          10/1998  - Andi Kleen. Use interface list primitives.
19
 */
20
 
21
#define DFLT_AF "inet"
22
 
23
#include "config.h"
24
 
25
#include <features.h>
26
#include <sys/types.h>
27
#ifdef EMBED
28
#include <gnu/types.h>
29
#endif
30
#include <sys/socket.h>
31
#include <sys/ioctl.h>
32
#include <netinet/in.h>
33
#include <net/if.h>
34
#include <net/if_arp.h>
35
#include <stdio.h>
36
#include <errno.h>
37
#include <fcntl.h>
38
#include <ctype.h>
39
#include <stdlib.h>
40
#include <string.h>
41
#include <unistd.h>
42
#include <netdb.h>
43
 
44
/* Ugh.  But libc5 doesn't provide POSIX types.  */
45
#include <asm/types.h>
46
 
47
#ifdef HAVE_HWSLIP
48
#include <linux/if_slip.h>
49
#endif
50
 
51
#if HAVE_AFINET6
52
 
53
#ifndef _LINUX_IN6_H
54
/*
55
 *    This is in linux/include/net/ipv6.h.
56
 */
57
 
58
struct in6_ifreq {
59
    struct in6_addr ifr6_addr;
60
    __u32 ifr6_prefixlen;
61
    unsigned int ifr6_ifindex;
62
};
63
 
64
#endif
65
 
66
#define IPV6_ADDR_ANY           0x0000U
67
 
68
#define IPV6_ADDR_UNICAST       0x0001U
69
#define IPV6_ADDR_MULTICAST     0x0002U
70
#define IPV6_ADDR_ANYCAST       0x0004U
71
 
72
#define IPV6_ADDR_LOOPBACK      0x0010U
73
#define IPV6_ADDR_LINKLOCAL     0x0020U
74
#define IPV6_ADDR_SITELOCAL     0x0040U
75
 
76
#define IPV6_ADDR_COMPATv4      0x0080U
77
 
78
#define IPV6_ADDR_SCOPE_MASK    0x00f0U
79
 
80
#define IPV6_ADDR_MAPPED        0x1000U
81
#define IPV6_ADDR_RESERVED      0x2000U         /* reserved address space */
82
 
83
#endif                          /* HAVE_AFINET6 */
84
 
85
#ifdef IFF_PORTSEL
86
static const char *if_port_text[][4] =
87
{
88
  /* Keep in step with <linux/netdevice.h> */
89
    {"unknown", NULL, NULL, NULL},
90
    {"10base2", "bnc", "coax", NULL},
91
    {"10baseT", "utp", "tpe", NULL},
92
    {"AUI", "thick", "db15", NULL},
93
    {"100baseT", NULL, NULL, NULL},
94
    {"100baseTX", NULL, NULL, NULL},
95
    {"100baseFX", NULL, NULL, NULL},
96
    {NULL, NULL, NULL, NULL},
97
};
98
#endif
99
 
100
#if HAVE_AFIPX
101
#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
102
#include <netipx/ipx.h>
103
#else
104
#include "ipx.h"
105
#endif
106
#endif
107
#include "net-support.h"
108
#include "pathnames.h"
109
#include "version.h"
110
#include "../intl.h"
111
#include "interface.h"
112
#include "sockets.h"
113
#include "util.h"
114
 
115
char *Release = RELEASE, *Version = "ifconfig 1.39 (1999-03-18)";
116
 
117
int opt_a = 0;                   /* show all interfaces          */
118
int opt_i = 0;                   /* show the statistics          */
119
int opt_v = 0;                   /* debugging output flag        */
120
 
121
int addr_family = 0;             /* currently selected AF        */
122
 
123
 
124
void ife_print(struct interface *ptr)
125
{
126
    struct aftype *ap;
127
    struct hwtype *hw;
128
    int hf;
129
    int can_compress = 0;
130
#if HAVE_AFIPX
131
    static struct aftype *ipxtype = NULL;
132
#endif
133
#if HAVE_AFECONET
134
    static struct aftype *ectype = NULL;
135
#endif
136
#if HAVE_AFATALK
137
    static struct aftype *ddptype = NULL;
138
#endif
139
#if HAVE_AFINET6
140
    FILE *f;
141
    char addr6[40], devname[20];
142
    struct sockaddr_in6 sap;
143
    int plen, scope, dad_status, if_idx;
144
    extern struct aftype inet6_aftype;
145
    char addr6p[8][5];
146
#endif
147
 
148
    ap = get_afntype(ptr->addr.sa_family);
149
    if (ap == NULL)
150
        ap = get_afntype(0);
151
 
152
    hf = ptr->type;
153
 
154
    if (hf == ARPHRD_CSLIP || hf == ARPHRD_CSLIP6)
155
        can_compress = 1;
156
 
157
    hw = get_hwntype(hf);
158
    if (hw == NULL)
159
        hw = get_hwntype(-1);
160
 
161
    printf(_("%-9.9s Link encap:%s  "), ptr->name, hw->title);
162
    /* For some hardware types (eg Ash, ATM) we don't print the
163
       hardware address if it's null.  */
164
    if (hw->sprint != NULL && (! (hw_null_address(hw, ptr->hwaddr) &&
165
                                  hw->suppress_null_addr)))
166
        printf(_("HWaddr %s  "), hw->print(ptr->hwaddr));
167
#ifdef IFF_PORTSEL
168
    if (ptr->flags & IFF_PORTSEL) {
169
        printf(_("Media:%s"), if_port_text[ptr->map.port][0]);
170
        if (ptr->flags & IFF_AUTOMEDIA)
171
            printf(_("(auto)"));
172
    }
173
#endif
174
    printf("\n");
175
 
176
#if HAVE_AFINET
177
    if (ptr->has_ip) {
178
        printf(_("          %s addr:%s "), ap->name,
179
               ap->sprint(&ptr->addr, 1));
180
        if (ptr->flags & IFF_POINTOPOINT) {
181
            printf(_(" P-t-P:%s "), ap->sprint(&ptr->dstaddr, 1));
182
        }
183
        if (ptr->flags & IFF_BROADCAST) {
184
            printf(_(" Bcast:%s "), ap->sprint(&ptr->broadaddr, 1));
185
        }
186
        printf(_(" Mask:%s\n"), ap->sprint(&ptr->netmask, 1));
187
    }
188
#endif
189
 
190
#if HAVE_AFINET6
191
    /* FIXME: should be integrated into interface.c.   */
192
 
193
    if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
194
        while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
195
                      addr6p[0], addr6p[1], addr6p[2], addr6p[3],
196
                      addr6p[4], addr6p[5], addr6p[6], addr6p[7],
197
                  &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
198
            if (!strcmp(devname, ptr->name)) {
199
                sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
200
                        addr6p[0], addr6p[1], addr6p[2], addr6p[3],
201
                        addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
202
                inet6_aftype.input(1, addr6, (struct sockaddr *) &sap);
203
                printf(_("          inet6 addr: %s/%d"),
204
                 inet6_aftype.sprint((struct sockaddr *) &sap, 1), plen);
205
                printf(_(" Scope:"));
206
                switch (scope) {
207
                case 0:
208
                    printf(_("Global"));
209
                    break;
210
                case IPV6_ADDR_LINKLOCAL:
211
                    printf(_("Link"));
212
                    break;
213
                case IPV6_ADDR_SITELOCAL:
214
                    printf(_("Site"));
215
                    break;
216
                case IPV6_ADDR_COMPATv4:
217
                    printf(_("Compat"));
218
                    break;
219
                case IPV6_ADDR_LOOPBACK:
220
                    printf(_("Host"));
221
                    break;
222
                default:
223
                    printf(_("Unknown"));
224
                }
225
                printf("\n");
226
            }
227
        }
228
        fclose(f);
229
    }
230
#endif
231
 
232
#if HAVE_AFIPX
233
    if (ipxtype == NULL)
234
        ipxtype = get_afntype(AF_IPX);
235
 
236
    if (ipxtype != NULL) {
237
        if (ptr->has_ipx_bb)
238
            printf(_("          IPX/Ethernet II addr:%s\n"),
239
                   ipxtype->sprint(&ptr->ipxaddr_bb, 1));
240
        if (ptr->has_ipx_sn)
241
            printf(_("          IPX/Ethernet SNAP addr:%s\n"),
242
                   ipxtype->sprint(&ptr->ipxaddr_sn, 1));
243
        if (ptr->has_ipx_e2)
244
            printf(_("          IPX/Ethernet 802.2 addr:%s\n"),
245
                   ipxtype->sprint(&ptr->ipxaddr_e2, 1));
246
        if (ptr->has_ipx_e3)
247
            printf(_("          IPX/Ethernet 802.3 addr:%s\n"),
248
                   ipxtype->sprint(&ptr->ipxaddr_e3, 1));
249
    }
250
#endif
251
 
252
#if HAVE_AFATALK
253
    if (ddptype == NULL)
254
        ddptype = get_afntype(AF_APPLETALK);
255
    if (ddptype != NULL) {
256
        if (ptr->has_ddp)
257
            printf(_("          EtherTalk Phase 2 addr:%s\n"), ddptype->sprint(&ptr->ddpaddr, 1));
258
    }
259
#endif
260
 
261
#if HAVE_AFECONET
262
    if (ectype == NULL)
263
        ectype = get_afntype(AF_ECONET);
264
    if (ectype != NULL) {
265
        if (ptr->has_econet)
266
            printf(_("          econet addr:%s\n"), ectype->sprint(&ptr->ecaddr, 1));
267
    }
268
#endif
269
 
270
    printf("          ");
271
    if (ptr->flags == 0)
272
        printf(_("[NO FLAGS] "));
273
    if (ptr->flags & IFF_UP)
274
        printf(_("UP "));
275
    if (ptr->flags & IFF_BROADCAST)
276
        printf(_("BROADCAST "));
277
    if (ptr->flags & IFF_DEBUG)
278
        printf(_("DEBUG "));
279
    if (ptr->flags & IFF_LOOPBACK)
280
        printf(_("LOOPBACK "));
281
    if (ptr->flags & IFF_POINTOPOINT)
282
        printf(_("POINTOPOINT "));
283
    if (ptr->flags & IFF_NOTRAILERS)
284
        printf(_("NOTRAILERS "));
285
    if (ptr->flags & IFF_RUNNING)
286
        printf(_("RUNNING "));
287
    if (ptr->flags & IFF_NOARP)
288
        printf(_("NOARP "));
289
    if (ptr->flags & IFF_PROMISC)
290
        printf(_("PROMISC "));
291
    if (ptr->flags & IFF_ALLMULTI)
292
        printf(_("ALLMULTI "));
293
    if (ptr->flags & IFF_SLAVE)
294
        printf(_("SLAVE "));
295
    if (ptr->flags & IFF_MASTER)
296
        printf(_("MASTER "));
297
    if (ptr->flags & IFF_MULTICAST)
298
        printf(_("MULTICAST "));
299
#ifdef HAVE_DYNAMIC
300
    if (ptr->flags & IFF_DYNAMIC)
301
        printf(_("DYNAMIC "));
302
#endif
303
 
304
    printf(_(" MTU:%d  Metric:%d"),
305
           ptr->mtu, ptr->metric ? ptr->metric : 1);
306
#ifdef SIOCSKEEPALIVE
307
    if (ptr->outfill || ptr->keepalive)
308
        printf(_("  Outfill:%d  Keepalive:%d"),
309
               ptr->outfill, ptr->keepalive);
310
#endif
311
    printf("\n");
312
 
313
    /* If needed, display the interface statistics. */
314
 
315
    if (ptr->statistics_valid) {
316
        /* XXX: statistics are currently only printed for the primary address,
317
         *      not for the aliases, although strictly speaking they're shared
318
         *      by all addresses.
319
         */
320
        printf("          ");
321
 
322
        printf(_("RX packets:%lu errors:%lu dropped:%lu overruns:%lu frame:%lu\n"),
323
               ptr->stats.rx_packets, ptr->stats.rx_errors,
324
               ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors,
325
               ptr->stats.rx_frame_errors);
326
        if (can_compress)
327
            printf(_("             compressed:%lu\n"), ptr->stats.rx_compressed);
328
 
329
        printf("          ");
330
 
331
        printf(_("TX packets:%lu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n"),
332
               ptr->stats.tx_packets, ptr->stats.tx_errors,
333
               ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors,
334
               ptr->stats.tx_carrier_errors);
335
        printf(_("          collisions:%lu "), ptr->stats.collisions);
336
        if (can_compress)
337
            printf(_("compressed:%lu "), ptr->stats.tx_compressed);
338
        if (ptr->tx_queue_len != -1)
339
            printf(_("txqueuelen:%d "), ptr->tx_queue_len);
340
        printf("\n");
341
    }
342
 
343
    if ((ptr->map.irq || ptr->map.mem_start || ptr->map.dma ||
344
         ptr->map.base_addr)) {
345
        printf("          ");
346
        if (ptr->map.irq)
347
            printf(_("Interrupt:%d "), ptr->map.irq);
348
        if (ptr->map.base_addr >= 0x100)        /* Only print devices using it for
349
                                                   I/O maps */
350
            printf(_("Base address:0x%x "), ptr->map.base_addr);
351
        if (ptr->map.mem_start) {
352
            printf(_("Memory:%lx-%lx "), ptr->map.mem_start, ptr->map.mem_end);
353
        }
354
        if (ptr->map.dma)
355
            printf(_("DMA chan:%x "), ptr->map.dma);
356
        printf("\n");
357
    }
358
    printf("\n");
359
}
360
 
361
static int if_print(char *ifname)
362
{
363
    int res;
364
 
365
    if (!ifname) {
366
        res = for_all_interfaces(do_if_print, &opt_a);
367
    } else {
368
        struct interface *ife;
369
 
370
        ife = lookup_interface(ifname);
371
        res = do_if_fetch(ife);
372
        if (res >= 0)
373
            ife_print(ife);
374
    }
375
    return res;
376
}
377
 
378
 
379
/* Set a certain interface flag. */
380
static int set_flag(char *ifname, short flag)
381
{
382
    struct ifreq ifr;
383
 
384
    strcpy(ifr.ifr_name, ifname);
385
    if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) {
386
        fprintf(stderr, _("%s: unknown interface: %s\n"),
387
                ifname, strerror(errno));
388
        return (-1);
389
    }
390
    strcpy(ifr.ifr_name, ifname);
391
    ifr.ifr_flags |= flag;
392
    if (ioctl(skfd, SIOCSIFFLAGS, &ifr) < 0) {
393
        perror("SIOCSIFFLAGS");
394
        return -1;
395
    }
396
    return (0);
397
}
398
 
399
 
400
/* Clear a certain interface flag. */
401
static int clr_flag(char *ifname, short flag)
402
{
403
    struct ifreq ifr;
404
 
405
    strcpy(ifr.ifr_name, ifname);
406
    if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) {
407
        fprintf(stderr, _("%s: unknown interface: %s\n"),
408
                ifname, strerror(errno));
409
        return -1;
410
    }
411
    strcpy(ifr.ifr_name, ifname);
412
    ifr.ifr_flags &= ~flag;
413
    if (ioctl(skfd, SIOCSIFFLAGS, &ifr) < 0) {
414
        perror("SIOCSIFFLAGS");
415
        return -1;
416
    }
417
    return (0);
418
}
419
 
420
 
421
static void usage(void)
422
{
423
    fprintf(stderr, _("Usage:\n  ifconfig [-a] [-i] [-v] <interface> [[<AF>] <address>]\n"));
424
    /* XXX: it would be useful to have the add/del syntax even without IPv6.
425
       the 2.1 interface address lists make this natural */
426
#ifdef HAVE_AFINET6
427
    fprintf(stderr, _("  [add <address>[/<prefixlen>]]\n"));
428
#ifdef SIOCDIFADDR
429
    fprintf(stderr, _("  [del <address>[/<prefixlen>]]\n"));
430
#endif
431
    /* XXX the kernel supports tunneling even without ipv6 */
432
#endif
433
#if HAVE_AFINET
434
    fprintf(stderr, _("  [[-]broadcast [<address>]]  [[-]pointopoint [<address>]]\n"));
435
    fprintf(stderr, _("  [netmask <address>]  [dstaddr <address>]  [tunnel <address>]\n"));
436
#endif
437
#ifdef SIOCSKEEPALIVE
438
    fprintf(stderr, _("  [outfill <NN>] [keepalive <NN>]\n"));
439
#endif
440
    fprintf(stderr, _("  [hw <HW> <address>]  [metric <NN>]  [mtu <NN>]\n"));
441
    fprintf(stderr, _("  [[-]trailers]  [[-]arp]  [[-]allmulti]\n"));
442
    fprintf(stderr, _("  [multicast]  [[-]promisc]\n"));
443
    fprintf(stderr, _("  [mem_start <NN>]  [io_addr <NN>]  [irq <NN>]  [media <type>]\n"));
444
#ifdef HAVE_TXQUEUELEN
445
    fprintf(stderr, _("  [txqueuelen <NN>]\n"));
446
#endif
447
#ifdef HAVE_DYNAMIC
448
    fprintf(stderr, _("  [[-]dynamic]\n"));
449
#endif
450
    fprintf(stderr, _("  [up|down] ...\n\n"));
451
 
452
    fprintf(stderr, _("  <HW>=Hardware Type.\n"));
453
    fprintf(stderr, _("  List of possible hardware types:\n"));
454
    print_hwlist(0); /* 1 = ARPable */
455
    fprintf(stderr, _("  <AF>=Address family. Default: %s\n"), DFLT_AF);
456
    fprintf(stderr, _("  List of possible address families:\n"));
457
    print_aflist(0); /* 1 = routeable */
458
    exit(E_USAGE);
459
}
460
 
461
static void version(void)
462
{
463
    fprintf(stderr, "%s\n%s\n", Release, Version);
464
    exit(1);
465
}
466
 
467
static int set_netmask(int skfd, struct ifreq *ifr, struct sockaddr *sa)
468
{
469
    int err = 0;
470
 
471
    memcpy((char *) &ifr->ifr_netmask, (char *) sa,
472
           sizeof(struct sockaddr));
473
    if (ioctl(skfd, SIOCSIFNETMASK, ifr) < 0) {
474
        fprintf(stderr, "SIOCSIFNETMASK: %s\n",
475
                strerror(errno));
476
        err = 1;
477
    }
478
    return 0;
479
}
480
 
481
int main(int argc, char **argv)
482
{
483
    struct sockaddr sa;
484
    char host[128];
485
    struct aftype *ap;
486
    struct hwtype *hw;
487
    struct ifreq ifr;
488
    int goterr = 0, didnetmask = 0;
489
    char **spp;
490
    int fd;
491
#if HAVE_AFINET6
492
    extern struct aftype inet6_aftype;
493
    struct sockaddr_in6 sa6;
494
    struct in6_ifreq ifr6;
495
    unsigned long prefix_len;
496
    char *cp;
497
#endif
498
 
499
#if I18N
500
    bindtextdomain("net-tools", "/usr/share/locale");
501
    textdomain("net-tools");
502
#endif
503
 
504
    /* Create a channel to the NET kernel. */
505
    if ((skfd = sockets_open(0)) < 0) {
506
        perror("socket");
507
        exit(1);
508
    }
509
 
510
    /* Find any options. */
511
    argc--;
512
    argv++;
513
    while (argc && *argv[0] == '-') {
514
        if (!strcmp(*argv, "-a"))
515
            opt_a = 1;
516
 
517
        if (!strcmp(*argv, "-v"))
518
            opt_v = 1;
519
 
520
        if (!strcmp(*argv, "-V") || !strcmp(*argv, "-version") ||
521
            !strcmp(*argv, "--version"))
522
            version();
523
 
524
        if (!strcmp(*argv, "-?") || !strcmp(*argv, "-h") ||
525
            !strcmp(*argv, "-help") || !strcmp(*argv, "--help"))
526
            usage();
527
 
528
        argv++;
529
        argc--;
530
    }
531
 
532
    /* Do we have to show the current setup? */
533
    if (argc == 0) {
534
        int err = if_print((char *) NULL);
535
        (void) close(skfd);
536
        exit(err < 0);
537
    }
538
    /* No. Fetch the interface name. */
539
    spp = argv;
540
    safe_strncpy(ifr.ifr_name, *spp++, IFNAMSIZ);
541
    if (*spp == (char *) NULL) {
542
        int err = if_print(ifr.ifr_name);
543
        (void) close(skfd);
544
        exit(err < 0);
545
    }
546
    /* The next argument is either an address family name, or an option. */
547
    if ((ap = get_aftype(*spp)) == NULL)
548
        ap = get_aftype(DFLT_AF);
549
    else {
550
        /* XXX: should print the current setup if no args left, but only
551
           for this family */
552
        spp++;
553
        addr_family = ap->af;
554
    }
555
 
556
    if (sockets_open(addr_family) < 0) {
557
        perror("family socket");
558
        exit(1);
559
    }
560
    /* Process the remaining arguments. */
561
    while (*spp != (char *) NULL) {
562
        if (!strcmp(*spp, "arp")) {
563
            goterr |= clr_flag(ifr.ifr_name, IFF_NOARP);
564
            spp++;
565
            continue;
566
        }
567
        if (!strcmp(*spp, "-arp")) {
568
            goterr |= set_flag(ifr.ifr_name, IFF_NOARP);
569
            spp++;
570
            continue;
571
        }
572
#ifdef IFF_PORTSEL
573
        if (!strcmp(*spp, "media") || !strcmp(*spp, "port")) {
574
            if (*++spp == NULL)
575
                usage();
576
            if (!strcasecmp(*spp, "auto")) {
577
                goterr |= set_flag(ifr.ifr_name, IFF_AUTOMEDIA);
578
            } else {
579
                int i, j, newport;
580
                char *endp;
581
                newport = strtol(*spp, &endp, 10);
582
                if (*endp != 0) {
583
                    newport = -1;
584
                    for (i = 0; if_port_text[i][0] && newport == -1; i++) {
585
                        for (j = 0; if_port_text[i][j]; j++) {
586
                            if (!strcasecmp(*spp, if_port_text[i][j])) {
587
                                newport = i;
588
                                break;
589
                            }
590
                        }
591
                    }
592
                }
593
                spp++;
594
                if (newport == -1) {
595
                    fprintf(stderr, _("Unknown media type.\n"));
596
                    goterr = 1;
597
                } else {
598
                    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
599
                        goterr = 1;
600
                        continue;
601
                    }
602
                    ifr.ifr_map.port = newport;
603
                    if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
604
                        perror("SIOCSIFMAP");
605
                        goterr = 1;
606
                    }
607
                }
608
            }
609
            continue;
610
        }
611
#endif
612
 
613
        if (!strcmp(*spp, "trailers")) {
614
            goterr |= clr_flag(ifr.ifr_name, IFF_NOTRAILERS);
615
            spp++;
616
            continue;
617
        }
618
        if (!strcmp(*spp, "-trailers")) {
619
            goterr |= set_flag(ifr.ifr_name, IFF_NOTRAILERS);
620
            spp++;
621
            continue;
622
        }
623
        if (!strcmp(*spp, "promisc")) {
624
            goterr |= set_flag(ifr.ifr_name, IFF_PROMISC);
625
            spp++;
626
            continue;
627
        }
628
        if (!strcmp(*spp, "-promisc")) {
629
            goterr |= clr_flag(ifr.ifr_name, IFF_PROMISC);
630
            spp++;
631
            continue;
632
        }
633
        if (!strcmp(*spp, "multicast")) {
634
            goterr |= set_flag(ifr.ifr_name, IFF_MULTICAST);
635
            spp++;
636
            continue;
637
        }
638
        if (!strcmp(*spp, "-multicast")) {
639
            goterr |= clr_flag(ifr.ifr_name, IFF_MULTICAST);
640
            spp++;
641
            continue;
642
        }
643
        if (!strcmp(*spp, "allmulti")) {
644
            goterr |= set_flag(ifr.ifr_name, IFF_ALLMULTI);
645
            spp++;
646
            continue;
647
        }
648
        if (!strcmp(*spp, "-allmulti")) {
649
            goterr |= clr_flag(ifr.ifr_name, IFF_ALLMULTI);
650
            spp++;
651
            continue;
652
        }
653
        if (!strcmp(*spp, "up")) {
654
            goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));
655
            spp++;
656
            continue;
657
        }
658
        if (!strcmp(*spp, "down")) {
659
            goterr |= clr_flag(ifr.ifr_name, IFF_UP);
660
            spp++;
661
            continue;
662
        }
663
#ifdef HAVE_DYNAMIC
664
        if (!strcmp(*spp, "dynamic")) {
665
            goterr |= set_flag(ifr.ifr_name, IFF_DYNAMIC);
666
            spp++;
667
            continue;
668
        }
669
        if (!strcmp(*spp, "-dynamic")) {
670
            goterr |= clr_flag(ifr.ifr_name, IFF_DYNAMIC);
671
            spp++;
672
            continue;
673
        }
674
#endif
675
 
676
        if (!strcmp(*spp, "metric")) {
677
            if (*++spp == NULL)
678
                usage();
679
            ifr.ifr_metric = atoi(*spp);
680
            if (ioctl(skfd, SIOCSIFMETRIC, &ifr) < 0) {
681
                fprintf(stderr, "SIOCSIFMETRIC: %s\n", strerror(errno));
682
                goterr = 1;
683
            }
684
            spp++;
685
            continue;
686
        }
687
        if (!strcmp(*spp, "mtu")) {
688
            if (*++spp == NULL)
689
                usage();
690
            ifr.ifr_mtu = atoi(*spp);
691
            if (ioctl(skfd, SIOCSIFMTU, &ifr) < 0) {
692
                fprintf(stderr, "SIOCSIFMTU: %s\n", strerror(errno));
693
                goterr = 1;
694
            }
695
            spp++;
696
            continue;
697
        }
698
#ifdef SIOCSKEEPALIVE
699
        if (!strcmp(*spp, "keepalive")) {
700
            if (*++spp == NULL)
701
                usage();
702
            ifr.ifr_data = (caddr_t) atoi(*spp);
703
            if (ioctl(skfd, SIOCSKEEPALIVE, &ifr) < 0) {
704
                fprintf(stderr, "SIOCSKEEPALIVE: %s\n", strerror(errno));
705
                goterr = 1;
706
            }
707
            spp++;
708
            continue;
709
        }
710
#endif
711
 
712
#ifdef SIOCSOUTFILL
713
        if (!strcmp(*spp, "outfill")) {
714
            if (*++spp == NULL)
715
                usage();
716
            ifr.ifr_data = (caddr_t) atoi(*spp);
717
            if (ioctl(skfd, SIOCSOUTFILL, &ifr) < 0) {
718
                fprintf(stderr, "SIOCSOUTFILL: %s\n", strerror(errno));
719
                goterr = 1;
720
            }
721
            spp++;
722
            continue;
723
        }
724
#endif
725
 
726
        if (!strcmp(*spp, "-broadcast")) {
727
            goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST);
728
            spp++;
729
            continue;
730
        }
731
        if (!strcmp(*spp, "broadcast")) {
732
            if (*++spp != NULL) {
733
                safe_strncpy(host, *spp, (sizeof host));
734
                if (ap->input(0, host, &sa) < 0) {
735
                    ap->herror(host);
736
                    goterr = 1;
737
                    spp++;
738
                    continue;
739
                }
740
                memcpy((char *) &ifr.ifr_broadaddr, (char *) &sa,
741
                       sizeof(struct sockaddr));
742
                if (ioctl(ap->fd, SIOCSIFBRDADDR, &ifr) < 0) {
743
                    fprintf(stderr, "SIOCSIFBRDADDR: %s\n",
744
                            strerror(errno));
745
                    goterr = 1;
746
                }
747
                spp++;
748
            }
749
            goterr |= set_flag(ifr.ifr_name, IFF_BROADCAST);
750
            continue;
751
        }
752
        if (!strcmp(*spp, "dstaddr")) {
753
            if (*++spp == NULL)
754
                usage();
755
            safe_strncpy(host, *spp, (sizeof host));
756
            if (ap->input(0, host, &sa) < 0) {
757
                ap->herror(host);
758
                goterr = 1;
759
                spp++;
760
                continue;
761
            }
762
            memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa,
763
                   sizeof(struct sockaddr));
764
            if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) {
765
                fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
766
                        strerror(errno));
767
                goterr = 1;
768
            }
769
            spp++;
770
            continue;
771
        }
772
        if (!strcmp(*spp, "netmask")) {
773
            if (*++spp == NULL || didnetmask)
774
                usage();
775
            safe_strncpy(host, *spp, (sizeof host));
776
            if (ap->input(0, host, &sa) < 0) {
777
                ap->herror(host);
778
                goterr = 1;
779
                spp++;
780
                continue;
781
            }
782
            didnetmask++;
783
            goterr = set_netmask(ap->fd, &ifr, &sa);
784
            spp++;
785
            continue;
786
        }
787
#ifdef HAVE_TXQUEUELEN
788
        if (!strcmp(*spp, "txqueuelen")) {
789
            if (*++spp == NULL)
790
                usage();
791
            ifr.ifr_qlen = strtoul(*spp, NULL, 0);
792
            if (ioctl(skfd, SIOCSIFTXQLEN, &ifr) < 0) {
793
                fprintf(stderr, "SIOCSIFTXQLEN: %s\n", strerror(errno));
794
                goterr = 1;
795
            }
796
            spp++;
797
            continue;
798
        }
799
#endif
800
 
801
        if (!strcmp(*spp, "mem_start")) {
802
            if (*++spp == NULL)
803
                usage();
804
            if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
805
                goterr = 1;
806
                continue;
807
            }
808
            ifr.ifr_map.mem_start = strtoul(*spp, NULL, 0);
809
            if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
810
                fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));
811
                goterr = 1;
812
            }
813
            spp++;
814
            continue;
815
        }
816
        if (!strcmp(*spp, "io_addr")) {
817
            if (*++spp == NULL)
818
                usage();
819
            if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
820
                goterr = 1;
821
                continue;
822
            }
823
            ifr.ifr_map.base_addr = strtol(*spp, NULL, 0);
824
            if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
825
                fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));
826
                goterr = 1;
827
            }
828
            spp++;
829
            continue;
830
        }
831
        if (!strcmp(*spp, "irq")) {
832
            if (*++spp == NULL)
833
                usage();
834
            if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
835
                goterr = 1;
836
                continue;
837
            }
838
            ifr.ifr_map.irq = atoi(*spp);
839
            if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
840
                fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));
841
                goterr = 1;
842
            }
843
            spp++;
844
            continue;
845
        }
846
        if (!strcmp(*spp, "-pointopoint")) {
847
            goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT);
848
            spp++;
849
            continue;
850
        }
851
        if (!strcmp(*spp, "pointopoint")) {
852
            if (*(spp + 1) != NULL) {
853
                spp++;
854
                safe_strncpy(host, *spp, (sizeof host));
855
                if (ap->input(0, host, &sa)) {
856
                    ap->herror(host);
857
                    goterr = 1;
858
                    spp++;
859
                    continue;
860
                }
861
                memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa,
862
                       sizeof(struct sockaddr));
863
                if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) {
864
                    fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
865
                            strerror(errno));
866
                    goterr = 1;
867
                }
868
            }
869
            goterr |= set_flag(ifr.ifr_name, IFF_POINTOPOINT);
870
            spp++;
871
            continue;
872
        };
873
 
874
        if (!strcmp(*spp, "hw")) {
875
            if (*++spp == NULL)
876
                usage();
877
            if ((hw = get_hwtype(*spp)) == NULL)
878
                usage();
879
            if (*++spp == NULL)
880
                usage();
881
            safe_strncpy(host, *spp, (sizeof host));
882
            if (hw->input(host, &sa) < 0) {
883
                fprintf(stderr, _("%s: invalid %s address.\n"), host, hw->name);
884
                goterr = 1;
885
                spp++;
886
                continue;
887
            }
888
            memcpy((char *) &ifr.ifr_hwaddr, (char *) &sa,
889
                   sizeof(struct sockaddr));
890
            if (ioctl(skfd, SIOCSIFHWADDR, &ifr) < 0) {
891
                fprintf(stderr, "SIOCSIFHWADDR: %s\n",
892
                        strerror(errno));
893
                goterr = 1;
894
            }
895
            spp++;
896
            continue;
897
        }
898
#if HAVE_AFINET6
899
        if (!strcmp(*spp, "add")) {
900
            if (*++spp == NULL)
901
                usage();
902
            if ((cp = strchr(*spp, '/'))) {
903
                prefix_len = atol(cp + 1);
904
                if ((prefix_len < 0) || (prefix_len > 128))
905
                    usage();
906
                *cp = 0;
907
            } else {
908
                prefix_len = 0;
909
            }
910
            safe_strncpy(host, *spp, (sizeof host));
911
            if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) {
912
                inet6_aftype.herror(host);
913
                goterr = 1;
914
                spp++;
915
                continue;
916
            }
917
            memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,
918
                   sizeof(struct in6_addr));
919
 
920
            fd = get_socket_for_af(AF_INET6);
921
            if (fd < 0) {
922
                fprintf(stderr, _("No support for INET6 on this system.\n"));
923
                goterr = 1;
924
                spp++;
925
                continue;
926
            }
927
            if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
928
                perror("SIOGIFINDEX");
929
                goterr = 1;
930
                spp++;
931
                continue;
932
            }
933
            ifr6.ifr6_ifindex = ifr.ifr_ifindex;
934
            ifr6.ifr6_prefixlen = prefix_len;
935
            if (ioctl(fd, SIOCSIFADDR, &ifr6) < 0) {
936
                perror("SIOCSIFADDR");
937
                goterr = 1;
938
            }
939
            spp++;
940
            continue;
941
        }
942
        if (!strcmp(*spp, "del")) {
943
            if (*++spp == NULL)
944
                usage();
945
            if ((cp = strchr(*spp, '/'))) {
946
                prefix_len = atol(cp + 1);
947
                if ((prefix_len < 0) || (prefix_len > 128))
948
                    usage();
949
                *cp = 0;
950
            } else {
951
                prefix_len = 0;
952
            }
953
            safe_strncpy(host, *spp, (sizeof host));
954
            if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) {
955
                inet6_aftype.herror(host);
956
                goterr = 1;
957
                spp++;
958
                continue;
959
            }
960
            memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,
961
                   sizeof(struct in6_addr));
962
 
963
            fd = get_socket_for_af(AF_INET6);
964
            if (fd < 0) {
965
                fprintf(stderr, _("No support for INET6 on this system.\n"));
966
                goterr = 1;
967
                spp++;
968
                continue;
969
            }
970
            if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
971
                perror("SIOGIFINDEX");
972
                goterr = 1;
973
                spp++;
974
                continue;
975
            }
976
            ifr6.ifr6_ifindex = ifr.ifr_ifindex;
977
            ifr6.ifr6_prefixlen = prefix_len;
978
#ifdef SIOCDIFADDR
979
            if (ioctl(fd, SIOCDIFADDR, &ifr6) < 0) {
980
                fprintf(stderr, "SIOCDIFADDR: %s\n",
981
                        strerror(errno));
982
                goterr = 1;
983
            }
984
#else
985
            fprintf(stderr, _("Address deletion not supported on this system.\n"));
986
#endif
987
            spp++;
988
            continue;
989
        }
990
        if (!strcmp(*spp, "tunnel")) {
991
            if (*++spp == NULL)
992
                usage();
993
            if ((cp = strchr(*spp, '/'))) {
994
                prefix_len = atol(cp + 1);
995
                if ((prefix_len < 0) || (prefix_len > 128))
996
                    usage();
997
                *cp = 0;
998
            } else {
999
                prefix_len = 0;
1000
            }
1001
            safe_strncpy(host, *spp, (sizeof host));
1002
            if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) {
1003
                inet6_aftype.herror(host);
1004
                goterr = 1;
1005
                spp++;
1006
                continue;
1007
            }
1008
            memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,
1009
                   sizeof(struct in6_addr));
1010
 
1011
            fd = get_socket_for_af(AF_INET6);
1012
            if (fd < 0) {
1013
                fprintf(stderr, _("No support for INET6 on this system.\n"));
1014
                goterr = 1;
1015
                spp++;
1016
                continue;
1017
            }
1018
            if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
1019
                perror("SIOGIFINDEX");
1020
                goterr = 1;
1021
                spp++;
1022
                continue;
1023
            }
1024
            ifr6.ifr6_ifindex = ifr.ifr_ifindex;
1025
            ifr6.ifr6_prefixlen = prefix_len;
1026
 
1027
            if (ioctl(fd, SIOCSIFDSTADDR, &ifr6) < 0) {
1028
                fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
1029
                        strerror(errno));
1030
                goterr = 1;
1031
            }
1032
            spp++;
1033
            continue;
1034
        }
1035
#endif
1036
 
1037
        /* If the next argument is a valid hostname, assume OK. */
1038
        safe_strncpy(host, *spp, (sizeof host));
1039
 
1040
        /* FIXME: sa is too small for INET6 addresses, inet6 should use that too,
1041
           broadcast is unexpected */
1042
        if (ap->getmask) {
1043
            switch (ap->getmask(host, &sa, NULL)) {
1044
            case -1:
1045
                usage();
1046
                break;
1047
            case 1:
1048
                if (didnetmask)
1049
                    usage();
1050
 
1051
                goterr = set_netmask(skfd, &ifr, &sa);
1052
                didnetmask++;
1053
                break;
1054
            }
1055
        }
1056
        if (ap->input(0, host, &sa) < 0) {
1057
            ap->herror(host);
1058
            usage();
1059
        }
1060
        memcpy((char *) &ifr.ifr_addr, (char *) &sa, sizeof(struct sockaddr));
1061
        {
1062
            int r = 0;           /* to shut gcc up */
1063
            switch (ap->af) {
1064
#if HAVE_AFINET
1065
            case AF_INET:
1066
                fd = get_socket_for_af(AF_INET);
1067
                if (fd < 0) {
1068
                    fprintf(stderr, _("No support for INET on this system.\n"));
1069
                    exit(1);
1070
                }
1071
                r = ioctl(fd, SIOCSIFADDR, &ifr);
1072
                break;
1073
#endif
1074
#if HAVE_AFECONET
1075
            case AF_ECONET:
1076
                fd = get_socket_for_af(AF_ECONET);
1077
                if (fd < 0) {
1078
                    fprintf(stderr, _("No support for ECONET on this system.\n"));
1079
                    exit(1);
1080
                }
1081
                r = ioctl(fd, SIOCSIFADDR, &ifr);
1082
                break;
1083
#endif
1084
            default:
1085
                fprintf(stderr,
1086
                _("Don't know how to set addresses for family %d.\n"), ap->af);
1087
                exit(1);
1088
            }
1089
            if (r < 0) {
1090
                perror("SIOCSIFADDR");
1091
                goterr = 1;
1092
            }
1093
        }
1094
       /*
1095
        * Don't do the set_flag() if the address is an alias with a - at the
1096
        * end, since it's deleted already! - Roman
1097
        *
1098
        * Should really use regex.h here, not sure though how well it'll go
1099
        * with the cross-platform support etc.
1100
        */
1101
        {
1102
            char *ptr;
1103
            short int found_colon = 0;
1104
            for (ptr = ifr.ifr_name; *ptr; ptr++ )
1105
                if (*ptr == ':') found_colon++;
1106
 
1107
            if (!(found_colon && *(ptr - 1) == '-'))
1108
                goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));
1109
        }
1110
 
1111
        spp++;
1112
    }
1113
 
1114
    return (goterr);
1115
}

powered by: WebSVN 2.1.0

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