X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fipxcp.c;h=7b2343e155377120273793d3be2ce2cf28daff29;hp=760106306d406d2249b6fbc5c950093e76762064;hb=37476164f15a45015310b9d4b197c2d7db1f7f8f;hpb=1fae28ce79350b03f0cf8a69ad06dd68637cd6b1 diff --git a/pppd/ipxcp.c b/pppd/ipxcp.c index 7601063..7b2343e 100644 --- a/pppd/ipxcp.c +++ b/pppd/ipxcp.c @@ -1,26 +1,48 @@ /* * ipxcp.c - PPP IPX Control Protocol. * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. + * Copyright (c) 1984-2000 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. + * 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 -#ifndef lint -static char rcsid[] = "$Id: ipxcp.c,v 1.9 1999/03/12 06:07:17 paulus Exp $"; -#endif + +#define RCSID "$Id: ipxcp.c,v 1.24 2005/08/25 23:59:34 paulus Exp $" /* * TODO: @@ -28,7 +50,6 @@ static char rcsid[] = "$Id: ipxcp.c,v 1.9 1999/03/12 06:07:17 paulus Exp $"; #include #include -#include #include #include #include @@ -41,6 +62,8 @@ static char rcsid[] = "$Id: ipxcp.c,v 1.9 1999/03/12 06:07:17 paulus Exp $"; #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 */ @@ -59,11 +82,12 @@ 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_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 */ @@ -79,7 +103,7 @@ static fsm_callbacks ipxcp_callbacks = { /* IPXCP callback routines */ 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 */ - NULL, /* Called when we want the lower layer down */ + 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 */ @@ -90,43 +114,55 @@ static fsm_callbacks ipxcp_callbacks = { /* IPXCP callback routines */ * 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)", 1 }, + "Enable IPXCP (and IPX)", OPT_PRIO | 1 }, { "+ipx", o_bool, &ipxcp_protent.enabled_flag, - "Enable IPXCP (and IPX)", 1 }, + "Enable IPXCP (and IPX)", OPT_PRIOSUB | OPT_ALIAS | 1 }, { "noipx", o_bool, &ipxcp_protent.enabled_flag, - "Disable IPXCP (and IPX)" }, + "Disable IPXCP (and IPX)", OPT_PRIOSUB }, { "-ipx", o_bool, &ipxcp_protent.enabled_flag, - "Disable IPXCP (and IPX)" } , - { "ipx-network", o_int, &ipxcp_wantoptions[0].our_network, - "Set our IPX network number", 0, &ipxcp_wantoptions[0].neg_nn }, + "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, setipxnode, - "Set IPX node number" }, + + { "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", 0, + "Set IPX routing proto number", OPT_PRIO, &ipxcp_wantoptions[0].neg_router }, + { "ipx-router-name", o_special, setipxname, - "Set IPX router name" }, + "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" }, + "Set timeout for IPXCP", OPT_PRIO }, { "ipxcp-max-terminate", o_int, &ipxcp_fsm[0].maxtermtransmits, - "Set max #xmits for IPXCP term-reqs" }, + "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" }, + "Set max #xmits for IPXCP conf-reqs", OPT_PRIO }, { "ipxcp-max-failure", o_int, &ipxcp_fsm[0].maxnakloops, - "Set max #conf-naks for IPXCP" }, + "Set max #conf-naks for IPXCP", OPT_PRIO }, + { NULL } }; @@ -157,6 +193,7 @@ struct protent ipxcp_protent = { NULL, 0, "IPXCP", + "IPX", ipxcp_option_list, NULL, NULL, @@ -178,6 +215,10 @@ struct protent ipxcp_protent = { #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] @@ -194,7 +235,7 @@ short int internal; { short int external; - if (internal & IPX_NONE) + if (internal & BIT(IPX_NONE) ) external = IPX_NONE; else external = RIP_SAP; @@ -206,12 +247,12 @@ short int internal; * Make a string representation of a network IP address. */ -char * +static char * ipx_ntoa(ipxaddr) u_int32_t ipxaddr; { static char b[64]; - sprintf(b, "%x", ipxaddr); + slprintf(b, sizeof(b), "%x", ipxaddr); return b; } @@ -242,21 +283,36 @@ u_char *src, *dst; return src; } +static int ipx_prio_our, ipx_prio_his; + static int setipxnode(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]); + u_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; } @@ -264,11 +320,30 @@ setipxnode(argv) return 0; } +static void +printipxnode(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 int setipxname (argv) char **argv; { - char *dest = ipxcp_wantoptions[0].name; + u_char *dest = ipxcp_wantoptions[0].name; char *src = *argv; int count; char ch; @@ -285,7 +360,7 @@ setipxname (argv) return 0; } - if (count >= sizeof (ipxcp_wantoptions[0].name)) { + 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; @@ -293,6 +368,7 @@ setipxname (argv) dest[count++] = toupper (ch); } + dest[count] = 0; return 1; } @@ -517,7 +593,7 @@ ipxcp_cilen(f) len = go->neg_nn ? CILEN_NETN : 0; len += go->neg_node ? CILEN_NODEN : 0; - len += go->neg_name ? CILEN_NAME + strlen (go->name) - 1 : 0; + len += go->neg_name ? CILEN_NAME + strlen ((char *)go->name) - 1 : 0; /* RFC says that defaults should not be included. */ if (go->neg_router && to_external(go->router) != RIP_SAP) @@ -554,7 +630,7 @@ ipxcp_addci(f, ucp, lenp) } if (go->neg_name) { - int cilen = strlen (go->name); + int cilen = strlen ((char *)go->name); int indx; PUTCHAR (IPX_ROUTER_NAME, ucp); PUTCHAR (CILEN_NAME + cilen - 1, ucp); @@ -623,7 +699,7 @@ ipxcp_ackci(f, p, len) } #define ACKCINODE(opt,neg,val) ACKCICHARS(opt,neg,val,sizeof(val)) -#define ACKCINAME(opt,neg,val) ACKCICHARS(opt,neg,val,strlen(val)) +#define ACKCINAME(opt,neg,val) ACKCICHARS(opt,neg,val,strlen((char *)val)) #define ACKCINETWORK(opt, neg, val) \ if (neg) { \ @@ -661,9 +737,8 @@ ipxcp_ackci(f, p, len) ACKCINETWORK (IPX_NETWORK_NUMBER, go->neg_nn, go->our_network); ACKCINODE (IPX_NODE_NUMBER, go->neg_node, go->our_node); ACKCINAME (IPX_ROUTER_NAME, go->neg_name, go->name); - ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router); - ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router); - ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router); + if (len > 0) + ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router); /* * This is the end of the record. */ @@ -673,7 +748,7 @@ ipxcp_ackci(f, p, len) /* * The frame is invalid */ - IPXCPDEBUG((LOG_INFO, "ipxcp_ackci: received bad Ack!")); + IPXCPDEBUG(("ipxcp_ackci: received bad Ack!")); return (0); } @@ -688,10 +763,11 @@ ipxcp_ackci(f, p, len) */ static int -ipxcp_nakci(f, p, len) +ipxcp_nakci(f, p, len, treat_as_reject) fsm *f; u_char *p; int len; + int treat_as_reject; { u_char citype, cilen, *next; u_short s; @@ -702,11 +778,11 @@ ipxcp_nakci(f, p, len) BZERO(&no, sizeof(no)); try = *go; - while (len > CILEN_VOID) { + while (len >= CILEN_VOID) { GETCHAR (citype, p); GETCHAR (cilen, p); len -= cilen; - if (len < 0) + if (cilen < CILEN_VOID || len < 0) goto bad; next = &p [cilen - CILEN_VOID]; @@ -717,8 +793,9 @@ ipxcp_nakci(f, p, len) no.neg_nn = 1; GETLONG(l, p); - IPXCPDEBUG((LOG_INFO, "local IP address %d", l)); - if (l && ao->accept_network) + if (treat_as_reject) + try.neg_nn = 0; + else if (l && ao->accept_network) try.our_network = l; break; @@ -727,12 +804,10 @@ ipxcp_nakci(f, p, len) goto bad; no.neg_node = 1; - IPXCPDEBUG((LOG_INFO, - "local node number %02X%02X%02X%02X%02X%02X", - NODE(p))); - - if (!zero_node (p) && ao->accept_local && - ! compare_node (p, ho->his_node)) + if (treat_as_reject) + try.neg_node = 0; + else if (!zero_node (p) && ao->accept_local && + ! compare_node (p, ho->his_node)) copy_node (p, try.our_node); break; @@ -758,8 +833,6 @@ ipxcp_nakci(f, p, len) no.router |= s; try.router |= s; try.neg_router = 1; - - IPXCPDEBUG((LOG_INFO, "Router protocol number %d", s)); break; /* These, according to the RFC, must never be NAKed. */ @@ -774,10 +847,6 @@ ipxcp_nakci(f, p, len) p = next; } - /* If there is still anything left, this packet is bad. */ - if (len != 0) - goto bad; - /* * Do not permit the peer to force a router protocol which we do not * support. However, default to the condition that will accept "NONE". @@ -791,6 +860,7 @@ ipxcp_nakci(f, p, len) /* * OK, the Nak is good. Now we can update state. + * If there are any options left, we ignore them. */ if (f->state != OPENED) *go = try; @@ -798,7 +868,7 @@ ipxcp_nakci(f, p, len) return 1; bad: - IPXCPDEBUG((LOG_INFO, "ipxcp_nakci: received bad Nak!")); + IPXCPDEBUG(("ipxcp_nakci: received bad Nak!")); return 0; } @@ -828,7 +898,6 @@ ipxcp_rejci(f, p, len) GETLONG(cilong, p); \ if (cilong != val) \ break; \ - IPXCPDEBUG((LOG_INFO,"ipxcp_rejci rejected long opt %d", opt)); \ neg = 0; \ } @@ -850,12 +919,11 @@ ipxcp_rejci(f, p, len) }\ if (indx != count) \ break; \ - IPXCPDEBUG((LOG_INFO,"ipxcp_rejci rejected opt %d", opt)); \ neg = 0; \ } #define REJCINODE(opt,neg,val) REJCICHARS(opt,neg,val,sizeof(val)) -#define REJCINAME(opt,neg,val) REJCICHARS(opt,neg,val,strlen(val)) +#define REJCINAME(opt,neg,val) REJCICHARS(opt,neg,val,strlen((char *)val)) #define REJCIVOID(opt, neg) \ if (neg && p[0] == opt) { \ @@ -865,7 +933,6 @@ ipxcp_rejci(f, p, len) GETCHAR(cilen, p); \ if (cilen != CILEN_VOID || citype != opt) \ break; \ - IPXCPDEBUG((LOG_INFO, "ipxcp_rejci rejected void opt %d", opt)); \ neg = 0; \ } @@ -882,7 +949,6 @@ ipxcp_rejci(f, p, len) GETSHORT(cishort, p); \ if (cishort != to_external (val) || cishort == RIP_SAP) \ break; \ - IPXCPDEBUG((LOG_INFO, "ipxcp_rejci short opt %d", opt)); \ neg = 0; \ } /* @@ -909,7 +975,7 @@ ipxcp_rejci(f, p, len) /* * The frame is invalid at this point. */ - IPXCPDEBUG((LOG_INFO, "ipxcp_rejci: received bad Reject!")); + IPXCPDEBUG(("ipxcp_rejci: received bad Reject!")); return 0; } @@ -952,7 +1018,7 @@ ipxcp_reqci(f, inp, len, reject_if_disagree) if (l < 2 || /* Not enough data for CI header or */ p[1] < 2 || /* CI length too small or */ p[1] > l) { /* CI length too big? */ - IPXCPDEBUG((LOG_INFO, "ipxcp_reqci: bad CI length!")); + IPXCPDEBUG(("ipxcp_reqci: bad CI length!")); orc = CONFREJ; /* Reject bad CI */ cilen = l; /* Reject till end of packet */ l = 0; /* Don't loop again */ @@ -968,8 +1034,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree) * The network number must match. Choose the larger of the two. */ case IPX_NETWORK_NUMBER: - IPXCPDEBUG((LOG_INFO, "ipxcp: received Network Number request")); - /* if we wont negotiate the network number or the length is wrong then reject the option */ if ( !ao->neg_nn || cilen != CILEN_NETN ) { @@ -977,7 +1041,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree) break; } GETLONG(cinetwork, p); - IPXCPDEBUG((LOG_INFO,"Remote proposed IPX network number is %8Lx",tl)); /* If the network numbers match then acknowledge them. */ if (cinetwork != 0) { @@ -1014,8 +1077,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree) * The node number is required */ case IPX_NODE_NUMBER: - IPXCPDEBUG((LOG_INFO, "ipxcp: received Node Number request")); - /* if we wont negotiate the node number or the length is wrong then reject the option */ if ( cilen != CILEN_NODEN ) { @@ -1073,7 +1134,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree) * Compression is not desired at this time. It is always rejected. */ case IPX_COMPRESSION_PROTOCOL: - IPXCPDEBUG((LOG_INFO, "ipxcp: received Compression Protocol request ")); orc = CONFREJ; break; /* @@ -1088,9 +1148,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree) } GETSHORT (cishort, p); - IPXCPDEBUG((LOG_INFO, - "Remote router protocol number 0x%04x", - cishort)); if (wo->neg_router == 0) { wo->neg_router = 1; @@ -1135,7 +1192,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree) * The router name is advisorary. Just accept it if it is not too large. */ case IPX_ROUTER_NAME: - IPXCPDEBUG((LOG_INFO, "ipxcp: received Router Name request")); if (cilen >= CILEN_NAME) { int name_size = cilen - CILEN_NAME; if (name_size > sizeof (ho->name)) @@ -1153,7 +1209,6 @@ ipxcp_reqci(f, inp, len, reject_if_disagree) * This is advisorary. */ case IPX_COMPLETE: - IPXCPDEBUG((LOG_INFO, "ipxcp: received Complete request")); if (cilen != CILEN_COMPLETE) orc = CONFREJ; else { @@ -1165,14 +1220,10 @@ ipxcp_reqci(f, inp, len, reject_if_disagree) * All other entries are not known at this time. */ default: - IPXCPDEBUG((LOG_INFO, "ipxcp: received Complete request")); orc = CONFREJ; break; } - endswitch: - IPXCPDEBUG((LOG_INFO, " (%s)\n", CODENAME(orc))); - if (orc == CONFACK && /* Good CI */ rc != CONFACK) /* but prior CI wasnt? */ continue; /* Don't send this one */ @@ -1228,7 +1279,7 @@ endswitch: } *len = ucp - inp; /* Compute output length */ - IPXCPDEBUG((LOG_INFO, "ipxcp: returning Configure-%s", CODENAME(rc))); + IPXCPDEBUG(("ipxcp: returning Configure-%s", CODENAME(rc))); return (rc); /* Return final code */ } @@ -1244,7 +1295,7 @@ ipxcp_up(f) { int unit = f->unit; - IPXCPDEBUG((LOG_INFO, "ipxcp: up")); + IPXCPDEBUG(("ipxcp: up")); /* The default router protocol is RIP/SAP. */ if (ho->router == 0) @@ -1265,7 +1316,8 @@ ipxcp_up(f) if (zero_node (go->our_node)) { static char errmsg[] = "Could not determine local IPX node address"; - IPXCPDEBUG((LOG_ERR, errmsg)); + if (debug) + error(errmsg); ipxcp_close(f->unit, errmsg); return; } @@ -1276,25 +1328,31 @@ ipxcp_up(f) if (go->network == 0) { static char errmsg[] = "Can not determine network number"; - IPXCPDEBUG((LOG_ERR, errmsg)); + if (debug) + error(errmsg); ipxcp_close (unit, errmsg); return; } /* bring the interface up */ if (!sifup(unit)) { - IPXCPDEBUG((LOG_WARNING, "sifup failed")); + if (debug) + warn("sifup failed (IPX)"); ipxcp_close(unit, "Interface configuration failed"); return; } + ipxcp_is_up = 1; /* set the network number for IPX */ if (!sipxfaddr(unit, go->network, go->our_node)) { - IPXCPDEBUG((LOG_WARNING, "sipxfaddr failed")); + if (debug) + warn("sipxfaddr failed"); ipxcp_close(unit, "Interface configuration failed"); return; } + np_up(f->unit, PPP_IPX); + /* * Execute the ipx-up script, like this: * /etc/ppp/ipx-up interface tty speed local-IPX remote-IPX @@ -1314,14 +1372,30 @@ static void ipxcp_down(f) fsm *f; { - IPXCPDEBUG((LOG_INFO, "ipxcp: down")); + IPXCPDEBUG(("ipxcp: down")); - cipxfaddr (f->unit); + if (!ipxcp_is_up) + return; + ipxcp_is_up = 0; + np_down(f->unit, PPP_IPX); + cipxfaddr(f->unit); + sifnpmode(f->unit, PPP_IPX, NPMODE_DROP); sifdown(f->unit); ipxcp_script (f, _PATH_IPXDOWN); } +/* + * ipxcp_finished - possibly shut down the lower layers. + */ +static void +ipxcp_finished(f) + fsm *f; +{ + np_finished(f->unit, PPP_IPX); +} + + /* * ipxcp_script - Execute a script with arguments * interface-name tty-name speed local-IPX remote-IPX networks. @@ -1335,44 +1409,40 @@ ipxcp_script(f, script) char strnetwork[32], strpid[32]; char *argv[14], strproto_lcl[32], strproto_rmt[32]; - sprintf (strpid, "%d", getpid()); - sprintf (strspeed, "%d", baud_rate); + slprintf(strpid, sizeof(strpid), "%d", getpid()); + slprintf(strspeed, sizeof(strspeed),"%d", baud_rate); strproto_lcl[0] = '\0'; if (go->neg_router && ((go->router & BIT(IPX_NONE)) == 0)) { if (go->router & BIT(RIP_SAP)) - strlcpy (strproto_lcl, sizeof(strproto_lcl), "RIP "); + strlcpy (strproto_lcl, "RIP ", sizeof(strproto_lcl)); if (go->router & BIT(NLSP)) - strlcat (strproto_lcl, sizeof(strproto_lcl), "NLSP "); + strlcat (strproto_lcl, "NLSP ", sizeof(strproto_lcl)); } if (strproto_lcl[0] == '\0') - strlcpy (strproto_lcl, sizeof(strproto_lcl), "NONE "); + strlcpy (strproto_lcl, "NONE ", sizeof(strproto_lcl)); strproto_lcl[strlen (strproto_lcl)-1] = '\0'; strproto_rmt[0] = '\0'; if (ho->neg_router && ((ho->router & BIT(IPX_NONE)) == 0)) { if (ho->router & BIT(RIP_SAP)) - strlcpy (strproto_rmt, sizeof(strproto_rmt), "RIP "); + strlcpy (strproto_rmt, "RIP ", sizeof(strproto_rmt)); if (ho->router & BIT(NLSP)) - strlcat (strproto_rmt, sizeof(strproto_rmt), "NLSP "); + strlcat (strproto_rmt, "NLSP ", sizeof(strproto_rmt)); } if (strproto_rmt[0] == '\0') - strlcpy (strproto_rmt, sizeof(strproto_rmt), "NONE "); + strlcpy (strproto_rmt, "NONE ", sizeof(strproto_rmt)); strproto_rmt[strlen (strproto_rmt)-1] = '\0'; - strlcpy (strnetwork, sizeof(strnetwork), ipx_ntoa (go->network)); + strlcpy (strnetwork, ipx_ntoa (go->network), sizeof(strnetwork)); - slprintf (strlocal, sizeof(strlocal), - "%02X%02X%02X%02X%02X%02X", - NODE(go->our_node)); + slprintf (strlocal, sizeof(strlocal), "%0.6B", go->our_node); - slprintf (strremote, sizeof(strremote), - "%02X%02X%02X%02X%02X%02X", - NODE(ho->his_node)); + slprintf (strremote, sizeof(strremote), "%0.6B", ho->his_node); argv[0] = script; argv[1] = ifname; @@ -1383,12 +1453,12 @@ ipxcp_script(f, script) argv[6] = strremote; argv[7] = strproto_lcl; argv[8] = strproto_rmt; - argv[9] = go->name; - argv[10] = ho->name; + argv[9] = (char *)go->name; + argv[10] = (char *)ho->name; argv[11] = ipparam; argv[12] = strpid; argv[13] = NULL; - run_program(script, argv, 0, NULL, NULL); + run_program(script, argv, 0, NULL, NULL, 0); } /* @@ -1510,7 +1580,7 @@ ipxcp_printpkt(p, plen, printer, arg) case TERMREQ: if (len > 0 && *p >= ' ' && *p < 0x7f) { printer(arg, " "); - print_string(p, len, printer, arg); + print_string((char *)p, len, printer, arg); p += len; len = 0; }