18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp.c - PPP IPX Control Protocol.
38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright (c) 1984-2000 Carnegie Mellon University. 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. Redistributions in binary form must reproduce the above copyright
148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    notice, this list of conditions and the following disclaimer in
158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    the documentation and/or other materials provided with the
168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    distribution.
178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 3. The name "Carnegie Mellon University" must not be used to
198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    endorse or promote products derived from this software without
208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    prior written permission. For permission or any legal
218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    details, please contact
228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      Office of Technology Transfer
238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      Carnegie Mellon University
248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      5000 Forbes Avenue
258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      Pittsburgh, PA  15213-3890
268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      (412) 268-4387, fax: (412) 268-7395
278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      tech-transfer@andrew.cmu.edu
288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 4. Redistributions of any form whatsoever must retain the following
308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    acknowledgment:
318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    "This product includes software developed by Computing Services
328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef IPX_CHANGE
448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define RCSID	"$Id: ipxcp.c,v 1.23 2004/11/13 02:28:15 paulus Exp $"
468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * TODO:
498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdio.h>
528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h>
538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <unistd.h>
548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <ctype.h>
558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/types.h>
568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/socket.h>
578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <netinet/in.h>
588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppd.h"
608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "fsm.h"
618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "ipxcp.h"
628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pathnames.h"
638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "magic.h"
648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic const char rcsid[] = RCSID;
668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* global vars */
688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_options ipxcp_wantoptions[NUM_PPP];	/* Options that we want to request */
698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_options ipxcp_gotoptions[NUM_PPP];	/* Options that peer ack'd */
708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_options ipxcp_allowoptions[NUM_PPP];	/* Options we allow peer to request */
718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_options ipxcp_hisoptions[NUM_PPP];	/* Options that we ack'd */
728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define wo (&ipxcp_wantoptions[0])
748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ao (&ipxcp_allowoptions[0])
758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define go (&ipxcp_gotoptions[0])
768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ho (&ipxcp_hisoptions[0])
778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Callbacks for fsm code.  (CI = Configuration Information)
808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ipxcp_resetci __P((fsm *));	/* Reset our CI */
828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  ipxcp_cilen __P((fsm *));		/* Return length of our CI */
838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ipxcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  ipxcp_ackci __P((fsm *, u_char *, int));	/* Peer ack'd our CI */
858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  ipxcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */
868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  ipxcp_rejci __P((fsm *, u_char *, int));	/* Peer rej'd our CI */
878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  ipxcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ipxcp_up __P((fsm *));		/* We're UP */
898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ipxcp_down __P((fsm *));		/* We're DOWN */
908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ipxcp_finished __P((fsm *));	/* Don't need lower layer */
918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ipxcp_script __P((fsm *, char *)); /* Run an up/down script */
928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectfsm ipxcp_fsm[NUM_PPP];		/* IPXCP fsm structure */
948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic fsm_callbacks ipxcp_callbacks = { /* IPXCP callback routines */
968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_resetci,		/* Reset our Configuration Information */
978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_cilen,		/* Length of our Configuration Information */
988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_addci,		/* Add our Configuration Information */
998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_ackci,		/* ACK our Configuration Information */
1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_nakci,		/* NAK our Configuration Information */
1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_rejci,		/* Reject our Configuration Information */
1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_reqci,		/* Request peer's Configuration Information */
1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_up,			/* Called when fsm reaches OPENED state */
1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_down,			/* Called when fsm leaves OPENED state */
1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,			/* Called when we want the lower layer up */
1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_finished,		/* Called when we want the lower layer down */
1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,			/* Called when Protocol-Reject received */
1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,			/* Retransmission is necessary */
1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,			/* Called to handle protocol-specific codes */
1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "IPXCP"			/* String name of protocol */
1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Command-line options.
1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int setipxnode __P((char **));
1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void printipxnode __P((option_t *,
1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			      void (*)(void *, char *, ...), void *));
1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int setipxname __P((char **));
1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic option_t ipxcp_option_list[] = {
1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "ipx", o_bool, &ipxcp_protent.enabled_flag,
1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Enable IPXCP (and IPX)", OPT_PRIO | 1 },
1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "+ipx", o_bool, &ipxcp_protent.enabled_flag,
1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Enable IPXCP (and IPX)", OPT_PRIOSUB | OPT_ALIAS | 1 },
1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "noipx", o_bool, &ipxcp_protent.enabled_flag,
1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable IPXCP (and IPX)", OPT_PRIOSUB },
1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "-ipx", o_bool, &ipxcp_protent.enabled_flag,
1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Disable IPXCP (and IPX)", OPT_PRIOSUB | OPT_ALIAS },
1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "ipx-network", o_uint32, &ipxcp_wantoptions[0].our_network,
1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set our IPX network number", OPT_PRIO, &ipxcp_wantoptions[0].neg_nn },
1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "ipxcp-accept-network", o_bool, &ipxcp_wantoptions[0].accept_network,
1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Accept peer IPX network number", 1,
1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ipxcp_allowoptions[0].accept_network },
1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "ipx-node", o_special, (void *)setipxnode,
1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set IPX node number", OPT_A2PRINTER, (void *)printipxnode },
1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "ipxcp-accept-local", o_bool, &ipxcp_wantoptions[0].accept_local,
1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Accept our IPX address", 1,
1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ipxcp_allowoptions[0].accept_local },
1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "ipxcp-accept-remote", o_bool, &ipxcp_wantoptions[0].accept_remote,
1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Accept peer's IPX address", 1,
1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ipxcp_allowoptions[0].accept_remote },
1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "ipx-routing", o_int, &ipxcp_wantoptions[0].router,
1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set IPX routing proto number", OPT_PRIO,
1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      &ipxcp_wantoptions[0].neg_router },
1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "ipx-router-name", o_special, setipxname,
1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set IPX router name", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC,
1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project       &ipxcp_wantoptions[0].name },
1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "ipxcp-restart", o_int, &ipxcp_fsm[0].timeouttime,
1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set timeout for IPXCP", OPT_PRIO },
1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "ipxcp-max-terminate", o_int, &ipxcp_fsm[0].maxtermtransmits,
1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set max #xmits for IPXCP term-reqs", OPT_PRIO },
1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "ipxcp-max-configure", o_int, &ipxcp_fsm[0].maxconfreqtransmits,
1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set max #xmits for IPXCP conf-reqs", OPT_PRIO },
1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "ipxcp-max-failure", o_int, &ipxcp_fsm[0].maxnakloops,
1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set max #conf-naks for IPXCP", OPT_PRIO },
1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { NULL }
1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Protocol entry points.
1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ipxcp_init __P((int));
1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ipxcp_open __P((int));
1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ipxcp_close __P((int, char *));
1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ipxcp_lowerup __P((int));
1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ipxcp_lowerdown __P((int));
1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ipxcp_input __P((int, u_char *, int));
1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void ipxcp_protrej __P((int));
1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  ipxcp_printpkt __P((u_char *, int,
1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				void (*) __P((void *, char *, ...)), void *));
1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct protent ipxcp_protent = {
1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    PPP_IPXCP,
1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_init,
1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_input,
1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_protrej,
1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_lowerup,
1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_lowerdown,
1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_open,
1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_close,
1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_printpkt,
1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,
1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    0,
1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "IPXCP",
1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "IPX",
1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_option_list,
1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,
1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL,
2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    NULL
2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Lengths of configuration options.
2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_VOID	2
2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_COMPLETE	2	/* length of complete option */
2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_NETN	6	/* network number length option */
2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_NODEN	8	/* node number length option */
2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_PROTOCOL	4	/* Minimum length of routing protocol */
2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_NAME	3	/* Minimum length of router name */
2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CILEN_COMPRESS	4	/* Minimum length of compression protocol */
2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CODENAME(x)	((x) == CONFACK ? "ACK" : \
2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 (x) == CONFNAK ? "NAK" : "REJ")
2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int ipxcp_is_up;
2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *ipx_ntoa __P((u_int32_t));
2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Used in printing the node number */
2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NODE(base) base[0], base[1], base[2], base[3], base[4], base[5]
2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Used to generate the proper bit mask */
2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define BIT(num)   (1 << (num))
2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Convert from internal to external notation
2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic short int
2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectto_external(internal)
2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectshort int internal;
2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    short int  external;
2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (internal & BIT(IPX_NONE) )
2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        external = IPX_NONE;
2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else
2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        external = RIP_SAP;
2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return external;
2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Make a string representation of a network IP address.
2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *
2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipx_ntoa(ipxaddr)
2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_int32_t ipxaddr;
2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    static char b[64];
2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf(b, sizeof(b), "%x", ipxaddr);
2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return b;
2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic u_char *
2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsetipxnodevalue(src,dst)
2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *src, *dst;
2638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int indx;
2658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int item;
2668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (;;) {
2688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        if (!isxdigit (*src))
2698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
2708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (indx = 0; indx < 5; ++indx) {
2728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    dst[indx] <<= 4;
2738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    dst[indx] |= (dst[indx + 1] >> 4) & 0x0F;
2748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
2758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	item = toupper (*src) - '0';
2778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (item > 9)
2788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    item -= 7;
2798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	dst[5] = (dst[5] << 4) | item;
2818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	++src;
2828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
2838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return src;
2848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int ipx_prio_our, ipx_prio_his;
2878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
2898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsetipxnode(argv)
2908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char **argv;
2918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *end;
2938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int have_his = 0;
2948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char our_node[6];
2958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char his_node[6];
2968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset (our_node, 0, 6);
2988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset (his_node, 0, 6);
2998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    end = setipxnodevalue (*argv, our_node);
3018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (*end == ':') {
3028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	have_his = 1;
3038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	end = setipxnodevalue (++end, his_node);
3048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (*end == '\0') {
3078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        ipxcp_wantoptions[0].neg_node = 1;
3088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (option_priority >= ipx_prio_our) {
3098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    memcpy(&ipxcp_wantoptions[0].our_node[0], our_node, 6);
3108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ipx_prio_our = option_priority;
3118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
3128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (have_his && option_priority >= ipx_prio_his) {
3138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    memcpy(&ipxcp_wantoptions[0].his_node[0], his_node, 6);
3148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ipx_prio_his = option_priority;
3158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
3168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        return 1;
3178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    option_error("invalid parameter '%s' for ipx-node option", *argv);
3208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
3218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
3248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectprintipxnode(opt, printer, arg)
3258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    option_t *opt;
3268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void (*printer) __P((void *, char *, ...));
3278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void *arg;
3288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	unsigned char *p;
3308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p = ipxcp_wantoptions[0].our_node;
3328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ipx_prio_our)
3338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		printer(arg, "%.2x%.2x%.2x%.2x%.2x%.2x",
3348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			p[0], p[1], p[2], p[3], p[4], p[5]);
3358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, ":");
3368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p = ipxcp_wantoptions[0].his_node;
3378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ipx_prio_his)
3388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		printer(arg, "%.2x%.2x%.2x%.2x%.2x%.2x",
3398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			p[0], p[1], p[2], p[3], p[4], p[5]);
3408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
3438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsetipxname (argv)
3448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char **argv;
3458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *dest = ipxcp_wantoptions[0].name;
3478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *src  = *argv;
3488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int  count;
3498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char ch;
3508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_wantoptions[0].neg_name  = 1;
3528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_allowoptions[0].neg_name = 1;
3538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset (dest, '\0', sizeof (ipxcp_wantoptions[0].name));
3548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    count = 0;
3568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (*src) {
3578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        ch = *src++;
3588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (! isalnum (ch) && ch != '_') {
3598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    option_error("IPX router name must be alphanumeric or _");
3608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
3618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
3628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (count >= sizeof (ipxcp_wantoptions[0].name) - 1) {
3648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    option_error("IPX router name is limited to %d characters",
3658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 sizeof (ipxcp_wantoptions[0].name) - 1);
3668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
3678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
3688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	dest[count++] = toupper (ch);
3708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    dest[count] = 0;
3728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
3748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
3778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_init - Initialize IPXCP.
3788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
3798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
3808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_init(unit)
3818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
3828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f = &ipxcp_fsm[unit];
3848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    f->unit	 = unit;
3868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    f->protocol	 = PPP_IPXCP;
3878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    f->callbacks = &ipxcp_callbacks;
3888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_init(&ipxcp_fsm[unit]);
3898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset (wo->name,	  0, sizeof (wo->name));
3918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset (wo->our_node, 0, sizeof (wo->our_node));
3928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset (wo->his_node, 0, sizeof (wo->his_node));
3938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->neg_nn	       = 1;
3958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->neg_complete   = 1;
3968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->network	       = 0;
3978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_node       = 1;
3998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_nn	       = 1;
4008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_name       = 1;
4018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_complete   = 1;
4028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->neg_router     = 1;
4038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->accept_local   = 0;
4058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->accept_remote  = 0;
4068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ao->accept_network = 0;
4078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->tried_rip      = 0;
4098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->tried_nlsp     = 0;
4108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copy the node number
4148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcopy_node (src, dst)
4188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *src, *dst;
4198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memcpy (dst, src, sizeof (ipxcp_wantoptions[0].our_node));
4218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Compare node numbers
4258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
4288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcompare_node (src, dst)
4298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *src, *dst;
4308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return memcmp (dst, src, sizeof (ipxcp_wantoptions[0].our_node)) == 0;
4328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Is the node number zero?
4368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
4398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectzero_node (node)
4408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *node;
4418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int indx;
4438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (indx = 0; indx < sizeof (ipxcp_wantoptions[0].our_node); ++indx)
4448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (node [indx] != 0)
4458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
4468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
4478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Increment the node number
4518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectinc_node (node)
4558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *node;
4568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char   *outp;
4588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t magic_num;
4598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    outp      = node;
4618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    magic_num = magic();
4628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *outp++   = '\0';
4638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *outp++   = '\0';
4648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    PUTLONG (magic_num, outp);
4658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_open - IPXCP is allowed to come up.
4698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_open(unit)
4728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
4738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_open(&ipxcp_fsm[unit]);
4758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_close - Take IPXCP down.
4798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_close(unit, reason)
4828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
4838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *reason;
4848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_close(&ipxcp_fsm[unit], reason);
4868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_lowerup - The lower layer is up.
4918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_lowerup(unit)
4948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
4958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_lowerup(&ipxcp_fsm[unit]);
4978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_lowerdown - The lower layer is down.
5028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
5048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_lowerdown(unit)
5058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
5068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_lowerdown(&ipxcp_fsm[unit]);
5088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_input - Input IPXCP packet.
5138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
5158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_input(unit, p, len)
5168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
5178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
5188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
5198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_input(&ipxcp_fsm[unit], p, len);
5218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_protrej - A Protocol-Reject was received for IPXCP.
5268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
5278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Pretend the lower layer went down, so we shut up.
5288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
5308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_protrej(unit)
5318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
5328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm_lowerdown(&ipxcp_fsm[unit]);
5348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_resetci - Reset our CI.
5398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
5418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_resetci(f)
5428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
5438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->req_node = wo->neg_node && ao->neg_node;
5458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->req_nn	 = wo->neg_nn	&& ao->neg_nn;
5468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (wo->our_network == 0) {
5488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	wo->neg_node	   = 1;
5498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ao->accept_network = 1;
5508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If our node number is zero then change it.
5538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (zero_node (wo->our_node)) {
5558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	inc_node (wo->our_node);
5568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ao->accept_local = 1;
5578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	wo->neg_node	 = 1;
5588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If his node number is zero then change it.
5618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (zero_node (wo->his_node)) {
5638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	inc_node (wo->his_node);
5648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ao->accept_remote = 1;
5658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If no routing agent was specified then we do RIP/SAP according to the
5688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * RFC documents. If you have specified something then OK. Otherwise, we
5698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * do RIP/SAP.
5708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ao->router == 0) {
5728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ao->router |= BIT(RIP_SAP);
5738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	wo->router |= BIT(RIP_SAP);
5748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Always specify a routing protocol unless it was REJected. */
5778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wo->neg_router = 1;
5788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Start with these default values
5808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *go = *wo;
5828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_cilen - Return length of our CI.
5868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
5898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_cilen(f)
5908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
5918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
5938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    len	 = go->neg_nn	    ? CILEN_NETN     : 0;
5958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    len += go->neg_node	    ? CILEN_NODEN    : 0;
5968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    len += go->neg_name	    ? CILEN_NAME + strlen (go->name) - 1 : 0;
5978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* RFC says that defaults should not be included. */
5998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg_router && to_external(go->router) != RIP_SAP)
6008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        len += CILEN_PROTOCOL;
6018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (len);
6038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
6048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
6078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_addci - Add our desired CIs to a packet.
6088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
6108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_addci(f, ucp, lenp)
6118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
6128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *ucp;
6138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int *lenp;
6148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
6158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
6168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Add the options to the record.
6178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg_nn) {
6198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR (IPX_NETWORK_NUMBER, ucp);
6208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR (CILEN_NETN, ucp);
6218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTLONG (go->our_network, ucp);
6228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg_node) {
6258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int indx;
6268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR (IPX_NODE_NUMBER, ucp);
6278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR (CILEN_NODEN, ucp);
6288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (indx = 0; indx < sizeof (go->our_node); ++indx)
6298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    PUTCHAR (go->our_node[indx], ucp);
6308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg_name) {
6338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int cilen = strlen (go->name);
6348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int indx;
6358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR (IPX_ROUTER_NAME, ucp);
6368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR (CILEN_NAME + cilen - 1, ucp);
6378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (indx = 0; indx < cilen; ++indx)
6388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    PUTCHAR (go->name [indx], ucp);
6398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg_router) {
6428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        short external = to_external (go->router);
6438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (external != RIP_SAP) {
6448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    PUTCHAR  (IPX_ROUTER_PROTOCOL, ucp);
6458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    PUTCHAR  (CILEN_PROTOCOL,      ucp);
6468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    PUTSHORT (external,            ucp);
6478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
6488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
6508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
6528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_ackci - Ack our CIs.
6538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
6548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns:
6558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	0 - Ack was bad.
6568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	1 - Ack was good.
6578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
6598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_ackci(f, p, len)
6608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
6618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
6628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
6638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
6648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cilen, citype, cishort;
6658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char cichar;
6668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cilong;
6678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCIVOID(opt, neg) \
6698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
6708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_VOID) < 0) \
6718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
6728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
6738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
6748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_VOID || \
6758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
6768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
6778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCICOMPLETE(opt,neg)	ACKCIVOID(opt, neg)
6808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCICHARS(opt, neg, val, cnt) \
6828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
6838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int indx, count = cnt; \
6848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= (count + 2); \
6858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < 0) \
6868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
6878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
6888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
6898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != (count + 2) || \
6908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
6918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
6928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (indx = 0; indx < count; ++indx) {\
6938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(cichar, p); \
6948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cichar != ((u_char *) &val)[indx]) \
6958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	       break; \
6968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}\
6978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (indx != count) \
6988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
6998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCINODE(opt,neg,val) ACKCICHARS(opt,neg,val,sizeof(val))
7028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCINAME(opt,neg,val) ACKCICHARS(opt,neg,val,strlen(val))
7038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCINETWORK(opt, neg, val) \
7058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_NETN) < 0) \
7078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
7088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
7098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
7108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_NETN || \
7118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
7128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
7138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, p); \
7148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilong != val) \
7158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
7168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ACKCIPROTO(opt, neg, val) \
7198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg) { \
7208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < 2) \
7218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
7228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
7238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
7248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_PROTOCOL || citype != opt) \
7258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
7268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= cilen; \
7278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < 0) \
7288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
7298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
7308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort != to_external (val) || cishort == RIP_SAP) \
7318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
7328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      }
7338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
7348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Process the ACK frame in the order in which the frame was assembled
7358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
7368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    do {
7378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ACKCINETWORK  (IPX_NETWORK_NUMBER,  go->neg_nn,	    go->our_network);
7388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ACKCINODE     (IPX_NODE_NUMBER,	    go->neg_node,   go->our_node);
7398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ACKCINAME     (IPX_ROUTER_NAME,	    go->neg_name,   go->name);
7408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len > 0)
7418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ACKCIPROTO    (IPX_ROUTER_PROTOCOL, go->neg_router, go->router);
7428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
7438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This is the end of the record.
7448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
7458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len == 0)
7468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return (1);
7478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } while (0);
7488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
7498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * The frame is invalid
7508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
7518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    IPXCPDEBUG(("ipxcp_ackci: received bad Ack!"));
7528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (0);
7538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
7548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
7568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_nakci - Peer has sent a NAK for some of our CIs.
7578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This should not modify any state if the Nak is bad
7588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * or if IPXCP is in the OPENED state.
7598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
7608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns:
7618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	0 - Nak was bad.
7628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *	1 - Nak was good.
7638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
7648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
7668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_nakci(f, p, len, treat_as_reject)
7678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
7688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
7698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
7708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int treat_as_reject;
7718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
7728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char citype, cilen, *next;
7738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short s;
7748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t l;
7758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_options no;		/* options we've seen Naks for */
7768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_options try;		/* options to request next time */
7778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    BZERO(&no, sizeof(no));
7798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    try = *go;
7808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (len >= CILEN_VOID) {
7828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR (citype, p);
7838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR (cilen,	 p);
7848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= cilen;
7858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen < CILEN_VOID || len < 0)
7868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad;
7878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	next = &p [cilen - CILEN_VOID];
7888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (citype) {
7908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case IPX_NETWORK_NUMBER:
7918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!go->neg_nn || no.neg_nn || (cilen != CILEN_NETN))
7928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
7938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    no.neg_nn = 1;
7948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETLONG(l, p);
7968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (treat_as_reject)
7978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_nn = 0;
7988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    else if (l && ao->accept_network)
7998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.our_network = l;
8008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
8018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case IPX_NODE_NUMBER:
8038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!go->neg_node || no.neg_node || (cilen != CILEN_NODEN))
8048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
8058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    no.neg_node = 1;
8068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (treat_as_reject)
8088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.neg_node = 0;
8098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    else if (!zero_node (p) && ao->accept_local &&
8108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     ! compare_node (p, ho->his_node))
8118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		copy_node (p, try.our_node);
8128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
8138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* This has never been sent. Ignore the NAK frame */
8158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case IPX_COMPRESSION_PROTOCOL:
8168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad;
8178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case IPX_ROUTER_PROTOCOL:
8198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!go->neg_router || (cilen < CILEN_PROTOCOL))
8208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
8218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETSHORT (s, p);
8238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (s > 15)         /* This is just bad, but ignore for now. */
8248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	        break;
8258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    s = BIT(s);
8278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (no.router & s)  /* duplicate NAKs are always bad */
8288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		goto bad;
8298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (no.router == 0) /* Reset on first NAK only */
8318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		try.router = 0;
8328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    no.router      |= s;
8348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    try.router     |= s;
8358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    try.neg_router  = 1;
8368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
8378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* These, according to the RFC, must never be NAKed. */
8398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case IPX_ROUTER_NAME:
8408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case IPX_COMPLETE:
8418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto bad;
8428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* These are for options which we have not seen. */
8448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	default:
8458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
8468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
8478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	p = next;
8488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
8518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Do not permit the peer to force a router protocol which we do not
8528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * support. However, default to the condition that will accept "NONE".
8538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
8548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    try.router &= (ao->router | BIT(IPX_NONE));
8558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (try.router == 0 && ao->router != 0)
8568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	try.router = BIT(IPX_NONE);
8578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (try.router != 0)
8598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        try.neg_router = 1;
8608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
8628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * OK, the Nak is good.  Now we can update state.
8638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If there are any options left, we ignore them.
8648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
8658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (f->state != OPENED)
8668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*go = try;
8678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
8698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbad:
8718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    IPXCPDEBUG(("ipxcp_nakci: received bad Nak!"));
8728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
8738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
8748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
8768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_rejci - Reject some of our CIs.
8778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
8788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
8798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_rejci(f, p, len)
8808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
8818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
8828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
8838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
8848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cilen, citype, cishort;
8858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char cichar;
8868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cilong;
8878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_options try;		/* options to request next time */
8888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCINETWORK(opt, neg, val) \
8908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg && p[0] == opt) { \
8918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_NETN) < 0) \
8928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
8938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
8948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
8958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_NETN || \
8968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
8978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
8988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETLONG(cilong, p); \
8998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilong != val) \
9008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
9018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	neg = 0; \
9028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCICHARS(opt, neg, val, cnt) \
9058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg && p[0] == opt) { \
9068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int indx, count = cnt; \
9078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= (count + 2); \
9088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < 0) \
9098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
9108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
9118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
9128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != (count + 2) || \
9138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    citype != opt) \
9148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
9158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (indx = 0; indx < count; ++indx) {\
9168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(cichar, p); \
9178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cichar != ((u_char *) &val)[indx]) \
9188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	       break; \
9198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}\
9208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (indx != count) \
9218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
9228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	neg = 0; \
9238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCINODE(opt,neg,val) REJCICHARS(opt,neg,val,sizeof(val))
9268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCINAME(opt,neg,val) REJCICHARS(opt,neg,val,strlen(val))
9278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCIVOID(opt, neg) \
9298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg && p[0] == opt) { \
9308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_VOID) < 0) \
9318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
9328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
9338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
9348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_VOID || citype != opt) \
9358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
9368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	neg = 0; \
9378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* a reject for RIP/SAP is invalid since we don't send it and you can't
9408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project   reject something which is not sent. (You can NAK, but you can't REJ.) */
9418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define REJCIPROTO(opt, neg, val, bit) \
9428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (neg && p[0] == opt) { \
9438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((len -= CILEN_PROTOCOL) < 0) \
9448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
9458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p); \
9468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p); \
9478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cilen != CILEN_PROTOCOL) \
9488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
9498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(cishort, p); \
9508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cishort != to_external (val) || cishort == RIP_SAP) \
9518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break; \
9528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	neg = 0; \
9538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Any Rejected CIs must be in exactly the same order that we sent.
9568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Check packet length and CI length at each step.
9578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If we find any deviations, then this packet is bad.
9588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    try = *go;
9608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    do {
9628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	REJCINETWORK (IPX_NETWORK_NUMBER,  try.neg_nn,	   try.our_network);
9638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	REJCINODE    (IPX_NODE_NUMBER,	   try.neg_node,   try.our_node);
9648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	REJCINAME    (IPX_ROUTER_NAME,	   try.neg_name,   try.name);
9658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	REJCIPROTO   (IPX_ROUTER_PROTOCOL, try.neg_router, try.router, 0);
9668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This is the end of the record.
9688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len == 0) {
9708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (f->state != OPENED)
9718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		*go = try;
9728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return (1);
9738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
9748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } while (0);
9758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * The frame is invalid at this point.
9778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    IPXCPDEBUG(("ipxcp_rejci: received bad Reject!"));
9798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
9808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
9818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_reqci - Check the peer's requested CIs and send appropriate response.
9848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
9858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
9868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * appropriately.  If reject_if_disagree is non-zero, doesn't return
9878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * CONFNAK; returns CONFREJ if it can't return CONFACK.
9888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
9908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_reqci(f, inp, len, reject_if_disagree)
9918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
9928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *inp;		/* Requested CIs */
9938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int *len;			/* Length of requested CIs */
9948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int reject_if_disagree;
9958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *cip, *next;		/* Pointer to current and next CIs */
9978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cilen, citype;	/* Parsed len, type */
9988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cishort;		/* Parsed short value */
9998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cinetwork;	/* Parsed address values */
10008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int rc = CONFACK;		/* Final packet return code */
10018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int orc;			/* Individual option return code */
10028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;			/* Pointer to next char to parse */
10038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *ucp = inp;		/* Pointer to current output char */
10048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int l = *len;		/* Length left */
10058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
10078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Reset all his options.
10088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
10098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    BZERO(ho, sizeof(*ho));
10108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
10128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Process all his options.
10138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
10148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    next = inp;
10158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (l) {
10168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	orc = CONFACK;			/* Assume success */
10178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cip = p = next;			/* Remember begining of CI */
10188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (l < 2 ||			/* Not enough data for CI header or */
10198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p[1] < 2 ||			/*  CI length too small or */
10208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p[1] > l) {			/*  CI length too big? */
10218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    IPXCPDEBUG(("ipxcp_reqci: bad CI length!"));
10228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    orc = CONFREJ;		/* Reject bad CI */
10238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    cilen = l;			/* Reject till end of packet */
10248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    l = 0;			/* Don't loop again */
10258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    goto endswitch;
10268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
10278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(citype, p);		/* Parse CI type */
10288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(cilen, p);		/* Parse CI length */
10298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	l -= cilen;			/* Adjust remaining length */
10308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	next += cilen;			/* Step to next CI */
10318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (citype) {		/* Check CI type */
10338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
10348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * The network number must match. Choose the larger of the two.
10358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
10368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case IPX_NETWORK_NUMBER:
10378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* if we wont negotiate the network number or the length is wrong
10388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	       then reject the option */
10398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if ( !ao->neg_nn || cilen != CILEN_NETN ) {
10408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
10418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
10428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
10438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETLONG(cinetwork, p);
10448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* If the network numbers match then acknowledge them. */
10468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cinetwork != 0) {
10478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->his_network = cinetwork;
10488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->neg_nn	= 1;
10498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (wo->our_network == cinetwork)
10508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    break;
10518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
10528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If the network number is not given or we don't accept their change or
10538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the network number is too small then NAK it.
10548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
10558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (! ao->accept_network || cinetwork < wo->our_network) {
10568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    DECPTR (sizeof (u_int32_t), p);
10578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    PUTLONG (wo->our_network, p);
10588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    orc = CONFNAK;
10598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
10608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
10618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
10628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
10638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * The peer sent '0' for the network. Give it ours if we have one.
10648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
10658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (go->our_network != 0) {
10668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		DECPTR (sizeof (u_int32_t), p);
10678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTLONG (wo->our_network, p);
10688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFNAK;
10698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
10708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * We don't have one. Reject the value.
10718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
10728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else
10738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
10748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
10768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
10778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * The node number is required
10788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
10798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case IPX_NODE_NUMBER:
10808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* if we wont negotiate the node number or the length is wrong
10818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	       then reject the option */
10828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if ( cilen != CILEN_NODEN ) {
10838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
10848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
10858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
10868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    copy_node (p, ho->his_node);
10888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_node = 1;
10898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
10908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If the remote does not have a number and we do then NAK it with the value
10918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * which we have for it. (We never have a default value of zero.)
10928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
10938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (zero_node (ho->his_node)) {
10948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFNAK;
10958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		copy_node (wo->his_node, p);
10968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		INCPTR (sizeof (wo->his_node), p);
10978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
10988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
10998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
11008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If you have given me the expected network node number then I'll accept
11018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * it now.
11028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
11038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (compare_node (wo->his_node, ho->his_node)) {
11048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFACK;
11058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->neg_node = 1;
11068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		INCPTR (sizeof (wo->his_node), p);
11078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
11088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
11098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
11108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If his node number is the same as ours then ask him to try the next
11118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * value.
11128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
11138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (compare_node (ho->his_node, go->our_node)) {
11148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		inc_node (ho->his_node);
11158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFNAK;
11168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		copy_node (ho->his_node, p);
11178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		INCPTR (sizeof (wo->his_node), p);
11188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
11198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
11208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
11218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If we don't accept a new value then NAK it.
11228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
11238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (! ao->accept_remote) {
11248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		copy_node (wo->his_node, p);
11258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		INCPTR (sizeof (wo->his_node), p);
11268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFNAK;
11278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
11288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
11298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    orc = CONFACK;
11308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_node = 1;
11318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    INCPTR (sizeof (wo->his_node), p);
11328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
11338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
11348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Compression is not desired at this time. It is always rejected.
11358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
11368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case IPX_COMPRESSION_PROTOCOL:
11378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    orc = CONFREJ;
11388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
11398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
11408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * The routing protocol is a bitmask of various types. Any combination
11418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * of the values RIP_SAP and NLSP are permissible. 'IPX_NONE' for no
11428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * routing protocol must be specified only once.
11438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
11448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case IPX_ROUTER_PROTOCOL:
11458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if ( !ao->neg_router || cilen < CILEN_PROTOCOL ) {
11468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
11478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
11488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
11498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETSHORT (cishort, p);
11518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (wo->neg_router == 0) {
11538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	        wo->neg_router = 1;
11548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		wo->router     = BIT(IPX_NONE);
11558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
11568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if ((cishort == IPX_NONE && ho->router != 0) ||
11588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		(ho->router & BIT(IPX_NONE))) {
11598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
11608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
11618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
11628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    cishort = BIT(cishort);
11648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (ho->router & cishort) {
11658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
11668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
11678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
11688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->router	  |= cishort;
11708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ho->neg_router = 1;
11718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* Finally do not allow a router protocol which we do not
11738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	       support. */
11748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if ((cishort & (ao->router | BIT(IPX_NONE))) == 0) {
11768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	        int protocol;
11778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (cishort == BIT(NLSP) &&
11798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    (ao->router & BIT(RIP_SAP)) &&
11808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    !wo->tried_rip) {
11818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    protocol      = RIP_SAP;
11828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    wo->tried_rip = 1;
11838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else
11848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    protocol = IPX_NONE;
11858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		DECPTR (sizeof (u_int16_t), p);
11878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTSHORT (protocol, p);
11888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFNAK;
11898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
11908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
11918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
11928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * The router name is advisorary. Just accept it if it is not too large.
11938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
11948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case IPX_ROUTER_NAME:
11958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cilen >= CILEN_NAME) {
11968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		int name_size = cilen - CILEN_NAME;
11978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (name_size > sizeof (ho->name))
11988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    name_size = sizeof (ho->name) - 1;
11998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		memset (ho->name, 0, sizeof (ho->name));
12008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		memcpy (ho->name, p, name_size);
12018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->name [name_size] = '\0';
12028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->neg_name = 1;
12038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFACK;
12048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
12058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
12068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    orc = CONFREJ;
12078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
12098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This is advisorary.
12108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
12118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case IPX_COMPLETE:
12128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (cilen != CILEN_COMPLETE)
12138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;
12148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    else {
12158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ho->neg_complete = 1;
12168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFACK;
12178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
12188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
12208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * All other entries are not known at this time.
12218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
12228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	default:
12238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    orc = CONFREJ;
12248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
12258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectendswitch:
12278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (orc == CONFACK &&		/* Good CI */
12288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    rc != CONFACK)		/*  but prior CI wasnt? */
12298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;			/* Don't send this one */
12308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (orc == CONFNAK) {		/* Nak this CI? */
12328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (reject_if_disagree)	/* Getting fed up with sending NAKs? */
12338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		orc = CONFREJ;		/* Get tough if so */
12348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (rc == CONFREJ)		/* Rejecting prior CI? */
12358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		continue;		/* Don't send this one */
12368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (rc == CONFACK) {	/* Ack'd all prior CIs? */
12378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		rc  = CONFNAK;		/* Not anymore... */
12388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ucp = inp;		/* Backup */
12398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
12408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (orc == CONFREJ &&		/* Reject this CI */
12438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    rc != CONFREJ) {		/*  but no prior ones? */
12448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    rc = CONFREJ;
12458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ucp = inp;			/* Backup */
12468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Need to move CI? */
12498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ucp != cip)
12508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    BCOPY(cip, ucp, cilen);	/* Move it */
12518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Update output pointer */
12538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(cilen, ucp);
12548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
12578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * If we aren't rejecting this packet, and we want to negotiate
12588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * their address, and they didn't send their address, then we
12598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * send a NAK with a IPX_NODE_NUMBER option appended. We assume the
12608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * input buffer is long enough that we can append the extra
12618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * option safely.
12628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
12638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rc != CONFREJ && !ho->neg_node &&
12658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	wo->req_nn && !reject_if_disagree) {
12668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (rc == CONFACK) {
12678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    rc = CONFNAK;
12688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    wo->req_nn = 0;		/* don't ask again */
12698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ucp = inp;			/* reset pointer */
12708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (zero_node (wo->his_node))
12738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    inc_node (wo->his_node);
12748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR (IPX_NODE_NUMBER, ucp);
12768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR (CILEN_NODEN, ucp);
12778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	copy_node (wo->his_node, ucp);
12788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR (sizeof (wo->his_node), ucp);
12798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *len = ucp - inp;			/* Compute output length */
12828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    IPXCPDEBUG(("ipxcp: returning Configure-%s", CODENAME(rc)));
12838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (rc);			/* Return final code */
12848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
12858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
12878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_up - IPXCP has come UP.
12888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
12898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Configure the IP network interface appropriately and bring it up.
12908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
12918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
12938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_up(f)
12948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
12958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
12968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit = f->unit;
12978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    IPXCPDEBUG(("ipxcp: up"));
12998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* The default router protocol is RIP/SAP. */
13018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ho->router == 0)
13028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        ho->router = BIT(RIP_SAP);
13038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->router == 0)
13058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        go->router = BIT(RIP_SAP);
13068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Fetch the network number */
13088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!ho->neg_nn)
13098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ho->his_network = wo->his_network;
13108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!ho->neg_node)
13128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	copy_node (wo->his_node, ho->his_node);
13138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!wo->neg_node && !go->neg_node)
13158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	copy_node (wo->our_node, go->our_node);
13168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (zero_node (go->our_node)) {
13188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        static char errmsg[] = "Could not determine local IPX node address";
13198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (debug)
13208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error(errmsg);
13218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ipxcp_close(f->unit, errmsg);
13228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
13238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    go->network = go->our_network;
13268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ho->his_network != 0 && ho->his_network > go->network)
13278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	go->network = ho->his_network;
13288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->network == 0) {
13308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        static char errmsg[] = "Can not determine network number";
13318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (debug)
13328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error(errmsg);
13338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ipxcp_close (unit, errmsg);
13348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
13358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* bring the interface up */
13388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!sifup(unit)) {
13398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (debug)
13408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    warn("sifup failed (IPX)");
13418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ipxcp_close(unit, "Interface configuration failed");
13428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
13438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_is_up = 1;
13458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* set the network number for IPX */
13478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!sipxfaddr(unit, go->network, go->our_node)) {
13488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (debug)
13498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    warn("sipxfaddr failed");
13508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ipxcp_close(unit, "Interface configuration failed");
13518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
13528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    np_up(f->unit, PPP_IPX);
13558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
13578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Execute the ipx-up script, like this:
13588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     *	/etc/ppp/ipx-up interface tty speed local-IPX remote-IPX
13598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
13608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_script (f, _PATH_IPXUP);
13628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_down - IPXCP has gone DOWN.
13668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
13678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Take the IP network interface down, clear its addresses
13688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * and delete routes through it.
13698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
13728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_down(f)
13738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
13748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    IPXCPDEBUG(("ipxcp: down"));
13768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!ipxcp_is_up)
13788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
13798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_is_up = 0;
13808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    np_down(f->unit, PPP_IPX);
13818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cipxfaddr(f->unit);
13828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    sifnpmode(f->unit, PPP_IPX, NPMODE_DROP);
13838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    sifdown(f->unit);
13848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipxcp_script (f, _PATH_IPXDOWN);
13858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_finished - possibly shut down the lower layers.
13908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
13928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_finished(f)
13938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
13948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    np_finished(f->unit, PPP_IPX);
13968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_script - Execute a script with arguments
14018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * interface-name tty-name speed local-IPX remote-IPX networks.
14028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
14048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_script(f, script)
14058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fsm *f;
14068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *script;
14078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char strspeed[32],	 strlocal[32],	   strremote[32];
14098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char strnetwork[32], strpid[32];
14108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *argv[14],	 strproto_lcl[32], strproto_rmt[32];
14118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf(strpid, sizeof(strpid), "%d", getpid());
14138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf(strspeed, sizeof(strspeed),"%d", baud_rate);
14148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strproto_lcl[0] = '\0';
14168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (go->neg_router && ((go->router & BIT(IPX_NONE)) == 0)) {
14178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (go->router & BIT(RIP_SAP))
14188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    strlcpy (strproto_lcl, "RIP ", sizeof(strproto_lcl));
14198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (go->router & BIT(NLSP))
14208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    strlcat (strproto_lcl, "NLSP ", sizeof(strproto_lcl));
14218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strproto_lcl[0] == '\0')
14248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strlcpy (strproto_lcl, "NONE ", sizeof(strproto_lcl));
14258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strproto_lcl[strlen (strproto_lcl)-1] = '\0';
14278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strproto_rmt[0] = '\0';
14298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ho->neg_router && ((ho->router & BIT(IPX_NONE)) == 0)) {
14308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ho->router & BIT(RIP_SAP))
14318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    strlcpy (strproto_rmt, "RIP ", sizeof(strproto_rmt));
14328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ho->router & BIT(NLSP))
14338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    strlcat (strproto_rmt, "NLSP ", sizeof(strproto_rmt));
14348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strproto_rmt[0] == '\0')
14378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strlcpy (strproto_rmt, "NONE ", sizeof(strproto_rmt));
14388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strproto_rmt[strlen (strproto_rmt)-1] = '\0';
14408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy (strnetwork, ipx_ntoa (go->network), sizeof(strnetwork));
14428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf (strlocal, sizeof(strlocal), "%0.6B", go->our_node);
14448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf (strremote, sizeof(strremote), "%0.6B", ho->his_node);
14468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[0]  = script;
14488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[1]  = ifname;
14498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[2]  = devnam;
14508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[3]  = strspeed;
14518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[4]  = strnetwork;
14528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[5]  = strlocal;
14538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[6]  = strremote;
14548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[7]  = strproto_lcl;
14558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[8]  = strproto_rmt;
14568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[9]  = go->name;
14578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[10] = ho->name;
14588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[11] = ipparam;
14598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[12] = strpid;
14608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    argv[13] = NULL;
14618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    run_program(script, argv, 0, NULL, NULL);
14628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ipxcp_printpkt - print the contents of an IPXCP packet.
14668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *ipxcp_codenames[] = {
14688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "ConfReq", "ConfAck", "ConfNak", "ConfRej",
14698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    "TermReq", "TermAck", "CodeRej"
14708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
14718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
14738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectipxcp_printpkt(p, plen, printer, arg)
14748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
14758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int plen;
14768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void (*printer) __P((void *, char *, ...));
14778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void *arg;
14788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int code, id, len, olen;
14808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *pstart, *optend;
14818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_short cishort;
14828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t cilong;
14838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (plen < HEADERLEN)
14858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
14868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pstart = p;
14878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    GETCHAR(code, p);
14888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    GETCHAR(id, p);
14898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    GETSHORT(len, p);
14908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (len < HEADERLEN || len > plen)
14918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
14928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (code >= 1 && code <= sizeof(ipxcp_codenames) / sizeof(char *))
14948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " %s", ipxcp_codenames[code-1]);
14958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else
14968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " code=0x%x", code);
14978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    printer(arg, " id=0x%x", id);
14988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    len -= HEADERLEN;
14998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch (code) {
15008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFREQ:
15018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFACK:
15028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFNAK:
15038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CONFREJ:
15048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* print option list */
15058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	while (len >= 2) {
15068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(code, p);
15078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    GETCHAR(olen, p);
15088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p -= 2;
15098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (olen < CILEN_VOID || olen > len) {
15108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
15128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    printer(arg, " <");
15138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    len -= olen;
15148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    optend = p + olen;
15158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    switch (code) {
15168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case IPX_NETWORK_NUMBER:
15178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_NETN) {
15188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
15198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETLONG(cilong, p);
15208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer (arg, "network %s", ipx_ntoa (cilong));
15218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
15228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case IPX_NODE_NUMBER:
15248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_NODEN) {
15258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
15268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer (arg, "node ");
15278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    while (p < optend) {
15288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			GETCHAR(code, p);
15298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "%.2x", (int) (unsigned int) (unsigned char) code);
15308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
15318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
15328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case IPX_COMPRESSION_PROTOCOL:
15348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_COMPRESS) {
15358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
15368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETSHORT (cishort, p);
15378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer (arg, "compression %d", (int) cishort);
15388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
15398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case IPX_ROUTER_PROTOCOL:
15418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_PROTOCOL) {
15428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
15438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    GETSHORT (cishort, p);
15448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer (arg, "router proto %d", (int) cishort);
15458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
15468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case IPX_ROUTER_NAME:
15488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen >= CILEN_NAME) {
15498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
15508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer (arg, "router name \"");
15518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    while (p < optend) {
15528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			GETCHAR(code, p);
15538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (code >= 0x20 && code <= 0x7E)
15548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    printer (arg, "%c", (int) (unsigned int) (unsigned char) code);
15558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			else
15568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    printer (arg, " \\%.2x", (int) (unsigned int) (unsigned char) code);
15578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
15588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer (arg, "\"");
15598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
15608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case IPX_COMPLETE:
15628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (olen == CILEN_COMPLETE) {
15638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    p += 2;
15648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    printer (arg, "complete");
15658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
15668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    default:
15688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
15698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
15708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    while (p < optend) {
15728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		GETCHAR(code, p);
15738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		printer(arg, " %.2x", (int) (unsigned int) (unsigned char) code);
15748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
15758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    printer(arg, ">");
15768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
15778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
15788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case TERMACK:
15808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case TERMREQ:
15818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len > 0 && *p >= ' ' && *p < 0x7f) {
15828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    printer(arg, " ");
15838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    print_string(p, len, printer, arg);
15848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    p += len;
15858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    len = 0;
15868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
15878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
15888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
15898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* print the rest of the bytes in the packet */
15918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (; len > 0; --len) {
15928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(code, p);
15938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " %.2x", (int) (unsigned int) (unsigned char) code);
15948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
15958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return p - pstart;
15978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
15988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* ifdef IPX_CHANGE */
1599