18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * demand.c - Support routines for demand-dialling.
38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright (c) 1996-2002 Paul Mackerras. All rights reserved.
58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Redistribution and use in source and binary forms, with or without
78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * modification, are permitted provided that the following conditions
88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * are met:
98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 2. The name(s) of the authors of this software must not be used to
148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    endorse or promote products derived from this software without
158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    prior written permission.
168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 3. Redistributions of any form whatsoever must retain the following
188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    acknowledgment:
198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    "This product includes software developed by Paul Mackerras
208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *     <paulus@samba.org>".
218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define RCSID	"$Id: demand.c,v 1.19 2004/11/04 10:02:26 paulus Exp $"
328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdio.h>
348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h>
358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h>
368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <errno.h>
378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <fcntl.h>
388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <netdb.h>
398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/param.h>
408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/types.h>
418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/wait.h>
428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/time.h>
438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/resource.h>
448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/stat.h>
458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/socket.h>
468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef PPP_FILTER
478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <pcap-bpf.h>
488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppd.h"
518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "fsm.h"
528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "ipcp.h"
538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "lcp.h"
548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic const char rcsid[] = RCSID;
568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *frame;
588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint framelen;
598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint framemax;
608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint escape_flag;
618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint flush_flag;
628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint fcs;
638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct packet {
658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int length;
668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct packet *next;
678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unsigned char data[1];
688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct packet *pend_q;
718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct packet *pend_qtail;
728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int active_packet __P((unsigned char *, int));
748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * demand_conf - configure the interface for doing dial-on-demand.
778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectdemand_conf()
808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int i;
828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct protent *protp;
838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*    framemax = lcp_allowoptions[0].mru;
858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (framemax < PPP_MRU) */
868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	framemax = PPP_MRU;
878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    framemax += PPP_HDRLEN + PPP_FCSLEN;
888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    frame = malloc(framemax);
898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (frame == NULL)
908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	novm("demand frame");
918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    framelen = 0;
928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pend_q = NULL;
938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    escape_flag = 0;
948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    flush_flag = 0;
958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fcs = PPP_INITFCS;
968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    netif_set_mtu(0, MIN(lcp_allowoptions[0].mru, PPP_MRU));
988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0
998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	|| ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0)
1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    fatal("Couldn't set up demand-dialled PPP interface: %m");
1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef PPP_FILTER
1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    set_filters(&pass_filter, &active_filter);
1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Call the demand_conf procedure for each protocol that's got one.
1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 0; (protp = protocols[i]) != NULL; ++i)
1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (protp->enabled_flag && protp->demand_conf != NULL)
1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!((*protp->demand_conf)(0)))
1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		die(1);
1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * demand_block - set each network protocol to block further packets.
1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectdemand_block()
1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int i;
1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct protent *protp;
1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 0; (protp = protocols[i]) != NULL; ++i)
1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (protp->enabled_flag && protp->demand_conf != NULL)
1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    sifnpmode(0, protp->protocol & ~0x8000, NPMODE_QUEUE);
1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    get_loop_output();
1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * demand_discard - set each network protocol to discard packets
1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * with an error.
1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectdemand_discard()
1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct packet *pkt, *nextpkt;
1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int i;
1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct protent *protp;
1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 0; (protp = protocols[i]) != NULL; ++i)
1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (protp->enabled_flag && protp->demand_conf != NULL)
1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    sifnpmode(0, protp->protocol & ~0x8000, NPMODE_ERROR);
1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    get_loop_output();
1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* discard all saved packets */
1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (pkt = pend_q; pkt != NULL; pkt = nextpkt) {
1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	nextpkt = pkt->next;
1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(pkt);
1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pend_q = NULL;
1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    framelen = 0;
1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    flush_flag = 0;
1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    escape_flag = 0;
1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fcs = PPP_INITFCS;
1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * demand_unblock - set each enabled network protocol to pass packets.
1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectdemand_unblock()
1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int i;
1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct protent *protp;
1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 0; (protp = protocols[i]) != NULL; ++i)
1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (protp->enabled_flag && protp->demand_conf != NULL)
1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    sifnpmode(0, protp->protocol & ~0x8000, NPMODE_PASS);
1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * FCS lookup table as calculated by genfcstab.
1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic u_short fcstab[256] = {
1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x0000,	0x1189,	0x2312,	0x329b,	0x4624,	0x57ad,	0x6536,	0x74bf,
1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x8c48,	0x9dc1,	0xaf5a,	0xbed3,	0xca6c,	0xdbe5,	0xe97e,	0xf8f7,
1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x1081,	0x0108,	0x3393,	0x221a,	0x56a5,	0x472c,	0x75b7,	0x643e,
1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x9cc9,	0x8d40,	0xbfdb,	0xae52,	0xdaed,	0xcb64,	0xf9ff,	0xe876,
1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x2102,	0x308b,	0x0210,	0x1399,	0x6726,	0x76af,	0x4434,	0x55bd,
1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xad4a,	0xbcc3,	0x8e58,	0x9fd1,	0xeb6e,	0xfae7,	0xc87c,	0xd9f5,
1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x3183,	0x200a,	0x1291,	0x0318,	0x77a7,	0x662e,	0x54b5,	0x453c,
1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xbdcb,	0xac42,	0x9ed9,	0x8f50,	0xfbef,	0xea66,	0xd8fd,	0xc974,
1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x4204,	0x538d,	0x6116,	0x709f,	0x0420,	0x15a9,	0x2732,	0x36bb,
1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xce4c,	0xdfc5,	0xed5e,	0xfcd7,	0x8868,	0x99e1,	0xab7a,	0xbaf3,
1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x5285,	0x430c,	0x7197,	0x601e,	0x14a1,	0x0528,	0x37b3,	0x263a,
1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xdecd,	0xcf44,	0xfddf,	0xec56,	0x98e9,	0x8960,	0xbbfb,	0xaa72,
1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x6306,	0x728f,	0x4014,	0x519d,	0x2522,	0x34ab,	0x0630,	0x17b9,
1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xef4e,	0xfec7,	0xcc5c,	0xddd5,	0xa96a,	0xb8e3,	0x8a78,	0x9bf1,
1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x7387,	0x620e,	0x5095,	0x411c,	0x35a3,	0x242a,	0x16b1,	0x0738,
1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xffcf,	0xee46,	0xdcdd,	0xcd54,	0xb9eb,	0xa862,	0x9af9,	0x8b70,
1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x8408,	0x9581,	0xa71a,	0xb693,	0xc22c,	0xd3a5,	0xe13e,	0xf0b7,
1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x0840,	0x19c9,	0x2b52,	0x3adb,	0x4e64,	0x5fed,	0x6d76,	0x7cff,
1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x9489,	0x8500,	0xb79b,	0xa612,	0xd2ad,	0xc324,	0xf1bf,	0xe036,
1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x18c1,	0x0948,	0x3bd3,	0x2a5a,	0x5ee5,	0x4f6c,	0x7df7,	0x6c7e,
1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xa50a,	0xb483,	0x8618,	0x9791,	0xe32e,	0xf2a7,	0xc03c,	0xd1b5,
1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x2942,	0x38cb,	0x0a50,	0x1bd9,	0x6f66,	0x7eef,	0x4c74,	0x5dfd,
1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xb58b,	0xa402,	0x9699,	0x8710,	0xf3af,	0xe226,	0xd0bd,	0xc134,
2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x39c3,	0x284a,	0x1ad1,	0x0b58,	0x7fe7,	0x6e6e,	0x5cf5,	0x4d7c,
2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xc60c,	0xd785,	0xe51e,	0xf497,	0x8028,	0x91a1,	0xa33a,	0xb2b3,
2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x4a44,	0x5bcd,	0x6956,	0x78df,	0x0c60,	0x1de9,	0x2f72,	0x3efb,
2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xd68d,	0xc704,	0xf59f,	0xe416,	0x90a9,	0x8120,	0xb3bb,	0xa232,
2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x5ac5,	0x4b4c,	0x79d7,	0x685e,	0x1ce1,	0x0d68,	0x3ff3,	0x2e7a,
2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xe70e,	0xf687,	0xc41c,	0xd595,	0xa12a,	0xb0a3,	0x8238,	0x93b1,
2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x6b46,	0x7acf,	0x4854,	0x59dd,	0x2d62,	0x3ceb,	0x0e70,	0x1ff9,
2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xf78f,	0xe606,	0xd49d,	0xc514,	0xb1ab,	0xa022,	0x92b9,	0x8330,
2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x7bc7,	0x6a4e,	0x58d5,	0x495c,	0x3de3,	0x2c6a,	0x1ef1,	0x0f78
2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * loop_chars - process characters received from the loopback.
2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Calls loop_frame when a complete frame has been accumulated.
2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Return value is 1 if we need to bring up the link, 0 otherwise.
2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectloop_chars(p, n)
2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unsigned char *p;
2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int n;
2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int c, rv;
2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rv = 0;
2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (; n > 0; --n) {
2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	c = *p++;
2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (c == PPP_FLAG) {
2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!escape_flag && !flush_flag
2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		&& framelen > 2 && fcs == PPP_GOODFCS) {
2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		framelen -= 2;
2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (loop_frame((unsigned char *)frame, framelen))
2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    rv = 1;
2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    framelen = 0;
2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    flush_flag = 0;
2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    escape_flag = 0;
2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    fcs = PPP_INITFCS;
2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (flush_flag)
2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (escape_flag) {
2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    c ^= PPP_TRANS;
2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    escape_flag = 0;
2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else if (c == PPP_ESCAPE) {
2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    escape_flag = 1;
2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (framelen >= framemax) {
2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    flush_flag = 1;
2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	frame[framelen++] = c;
2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fcs = PPP_FCS(fcs, c);
2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return rv;
2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * loop_frame - given a frame obtained from the loopback,
2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * decide whether to bring up the link or not, and, if we want
2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * to transmit this frame later, put it on the pending queue.
2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Return value is 1 if we need to bring up the link, 0 otherwise.
2638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * We assume that the kernel driver has already applied the
2648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * pass_filter, so we won't get packets it rejected.
2658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * We apply the active_filter to see if we want this packet to
2668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * bring up the link.
2678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
2698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectloop_frame(frame, len)
2708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unsigned char *frame;
2718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
2728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct packet *pkt;
2748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* dbglog("from loop: %P", frame, len); */
2768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len < PPP_HDRLEN)
2778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
2788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((PPP_PROTOCOL(frame) & 0x8000) != 0)
2798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;		/* shouldn't get any of these anyway */
2808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!active_packet(frame, len))
2818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
2828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pkt = (struct packet *) malloc(sizeof(struct packet) + len);
2848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (pkt != NULL) {
2858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pkt->length = len;
2868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pkt->next = NULL;
2878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	memcpy(pkt->data, frame, len);
2888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (pend_q == NULL)
2898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    pend_q = pkt;
2908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else
2918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    pend_qtail->next = pkt;
2928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pend_qtail = pkt;
2938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
2948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
2958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * demand_rexmit - Resend all those frames which we got via the
2998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * loopback, now that the real serial link is up.
3008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
3018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
3028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectdemand_rexmit(proto)
3038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int proto;
3048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct packet *pkt, *prev, *nextpkt;
3068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    prev = NULL;
3088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pkt = pend_q;
3098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pend_q = NULL;
3108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (; pkt != NULL; pkt = nextpkt) {
3118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	nextpkt = pkt->next;
3128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (PPP_PROTOCOL(pkt->data) == proto) {
3138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    output(0, pkt->data, pkt->length);
3148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    free(pkt);
3158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else {
3168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (prev == NULL)
3178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		pend_q = pkt;
3188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    else
3198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		prev->next = pkt;
3208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    prev = pkt;
3218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
3228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pend_qtail = prev;
3248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (prev != NULL)
3258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	prev->next = NULL;
3268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
3298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Scan a packet to decide whether it is an "active" packet,
3308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * that is, whether it is worth bringing up the link for.
3318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
3328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
3338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectactive_packet(p, len)
3348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unsigned char *p;
3358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
3368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int proto, i;
3388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct protent *protp;
3398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len < PPP_HDRLEN)
3418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
3428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    proto = PPP_PROTOCOL(p);
3438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef PPP_FILTER
3448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (pass_filter.bf_len != 0
3458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& bpf_filter(pass_filter.bf_insns, p, len, len) == 0)
3468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
3478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (active_filter.bf_len != 0
3488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& bpf_filter(active_filter.bf_insns, p, len, len) == 0)
3498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
3508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
3518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 0; (protp = protocols[i]) != NULL; ++i) {
3528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) {
3538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!protp->enabled_flag)
3548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return 0;
3558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (protp->active_pkt == NULL)
3568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return 1;
3578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return (*protp->active_pkt)(p, len);
3588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
3598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;			/* not a supported protocol !!?? */
3618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
362