?? ipxcp.c
字號:
/* * ipxcp.c - PPP IPX Control Protocol. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */#ifdef IPX_CHANGE#define RCSID "$Id: ipxcp.c,v 1.24 2005/08/25 23:59:34 paulus Exp $"/* * TODO: */#include <stdio.h>#include <string.h>#include <unistd.h>#include <ctype.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include "pppd.h"#include "fsm.h"#include "ipxcp.h"#include "pathnames.h"#include "magic.h"static const char rcsid[] = RCSID;/* global vars */ipxcp_options ipxcp_wantoptions[NUM_PPP]; /* Options that we want to request */ipxcp_options ipxcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ipxcp_options ipxcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ipxcp_options ipxcp_hisoptions[NUM_PPP]; /* Options that we ack'd */#define wo (&ipxcp_wantoptions[0])#define ao (&ipxcp_allowoptions[0])#define go (&ipxcp_gotoptions[0])#define ho (&ipxcp_hisoptions[0])/* * Callbacks for fsm code. (CI = Configuration Information) */static void ipxcp_resetci __P((fsm *)); /* Reset our CI */static int ipxcp_cilen __P((fsm *)); /* Return length of our CI */static void ipxcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */static int ipxcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */static int ipxcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */static int ipxcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */static int ipxcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */static void ipxcp_up __P((fsm *)); /* We're UP */static void ipxcp_down __P((fsm *)); /* We're DOWN */static void ipxcp_finished __P((fsm *)); /* Don't need lower layer */static void ipxcp_script __P((fsm *, char *)); /* Run an up/down script */fsm ipxcp_fsm[NUM_PPP]; /* IPXCP fsm structure */static fsm_callbacks ipxcp_callbacks = { /* IPXCP callback routines */ ipxcp_resetci, /* Reset our Configuration Information */ ipxcp_cilen, /* Length of our Configuration Information */ ipxcp_addci, /* Add our Configuration Information */ ipxcp_ackci, /* ACK our Configuration Information */ ipxcp_nakci, /* NAK our Configuration Information */ ipxcp_rejci, /* Reject our Configuration Information */ ipxcp_reqci, /* Request peer's Configuration Information */ ipxcp_up, /* Called when fsm reaches OPENED state */ ipxcp_down, /* Called when fsm leaves OPENED state */ NULL, /* Called when we want the lower layer up */ ipxcp_finished, /* Called when we want the lower layer down */ NULL, /* Called when Protocol-Reject received */ NULL, /* Retransmission is necessary */ NULL, /* Called to handle protocol-specific codes */ "IPXCP" /* String name of protocol */};/* * Command-line options. */static int setipxnode __P((char **));static void printipxnode __P((option_t *, void (*)(void *, char *, ...), void *));static int setipxname __P((char **));static option_t ipxcp_option_list[] = { { "ipx", o_bool, &ipxcp_protent.enabled_flag, "Enable IPXCP (and IPX)", OPT_PRIO | 1 }, { "+ipx", o_bool, &ipxcp_protent.enabled_flag, "Enable IPXCP (and IPX)", OPT_PRIOSUB | OPT_ALIAS | 1 }, { "noipx", o_bool, &ipxcp_protent.enabled_flag, "Disable IPXCP (and IPX)", OPT_PRIOSUB }, { "-ipx", o_bool, &ipxcp_protent.enabled_flag, "Disable IPXCP (and IPX)", OPT_PRIOSUB | OPT_ALIAS }, { "ipx-network", o_uint32, &ipxcp_wantoptions[0].our_network, "Set our IPX network number", OPT_PRIO, &ipxcp_wantoptions[0].neg_nn }, { "ipxcp-accept-network", o_bool, &ipxcp_wantoptions[0].accept_network, "Accept peer IPX network number", 1, &ipxcp_allowoptions[0].accept_network }, { "ipx-node", o_special, (void *)setipxnode, "Set IPX node number", OPT_A2PRINTER, (void *)printipxnode }, { "ipxcp-accept-local", o_bool, &ipxcp_wantoptions[0].accept_local, "Accept our IPX address", 1, &ipxcp_allowoptions[0].accept_local }, { "ipxcp-accept-remote", o_bool, &ipxcp_wantoptions[0].accept_remote, "Accept peer's IPX address", 1, &ipxcp_allowoptions[0].accept_remote }, { "ipx-routing", o_int, &ipxcp_wantoptions[0].router, "Set IPX routing proto number", OPT_PRIO, &ipxcp_wantoptions[0].neg_router }, { "ipx-router-name", o_special, setipxname, "Set IPX router name", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, &ipxcp_wantoptions[0].name }, { "ipxcp-restart", o_int, &ipxcp_fsm[0].timeouttime, "Set timeout for IPXCP", OPT_PRIO }, { "ipxcp-max-terminate", o_int, &ipxcp_fsm[0].maxtermtransmits, "Set max #xmits for IPXCP term-reqs", OPT_PRIO }, { "ipxcp-max-configure", o_int, &ipxcp_fsm[0].maxconfreqtransmits, "Set max #xmits for IPXCP conf-reqs", OPT_PRIO }, { "ipxcp-max-failure", o_int, &ipxcp_fsm[0].maxnakloops, "Set max #conf-naks for IPXCP", OPT_PRIO }, { NULL }};/* * Protocol entry points. */static void ipxcp_init __P((int));static void ipxcp_open __P((int));static void ipxcp_close __P((int, char *));static void ipxcp_lowerup __P((int));static void ipxcp_lowerdown __P((int));static void ipxcp_input __P((int, u_char *, int));static void ipxcp_protrej __P((int));static int ipxcp_printpkt __P((u_char *, int, void (*) __P((void *, char *, ...)), void *));struct protent ipxcp_protent = { PPP_IPXCP, ipxcp_init, ipxcp_input, ipxcp_protrej, ipxcp_lowerup, ipxcp_lowerdown, ipxcp_open, ipxcp_close, ipxcp_printpkt, NULL, 0, "IPXCP", "IPX", ipxcp_option_list, NULL, NULL, NULL};/* * Lengths of configuration options. */#define CILEN_VOID 2#define CILEN_COMPLETE 2 /* length of complete option */#define CILEN_NETN 6 /* network number length option */#define CILEN_NODEN 8 /* node number length option */#define CILEN_PROTOCOL 4 /* Minimum length of routing protocol */#define CILEN_NAME 3 /* Minimum length of router name */#define CILEN_COMPRESS 4 /* Minimum length of compression protocol */#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ")static int ipxcp_is_up;static char *ipx_ntoa __P((u_int32_t));/* Used in printing the node number */#define NODE(base) base[0], base[1], base[2], base[3], base[4], base[5]/* Used to generate the proper bit mask */#define BIT(num) (1 << (num))/* * Convert from internal to external notation */static short intto_external(internal)short int internal;{ short int external; if (internal & BIT(IPX_NONE) ) external = IPX_NONE; else external = RIP_SAP; return external;}/* * Make a string representation of a network IP address. */static char *ipx_ntoa(ipxaddr)u_int32_t ipxaddr;{ static char b[64]; slprintf(b, sizeof(b), "%x", ipxaddr); return b;}static u_char *setipxnodevalue(src,dst)u_char *src, *dst;{ int indx; int item; for (;;) { if (!isxdigit (*src)) break; for (indx = 0; indx < 5; ++indx) { dst[indx] <<= 4; dst[indx] |= (dst[indx + 1] >> 4) & 0x0F; } item = toupper (*src) - '0'; if (item > 9) item -= 7; dst[5] = (dst[5] << 4) | item; ++src; } return src;}static int ipx_prio_our, ipx_prio_his;static intsetipxnode(argv) char **argv;{ char *end; int have_his = 0; u_char our_node[6]; u_char his_node[6]; memset (our_node, 0, 6); memset (his_node, 0, 6); end = setipxnodevalue (*argv, our_node); if (*end == ':') { have_his = 1; end = setipxnodevalue (++end, his_node); } if (*end == '\0') { ipxcp_wantoptions[0].neg_node = 1; if (option_priority >= ipx_prio_our) { memcpy(&ipxcp_wantoptions[0].our_node[0], our_node, 6); ipx_prio_our = option_priority; } if (have_his && option_priority >= ipx_prio_his) { memcpy(&ipxcp_wantoptions[0].his_node[0], his_node, 6); ipx_prio_his = option_priority; } return 1; } option_error("invalid parameter '%s' for ipx-node option", *argv); return 0;}static voidprintipxnode(opt, printer, arg) option_t *opt; void (*printer) __P((void *, char *, ...)); void *arg;{ unsigned char *p; p = ipxcp_wantoptions[0].our_node; if (ipx_prio_our) printer(arg, "%.2x%.2x%.2x%.2x%.2x%.2x", p[0], p[1], p[2], p[3], p[4], p[5]); printer(arg, ":"); p = ipxcp_wantoptions[0].his_node; if (ipx_prio_his) printer(arg, "%.2x%.2x%.2x%.2x%.2x%.2x", p[0], p[1], p[2], p[3], p[4], p[5]);}static intsetipxname (argv) char **argv;{ char *dest = ipxcp_wantoptions[0].name; char *src = *argv; int count; char ch; ipxcp_wantoptions[0].neg_name = 1; ipxcp_allowoptions[0].neg_name = 1; memset (dest, '\0', sizeof (ipxcp_wantoptions[0].name)); count = 0; while (*src) { ch = *src++; if (! isalnum (ch) && ch != '_') { option_error("IPX router name must be alphanumeric or _"); return 0; } if (count >= sizeof (ipxcp_wantoptions[0].name) - 1) { option_error("IPX router name is limited to %d characters", sizeof (ipxcp_wantoptions[0].name) - 1); return 0; } dest[count++] = toupper (ch); } dest[count] = 0; return 1;}/* * ipxcp_init - Initialize IPXCP. */static voidipxcp_init(unit) int unit;{ fsm *f = &ipxcp_fsm[unit]; f->unit = unit; f->protocol = PPP_IPXCP; f->callbacks = &ipxcp_callbacks; fsm_init(&ipxcp_fsm[unit]); memset (wo->name, 0, sizeof (wo->name)); memset (wo->our_node, 0, sizeof (wo->our_node)); memset (wo->his_node, 0, sizeof (wo->his_node)); wo->neg_nn = 1; wo->neg_complete = 1; wo->network = 0; ao->neg_node = 1; ao->neg_nn = 1; ao->neg_name = 1; ao->neg_complete = 1; ao->neg_router = 1; ao->accept_local = 0; ao->accept_remote = 0; ao->accept_network = 0; wo->tried_rip = 0; wo->tried_nlsp = 0;}/* * Copy the node number */static voidcopy_node (src, dst)u_char *src, *dst;{ memcpy (dst, src, sizeof (ipxcp_wantoptions[0].our_node));}/* * Compare node numbers */static intcompare_node (src, dst)u_char *src, *dst;{ return memcmp (dst, src, sizeof (ipxcp_wantoptions[0].our_node)) == 0;}/* * Is the node number zero? */static intzero_node (node)u_char *node;{ int indx; for (indx = 0; indx < sizeof (ipxcp_wantoptions[0].our_node); ++indx) if (node [indx] != 0) return 0; return 1;}/* * Increment the node number */static voidinc_node (node)u_char *node;{ u_char *outp; u_int32_t magic_num; outp = node; magic_num = magic(); *outp++ = '\0'; *outp++ = '\0'; PUTLONG (magic_num, outp);}/* * ipxcp_open - IPXCP is allowed to come up. */static voidipxcp_open(unit) int unit;{ fsm_open(&ipxcp_fsm[unit]);}/* * ipxcp_close - Take IPXCP down. */static voidipxcp_close(unit, reason) int unit; char *reason;{ fsm_close(&ipxcp_fsm[unit], reason);}/* * ipxcp_lowerup - The lower layer is up. */static voidipxcp_lowerup(unit) int unit;{ fsm_lowerup(&ipxcp_fsm[unit]);}/* * ipxcp_lowerdown - The lower layer is down. */static voidipxcp_lowerdown(unit) int unit;{ fsm_lowerdown(&ipxcp_fsm[unit]);}/* * ipxcp_input - Input IPXCP packet. */static voidipxcp_input(unit, p, len) int unit; u_char *p; int len;{ fsm_input(&ipxcp_fsm[unit], p, len);}/* * ipxcp_protrej - A Protocol-Reject was received for IPXCP. * * Pretend the lower layer went down, so we shut up. */static voidipxcp_protrej(unit) int unit;{ fsm_lowerdown(&ipxcp_fsm[unit]);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -