⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipxcp.c

📁 unix and linux net driver
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * ipxcp.c - PPP IPX Control Protocol. * * Copyright (c) 1989 Carnegie Mellon University. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by Carnegie Mellon University.  The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#ifdef IPX_CHANGE#define RCSID	"$Id: ipxcp.c,v 1.18 1999/08/24 05:31:09 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));	/* 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 int setipxname __P((char **));static option_t ipxcp_option_list[] = {    { "ipx", o_bool, &ipxcp_protent.enabled_flag,      "Enable IPXCP (and IPX)", 1 },    { "+ipx", o_bool, &ipxcp_protent.enabled_flag,      "Enable IPXCP (and IPX)", 1 },    { "noipx", o_bool, &ipxcp_protent.enabled_flag,      "Disable IPXCP (and IPX)" },    { "-ipx", o_bool, &ipxcp_protent.enabled_flag,      "Disable IPXCP (and IPX)" } ,    { "ipx-network", o_uint32, &ipxcp_wantoptions[0].our_network,      "Set our IPX network number", 0, &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, setipxnode,      "Set IPX node number" },    { "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", 0,      &ipxcp_wantoptions[0].neg_router },    { "ipx-router-name", o_special, setipxname,      "Set IPX router name" },    { "ipxcp-restart", o_int, &ipxcp_fsm[0].timeouttime,      "Set timeout for IPXCP" },    { "ipxcp-max-terminate", o_int, &ipxcp_fsm[0].maxtermtransmits,      "Set max #xmits for IPXCP term-reqs" },    { "ipxcp-max-configure", o_int, &ipxcp_fsm[0].maxconfreqtransmits,      "Set max #xmits for IPXCP conf-reqs" },    { "ipxcp-max-failure", o_int, &ipxcp_fsm[0].maxnakloops,      "Set max #conf-naks for IPXCP" },    { 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 intsetipxnode(argv)    char **argv;{    char *end;    memset (&ipxcp_wantoptions[0].our_node[0], 0, 6);    memset (&ipxcp_wantoptions[0].his_node[0], 0, 6);    end = setipxnodevalue (*argv, &ipxcp_wantoptions[0].our_node[0]);    if (*end == ':')	end = setipxnodevalue (++end, &ipxcp_wantoptions[0].his_node[0]);    if (*end == '\0') {        ipxcp_wantoptions[0].neg_node = 1;        return 1;    }    option_error("invalid parameter '%s' for ipx-node option", *argv);    return 0;}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)) {	    option_error("IPX router name is limited to %d characters",			 sizeof (ipxcp_wantoptions[0].name) - 1);	    return 0;	}	dest[count++] = toupper (ch);    }    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]);}/* * ipxcp_resetci - Reset our CI. */static voidipxcp_resetci(f)    fsm *f;{    wo->req_node = wo->neg_node && ao->neg_node;    wo->req_nn	 = wo->neg_nn	&& ao->neg_nn;    if (wo->our_network == 0) {	wo->neg_node	   = 1;	ao->accept_network = 1;    }/* * If our node number is zero then change it. */    if (zero_node (wo->our_node)) {	inc_node (wo->our_node);	ao->accept_local = 1;	wo->neg_node	 = 1;    }/* * If his node number is zero then change it. */    if (zero_node (wo->his_node)) {	inc_node (wo->his_node);	ao->accept_remote = 1;    }/* * If no routing agent was specified then we do RIP/SAP according to the * RFC documents. If you have specified something then OK. Otherwise, we * do RIP/SAP. */    if (ao->router == 0) {	ao->router |= BIT(RIP_SAP);	wo->router |= BIT(RIP_SAP);    }    /* Always specify a routing protocol unless it was REJected. */    wo->neg_router = 1;/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -