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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [libnetworking/] [pppd/] [rtems-ppp.c] - Blame information for rev 284

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

Line No. Rev Author Line
1 30 unneback
/*
2
 * sys-bsd.c - System-dependent procedures for setting up
3
 * PPP interfaces on bsd-4.4-ish systems (including 386BSD, NetBSD, RTEMS, etc.)
4
 *
5
 * Copyright (c) 1989 Carnegie Mellon University.
6
 * Copyright (c) 1995 The Australian National University.
7
 * All rights reserved.
8
 *
9
 * Redistribution and use in source and binary forms are permitted
10
 * provided that the above copyright notice and this paragraph are
11
 * duplicated in all such forms and that any documentation,
12
 * advertising materials, and other materials related to such
13
 * distribution and use acknowledge that the software was developed
14
 * by Carnegie Mellon University and The Australian National University.
15
 * The names of the Universities may not be used to endorse or promote
16
 * products derived from this software without specific prior written
17
 * permission.
18
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21
 */
22
 
23
#ifndef lint
24
/* static char rcsid[] = "$Id: rtems-ppp.c,v 1.2 2001-09-27 12:01:57 chris Exp $"; */
25
/*      $NetBSD: sys-bsd.c,v 1.1.1.3 1997/09/26 18:53:04 christos Exp $ */
26
#endif
27
 
28
/*
29
 * TODO:
30
 */
31
 
32
#include <stdio.h>
33
#include <syslog.h>
34
#include <string.h>
35
#include <stdlib.h> 
36
#include <unistd.h>
37
#include <errno.h>
38
#include <fcntl.h>
39
#include <termios.h>
40
#include <signal.h>
41
#include <sys/ioctl.h>
42
#include <sys/types.h>
43
#include <sys/socket.h>
44
#include <sys/time.h>
45
#include <sys/stat.h>
46
#include <sys/param.h>
47
#ifdef NetBSD1_2
48
#include <util.h>
49
#endif
50
#ifdef PPP_FILTER
51
#include <net/bpf.h>
52
#endif
53
 
54
#include <net/if.h>
55
#include <net/ppp_defs.h>
56
#include <net/if_ppp.h>
57
#include <net/route.h>
58
#include <net/if_dl.h>
59
#include <netinet/in.h>
60
 
61
#if RTM_VERSION >= 3
62
#include <sys/param.h>
63
#if defined(NetBSD) && (NetBSD >= 199703)
64
#include <netinet/if_inarp.h>
65
#else   /* NetBSD 1.2D or later */
66
#include <netinet/if_ether.h>
67
#endif
68
#endif
69
 
70
#include "pppd.h"
71
#include "fsm.h"
72
#include "ipcp.h"
73
 
74
static int initdisc = -1;       /* Initial TTY discipline for ppp_fd */
75
static int initfdflags = -1;    /* Initial file descriptor flags for ppp_fd */
76
static int ppp_fd = -1;         /* fd which is set to PPP discipline */
77
static int rtm_seq;
78
 
79
static int restore_term;        /* 1 => we've munged the terminal */
80
static struct termios inittermios; /* Initial TTY termios */
81
static struct winsize wsinfo;   /* Initial window size info */
82
 
83
#if 0
84
static char *lock_file;         /* name of lock file created */
85
#endif
86
 
87
static int loop_slave = -1;
88
static int loop_master;
89
#if 0
90
static char loop_name[20];
91
#endif
92
 
93
static unsigned char inbuf[512]; /* buffer for chars read from loopback */
94
 
95
static int sockfd;              /* socket for doing interface ioctls */
96
 
97
static int if_is_up;            /* the interface is currently up */
98
static u_int32_t ifaddrs[2];    /* local and remote addresses we set */
99
static u_int32_t default_route_gateway; /* gateway addr for default route */
100
static u_int32_t proxy_arp_addr;        /* remote addr for proxy arp */
101
 
102
/* Prototypes for procedures local to this file. */
103
static int dodefaultroute __P((u_int32_t, int));
104
static int get_ether_addr __P((u_int32_t, struct sockaddr_dl *));
105
 
106
 
107
/*
108
 * sys_init - System-dependent initialization.
109
 */
110
void
111
sys_init()
112
{
113
    /* Get an internet socket for doing socket ioctl's on. */
114
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
115
        syslog(LOG_ERR, "Couldn't create IP socket: %m");
116
        die(1);
117
    }
118
}
119
 
120
/*
121
 * sys_cleanup - restore any system state we modified before exiting:
122
 * mark the interface down, delete default route and/or proxy arp entry.
123
 * This should call die() because it's called from die().
124
 */
125
void
126
sys_cleanup()
127
{
128
    struct ifreq ifr;
129
 
130
    if (if_is_up) {
131
        strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
132
        if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) >= 0
133
            && ((ifr.ifr_flags & IFF_UP) != 0)) {
134
            ifr.ifr_flags &= ~IFF_UP;
135
            ioctl(sockfd, SIOCSIFFLAGS, &ifr);
136
        }
137
    }
138
    if (ifaddrs[0] != 0)
139
        cifaddr(0, ifaddrs[0], ifaddrs[1]);
140
    if (default_route_gateway)
141
        cifdefaultroute(0, 0, default_route_gateway);
142
    if (proxy_arp_addr)
143
        cifproxyarp(0, proxy_arp_addr);
144
}
145
 
146
/*
147
 * sys_close - Clean up in a child process before execing.
148
 */
149
void
150
sys_close()
151
{
152
    close(sockfd);
153
    if (loop_slave >= 0) {
154
        close(loop_slave);
155
        close(loop_master);
156
    }
157
}
158
 
159
/*
160
 * sys_check_options - check the options that the user specified
161
 */
162
void
163
sys_check_options()
164
{
165
}
166
 
167
/*
168
 * ppp_available - check whether the system has any ppp interfaces
169
 * (in fact we check whether we can do an ioctl on ppp0).
170
 */
171
int
172
ppp_available()
173
{
174
    int s, ok;
175
    struct ifreq ifr;
176
    extern char *no_ppp_msg;
177
 
178
    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
179
        return 1;               /* can't tell */
180
 
181
    strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
182
    ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
183
    close(s);
184
 
185
    no_ppp_msg = "\
186
This system lacks kernel support for PPP.  To include PPP support\n\
187
in the kernel, please follow the steps detailed in the README.bsd\n\
188
file in the ppp-2.2 distribution.\n";
189
    return ok;
190
}
191
 
192
/*
193
 * establish_ppp - Turn the serial port into a ppp interface.
194
 */
195
void
196
establish_ppp(fd)
197
    int fd;
198
{
199
    int pppdisc = PPPDISC;
200
    int x;
201
 
202
    if (demand) {
203
        /*
204
         * Demand mode - prime the old ppp device to relinquish the unit.
205
         */
206
        if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) < 0) {
207
            syslog(LOG_ERR, "ioctl(transfer ppp unit): %m");
208
            die(1);
209
        }
210
    }
211
 
212
    /*
213
     * Save the old line discipline of fd, and set it to PPP.
214
     */
215
    if (ioctl(fd, TIOCGETD, &initdisc) < 0) {
216
        syslog(LOG_ERR, "ioctl(TIOCGETD): %m");
217
        die(1);
218
    }
219
    if (ioctl(fd, TIOCSETD, &pppdisc) < 0) {
220
        syslog(LOG_ERR, "ioctl(TIOCSETD): %m");
221
        die(1);
222
    }
223
 
224
    if (!demand) {
225
        /*
226
         * Find out which interface we were given.
227
         */
228
        if (ioctl(fd, PPPIOCGUNIT, &interfunit) < 0) {
229
            syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m");
230
            die(1);
231
        }
232
    } else {
233
        /*
234
         * Check that we got the same unit again.
235
         */
236
 
237
        if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
238
            syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m");
239
            die(1);
240
        }
241
        if (x != interfunit) {
242
            syslog(LOG_ERR, "transfer_ppp failed: wanted unit %d, got %d",
243
                   interfunit, x);
244
            die(1);
245
        }
246
        x = TTYDISC;
247
        ioctl(loop_slave, TIOCSETD, &x);
248
    }
249
 
250
    ppp_fd = fd;
251
 
252
    /*
253
     * Enable debug in the driver if requested.
254
     */
255
    if (kdebugflag) {
256
        if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
257
            syslog(LOG_WARNING, "ioctl (PPPIOCGFLAGS): %m");
258
        } else {
259
            x |= (kdebugflag & 0xFF) * SC_DEBUG;
260
            if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)
261
                syslog(LOG_WARNING, "ioctl(PPPIOCSFLAGS): %m")
262
;
263
        }
264
    }
265
 
266
    /*
267
     * Set device for non-blocking reads.
268
     */
269
#define fcntl(a)
270
 
271
 
272
/*    if ((initfdflags = fcntl(fd, F_GETFL)) == -1
273
        || fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
274
*/
275
/*      syslog(LOG_WARNING, "Couldn't set device to non-blocking mode: %m");
276
*/    /*}*/
277
}
278
 
279
/*
280
 * restore_loop - reattach the ppp unit to the loopback.
281
 */
282
void
283
restore_loop()
284
{
285
    int x;
286
 
287
    /*
288
     * Transfer the ppp interface back to the loopback.
289
     */
290
    if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) < 0) {
291
        syslog(LOG_ERR, "ioctl(transfer ppp unit): %m");
292
        die(1);
293
    }
294
    x = PPPDISC;
295
    if (ioctl(loop_slave, TIOCSETD, &x) < 0) {
296
        syslog(LOG_ERR, "ioctl(TIOCSETD): %m");
297
        die(1);
298
    }
299
 
300
    /*
301
     * Check that we got the same unit again.
302
     */
303
    if (ioctl(loop_slave, PPPIOCGUNIT, &x) < 0) {
304
        syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m");
305
        die(1);
306
    }
307
    if (x != interfunit) {
308
        syslog(LOG_ERR, "transfer_ppp failed: wanted unit %d, got %d",
309
               interfunit, x);
310
        die(1);
311
    }
312
    ppp_fd = loop_slave;
313
}
314
 
315
 
316
/*
317
 * disestablish_ppp - Restore the serial port to normal operation.
318
 * This shouldn't call die() because it's called from die().
319
 */
320
void
321
disestablish_ppp(fd)
322
    int fd;
323
{
324
    /* Reset non-blocking mode on fd. */
325
/*    if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) < 0)*/
326
/*      syslog(LOG_WARNING, "Couldn't restore device fd flags: %m");
327
*/    initfdflags = -1;
328
 
329
    /* Restore old line discipline. */
330
    if (initdisc >= 0 && ioctl(fd, TIOCSETD, &initdisc) < 0)
331
/*      syslog(LOG_ERR, "ioctl(TIOCSETD): %m");
332
*/    initdisc = -1;
333
 
334
    if (fd == ppp_fd)
335
        ppp_fd = -1;
336
}
337
 
338
/*
339
 * Check whether the link seems not to be 8-bit clean.
340
 */
341
void
342
clean_check()
343
{
344
    int x;
345
    char *s;
346
 
347
    if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
348
        s = NULL;
349
        switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
350
        case SC_RCV_B7_0:
351
            s = "bit 7 set to 1";
352
            break;
353
        case SC_RCV_B7_1:
354
            s = "bit 7 set to 0";
355
            break;
356
        case SC_RCV_EVNP:
357
            s = "odd parity";
358
            break;
359
        case SC_RCV_ODDP:
360
            s = "even parity";
361
            break;
362
        }
363
/*      if (s != NULL) {
364
            syslog(LOG_WARNING, "Serial link is not 8-bit clean:");
365
            syslog(LOG_WARNING, "All received characters had %s", s);
366
        }
367
*/    }
368
}
369
 
370
/*
371
 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
372
 * at the requested speed, etc.  If `local' is true, set CLOCAL
373
 * regardless of whether the modem option was specified.
374
 *
375
 * For *BSD, we assume that speed_t values numerically equal bits/second.
376
 */
377
void
378
set_up_tty(fd, local)
379
    int fd, local;
380
{
381
    struct termios tios;
382
 
383
    if (tcgetattr(fd, &tios) < 0) {
384
        syslog(LOG_ERR, "tcgetattr: %m");
385
        die(1);
386
    }
387
 
388
    if (!restore_term) {
389
        inittermios = tios;
390
        ioctl(fd, TIOCGWINSZ, &wsinfo);
391
    }
392
 
393
    tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
394
    if (crtscts > 0 && !local)
395
        tios.c_cflag |= CRTSCTS;
396
    else if (crtscts < 0)
397
        tios.c_cflag &= ~CRTSCTS;
398
 
399
    tios.c_cflag |= CS8 | CREAD | HUPCL;
400
    if (local || !modem)
401
        tios.c_cflag |= CLOCAL;
402
    tios.c_iflag = IGNBRK | IGNPAR;
403
    tios.c_oflag = 0;
404
    tios.c_lflag = 0;
405
    tios.c_cc[VMIN] = 1;
406
    tios.c_cc[VTIME] = 0;
407
 
408
    if (crtscts == -2) {
409
        tios.c_iflag |= IXON | IXOFF;
410
        tios.c_cc[VSTOP] = 0x13;
411
        tios.c_cc[VSTART] = 0x11;
412
    }
413
 
414
    if (inspeed) {
415
        cfsetospeed(&tios, inspeed);
416
        cfsetispeed(&tios, inspeed);
417
    } else {
418
        inspeed = cfgetospeed(&tios);
419
        /*
420
         * We can't proceed if the serial port speed is 0,
421
         * since that implies that the serial port is disabled.
422
         */
423
        if (inspeed == 0) {
424
            syslog(LOG_ERR, "Baud rate for %s is 0; need explicit baud rate",
425
                   devnam);
426
            die(1);
427
        }
428
    }
429
/*    baud_rate = 9600;*/
430
/* na razie wpisujemy na twardo*/
431
 
432
    if (tcsetattr(fd, TCSANOW, &tios) < 0) {
433
        syslog(LOG_ERR, "tcsetattr: %m");
434
        die(1);
435
    }
436
 
437
    restore_term = 1;
438
}
439
 
440
/*
441
 * restore_tty - restore the terminal to the saved settings.
442
 */
443
void
444
restore_tty(fd)
445
    int fd;
446
{
447
/*    if (restore_term) {
448
        if (!default_device) {
449
*/          /*
450
             * Turn off echoing, because otherwise we can get into
451
             * a loop with the tty and the modem echoing to each other.
452
             * We presume we are the sole user of this tty device, so
453
             * when we close it, it will revert to its defaults anyway.
454
             */
455
/*          inittermios.c_lflag &= ~(ECHO | ECHONL);
456
        }
457
        if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
458
            if (errno != ENXIO)
459
                syslog(LOG_WARNING, "tcsetattr: %m");
460
        ioctl(fd, TIOCSWINSZ, &wsinfo);
461
        restore_term = 0;
462
    }
463
*/}
464
 
465
/*
466
 *  - control the DTR line on the serial port.
467
 * This is called from die(), so it shouldn't call die().
468
 */
469
void
470
setdtr(fd, on)
471
int fd, on;
472
{
473
    int modembits = TIOCM_DTR;
474
 
475
    ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
476
}
477
 
478
 
479
/*
480
 * open_ppp_loopback - open the device we use for getting
481
 * packets in demand mode, and connect it to a ppp interface.
482
 * Here we use a pty.
483
 */
484
void
485
open_ppp_loopback()
486
{
487
 
488
}
489
 
490
 
491
/*
492
 * output - Output PPP packet.
493
 */
494
void
495
output(unit, p, len)
496
    int unit;
497
    u_char *p;
498
    int len;
499
{
500
    if (debug);
501
        syslog(LOG_DEBUG, "sent %d bytes ", len );
502
 
503
    if (write(ttyfd, p, len) < 0) {
504
/*      if (errno != EIO)
505
            syslog(LOG_ERR, "write: %m");
506
*/    }
507
}
508
 
509
extern int rtems_bsdnet_microseconds_per_tick;
510
#include <rtems.h>
511
#include <rtems/rtems_bsdnet.h>
512
/*
513
 * wait_input - wait until there is data available on ttyfd,
514
 * for the length of time specified by *timo (indefinite
515
 * if timo is NULL).
516
 */
517
 
518
/*
519
 * wait_loop_output - wait until there is data available on the
520
 * loopback, for the length of time specified by *timo (indefinite
521
 * if timo is NULL).
522
 */
523
void
524
wait_loop_output(timo)
525
    struct timeval *timo;
526
{
527
/*
528
    fd_set ready;
529
    int n;
530
*/
531
 
532
/*    FD_ZERO(&ready);
533
    FD_SET(loop_master, &ready);
534
    n = select(loop_master + 1, &ready, NULL, &ready, timo);
535
    if (n < 0 && errno != EINTR) {
536
*/
537
/*      syslog(LOG_ERR, "select: %m");*/
538
/*      die(1);
539
    }
540
*/
541
}
542
 
543
 
544
/*
545
 * wait_time - wait for a given length of time or until a
546
 * signal is received.
547
 */
548
void
549
wait_time(timo)
550
    struct timeval *timo;
551
{
552
  rtems_status_code status;
553
  rtems_interval    ticks;
554
 
555
  ticks =
556
     (timo->tv_sec*1000000+timo->tv_usec)/rtems_bsdnet_microseconds_per_tick;
557
  status = rtems_task_wake_after( ticks );
558
}
559
 
560
 
561
/*
562
 * read_packet - get a PPP packet from the serial device.
563
 */
564
int
565
read_packet(buf)
566
    u_char *buf;
567
{
568
    int len;
569
 
570
    if ((len = read(ttyfd, buf, PPP_MTU + PPP_HDRLEN)) < 0) {
571
        if (errno == EWOULDBLOCK || errno == EINTR || errno == ETIMEDOUT)
572
            return -1;
573
        syslog(LOG_ERR, "read: %m");
574
    }
575
    return len;
576
}
577
 
578
 
579
/*
580
 * get_loop_output - read characters from the loopback, form them
581
 * into frames, and detect when we want to bring the real link up.
582
 * Return value is 1 if we need to bring up the link, 0 otherwise.
583
 */
584
int
585
get_loop_output()
586
{
587
    int rv = 0;
588
    int n;
589
 
590
    while ((n = read(loop_master, inbuf, sizeof(inbuf))) >= 0) {
591
        if (loop_chars(inbuf, n))
592
            rv = 1;
593
    }
594
 
595
    if (n == 0) {
596
        syslog(LOG_ERR, "eof on loopback");
597
        die(1);
598
    } else if (errno != EWOULDBLOCK){
599
        syslog(LOG_ERR, "read from loopback: %m");
600
        die(1);
601
    }
602
 
603
    return rv;
604
}
605
 
606
 
607
/*
608
 * ppp_send_config - configure the transmit characteristics of
609
 * the ppp interface.
610
 */
611
void
612
ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
613
    int unit, mtu;
614
    u_int32_t asyncmap;
615
    int pcomp, accomp;
616
{
617
    u_int x;
618
    struct ifreq ifr;
619
 
620
    strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
621
    ifr.ifr_mtu = mtu;
622
    if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0) {
623
                syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m");
624
                quit();
625
    }
626
 
627
    if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
628
        syslog(LOG_ERR, "ioctl(PPPIOCSASYNCMAP): %m");
629
        quit();
630
    }
631
 
632
    if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
633
        syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
634
        quit();
635
    }
636
    x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT;
637
    x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC;
638
    if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
639
        syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
640
        quit();
641
    }
642
}
643
 
644
 
645
/*
646
 * ppp_set_xaccm - set the extended transmit ACCM for the interface.
647
 */
648
void
649
ppp_set_xaccm(unit, accm)
650
    int unit;
651
    ext_accm accm;
652
{
653
    if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY)
654
        /*syslog(LOG_WARNING, "ioctl(set extended ACCM): %m")*/;
655
}
656
 
657
 
658
/*
659
 * ppp_recv_config - configure the receive-side characteristics of
660
 * the ppp interface.
661
 */
662
void
663
ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
664
    int unit, mru;
665
    u_int32_t asyncmap;
666
    int pcomp, accomp;
667
{
668
/*
669
    int x;
670
*/
671
 
672
/*    if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
673
        syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %m");
674
        quit();
675
    }
676
*/
677
/*    if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
678
        syslog(LOG_ERR, "ioctl(PPPIOCSRASYNCMAP): %m");
679
        quit();
680
    }
681
*/
682
/*    if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
683
        syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
684
        quit();
685
    }
686
*/
687
/*    x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC;
688
    if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
689
        syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
690
        quit();
691
    }
692
*/
693
}
694
 
695
/*
696
 * ccp_test - ask kernel whether a given compression method
697
 * is acceptable for use.  Returns 1 if the method and parameters
698
 * are OK, 0 if the method is known but the parameters are not OK
699
 * (e.g. code size should be reduced), or -1 if the method is unknown.
700
 */
701
int
702
ccp_test(unit, opt_ptr, opt_len, for_transmit)
703
    int unit, opt_len, for_transmit;
704
    u_char *opt_ptr;
705
{
706
    struct ppp_option_data data;
707
 
708
    data.ptr = opt_ptr;
709
    data.length = opt_len;
710
    data.transmit = for_transmit;
711
    if (ioctl(ttyfd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
712
        return 1;
713
    return (errno == ENOBUFS)? 0: -1;
714
}
715
 
716
/*
717
 * ccp_flags_set - inform kernel about the current state of CCP.
718
 */
719
void
720
ccp_flags_set(unit, isopen, isup)
721
    int unit, isopen, isup;
722
{
723
    int x;
724
 
725
    if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
726
/*      syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
727
*/      return;
728
    }
729
    x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN;
730
    x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP;
731
    if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)
732
/*      syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m")*/;
733
}
734
 
735
/*
736
 * ccp_fatal_error - returns 1 if decompression was disabled as a
737
 * result of an error detected after decompression of a packet,
738
 * 0 otherwise.  This is necessary because of patent nonsense.
739
 */
740
int
741
ccp_fatal_error(unit)
742
    int unit;
743
{
744
    int x;
745
 
746
    if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
747
/*      syslog(LOG_ERR, "ioctl(PPPIOCGFLAGS): %m");*/
748
        return 0;
749
    }
750
    return x & SC_DC_FERROR;
751
}
752
 
753
/*
754
 * get_idle_time - return how long the link has been idle.
755
 */
756
int
757
get_idle_time(u, ip)
758
    int u;
759
    struct ppp_idle *ip;
760
{
761
    return ioctl(ppp_fd, PPPIOCGIDLE, ip) >= 0;
762
}
763
 
764
 
765
#ifdef PPP_FILTER
766
/*
767
 * set_filters - transfer the pass and active filters to the kernel.
768
 */
769
int
770
set_filters(pass, active)
771
    struct bpf_program *pass, *active;
772
{
773
    int ret = 1;
774
 
775
    if (pass->bf_len > 0) {
776
        if (ioctl(ppp_fd, PPPIOCSPASS, pass) < 0) {
777
            syslog(LOG_ERR, "Couldn't set pass-filter in kernel: %m");
778
            ret = 0;
779
        }
780
    }
781
    if (active->bf_len > 0) {
782
        if (ioctl(ppp_fd, PPPIOCSACTIVE, active) < 0) {
783
            syslog(LOG_ERR, "Couldn't set active-filter in kernel: %m");
784
            ret = 0;
785
        }
786
    }
787
    return ret;
788
}
789
#endif
790
 
791
/*
792
 * sifvjcomp - config tcp header compression
793
 */
794
int
795
sifvjcomp(u, vjcomp, cidcomp, maxcid)
796
    int u, vjcomp, cidcomp, maxcid;
797
{
798
    u_int x;
799
 
800
    if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
801
        syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m");
802
        return 0;
803
    }
804
    x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP;
805
    x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID;
806
    if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
807
        syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
808
        return 0;
809
    }
810
    if (vjcomp && ioctl(ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
811
        syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m");
812
        return 0;
813
    }
814
    return 1;
815
}
816
 
817
/*
818
 * sifup - Config the interface up and enable IP packets to pass.
819
 */
820
int
821
sifup(u)
822
    int u;
823
{
824
    struct ifreq ifr;
825
 
826
    strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
827
    if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
828
        syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
829
        return 0;
830
    }
831
    ifr.ifr_flags |= IFF_UP;
832
    if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
833
        syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
834
        return 0;
835
    }
836
    if_is_up = 1;
837
    return 1;
838
}
839
 
840
/*
841
 * sifnpmode - Set the mode for handling packets for a given NP.
842
 */
843
int
844
sifnpmode(u, proto, mode)
845
    int u;
846
    int proto;
847
    enum NPmode mode;
848
{
849
    struct npioctl npi;
850
 
851
    npi.protocol = proto;
852
    npi.mode = mode;
853
    if (ioctl(ppp_fd, PPPIOCSNPMODE, &npi) < 0) {
854
/*      syslog(LOG_ERR, "ioctl(set NP %d mode to %d): %m", proto, mode);*/
855
        return 0;
856
    }
857
    return 1;
858
}
859
 
860
/*
861
 * sifdown - Config the interface down and disable IP.
862
 */
863
int
864
sifdown(u)
865
    int u;
866
{
867
    struct ifreq ifr;
868
    int rv;
869
    struct npioctl npi;
870
 
871
    rv = 1;
872
    npi.protocol = PPP_IP;
873
    npi.mode = NPMODE_ERROR;
874
    ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi);
875
    /* ignore errors, because ppp_fd might have been closed by now. */
876
 
877
    strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
878
    if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
879
/*      syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");*/
880
        rv = 0;
881
    } else {
882
        ifr.ifr_flags &= ~IFF_UP;
883
        if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
884
/*          syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");*/
885
            rv = 0;
886
        } else
887
            if_is_up = 0;
888
    }
889
    return rv;
890
}
891
 
892
/*
893
 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
894
 * if it exists.
895
 */
896
#define SET_SA_FAMILY(addr, family)             \
897
    BZERO((char *) &(addr), sizeof(addr));      \
898
    addr.sa_family = (family);                  \
899
    addr.sa_len = sizeof(addr);
900
 
901
/*
902
 * sifaddr - Config the interface IP addresses and netmask.
903
 */
904
int
905
sifaddr(u, o, h, m)
906
    int u;
907
    u_int32_t o, h, m;
908
{
909
    struct ifaliasreq ifra;
910
    struct ifreq ifr;
911
/*      struct sockaddr_in address;
912
        struct sockaddr_in netmask;
913
        struct sockaddr_in broadcast;
914
 
915
   strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
916
        memset (&address, '\0', sizeof address);
917
        address.sin_len = sizeof address;
918
        address.sin_family = AF_INET;
919
        address.sin_addr.s_addr =  o;
920
        memcpy (&ifr.ifr_addr, &address, sizeof address);
921
   if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifr) < 0) {
922
        if (errno != EADDRNOTAVAIL)
923
            syslog(LOG_WARNING, "Couldn't remove interface address: %m");
924
    }
925
 
926
        if (ioctl (sockfd, SIOCSIFADDR, &ifr) < 0)
927
                syslog(LOG_ERR, "Can't set  address: ");
928
 
929
 
930
        memset (&netmask, '\0', sizeof netmask);
931
        netmask.sin_len = sizeof netmask;
932
        netmask.sin_family = AF_INET;
933
        netmask.sin_addr.s_addr =   m ;
934
        memcpy (&ifr.ifr_addr, &netmask, sizeof netmask);
935
 
936
        if (ioctl (sockfd, SIOCSIFNETMASK, &ifr) < 0)
937
                        syslog(LOG_ERR,"Can't set  netmask: ");
938
        memset (&broadcast, '\0', sizeof broadcast);
939
        broadcast.sin_len = sizeof broadcast;
940
        broadcast.sin_family = AF_INET;
941
        broadcast.sin_addr.s_addr = h;
942
        memcpy (&ifr.ifr_broadaddr, &broadcast, sizeof broadcast);
943
        if (ioctl (sockfd, SIOCSIFBRDADDR, &ifr) < 0)
944
                syslog(LOG_ERR,"Can't set  broadcast address:  ");
945
 
946
*/
947
   strncpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
948
    SET_SA_FAMILY(ifra.ifra_addr, AF_INET);
949
    ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o;
950
    SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);
951
    ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h;
952
    if (m != 0) {
953
        SET_SA_FAMILY(ifra.ifra_mask, AF_INET);
954
        ((struct sockaddr_in *) &ifra.ifra_mask)->sin_addr.s_addr = m;
955
    } else
956
        BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));
957
    BZERO(&ifr, sizeof(ifr));
958
    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
959
 
960
    if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifr) < 0) {
961
/*      if (errno != EADDRNOTAVAIL)
962
            syslog(LOG_WARNING, "Couldn't remove interface address: %m");
963
*/
964
    }
965
 
966
 
967
 
968
    if (ioctl(sockfd, SIOCAIFADDR, (caddr_t) &ifra) < 0) {
969
        if (errno != EEXIST) {
970
            syslog(LOG_ERR, "Couldn't set interface address: %m");
971
            return 0;
972
        }
973
/*      syslog(LOG_WARNING,
974
               "Couldn't set interface address: Address %s already exists",
975
                ip_ntoa(o));
976
*/    }
977
    ifaddrs[0] = o;
978
    ifaddrs[1] = h;
979
    return 1;
980
}
981
 
982
/*
983
 * cifaddr - Clear the interface IP addresses, and delete routes
984
 * through the interface if possible.
985
 */
986
int
987
cifaddr(u, o, h)
988
    int u;
989
    u_int32_t o, h;
990
{
991
    struct ifaliasreq ifra;
992
 
993
    ifaddrs[0] = 0;
994
    strncpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
995
    SET_SA_FAMILY(ifra.ifra_addr, AF_INET);
996
    ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o;
997
    SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);
998
    ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h;
999
    BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));
1000
    if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifra) < 0) {
1001
/*      if (errno != EADDRNOTAVAIL)
1002
            syslog(LOG_WARNING, "Couldn't delete interface address: %m");
1003
*/      return 0;
1004
    }
1005
    return 1;
1006
}
1007
 
1008
/*
1009
 * sifdefaultroute - assign a default route through the address given.
1010
 */
1011
int
1012
sifdefaultroute(u, l, g)
1013
    int u;
1014
    u_int32_t l, g;
1015
{
1016
    return dodefaultroute(g, 's');
1017
}
1018
 
1019
/*
1020
 * cifdefaultroute - delete a default route through the address given.
1021
 */
1022
int
1023
cifdefaultroute(u, l, g)
1024
    int u;
1025
    u_int32_t l, g;
1026
{
1027
    return dodefaultroute(g, 'c');
1028
}
1029
 
1030
/*
1031
 * dodefaultroute - talk to a routing socket to add/delete a default route.
1032
 */
1033
static int
1034
dodefaultroute(g, cmd)
1035
    u_int32_t g;
1036
    int cmd;
1037
{
1038
/*    int routes;*/
1039
 
1040
        struct sockaddr_in address;
1041
        struct sockaddr_in netmask;
1042
        /* struct sockaddr_in broadcast; */
1043
        struct sockaddr_in gateway;
1044
 
1045
/*    struct {
1046
        struct rt_msghdr        hdr;
1047
        struct sockaddr_in      dst;
1048
        struct sockaddr_in      gway;
1049
        struct sockaddr_in      mask;
1050
    } rtmsg;
1051
*/
1052
/*    if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
1053
        syslog(LOG_ERR, "Couldn't %s default route: socket: %m",
1054
               cmd=='s'? "add": "delete");
1055
        return 0;
1056
    }
1057
*/
1058
        memset((void *) &address, 0, sizeof(address));
1059
        address.sin_len = sizeof address;
1060
        address.sin_family = AF_INET;
1061
        address.sin_addr.s_addr = INADDR_ANY;
1062
 
1063
        memset((void *) &netmask, 0, sizeof(netmask));
1064
        netmask.sin_len = sizeof netmask;
1065
        netmask.sin_addr.s_addr = INADDR_ANY;
1066
        netmask.sin_family = AF_INET;
1067
 
1068
 
1069
        if (cmd=='s')
1070
        {
1071
        memset((void *) &gateway, 0, sizeof(gateway));
1072
        gateway.sin_len = sizeof gateway;
1073
        gateway.sin_family = AF_INET;
1074
        gateway.sin_addr.s_addr =  htons(g)  ;
1075
 
1076
 
1077
                if (rtems_bsdnet_rtrequest (RTM_ADD,
1078
                      (struct sockaddr *)&address,
1079
                      (struct sockaddr *)&gateway,
1080
                      (struct sockaddr *)&netmask,
1081
                      (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL) < 0)
1082
                                                                                        /*syslog(LOG_WARNING,"Can't set default route: ")*/
1083
                                                                                        ;
1084
        }
1085
        else
1086
        {
1087
        memset((void *) &gateway, 0, sizeof(gateway));
1088
        gateway.sin_len = sizeof gateway;
1089
        gateway.sin_family = AF_INET;
1090
        gateway.sin_addr.s_addr =  INADDR_ANY;
1091
 
1092
                if  (rtems_bsdnet_rtrequest (RTM_DELETE,
1093
                  (struct sockaddr *)&address,
1094
                  (struct sockaddr *)&gateway,
1095
                  (struct sockaddr *)&netmask,
1096
                  (RTF_UP  | RTF_STATIC), NULL) < 0)
1097
                                                                                        /*syslog(LOG_WARNING,"Can't set default route: ")*/
1098
                                                                                        ;
1099
        }
1100
 
1101
/*
1102
    rtmsg.hdr.rtm_type = cmd == 's'? RTM_ADD: RTM_DELETE;
1103
    rtmsg.hdr.rtm_flags = RTF_UP | RTF_GATEWAY;
1104
    rtmsg.hdr.rtm_version = RTM_VERSION;
1105
    rtmsg.hdr.rtm_seq = ++rtm_seq;
1106
    rtmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
1107
    rtmsg.dst.sin_len = sizeof(rtmsg.dst);
1108
    rtmsg.dst.sin_family = AF_INET;
1109
    rtmsg.gway.sin_len = sizeof(rtmsg.gway);
1110
    rtmsg.gway.sin_family = AF_INET;
1111
    rtmsg.gway.sin_addr.s_addr = g;
1112
    rtmsg.mask.sin_len = sizeof(rtmsg.dst);
1113
    rtmsg.mask.sin_family = AF_INET;
1114
 
1115
    rtmsg.hdr.rtm_msglen = sizeof(rtmsg);
1116
 
1117
 
1118
    if (write(routes, &rtmsg, sizeof(rtmsg)) < 0) {
1119
        syslog(LOG_ERR, "Couldn't %s default route: %m",
1120
               cmd=='s'? "add": "delete");
1121
        close(routes);
1122
        return 0;
1123
    }
1124
 
1125
    close(routes);*/
1126
   default_route_gateway = (cmd == 's')? g: 0;
1127
    return 1;
1128
}
1129
 
1130
#if RTM_VERSION >= 3
1131
 
1132
/*
1133
 * sifproxyarp - Make a proxy ARP entry for the peer.
1134
 */
1135
static struct {
1136
    struct rt_msghdr            hdr;
1137
    struct sockaddr_inarp       dst;
1138
    struct sockaddr_dl          hwa;
1139
    char                        extra[128];
1140
} arpmsg;
1141
 
1142
static int arpmsg_valid;
1143
 
1144
int
1145
sifproxyarp(unit, hisaddr)
1146
    int unit;
1147
    u_int32_t hisaddr;
1148
{
1149
    int routes;
1150
        return 0;
1151
 
1152
 
1153
    /*
1154
     * Get the hardware address of an interface on the same subnet
1155
     * as our local address.
1156
     */
1157
    memset(&arpmsg, 0, sizeof(arpmsg));
1158
    if (!get_ether_addr(hisaddr, &arpmsg.hwa)) {
1159
/*      syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP");
1160
*/      return 0;
1161
    }
1162
 
1163
    if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
1164
/*      syslog(LOG_ERR, "Couldn't add proxy arp entry: socket: %m");
1165
*/      return 0;
1166
    }
1167
 
1168
    arpmsg.hdr.rtm_type = RTM_ADD;
1169
    arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC;
1170
    arpmsg.hdr.rtm_version = RTM_VERSION;
1171
    arpmsg.hdr.rtm_seq = ++rtm_seq;
1172
    arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
1173
    arpmsg.hdr.rtm_inits = RTV_EXPIRE;
1174
    arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp);
1175
    arpmsg.dst.sin_family = AF_INET;
1176
    arpmsg.dst.sin_addr.s_addr = hisaddr;
1177
    arpmsg.dst.sin_other = SIN_PROXY;
1178
 
1179
    arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg
1180
        + arpmsg.hwa.sdl_len;
1181
    if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) {
1182
/*      syslog(LOG_ERR, "Couldn't add proxy arp entry: %m");
1183
*/      close(routes);
1184
        return 0;
1185
    }
1186
 
1187
    close(routes);
1188
    arpmsg_valid = 1;
1189
    proxy_arp_addr = hisaddr;
1190
    return 1;
1191
}
1192
 
1193
/*
1194
 * cifproxyarp - Delete the proxy ARP entry for the peer.
1195
 */
1196
int
1197
cifproxyarp(unit, hisaddr)
1198
    int unit;
1199
    u_int32_t hisaddr;
1200
{
1201
    int routes;
1202
 
1203
    if (!arpmsg_valid)
1204
        return 0;
1205
    arpmsg_valid = 0;
1206
 
1207
    arpmsg.hdr.rtm_type = RTM_DELETE;
1208
    arpmsg.hdr.rtm_seq = ++rtm_seq;
1209
 
1210
    if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
1211
        syslog(LOG_ERR, "Couldn't delete proxy arp entry: socket: %m");
1212
        return 0;
1213
    }
1214
 
1215
    if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) {
1216
        syslog(LOG_ERR, "Couldn't delete proxy arp entry: %m");
1217
        close(routes);
1218
        return 0;
1219
    }
1220
 
1221
    close(routes);
1222
    proxy_arp_addr = 0;
1223
    return 1;
1224
}
1225
 
1226
#else   /* RTM_VERSION */
1227
 
1228
/*
1229
 * sifproxyarp - Make a proxy ARP entry for the peer.
1230
 */
1231
int
1232
sifproxyarp(unit, hisaddr)
1233
    int unit;
1234
    u_int32_t hisaddr;
1235
{
1236
    struct arpreq arpreq;
1237
    struct {
1238
        struct sockaddr_dl      sdl;
1239
        char                    space[128];
1240
    } dls;
1241
 
1242
    BZERO(&arpreq, sizeof(arpreq));
1243
 
1244
    /*
1245
     * Get the hardware address of an interface on the same subnet
1246
     * as our local address.
1247
     */
1248
    if (!get_ether_addr(hisaddr, &dls.sdl)) {
1249
        syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP");
1250
        return 0;
1251
    }
1252
 
1253
    arpreq.arp_ha.sa_len = sizeof(struct sockaddr);
1254
    arpreq.arp_ha.sa_family = AF_UNSPEC;
1255
    BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen);
1256
    SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1257
    ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
1258
    arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1259
    if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1260
        syslog(LOG_ERR, "Couldn't add proxy arp entry: %m");
1261
        return 0;
1262
    }
1263
 
1264
    proxy_arp_addr = hisaddr;
1265
    return 1;
1266
}
1267
 
1268
/*
1269
 * cifproxyarp - Delete the proxy ARP entry for the peer.
1270
 */
1271
int
1272
cifproxyarp(unit, hisaddr)
1273
    int unit;
1274
    u_int32_t hisaddr;
1275
{
1276
    struct arpreq arpreq;
1277
 
1278
    BZERO(&arpreq, sizeof(arpreq));
1279
    SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1280
    ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
1281
    if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1282
        syslog(LOG_WARNING, "Couldn't delete proxy arp entry: %m");
1283
        return 0;
1284
    }
1285
    proxy_arp_addr = 0;
1286
    return 1;
1287
}
1288
#endif  /* RTM_VERSION */
1289
 
1290
 
1291
/*
1292
 * get_ether_addr - get the hardware address of an interface on the
1293
 * the same subnet as ipaddr.
1294
 */
1295
#define MAX_IFS         32
1296
 
1297
static int
1298
get_ether_addr(ipaddr, hwaddr)
1299
    u_int32_t ipaddr;
1300
    struct sockaddr_dl *hwaddr;
1301
{
1302
    struct ifreq *ifr, *ifend, *ifp;
1303
    u_int32_t ina, mask;
1304
    struct sockaddr_dl *dla;
1305
    struct ifreq ifreq;
1306
    struct ifconf ifc;
1307
    struct ifreq ifs[MAX_IFS];
1308
 
1309
    ifc.ifc_len = sizeof(ifs);
1310
    ifc.ifc_req = ifs;
1311
    if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
1312
        syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m");
1313
        return 0;
1314
    }
1315
 
1316
    /*
1317
     * Scan through looking for an interface with an Internet
1318
     * address on the same subnet as `ipaddr'.
1319
     */
1320
    ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1321
    for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *)
1322
                ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) {
1323
        if (ifr->ifr_addr.sa_family == AF_INET) {
1324
            ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
1325
            strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1326
            /*
1327
             * Check that the interface is up, and not point-to-point
1328
             * or loopback.
1329
             */
1330
            if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
1331
                continue;
1332
            if ((ifreq.ifr_flags &
1333
                 (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
1334
                 != (IFF_UP|IFF_BROADCAST))
1335
                continue;
1336
            /*
1337
             * Get its netmask and check that it's on the right subnet.
1338
             */
1339
            if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
1340
                continue;
1341
            mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;
1342
            if ((ipaddr & mask) != (ina & mask))
1343
                continue;
1344
 
1345
            break;
1346
        }
1347
    }
1348
 
1349
    if (ifr >= ifend)
1350
        return 0;
1351
    syslog(LOG_INFO, "found interface %s for proxy arp", ifr->ifr_name);
1352
 
1353
    /*
1354
     * Now scan through again looking for a link-level address
1355
     * for this interface.
1356
     */
1357
    ifp = ifr;
1358
    for (ifr = ifc.ifc_req; ifr < ifend; ) {
1359
        if (strcmp(ifp->ifr_name, ifr->ifr_name) == 0
1360
            && ifr->ifr_addr.sa_family == AF_LINK) {
1361
            /*
1362
             * Found the link-level address - copy it out
1363
             */
1364
            dla = (struct sockaddr_dl *) &ifr->ifr_addr;
1365
            BCOPY(dla, hwaddr, dla->sdl_len);
1366
            return 1;
1367
        }
1368
        ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len);
1369
    }
1370
 
1371
    return 0;
1372
}
1373
 
1374
/*
1375
 * Return user specified netmask, modified by any mask we might determine
1376
 * for address `addr' (in network byte order).
1377
 * Here we scan through the system's list of interfaces, looking for
1378
 * any non-point-to-point interfaces which might appear to be on the same
1379
 * network as `addr'.  If we find any, we OR in their netmask to the
1380
 * user-specified netmask.
1381
 */
1382
u_int32_t
1383
GetMask(addr)
1384
    u_int32_t addr;
1385
{
1386
    u_int32_t mask, nmask, ina;
1387
    struct ifreq *ifr, *ifend, ifreq;
1388
    struct ifconf ifc;
1389
    struct ifreq ifs[MAX_IFS];
1390
 
1391
    addr = ntohl(addr);
1392
    if (IN_CLASSA(addr))        /* determine network mask for address class */
1393
        nmask = IN_CLASSA_NET;
1394
    else if (IN_CLASSB(addr))
1395
        nmask = IN_CLASSB_NET;
1396
    else
1397
        nmask = IN_CLASSC_NET;
1398
    /* class D nets are disallowed by bad_ip_adrs */
1399
    mask = netmask | htonl(nmask);
1400
 
1401
    /*
1402
     * Scan through the system's network interfaces.
1403
     */
1404
    ifc.ifc_len = sizeof(ifs);
1405
    ifc.ifc_req = ifs;
1406
    if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
1407
        syslog(LOG_WARNING, "ioctl(SIOCGIFCONF): %m");
1408
        return mask;
1409
    }
1410
    ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1411
    for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *)
1412
                ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) {
1413
        /*
1414
         * Check the interface's internet address.
1415
         */
1416
        if (ifr->ifr_addr.sa_family != AF_INET)
1417
            continue;
1418
        ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
1419
        if ((ntohl(ina) & nmask) != (addr & nmask))
1420
            continue;
1421
        /*
1422
         * Check that the interface is up, and not point-to-point or loopback.
1423
         */
1424
        strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1425
        if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
1426
            continue;
1427
        if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))
1428
            != IFF_UP)
1429
            continue;
1430
        /*
1431
         * Get its netmask and OR it into our mask.
1432
         */
1433
        if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
1434
            continue;
1435
        mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;
1436
    }
1437
 
1438
    return mask;
1439
}
1440
 
1441
/*
1442
 * Use the hostid as part of the random number seed.
1443
 */
1444
int
1445
get_host_seed()
1446
{
1447
                return 33;
1448
/*    return gethostid();*/
1449
}
1450
 
1451
/*
1452
 * lock - create a lock file for the named lock device
1453
 */
1454
#define LOCK_PREFIX     "/var/spool/lock/LCK.."
1455
 
1456
int
1457
lock(dev)
1458
    char *dev;
1459
{
1460
/*    char hdb_lock_buffer[12];
1461
    int fd, pid, n;
1462
    char *p;
1463
 
1464
    if ((p = strrchr(dev, '/')) != NULL)
1465
        dev = p + 1;
1466
    lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1);
1467
    if (lock_file == NULL)
1468
        novm("lock file name");
1469
    strcat(strcpy(lock_file, LOCK_PREFIX), dev);
1470
 
1471
    while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
1472
        if (errno == EEXIST
1473
            && (fd = open(lock_file, O_RDONLY, 0)) >= 0) {
1474
 
1475
            n = read(fd, hdb_lock_buffer, 11);
1476
            if (n <= 0) {
1477
                syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file);
1478
                close(fd);
1479
            } else {
1480
                hdb_lock_buffer[n] = 0;
1481
                pid = atoi(hdb_lock_buffer);
1482
                if (kill(pid, 0) == -1 && errno == ESRCH) {
1483
 
1484
                    if (unlink(lock_file) == 0) {
1485
                        close(fd);
1486
                        syslog(LOG_NOTICE, "Removed stale lock on %s (pid %d)",
1487
                               dev, pid);
1488
                        continue;
1489
                    } else
1490
                        syslog(LOG_WARNING, "Couldn't remove stale lock on %s",
1491
                               dev);
1492
                } else
1493
                    syslog(LOG_NOTICE, "Device %s is locked by pid %d",
1494
                           dev, pid);
1495
            }
1496
            close(fd);
1497
        } else
1498
            syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file);
1499
        free(lock_file);
1500
        lock_file = NULL;
1501
        return -1;
1502
    }
1503
 
1504
    sprintf(hdb_lock_buffer, "%10d\n", getpid());
1505
    write(fd, hdb_lock_buffer, 11);
1506
 
1507
    close(fd);
1508
*/    return 0;
1509
}
1510
 
1511
/*
1512
 * unlock - remove our lockfile
1513
 */
1514
void
1515
unlock()
1516
{
1517
/*    if (lock_file) {
1518
        unlink(lock_file);
1519
        free(lock_file);
1520
        lock_file = NULL;
1521
    }
1522
*/}

powered by: WebSVN 2.1.0

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