1  | 
     | 
     | 
    /*	$OpenBSD: demand.c,v 1.11 2015/01/16 06:40:19 deraadt Exp $	*/  | 
    
    
    2  | 
     | 
     | 
     | 
    
    
    3  | 
     | 
     | 
    /*  | 
    
    
    4  | 
     | 
     | 
     * demand.c - Support routines for demand-dialling.  | 
    
    
    5  | 
     | 
     | 
     *  | 
    
    
    6  | 
     | 
     | 
     * Copyright (c) 1989-2002 Paul Mackerras. All rights reserved.  | 
    
    
    7  | 
     | 
     | 
     *  | 
    
    
    8  | 
     | 
     | 
     * Redistribution and use in source and binary forms, with or without  | 
    
    
    9  | 
     | 
     | 
     * modification, are permitted provided that the following conditions  | 
    
    
    10  | 
     | 
     | 
     * are met:  | 
    
    
    11  | 
     | 
     | 
     *  | 
    
    
    12  | 
     | 
     | 
     * 1. Redistributions of source code must retain the above copyright  | 
    
    
    13  | 
     | 
     | 
     *    notice, this list of conditions and the following disclaimer.  | 
    
    
    14  | 
     | 
     | 
     *  | 
    
    
    15  | 
     | 
     | 
     * 2. Redistributions in binary form must reproduce the above copyright  | 
    
    
    16  | 
     | 
     | 
     *    notice, this list of conditions and the following disclaimer in  | 
    
    
    17  | 
     | 
     | 
     *    the documentation and/or other materials provided with the  | 
    
    
    18  | 
     | 
     | 
     *    distribution.  | 
    
    
    19  | 
     | 
     | 
     *  | 
    
    
    20  | 
     | 
     | 
     * 3. The name(s) of the authors of this software must not be used to  | 
    
    
    21  | 
     | 
     | 
     *    endorse or promote products derived from this software without  | 
    
    
    22  | 
     | 
     | 
     *    prior written permission.  | 
    
    
    23  | 
     | 
     | 
     *  | 
    
    
    24  | 
     | 
     | 
     * 4. Redistributions of any form whatsoever must retain the following  | 
    
    
    25  | 
     | 
     | 
     *    acknowledgment:  | 
    
    
    26  | 
     | 
     | 
     *    "This product includes software developed by Paul Mackerras  | 
    
    
    27  | 
     | 
     | 
     *     <paulus@samba.org>".  | 
    
    
    28  | 
     | 
     | 
     *  | 
    
    
    29  | 
     | 
     | 
     * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO  | 
    
    
    30  | 
     | 
     | 
     * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY  | 
    
    
    31  | 
     | 
     | 
     * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY  | 
    
    
    32  | 
     | 
     | 
     * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES  | 
    
    
    33  | 
     | 
     | 
     * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN  | 
    
    
    34  | 
     | 
     | 
     * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING  | 
    
    
    35  | 
     | 
     | 
     * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  | 
    
    
    36  | 
     | 
     | 
     */  | 
    
    
    37  | 
     | 
     | 
     | 
    
    
    38  | 
     | 
     | 
    #include <sys/types.h>  | 
    
    
    39  | 
     | 
     | 
    #include <sys/wait.h>  | 
    
    
    40  | 
     | 
     | 
    #include <sys/time.h>  | 
    
    
    41  | 
     | 
     | 
    #include <sys/resource.h>  | 
    
    
    42  | 
     | 
     | 
    #include <sys/stat.h>  | 
    
    
    43  | 
     | 
     | 
    #include <sys/socket.h>  | 
    
    
    44  | 
     | 
     | 
    #ifdef PPP_FILTER  | 
    
    
    45  | 
     | 
     | 
    #include <net/if.h>  | 
    
    
    46  | 
     | 
     | 
    #include <net/bpf.h>  | 
    
    
    47  | 
     | 
     | 
    #include <pcap.h>  | 
    
    
    48  | 
     | 
     | 
    #endif  | 
    
    
    49  | 
     | 
     | 
    #include <stdio.h>  | 
    
    
    50  | 
     | 
     | 
    #include <stdlib.h>  | 
    
    
    51  | 
     | 
     | 
    #include <string.h>  | 
    
    
    52  | 
     | 
     | 
    #include <errno.h>  | 
    
    
    53  | 
     | 
     | 
    #include <fcntl.h>  | 
    
    
    54  | 
     | 
     | 
    #include <syslog.h>  | 
    
    
    55  | 
     | 
     | 
     | 
    
    
    56  | 
     | 
     | 
    #include "pppd.h"  | 
    
    
    57  | 
     | 
     | 
    #include "fsm.h"  | 
    
    
    58  | 
     | 
     | 
    #include "ipcp.h"  | 
    
    
    59  | 
     | 
     | 
    #include "lcp.h"  | 
    
    
    60  | 
     | 
     | 
     | 
    
    
    61  | 
     | 
     | 
    char *frame;  | 
    
    
    62  | 
     | 
     | 
    int framelen;  | 
    
    
    63  | 
     | 
     | 
    int framemax;  | 
    
    
    64  | 
     | 
     | 
    int escape_flag;  | 
    
    
    65  | 
     | 
     | 
    int flush_flag;  | 
    
    
    66  | 
     | 
     | 
    int fcs;  | 
    
    
    67  | 
     | 
     | 
     | 
    
    
    68  | 
     | 
     | 
    struct packet { | 
    
    
    69  | 
     | 
     | 
        int length;  | 
    
    
    70  | 
     | 
     | 
        struct packet *next;  | 
    
    
    71  | 
     | 
     | 
        unsigned char data[1];  | 
    
    
    72  | 
     | 
     | 
    };  | 
    
    
    73  | 
     | 
     | 
     | 
    
    
    74  | 
     | 
     | 
    struct packet *pend_q;  | 
    
    
    75  | 
     | 
     | 
    struct packet *pend_qtail;  | 
    
    
    76  | 
     | 
     | 
     | 
    
    
    77  | 
     | 
     | 
    static int active_packet(unsigned char *, int);  | 
    
    
    78  | 
     | 
     | 
     | 
    
    
    79  | 
     | 
     | 
    /*  | 
    
    
    80  | 
     | 
     | 
     * demand_conf - configure the interface for doing dial-on-demand.  | 
    
    
    81  | 
     | 
     | 
     */  | 
    
    
    82  | 
     | 
     | 
    void  | 
    
    
    83  | 
     | 
     | 
    demand_conf()  | 
    
    
    84  | 
     | 
     | 
    { | 
    
    
    85  | 
     | 
     | 
        int i;  | 
    
    
    86  | 
     | 
     | 
        struct protent *protp;  | 
    
    
    87  | 
     | 
     | 
     | 
    
    
    88  | 
     | 
     | 
    /*    framemax = lcp_allowoptions[0].mru;  | 
    
    
    89  | 
     | 
     | 
        if (framemax < PPP_MRU) */  | 
    
    
    90  | 
     | 
     | 
    	framemax = PPP_MRU;  | 
    
    
    91  | 
     | 
     | 
        framemax += PPP_HDRLEN + PPP_FCSLEN;  | 
    
    
    92  | 
     | 
     | 
        frame = malloc(framemax);  | 
    
    
    93  | 
     | 
     | 
        if (frame == NULL)  | 
    
    
    94  | 
     | 
     | 
    	novm("demand frame"); | 
    
    
    95  | 
     | 
     | 
        framelen = 0;  | 
    
    
    96  | 
     | 
     | 
        pend_q = NULL;  | 
    
    
    97  | 
     | 
     | 
        escape_flag = 0;  | 
    
    
    98  | 
     | 
     | 
        flush_flag = 0;  | 
    
    
    99  | 
     | 
     | 
        fcs = PPP_INITFCS;  | 
    
    
    100  | 
     | 
     | 
     | 
    
    
    101  | 
     | 
     | 
        ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);  | 
    
    
    102  | 
     | 
     | 
        ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);  | 
    
    
    103  | 
     | 
     | 
     | 
    
    
    104  | 
     | 
     | 
    #ifdef PPP_FILTER  | 
    
    
    105  | 
     | 
     | 
        set_filters(&pass_filter, &active_filter);  | 
    
    
    106  | 
     | 
     | 
    #endif  | 
    
    
    107  | 
     | 
     | 
     | 
    
    
    108  | 
     | 
     | 
        /*  | 
    
    
    109  | 
     | 
     | 
         * Call the demand_conf procedure for each protocol that's got one.  | 
    
    
    110  | 
     | 
     | 
         */  | 
    
    
    111  | 
     | 
     | 
        for (i = 0; (protp = protocols[i]) != NULL; ++i)  | 
    
    
    112  | 
     | 
     | 
    	if (protp->enabled_flag && protp->demand_conf != NULL)  | 
    
    
    113  | 
     | 
     | 
    	    if (!((*protp->demand_conf)(0)))  | 
    
    
    114  | 
     | 
     | 
    		die(1);  | 
    
    
    115  | 
     | 
     | 
    }  | 
    
    
    116  | 
     | 
     | 
     | 
    
    
    117  | 
     | 
     | 
    /*  | 
    
    
    118  | 
     | 
     | 
     * demand_drop - set each network protocol to discard packets  | 
    
    
    119  | 
     | 
     | 
     * without an error.  | 
    
    
    120  | 
     | 
     | 
     */  | 
    
    
    121  | 
     | 
     | 
    void  | 
    
    
    122  | 
     | 
     | 
    demand_drop()  | 
    
    
    123  | 
     | 
     | 
    { | 
    
    
    124  | 
     | 
     | 
        struct packet *pkt, *nextpkt;  | 
    
    
    125  | 
     | 
     | 
        int i;  | 
    
    
    126  | 
     | 
     | 
        struct protent *protp;  | 
    
    
    127  | 
     | 
     | 
     | 
    
    
    128  | 
     | 
     | 
        for (i = 0; (protp = protocols[i]) != NULL; ++i)  | 
    
    
    129  | 
     | 
     | 
            if (protp->enabled_flag && protp->demand_conf != NULL)  | 
    
    
    130  | 
     | 
     | 
                sifnpmode(0, protp->protocol & ~0x8000, NPMODE_DROP);  | 
    
    
    131  | 
     | 
     | 
        get_loop_output();  | 
    
    
    132  | 
     | 
     | 
     | 
    
    
    133  | 
     | 
     | 
        /* discard all saved packets */  | 
    
    
    134  | 
     | 
     | 
        for (pkt = pend_q; pkt != NULL; pkt = nextpkt) { | 
    
    
    135  | 
     | 
     | 
            nextpkt = pkt->next;  | 
    
    
    136  | 
     | 
     | 
            free(pkt);  | 
    
    
    137  | 
     | 
     | 
        }  | 
    
    
    138  | 
     | 
     | 
        pend_q = NULL;  | 
    
    
    139  | 
     | 
     | 
        framelen = 0;  | 
    
    
    140  | 
     | 
     | 
        flush_flag = 0;  | 
    
    
    141  | 
     | 
     | 
        escape_flag = 0;  | 
    
    
    142  | 
     | 
     | 
        fcs = PPP_INITFCS;  | 
    
    
    143  | 
     | 
     | 
    }  | 
    
    
    144  | 
     | 
     | 
     | 
    
    
    145  | 
     | 
     | 
    /*  | 
    
    
    146  | 
     | 
     | 
     * demand_unblock - set each enabled network protocol to pass packets.  | 
    
    
    147  | 
     | 
     | 
     */  | 
    
    
    148  | 
     | 
     | 
    void  | 
    
    
    149  | 
     | 
     | 
    demand_unblock()  | 
    
    
    150  | 
     | 
     | 
    { | 
    
    
    151  | 
     | 
     | 
        int i;  | 
    
    
    152  | 
     | 
     | 
        struct protent *protp;  | 
    
    
    153  | 
     | 
     | 
     | 
    
    
    154  | 
     | 
     | 
        for (i = 0; (protp = protocols[i]) != NULL; ++i)  | 
    
    
    155  | 
     | 
     | 
    	if (protp->enabled_flag && protp->demand_conf != NULL)  | 
    
    
    156  | 
     | 
     | 
    	    sifnpmode(0, protp->protocol & ~0x8000, NPMODE_PASS);  | 
    
    
    157  | 
     | 
     | 
    }  | 
    
    
    158  | 
     | 
     | 
     | 
    
    
    159  | 
     | 
     | 
    /*  | 
    
    
    160  | 
     | 
     | 
     * FCS lookup table as calculated by genfcstab.  | 
    
    
    161  | 
     | 
     | 
     */  | 
    
    
    162  | 
     | 
     | 
    static u_short fcstab[256] = { | 
    
    
    163  | 
     | 
     | 
    	0x0000,	0x1189,	0x2312,	0x329b,	0x4624,	0x57ad,	0x6536,	0x74bf,  | 
    
    
    164  | 
     | 
     | 
    	0x8c48,	0x9dc1,	0xaf5a,	0xbed3,	0xca6c,	0xdbe5,	0xe97e,	0xf8f7,  | 
    
    
    165  | 
     | 
     | 
    	0x1081,	0x0108,	0x3393,	0x221a,	0x56a5,	0x472c,	0x75b7,	0x643e,  | 
    
    
    166  | 
     | 
     | 
    	0x9cc9,	0x8d40,	0xbfdb,	0xae52,	0xdaed,	0xcb64,	0xf9ff,	0xe876,  | 
    
    
    167  | 
     | 
     | 
    	0x2102,	0x308b,	0x0210,	0x1399,	0x6726,	0x76af,	0x4434,	0x55bd,  | 
    
    
    168  | 
     | 
     | 
    	0xad4a,	0xbcc3,	0x8e58,	0x9fd1,	0xeb6e,	0xfae7,	0xc87c,	0xd9f5,  | 
    
    
    169  | 
     | 
     | 
    	0x3183,	0x200a,	0x1291,	0x0318,	0x77a7,	0x662e,	0x54b5,	0x453c,  | 
    
    
    170  | 
     | 
     | 
    	0xbdcb,	0xac42,	0x9ed9,	0x8f50,	0xfbef,	0xea66,	0xd8fd,	0xc974,  | 
    
    
    171  | 
     | 
     | 
    	0x4204,	0x538d,	0x6116,	0x709f,	0x0420,	0x15a9,	0x2732,	0x36bb,  | 
    
    
    172  | 
     | 
     | 
    	0xce4c,	0xdfc5,	0xed5e,	0xfcd7,	0x8868,	0x99e1,	0xab7a,	0xbaf3,  | 
    
    
    173  | 
     | 
     | 
    	0x5285,	0x430c,	0x7197,	0x601e,	0x14a1,	0x0528,	0x37b3,	0x263a,  | 
    
    
    174  | 
     | 
     | 
    	0xdecd,	0xcf44,	0xfddf,	0xec56,	0x98e9,	0x8960,	0xbbfb,	0xaa72,  | 
    
    
    175  | 
     | 
     | 
    	0x6306,	0x728f,	0x4014,	0x519d,	0x2522,	0x34ab,	0x0630,	0x17b9,  | 
    
    
    176  | 
     | 
     | 
    	0xef4e,	0xfec7,	0xcc5c,	0xddd5,	0xa96a,	0xb8e3,	0x8a78,	0x9bf1,  | 
    
    
    177  | 
     | 
     | 
    	0x7387,	0x620e,	0x5095,	0x411c,	0x35a3,	0x242a,	0x16b1,	0x0738,  | 
    
    
    178  | 
     | 
     | 
    	0xffcf,	0xee46,	0xdcdd,	0xcd54,	0xb9eb,	0xa862,	0x9af9,	0x8b70,  | 
    
    
    179  | 
     | 
     | 
    	0x8408,	0x9581,	0xa71a,	0xb693,	0xc22c,	0xd3a5,	0xe13e,	0xf0b7,  | 
    
    
    180  | 
     | 
     | 
    	0x0840,	0x19c9,	0x2b52,	0x3adb,	0x4e64,	0x5fed,	0x6d76,	0x7cff,  | 
    
    
    181  | 
     | 
     | 
    	0x9489,	0x8500,	0xb79b,	0xa612,	0xd2ad,	0xc324,	0xf1bf,	0xe036,  | 
    
    
    182  | 
     | 
     | 
    	0x18c1,	0x0948,	0x3bd3,	0x2a5a,	0x5ee5,	0x4f6c,	0x7df7,	0x6c7e,  | 
    
    
    183  | 
     | 
     | 
    	0xa50a,	0xb483,	0x8618,	0x9791,	0xe32e,	0xf2a7,	0xc03c,	0xd1b5,  | 
    
    
    184  | 
     | 
     | 
    	0x2942,	0x38cb,	0x0a50,	0x1bd9,	0x6f66,	0x7eef,	0x4c74,	0x5dfd,  | 
    
    
    185  | 
     | 
     | 
    	0xb58b,	0xa402,	0x9699,	0x8710,	0xf3af,	0xe226,	0xd0bd,	0xc134,  | 
    
    
    186  | 
     | 
     | 
    	0x39c3,	0x284a,	0x1ad1,	0x0b58,	0x7fe7,	0x6e6e,	0x5cf5,	0x4d7c,  | 
    
    
    187  | 
     | 
     | 
    	0xc60c,	0xd785,	0xe51e,	0xf497,	0x8028,	0x91a1,	0xa33a,	0xb2b3,  | 
    
    
    188  | 
     | 
     | 
    	0x4a44,	0x5bcd,	0x6956,	0x78df,	0x0c60,	0x1de9,	0x2f72,	0x3efb,  | 
    
    
    189  | 
     | 
     | 
    	0xd68d,	0xc704,	0xf59f,	0xe416,	0x90a9,	0x8120,	0xb3bb,	0xa232,  | 
    
    
    190  | 
     | 
     | 
    	0x5ac5,	0x4b4c,	0x79d7,	0x685e,	0x1ce1,	0x0d68,	0x3ff3,	0x2e7a,  | 
    
    
    191  | 
     | 
     | 
    	0xe70e,	0xf687,	0xc41c,	0xd595,	0xa12a,	0xb0a3,	0x8238,	0x93b1,  | 
    
    
    192  | 
     | 
     | 
    	0x6b46,	0x7acf,	0x4854,	0x59dd,	0x2d62,	0x3ceb,	0x0e70,	0x1ff9,  | 
    
    
    193  | 
     | 
     | 
    	0xf78f,	0xe606,	0xd49d,	0xc514,	0xb1ab,	0xa022,	0x92b9,	0x8330,  | 
    
    
    194  | 
     | 
     | 
    	0x7bc7,	0x6a4e,	0x58d5,	0x495c,	0x3de3,	0x2c6a,	0x1ef1,	0x0f78  | 
    
    
    195  | 
     | 
     | 
    };  | 
    
    
    196  | 
     | 
     | 
     | 
    
    
    197  | 
     | 
     | 
    /*  | 
    
    
    198  | 
     | 
     | 
     * loop_chars - process characters received from the loopback.  | 
    
    
    199  | 
     | 
     | 
     * Calls loop_frame when a complete frame has been accumulated.  | 
    
    
    200  | 
     | 
     | 
     * Return value is 1 if we need to bring up the link, 0 otherwise.  | 
    
    
    201  | 
     | 
     | 
     */  | 
    
    
    202  | 
     | 
     | 
    int  | 
    
    
    203  | 
     | 
     | 
    loop_chars(p, n)  | 
    
    
    204  | 
     | 
     | 
        unsigned char *p;  | 
    
    
    205  | 
     | 
     | 
        int n;  | 
    
    
    206  | 
     | 
     | 
    { | 
    
    
    207  | 
     | 
     | 
        int c, rv;  | 
    
    
    208  | 
     | 
     | 
     | 
    
    
    209  | 
     | 
     | 
        rv = 0;  | 
    
    
    210  | 
     | 
     | 
        for (; n > 0; --n) { | 
    
    
    211  | 
     | 
     | 
    	c = *p++;  | 
    
    
    212  | 
     | 
     | 
    	if (c == PPP_FLAG) { | 
    
    
    213  | 
     | 
     | 
    	    if (!escape_flag && !flush_flag  | 
    
    
    214  | 
     | 
     | 
    		&& framelen > 2 && fcs == PPP_GOODFCS) { | 
    
    
    215  | 
     | 
     | 
    		framelen -= 2;  | 
    
    
    216  | 
     | 
     | 
    		if (loop_frame(frame, framelen))  | 
    
    
    217  | 
     | 
     | 
    		    rv = 1;  | 
    
    
    218  | 
     | 
     | 
    	    }  | 
    
    
    219  | 
     | 
     | 
    	    framelen = 0;  | 
    
    
    220  | 
     | 
     | 
    	    flush_flag = 0;  | 
    
    
    221  | 
     | 
     | 
    	    escape_flag = 0;  | 
    
    
    222  | 
     | 
     | 
    	    fcs = PPP_INITFCS;  | 
    
    
    223  | 
     | 
     | 
    	    continue;  | 
    
    
    224  | 
     | 
     | 
    	}  | 
    
    
    225  | 
     | 
     | 
    	if (flush_flag)  | 
    
    
    226  | 
     | 
     | 
    	    continue;  | 
    
    
    227  | 
     | 
     | 
    	if (escape_flag) { | 
    
    
    228  | 
     | 
     | 
    	    c ^= PPP_TRANS;  | 
    
    
    229  | 
     | 
     | 
    	    escape_flag = 0;  | 
    
    
    230  | 
     | 
     | 
    	} else if (c == PPP_ESCAPE) { | 
    
    
    231  | 
     | 
     | 
    	    escape_flag = 1;  | 
    
    
    232  | 
     | 
     | 
    	    continue;  | 
    
    
    233  | 
     | 
     | 
    	}  | 
    
    
    234  | 
     | 
     | 
    	if (framelen >= framemax) { | 
    
    
    235  | 
     | 
     | 
    	    flush_flag = 1;  | 
    
    
    236  | 
     | 
     | 
    	    continue;  | 
    
    
    237  | 
     | 
     | 
    	}  | 
    
    
    238  | 
     | 
     | 
    	frame[framelen++] = c;  | 
    
    
    239  | 
     | 
     | 
    	fcs = PPP_FCS(fcs, c);  | 
    
    
    240  | 
     | 
     | 
        }  | 
    
    
    241  | 
     | 
     | 
        return rv;  | 
    
    
    242  | 
     | 
     | 
    }  | 
    
    
    243  | 
     | 
     | 
     | 
    
    
    244  | 
     | 
     | 
    /*  | 
    
    
    245  | 
     | 
     | 
     * loop_frame - given a frame obtained from the loopback,  | 
    
    
    246  | 
     | 
     | 
     * decide whether to bring up the link or not, and, if we want  | 
    
    
    247  | 
     | 
     | 
     * to transmit this frame later, put it on the pending queue.  | 
    
    
    248  | 
     | 
     | 
     * Return value is 1 if we need to bring up the link, 0 otherwise.  | 
    
    
    249  | 
     | 
     | 
     * We assume that the kernel driver has already applied the  | 
    
    
    250  | 
     | 
     | 
     * pass_filter, so we won't get packets it rejected.  | 
    
    
    251  | 
     | 
     | 
     * We apply the active_filter to see if we want this packet to  | 
    
    
    252  | 
     | 
     | 
     * bring up the link.  | 
    
    
    253  | 
     | 
     | 
     */  | 
    
    
    254  | 
     | 
     | 
    int  | 
    
    
    255  | 
     | 
     | 
    loop_frame(frame, len)  | 
    
    
    256  | 
     | 
     | 
        unsigned char *frame;  | 
    
    
    257  | 
     | 
     | 
        int len;  | 
    
    
    258  | 
     | 
     | 
    { | 
    
    
    259  | 
     | 
     | 
        struct packet *pkt;  | 
    
    
    260  | 
     | 
     | 
     | 
    
    
    261  | 
     | 
     | 
        /* log_packet(frame, len, "from loop: ", LOG_DEBUG); */  | 
    
    
    262  | 
     | 
     | 
        if (len < PPP_HDRLEN)  | 
    
    
    263  | 
     | 
     | 
    	return 0;  | 
    
    
    264  | 
     | 
     | 
        if ((PPP_PROTOCOL(frame) & 0x8000) != 0)  | 
    
    
    265  | 
     | 
     | 
    	return 0;		/* shouldn't get any of these anyway */  | 
    
    
    266  | 
     | 
     | 
        if (!active_packet(frame, len))  | 
    
    
    267  | 
     | 
     | 
    	return 0;  | 
    
    
    268  | 
     | 
     | 
     | 
    
    
    269  | 
     | 
     | 
        pkt = (struct packet *) malloc(sizeof(struct packet) + len);  | 
    
    
    270  | 
     | 
     | 
        if (pkt != NULL) { | 
    
    
    271  | 
     | 
     | 
    	pkt->length = len;  | 
    
    
    272  | 
     | 
     | 
    	pkt->next = NULL;  | 
    
    
    273  | 
     | 
     | 
    	memcpy(pkt->data, frame, len);  | 
    
    
    274  | 
     | 
     | 
    	if (pend_q == NULL)  | 
    
    
    275  | 
     | 
     | 
    	    pend_q = pkt;  | 
    
    
    276  | 
     | 
     | 
    	else  | 
    
    
    277  | 
     | 
     | 
    	    pend_qtail->next = pkt;  | 
    
    
    278  | 
     | 
     | 
    	pend_qtail = pkt;  | 
    
    
    279  | 
     | 
     | 
        }  | 
    
    
    280  | 
     | 
     | 
        return 1;  | 
    
    
    281  | 
     | 
     | 
    }  | 
    
    
    282  | 
     | 
     | 
     | 
    
    
    283  | 
     | 
     | 
    /*  | 
    
    
    284  | 
     | 
     | 
     * demand_rexmit - Resend all those frames which we got via the  | 
    
    
    285  | 
     | 
     | 
     * loopback, now that the real serial link is up.  | 
    
    
    286  | 
     | 
     | 
     */  | 
    
    
    287  | 
     | 
     | 
    void  | 
    
    
    288  | 
     | 
     | 
    demand_rexmit(proto)  | 
    
    
    289  | 
     | 
     | 
        int proto;  | 
    
    
    290  | 
     | 
     | 
    { | 
    
    
    291  | 
     | 
     | 
        struct packet *pkt, *prev, *nextpkt;  | 
    
    
    292  | 
     | 
     | 
     | 
    
    
    293  | 
     | 
     | 
        prev = NULL;  | 
    
    
    294  | 
     | 
     | 
        pkt = pend_q;  | 
    
    
    295  | 
     | 
     | 
        pend_q = NULL;  | 
    
    
    296  | 
     | 
     | 
        for (; pkt != NULL; pkt = nextpkt) { | 
    
    
    297  | 
     | 
     | 
    	nextpkt = pkt->next;  | 
    
    
    298  | 
     | 
     | 
    	if (PPP_PROTOCOL(pkt->data) == proto) { | 
    
    
    299  | 
     | 
     | 
    	    output(0, pkt->data, pkt->length);  | 
    
    
    300  | 
     | 
     | 
    	    free(pkt);  | 
    
    
    301  | 
     | 
     | 
    	} else { | 
    
    
    302  | 
     | 
     | 
    	    if (prev == NULL)  | 
    
    
    303  | 
     | 
     | 
    		pend_q = pkt;  | 
    
    
    304  | 
     | 
     | 
    	    else  | 
    
    
    305  | 
     | 
     | 
    		prev->next = pkt;  | 
    
    
    306  | 
     | 
     | 
    	    prev = pkt;  | 
    
    
    307  | 
     | 
     | 
    	}  | 
    
    
    308  | 
     | 
     | 
        }  | 
    
    
    309  | 
     | 
     | 
        pend_qtail = prev;  | 
    
    
    310  | 
     | 
     | 
        if (prev != NULL)  | 
    
    
    311  | 
     | 
     | 
    	prev->next = NULL;  | 
    
    
    312  | 
     | 
     | 
    }  | 
    
    
    313  | 
     | 
     | 
     | 
    
    
    314  | 
     | 
     | 
    /*  | 
    
    
    315  | 
     | 
     | 
     * Scan a packet to decide whether it is an "active" packet,  | 
    
    
    316  | 
     | 
     | 
     * that is, whether it is worth bringing up the link for.  | 
    
    
    317  | 
     | 
     | 
     */  | 
    
    
    318  | 
     | 
     | 
    static int  | 
    
    
    319  | 
     | 
     | 
    active_packet(p, len)  | 
    
    
    320  | 
     | 
     | 
        unsigned char *p;  | 
    
    
    321  | 
     | 
     | 
        int len;  | 
    
    
    322  | 
     | 
     | 
    { | 
    
    
    323  | 
     | 
     | 
        int proto, i;  | 
    
    
    324  | 
     | 
     | 
        struct protent *protp;  | 
    
    
    325  | 
     | 
     | 
     | 
    
    
    326  | 
     | 
     | 
        if (len < PPP_HDRLEN)  | 
    
    
    327  | 
     | 
     | 
    	return 0;  | 
    
    
    328  | 
     | 
     | 
        proto = PPP_PROTOCOL(p);  | 
    
    
    329  | 
     | 
     | 
    #ifdef PPP_FILTER  | 
    
    
    330  | 
     | 
     | 
        if (active_filter.bf_len != 0  | 
    
    
    331  | 
     | 
     | 
    	&& bpf_filter(active_filter.bf_insns, frame, len, len) == 0)  | 
    
    
    332  | 
     | 
     | 
    	return 0;  | 
    
    
    333  | 
     | 
     | 
    #endif  | 
    
    
    334  | 
     | 
     | 
        for (i = 0; (protp = protocols[i]) != NULL; ++i) { | 
    
    
    335  | 
     | 
     | 
    	if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) { | 
    
    
    336  | 
     | 
     | 
    	    if (!protp->enabled_flag)  | 
    
    
    337  | 
     | 
     | 
    		return 0;  | 
    
    
    338  | 
     | 
     | 
    	    if (protp->active_pkt == NULL)  | 
    
    
    339  | 
     | 
     | 
    		return 1;  | 
    
    
    340  | 
     | 
     | 
    	    return (*protp->active_pkt)(p, len);  | 
    
    
    341  | 
     | 
     | 
    	}  | 
    
    
    342  | 
     | 
     | 
        }  | 
    
    
    343  | 
     | 
     | 
        return 0;			/* not a supported protocol !!?? */  | 
    
    
    344  | 
     | 
     | 
    }  |