X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fipxcp.c;h=86124518c2f24529bb88b9737453fb76cba0a23c;hp=47d7af7f633f8cfa303959a0701d500c8aadf294;hb=dbfeebc9adcf76a50c1d4e9035d5d481914edb43;hpb=7a4dc0ff500aaa176a41965d8d4ad15a97a70904 diff --git a/pppd/ipxcp.c b/pppd/ipxcp.c index 47d7af7..8612451 100644 --- a/pppd/ipxcp.c +++ b/pppd/ipxcp.c @@ -18,9 +18,8 @@ */ #ifdef IPX_CHANGE -#ifndef lint -static char rcsid[] = "$Id: ipxcp.c,v 1.10 1999/03/16 03:15:15 paulus Exp $"; -#endif + +#define RCSID "$Id: ipxcp.c,v 1.20 2001/03/08 05:11:13 paulus Exp $" /* * TODO: @@ -40,6 +39,8 @@ static char rcsid[] = "$Id: ipxcp.c,v 1.10 1999/03/16 03:15:15 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 */ @@ -63,6 +64,7 @@ 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 */ @@ -78,7 +80,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 */ @@ -89,43 +91,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 } }; @@ -156,6 +170,7 @@ struct protent ipxcp_protent = { NULL, 0, "IPXCP", + "IPX", ipxcp_option_list, NULL, NULL, @@ -177,6 +192,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] @@ -193,7 +212,7 @@ short int internal; { short int external; - if (internal & IPX_NONE) + if (internal & BIT(IPX_NONE) ) external = IPX_NONE; else external = RIP_SAP; @@ -205,7 +224,7 @@ short int internal; * Make a string representation of a network IP address. */ -char * +static char * ipx_ntoa(ipxaddr) u_int32_t ipxaddr; { @@ -241,21 +260,36 @@ u_char *src, *dst; return src; } +static int ipx_prio_our, ipx_prio_his; + static int setipxnode(argv) char **argv; { char *end; + int have_his = 0; + u_char our_node[6]; + u_char his_node[6]; - memset (&ipxcp_wantoptions[0].our_node[0], 0, 6); - memset (&ipxcp_wantoptions[0].his_node[0], 0, 6); + memset (our_node, 0, 6); + memset (his_node, 0, 6); - end = setipxnodevalue (*argv, &ipxcp_wantoptions[0].our_node[0]); - if (*end == ':') - end = setipxnodevalue (++end, &ipxcp_wantoptions[0].his_node[0]); + 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; } @@ -263,6 +297,25 @@ 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; @@ -284,7 +337,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; @@ -292,6 +345,7 @@ setipxname (argv) dest[count++] = toupper (ch); } + dest[count] = 0; return 1; } @@ -660,9 +714,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. */ @@ -766,10 +819,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". @@ -783,6 +832,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; @@ -1263,6 +1313,7 @@ ipxcp_up(f) 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)) { @@ -1272,6 +1323,8 @@ ipxcp_up(f) 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 @@ -1293,12 +1346,28 @@ ipxcp_down(f) { 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. @@ -1318,38 +1387,34 @@ ipxcp_script(f, script) 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;