File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / ipcp.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 08:44:29 2013 UTC (10 years, 11 months ago) by misho
Branches: mpd, MAIN
CVS tags: v5_8p7, v5_8p1_cross, v5_8p1, v5_8, v5_7p0, v5_7, v5_6, HEAD
5.7

    1: 
    2: /*
    3:  * ipcp.c
    4:  *
    5:  * Written by Toshiharu OHNO <tony-o@iij.ad.jp>
    6:  * Copyright (c) 1993, Internet Initiative Japan, Inc. All rights reserved.
    7:  * See ``COPYRIGHT.iij''
    8:  * 
    9:  * Rewritten by Archie Cobbs <archie@freebsd.org>
   10:  * Copyright (c) 1995-1999 Whistle Communications, Inc. All rights reserved.
   11:  * See ``COPYRIGHT.whistle''
   12:  */
   13: 
   14: #include "ppp.h"
   15: #include "ipcp.h"
   16: #include "fsm.h"
   17: #include "ip.h"
   18: #include "iface.h"
   19: #include "msg.h"
   20: #include "ngfunc.h"
   21: #include "ippool.h"
   22: #include "util.h"
   23: 
   24: #include <netgraph.h>
   25: #include <sys/mbuf.h>
   26: #ifdef USE_NG_VJC
   27: #include <net/slcompress.h>
   28: #include <netgraph/ng_vjc.h>
   29: #endif
   30: 
   31: /*
   32:  * DEFINITIONS
   33:  */
   34: 
   35:   #define IPCP_KNOWN_CODES	(   (1 << CODE_CONFIGREQ)	\
   36: 				  | (1 << CODE_CONFIGACK)	\
   37: 				  | (1 << CODE_CONFIGNAK)	\
   38: 				  | (1 << CODE_CONFIGREJ)	\
   39: 				  | (1 << CODE_TERMREQ)		\
   40: 				  | (1 << CODE_TERMACK)		\
   41: 				  | (1 << CODE_CODEREJ)		)
   42: 
   43:   #define TY_IPADDRS		1
   44:   #define TY_COMPPROTO		2
   45:   #define TY_IPADDR		3
   46:   #define TY_PRIMARYDNS		129
   47:   #define TY_PRIMARYNBNS	130
   48:   #define TY_SECONDARYDNS	131
   49:   #define TY_SECONDARYNBNS	132
   50: 
   51:   /* Keep sync with above */
   52:   #define o2b(x)		(((x)<128)?(x):(x)-128+3)
   53: 
   54:   #define IPCP_REJECTED(p,x)	((p)->peer_reject & (1<<o2b(x)))
   55:   #define IPCP_PEER_REJ(p,x)	do{(p)->peer_reject |= (1<<o2b(x));}while(0)
   56: 
   57: #ifdef USE_NG_VJC
   58:   #define IPCP_VJCOMP_MIN_MAXCHAN	(NG_VJC_MIN_CHANNELS - 1)
   59:   #define IPCP_VJCOMP_MAX_MAXCHAN	(NG_VJC_MAX_CHANNELS - 1)
   60:   #define IPCP_VJCOMP_DEFAULT_MAXCHAN	IPCP_VJCOMP_MAX_MAXCHAN
   61: #endif
   62: 
   63:   /* Set menu options */
   64:   enum {
   65:     SET_RANGES,
   66:     SET_ENABLE,
   67:     SET_DNS,
   68:     SET_NBNS,
   69:     SET_DISABLE,
   70:     SET_ACCEPT,
   71:     SET_DENY,
   72:     SET_YES,
   73:     SET_NO
   74:   };
   75: 
   76: /*
   77:  * INTERNAL FUNCTIONS
   78:  */
   79: 
   80:   static void	IpcpConfigure(Fsm fp);
   81:   static void	IpcpUnConfigure(Fsm fp);
   82: 
   83:   static u_char	*IpcpBuildConfigReq(Fsm fp, u_char *cp);
   84:   static void	IpcpDecodeConfig(Fsm fp, FsmOption list, int num, int mode);
   85:   static void	IpcpLayerStart(Fsm fp);
   86:   static void	IpcpLayerFinish(Fsm fp);
   87:   static void	IpcpLayerUp(Fsm fp);
   88:   static void	IpcpLayerDown(Fsm fp);
   89:   static void	IpcpFailure(Fsm fp, enum fsmfail reason);
   90: 
   91: #ifdef USE_NG_VJC
   92:   static int	IpcpNgInitVJ(Bund b);
   93:   static void	IpcpNgShutdownVJ(Bund b);
   94: #endif
   95: 
   96:   static int	IpcpSetCommand(Context ctx, int ac, char *av[], void *arg);
   97: 
   98: /*
   99:  * GLOBAL VARIABLES
  100:  */
  101: 
  102:   const struct cmdtab IpcpSetCmds[] = {
  103:     { "ranges {self}[/{width}]|ippool {pool} {peer}[/{width}]|ippool {pool}",	"Allowed IP address ranges",
  104: 	IpcpSetCommand, NULL, 2, (void *) SET_RANGES },
  105:     { "enable [opt ...]",		"Enable option",
  106: 	IpcpSetCommand, NULL, 2, (void *) SET_ENABLE},
  107:     { "dns primary [secondary]",	"Set peer DNS servers",
  108: 	IpcpSetCommand, NULL, 2, (void *) SET_DNS},
  109:     { "nbns primary [secondary]",	"Set peer NBNS servers",
  110: 	IpcpSetCommand, NULL, 2, (void *) SET_NBNS},
  111:     { "disable [opt ...]",		"Disable option",
  112: 	IpcpSetCommand, NULL, 2, (void *) SET_DISABLE},
  113:     { "accept [opt ...]",		"Accept option",
  114: 	IpcpSetCommand, NULL, 2, (void *) SET_ACCEPT},
  115:     { "deny [opt ...]",			"Deny option",
  116: 	IpcpSetCommand, NULL, 2, (void *) SET_DENY},
  117:     { "yes [opt ...]",			"Enable and accept option",
  118: 	IpcpSetCommand, NULL, 2, (void *) SET_YES},
  119:     { "no [opt ...]",			"Disable and deny option",
  120: 	IpcpSetCommand, NULL, 2, (void *) SET_NO},
  121:     { NULL },
  122:   };
  123: 
  124: /*
  125:  * INTERNAL VARIABLES
  126:  */
  127: 
  128:   static const struct fsmoptinfo	gIpcpConfOpts[] = {
  129:     { "IPADDRS",	TY_IPADDRS,		8, 8, FALSE },
  130: #ifdef USE_NG_VJC
  131:     { "COMPPROTO",	TY_COMPPROTO,		4, 4, TRUE },
  132: #endif
  133:     { "IPADDR",		TY_IPADDR,		4, 4, TRUE },
  134:     { "PRIDNS",		TY_PRIMARYDNS,		4, 4, TRUE },
  135:     { "PRINBNS",	TY_PRIMARYNBNS,		4, 4, TRUE },
  136:     { "SECDNS",		TY_SECONDARYDNS,	4, 4, TRUE },
  137:     { "SECNBNS",	TY_SECONDARYNBNS,	4, 4, TRUE },
  138:     { NULL }
  139:   };
  140: 
  141:   static const struct confinfo gConfList[] = {
  142: #ifdef USE_NG_VJC
  143:     { 1,	IPCP_CONF_VJCOMP,	"vjcomp"	},
  144: #endif
  145:     { 0,	IPCP_CONF_REQPRIDNS,	"req-pri-dns"	},
  146:     { 0,	IPCP_CONF_REQSECDNS,	"req-sec-dns"	},
  147:     { 0,	IPCP_CONF_REQPRINBNS,	"req-pri-nbns"	},
  148:     { 0,	IPCP_CONF_REQSECNBNS,	"req-sec-nbns"	},
  149:     { 0,	IPCP_CONF_PRETENDIP,	"pretend-ip"	},
  150:     { 0,	0,			NULL		},
  151:   };
  152: 
  153:   static const struct fsmtype gIpcpFsmType = {
  154:     "IPCP",
  155:     PROTO_IPCP,
  156:     IPCP_KNOWN_CODES,
  157:     FALSE,
  158:     LG_IPCP, LG_IPCP2,
  159:     NULL,
  160:     IpcpLayerUp,
  161:     IpcpLayerDown,
  162:     IpcpLayerStart,
  163:     IpcpLayerFinish,
  164:     IpcpBuildConfigReq,
  165:     IpcpDecodeConfig,
  166:     IpcpConfigure,
  167:     IpcpUnConfigure,
  168:     NULL,
  169:     NULL,
  170:     NULL,
  171:     NULL,
  172:     IpcpFailure,
  173:     NULL,
  174:     NULL,
  175:     NULL,
  176:   };
  177: 
  178: /*
  179:  * IpcpStat()
  180:  */
  181: 
  182: int
  183: IpcpStat(Context ctx, int ac, char *av[], void *arg)
  184: {
  185: #ifdef USE_NG_VJC
  186:   char			path[NG_PATHSIZ];
  187: #endif
  188:   IpcpState		const ipcp = &ctx->bund->ipcp;
  189:   Fsm			fp = &ipcp->fsm;
  190: #ifdef USE_NG_VJC
  191:   union {
  192:       u_char		buf[sizeof(struct ng_mesg) + sizeof(struct slcompress)];
  193:       struct ng_mesg	reply;
  194:   }			u;
  195:   struct slcompress	*const sls = (struct slcompress *)(void *)u.reply.data;
  196: #endif
  197:   char			buf[48];
  198: 
  199:   Printf("[%s] %s [%s]\r\n", Pref(fp), Fsm(fp), FsmStateName(fp->state));
  200:   Printf("Allowed IP address ranges:\r\n");
  201:     if (ipcp->conf.self_ippool[0]) {
  202: 	Printf("\tPeer: ippool %s\r\n",
  203: 	  ipcp->conf.self_ippool);
  204:     } else {
  205: 	Printf("\tSelf: %s\r\n",
  206: 	    u_rangetoa(&ipcp->conf.self_allow,buf,sizeof(buf)));
  207:     }
  208:     if (ipcp->conf.ippool[0]) {
  209: 	Printf("\tPeer: ippool %s\r\n",
  210: 	  ipcp->conf.ippool);
  211:     } else {
  212: 	Printf("\tPeer: %s\r\n",
  213: 	  u_rangetoa(&ipcp->conf.peer_allow,buf,sizeof(buf)));
  214:     }
  215:   Printf("IPCP Options:\r\n");
  216:   OptStat(ctx, &ipcp->conf.options, gConfList);
  217:   Printf("Current addressing:\r\n");
  218:   Printf("\tSelf: %s\r\n", inet_ntoa(ipcp->want_addr));
  219:   Printf("\tPeer: %s\r\n", inet_ntoa(ipcp->peer_addr));
  220: #ifdef USE_NG_VJC
  221:   Printf("Compression:\r\n");
  222:   Printf("\tSelf: ");
  223:   if (ipcp->want_comp.proto != 0)
  224:     Printf("%s, %d compression channels, CID %scompressible\r\n",
  225:       ProtoName(ntohs(ipcp->want_comp.proto)),
  226:       ipcp->want_comp.maxchan + 1, ipcp->want_comp.compcid ? "" : "not ");
  227:   else
  228:     Printf("None\r\n");
  229:   Printf("\tPeer: ");
  230:   if (ipcp->peer_comp.proto != 0)
  231:     Printf("%s, %d compression channels, CID %scompressible\n",
  232:       ProtoName(ntohs(ipcp->peer_comp.proto)),
  233:       ipcp->peer_comp.maxchan + 1, ipcp->peer_comp.compcid ? "" : "not ");
  234:   else
  235:     Printf("None\r\n");
  236: #endif /* USE_NG_VJC */
  237:   Printf("Server info we give to peer:\r\n");
  238:   Printf("DNS servers : %15s", inet_ntoa(ipcp->conf.peer_dns[0]));
  239:   Printf("  %15s\r\n", inet_ntoa(ipcp->conf.peer_dns[1]));
  240:   Printf("NBNS servers: %15s", inet_ntoa(ipcp->conf.peer_nbns[0]));
  241:   Printf("  %15s\r\n", inet_ntoa(ipcp->conf.peer_nbns[1]));
  242:   Printf("Server info peer gave to us:\r\n");
  243:   Printf("DNS servers : %15s", inet_ntoa(ipcp->want_dns[0]));
  244:   Printf("  %15s\r\n", inet_ntoa(ipcp->want_dns[1]));
  245:   Printf("NBNS servers: %15s", inet_ntoa(ipcp->want_nbns[0]));
  246:   Printf("  %15s\r\n", inet_ntoa(ipcp->want_nbns[1]));
  247: 
  248: #ifdef USE_NG_VJC
  249:   /* Get VJC state */
  250:   snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, ctx->bund->name, NG_PPP_HOOK_VJC_IP);
  251:   if (NgFuncSendQuery(path, NGM_VJC_COOKIE, NGM_VJC_GET_STATE,
  252:       NULL, 0, &u.reply, sizeof(u), NULL) < 0)
  253:     return(0);
  254: 
  255:   Printf("VJ Compression:\r\n");
  256:   Printf("\tOut comp : %d\r\n", sls->sls_compressed);
  257:   Printf("\tOut total: %d\r\n", sls->sls_packets);
  258:   Printf("\tMissed   : %d\r\n", sls->sls_misses);
  259:   Printf("\tSearched : %d\r\n", sls->sls_searches);
  260:   Printf("\tIn comp  : %d\r\n", sls->sls_compressedin);
  261:   Printf("\tIn uncomp: %d\r\n", sls->sls_uncompressedin);
  262:   Printf("\tIn error : %d\r\n", sls->sls_errorin);
  263:   Printf("\tIn tossed: %d\r\n", sls->sls_tossed);
  264: #endif /* USE_NG_VJC */
  265:   return(0);
  266: }
  267: 
  268: /*
  269:  * IpcpInit()
  270:  */
  271: 
  272: void
  273: IpcpInit(Bund b)
  274: {
  275:   IpcpState		const ipcp = &b->ipcp;
  276: 
  277:   /* Init state machine */
  278:   memset(ipcp, 0, sizeof(*ipcp));
  279:   FsmInit(&ipcp->fsm, &gIpcpFsmType, b);
  280: 
  281:   /* Come up with a default IP address for my side of the link */
  282:   u_rangeclear(&ipcp->conf.self_allow);
  283:   GetAnyIpAddress(&ipcp->conf.self_allow.addr, NULL);
  284: 
  285: #ifdef USE_NG_VJC
  286:   /* Default we want VJ comp */
  287:   Enable(&ipcp->conf.options, IPCP_CONF_VJCOMP);
  288:   Accept(&ipcp->conf.options, IPCP_CONF_VJCOMP);
  289: #endif
  290: }
  291: 
  292: /*
  293:  * IpcpInst()
  294:  */
  295: 
  296: void
  297: IpcpInst(Bund b, Bund bt)
  298: {
  299:   IpcpState		const ipcp = &b->ipcp;
  300: 
  301:   /* Init state machine */
  302:   memcpy(ipcp, &bt->ipcp, sizeof(*ipcp));
  303:   FsmInst(&ipcp->fsm, &bt->ipcp.fsm, b);
  304: }
  305: 
  306: /*
  307:  * IpcpConfigure()
  308:  */
  309: 
  310: static void
  311: IpcpConfigure(Fsm fp)
  312: {
  313:     Bund 	b = (Bund)fp->arg;
  314:     IpcpState	const ipcp = &b->ipcp;
  315:     char	buf[48];
  316: 
  317:     /* FSM stuff */
  318:     ipcp->peer_reject = 0;
  319: 
  320:     /* Get allowed IP addresses from config and/or from current bundle */
  321:     if (ipcp->conf.self_ippool[0]) {
  322: 	if (IPPoolGet(ipcp->conf.self_ippool, &ipcp->self_allow.addr)) {
  323: 	    Log(LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\" for self",
  324: 		b->name, ipcp->conf.self_ippool));
  325: 	} else {
  326: 	    Log(LG_IPCP, ("[%s] IPCP: Got IP %s from pool \"%s\" for self",
  327: 		b->name,
  328: 		u_addrtoa(&ipcp->self_allow.addr, buf, sizeof(buf)),
  329: 		ipcp->conf.self_ippool));
  330: 	    ipcp->self_allow.width = 32;
  331: 	    ipcp->self_ippool_used = 1;
  332: 	}
  333:     } else
  334: 	ipcp->self_allow = ipcp->conf.self_allow;
  335: 
  336:     if ((b->params.range_valid) && (!u_rangeempty(&b->params.range)))
  337: 	ipcp->peer_allow = b->params.range;
  338:     else if (b->params.ippool[0]) {
  339: 	/* Get IP from pool if needed */
  340: 	if (IPPoolGet(b->params.ippool, &ipcp->peer_allow.addr)) {
  341: 	    Log(LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\" for peer",
  342: 		b->name, b->params.ippool));
  343: 	} else {
  344: 	    Log(LG_IPCP, ("[%s] IPCP: Got IP %s from pool \"%s\" for peer",
  345: 		b->name,
  346: 		u_addrtoa(&ipcp->peer_allow.addr, buf, sizeof(buf)),
  347: 		b->params.ippool));
  348: 	    ipcp->peer_allow.width = 32;
  349: 	    b->params.ippool_used = 1;
  350: 	}
  351:     } else if (ipcp->conf.ippool[0]) {
  352: 	if (IPPoolGet(ipcp->conf.ippool, &ipcp->peer_allow.addr)) {
  353: 	    Log(LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\"",
  354: 		b->name, ipcp->conf.ippool));
  355: 	} else {
  356: 	    Log(LG_IPCP, ("[%s] IPCP: Got IP %s from pool \"%s\" for peer",
  357: 		b->name,
  358: 		u_addrtoa(&ipcp->peer_allow.addr, buf, sizeof(buf)),
  359: 		ipcp->conf.ippool));
  360: 	    ipcp->peer_allow.width = 32;
  361: 	    ipcp->ippool_used = 1;
  362: 	}
  363:     } else
  364: 	ipcp->peer_allow = ipcp->conf.peer_allow;
  365:     
  366:     /* Initially request addresses as specified by config */
  367:     u_addrtoin_addr(&ipcp->self_allow.addr, &ipcp->want_addr);
  368:     u_addrtoin_addr(&ipcp->peer_allow.addr, &ipcp->peer_addr);
  369: 
  370: #ifdef USE_NG_VJC
  371:     /* Van Jacobson compression */
  372:     ipcp->peer_comp.proto = 0;
  373:     ipcp->peer_comp.maxchan = IPCP_VJCOMP_DEFAULT_MAXCHAN;
  374:     ipcp->peer_comp.compcid = 0;
  375: 
  376:     ipcp->want_comp.proto =
  377: 	(b->params.vjc_enable || Enabled(&ipcp->conf.options, IPCP_CONF_VJCOMP)) ?
  378: 	    htons(PROTO_VJCOMP) : 0;
  379:     ipcp->want_comp.maxchan = IPCP_VJCOMP_MAX_MAXCHAN;
  380: 
  381:     /* If any of our links are unable to give receive error indications, we must
  382:      tell the peer not to compress the slot-id in VJCOMP packets (cf. RFC1144).
  383:      To be on the safe side, we always say this. */
  384:     ipcp->want_comp.compcid = 0;
  385: #endif
  386: 
  387:     /* DNS and NBNS servers */
  388:     memset(&ipcp->want_dns, 0, sizeof(ipcp->want_dns));
  389:     memset(&ipcp->want_nbns, 0, sizeof(ipcp->want_nbns));
  390: }
  391: 
  392: /*
  393:  * IpcpUnConfigure()
  394:  */
  395: 
  396: static void
  397: IpcpUnConfigure(Fsm fp)
  398: {
  399:     Bund 	b = (Bund)fp->arg;
  400:     IpcpState	const ipcp = &b->ipcp;
  401:   
  402:     if (ipcp->self_ippool_used) {
  403: 	struct u_addr ip;
  404: 	in_addrtou_addr(&ipcp->want_addr, &ip);
  405: 	IPPoolFree(ipcp->conf.self_ippool, &ip);
  406: 	ipcp->self_ippool_used = 0;
  407:     }
  408:     if (b->params.ippool_used) {
  409: 	struct u_addr ip;
  410: 	in_addrtou_addr(&ipcp->peer_addr, &ip);
  411: 	IPPoolFree(b->params.ippool, &ip);
  412: 	b->params.ippool_used = 0;
  413:     } else if (ipcp->ippool_used) {
  414: 	struct u_addr ip;
  415: 	in_addrtou_addr(&ipcp->peer_addr, &ip);
  416: 	IPPoolFree(ipcp->conf.ippool, &ip);
  417: 	ipcp->ippool_used = 0;
  418:     }
  419: }
  420: 
  421: /*
  422:  * IpcpBuildConfigReq()
  423:  */
  424: 
  425: static u_char *
  426: IpcpBuildConfigReq(Fsm fp, u_char *cp)
  427: {
  428:     Bund 	b = (Bund)fp->arg;
  429:     IpcpState	const ipcp = &b->ipcp;
  430: 
  431:     /* Put in my desired IP address */
  432:     if (!IPCP_REJECTED(ipcp, TY_IPADDR) || ipcp->want_addr.s_addr == 0)
  433: 	cp = FsmConfValue(cp, TY_IPADDR, 4, &ipcp->want_addr.s_addr);
  434: 
  435: #ifdef USE_NG_VJC
  436:     /* Put in my requested compression protocol */
  437:     if (ipcp->want_comp.proto != 0 && !IPCP_REJECTED(ipcp, TY_COMPPROTO))
  438: 	cp = FsmConfValue(cp, TY_COMPPROTO, 4, &ipcp->want_comp);
  439: #endif
  440: 
  441:   /* Request peer's DNS and NBNS servers */
  442:   {
  443:     const int	sopts[2][2] = { { IPCP_CONF_REQPRIDNS, IPCP_CONF_REQSECDNS },
  444: 				{ IPCP_CONF_REQPRINBNS, IPCP_CONF_REQSECNBNS }};
  445:     const int	nopts[2][2] = { { TY_PRIMARYDNS, TY_SECONDARYDNS }, 
  446: 				{ TY_PRIMARYNBNS, TY_SECONDARYNBNS } };
  447:     struct in_addr	*vals[2] = { ipcp->want_dns, ipcp->want_nbns };
  448:     int			sopt, pri;
  449: 
  450:     for (sopt = 0; sopt < 2; sopt++) {
  451:       for (pri = 0; pri < 2; pri++) {
  452: 	const int	opt = nopts[sopt][pri];
  453: 
  454: 	/* Add option if we desire it and it hasn't been rejected */
  455: 	if (Enabled(&ipcp->conf.options, sopts[sopt][pri])
  456: 	    && !IPCP_REJECTED(ipcp, opt)) {
  457: 	  cp = FsmConfValue(cp, opt, 4, &vals[sopt][pri]);
  458: 	}
  459:       }
  460:     }
  461:   }
  462: 
  463: /* Done */
  464: 
  465:   return(cp);
  466: }
  467: 
  468: /*
  469:  * IpcpLayerStart()
  470:  *
  471:  * Tell the lower layer (the bundle) that we need it
  472:  */
  473: 
  474: static void
  475: IpcpLayerStart(Fsm fp)
  476: {
  477:   BundNcpsStart((Bund)(fp->arg), NCP_IPCP);
  478: }
  479: 
  480: /*
  481:  * IpcpLayerFinish()
  482:  *
  483:  * Tell the lower layer (the bundle) that we no longer need it
  484:  */
  485: 
  486: static void
  487: IpcpLayerFinish(Fsm fp)
  488: {
  489:   BundNcpsFinish((Bund)(fp->arg), NCP_IPCP);
  490: }
  491: 
  492: /*
  493:  * IpcpLayerUp()
  494:  *
  495:  * Called when IPCP has reached the OPEN state
  496:  */
  497: 
  498: static void
  499: IpcpLayerUp(Fsm fp)
  500: {
  501:     Bund 			b = (Bund)fp->arg;
  502:     IpcpState			const ipcp = &b->ipcp;
  503:     char			ipbuf[20];
  504: #ifdef USE_NG_VJC
  505:     char			path[NG_PATHSIZ];
  506:     struct ngm_vjc_config	vjc;
  507: #endif
  508:     struct u_addr		tmp;
  509: 
  510:     /* Determine actual address we'll use for ourselves */
  511:     in_addrtou_addr(&ipcp->want_addr, &tmp);
  512:     if (!IpAddrInRange(&ipcp->self_allow, &tmp)) {
  513: 	Log(LG_IPCP, ("[%s]   Note: ignoring negotiated %s IP %s,",
  514:     	    b->name, "self", inet_ntoa(ipcp->want_addr)));
  515: 	u_addrtoin_addr(&ipcp->self_allow.addr, &ipcp->want_addr);
  516: 	Log(LG_IPCP, ("[%s]        using %s instead.",
  517:     	    b->name, inet_ntoa(ipcp->want_addr)));
  518:     }
  519: 
  520:     /* Determine actual address we'll use for peer */
  521:     in_addrtou_addr(&ipcp->peer_addr, &tmp);
  522:     if (!IpAddrInRange(&ipcp->peer_allow, &tmp)
  523:     	    && !u_addrempty(&ipcp->peer_allow.addr)) {
  524: 	Log(LG_IPCP, ("[%s]   Note: ignoring negotiated %s IP %s,",
  525:     	    b->name, "peer", inet_ntoa(ipcp->peer_addr)));
  526: 	u_addrtoin_addr(&ipcp->peer_allow.addr, &ipcp->peer_addr);
  527: 	Log(LG_IPCP, ("[%s]        using %s instead.",
  528:     	    b->name, inet_ntoa(ipcp->peer_addr)));
  529:     }
  530: 
  531:     /* Report */
  532:     strlcpy(ipbuf, inet_ntoa(ipcp->peer_addr), sizeof(ipbuf));
  533:     Log(LG_IPCP, ("[%s]   %s -> %s", b->name, inet_ntoa(ipcp->want_addr), ipbuf));
  534: 
  535: #ifdef USE_NG_VJC
  536:     memset(&vjc, 0, sizeof(vjc));
  537:     if (ntohs(ipcp->peer_comp.proto) == PROTO_VJCOMP || 
  538: 	    ntohs(ipcp->want_comp.proto) == PROTO_VJCOMP) {
  539:   
  540: 	IpcpNgInitVJ(b);
  541: 
  542: 	/* Configure VJ compression node */
  543: 	vjc.enableComp = ntohs(ipcp->peer_comp.proto) == PROTO_VJCOMP;
  544: 	vjc.enableDecomp = ntohs(ipcp->want_comp.proto) == PROTO_VJCOMP;
  545: 	vjc.maxChannel = ipcp->peer_comp.maxchan;
  546: 	vjc.compressCID = ipcp->peer_comp.compcid;
  547:         snprintf(path, sizeof(path), "[%x]:%s", b->nodeID, NG_PPP_HOOK_VJC_IP);
  548: 	if (NgSendMsg(gLinksCsock, path,
  549:     		NGM_VJC_COOKIE, NGM_VJC_SET_CONFIG, &vjc, sizeof(vjc)) < 0) {
  550: 	    Perror("[%s] can't config %s node", b->name, NG_VJC_NODE_TYPE);
  551: 	}
  552:     }
  553: #endif /* USE_NG_VJC */
  554: 
  555:     /* Enable IP packets in the PPP node */
  556:     b->pppConfig.bund.enableIP = 1;
  557: #ifdef USE_NG_VJC
  558:     b->pppConfig.bund.enableVJCompression = vjc.enableComp;
  559:     b->pppConfig.bund.enableVJDecompression = vjc.enableDecomp;
  560: #endif
  561:     NgFuncSetConfig(b);
  562: 
  563:     BundNcpsJoin(b, NCP_IPCP);
  564: }
  565: 
  566: /*
  567:  * IpcpLayerDown()
  568:  *
  569:  * Called when IPCP leaves the OPEN state
  570:  */
  571: 
  572: static void
  573: IpcpLayerDown(Fsm fp)
  574: {
  575:     Bund 	b = (Bund)fp->arg;
  576: #ifdef USE_NG_VJC
  577:     IpcpState	const ipcp = &b->ipcp;
  578: #endif
  579: 
  580:     BundNcpsLeave(b, NCP_IPCP);
  581: 
  582:     /* Turn off IP packets */
  583:     b->pppConfig.bund.enableIP = 0;
  584: #ifdef USE_NG_VJC
  585:     b->pppConfig.bund.enableVJCompression = 0;
  586:     b->pppConfig.bund.enableVJDecompression = 0;
  587: #endif
  588:     NgFuncSetConfig(b);
  589: 
  590: #ifdef USE_NG_VJC
  591:     if (ntohs(ipcp->peer_comp.proto) == PROTO_VJCOMP || 
  592: 	    ntohs(ipcp->want_comp.proto) == PROTO_VJCOMP) {
  593: 	IpcpNgShutdownVJ(b);
  594:     }
  595: #endif /* USE_NG_VJC */
  596: }
  597: 
  598: /*
  599:  * IpcpUp()
  600:  */
  601: 
  602: void
  603: IpcpUp(Bund b)
  604: {
  605:     FsmUp(&b->ipcp.fsm);
  606: }
  607: 
  608: /*
  609:  * IpcpDown()
  610:  */
  611: 
  612: void
  613: IpcpDown(Bund b)
  614: {
  615:     FsmDown(&b->ipcp.fsm);
  616: }
  617: 
  618: /*
  619:  * IpcpOpen()
  620:  */
  621: 
  622: void
  623: IpcpOpen(Bund b)
  624: {
  625:     FsmOpen(&b->ipcp.fsm);
  626: }
  627: 
  628: /*
  629:  * IpcpClose()
  630:  */
  631: 
  632: void
  633: IpcpClose(Bund b)
  634: {
  635:     FsmClose(&b->ipcp.fsm);
  636: }
  637: 
  638: /*
  639:  * IpcpOpenCmd()
  640:  */
  641: 
  642: int
  643: IpcpOpenCmd(Context ctx)
  644: {
  645:     if (ctx->bund->tmpl)
  646: 	Error("impossible to open template");
  647:     FsmOpen(&ctx->bund->ipcp.fsm);
  648:     return (0);
  649: }
  650: 
  651: /*
  652:  * IpcpCloseCmd()
  653:  */
  654: 
  655: int
  656: IpcpCloseCmd(Context ctx)
  657: {
  658:     if (ctx->bund->tmpl)
  659: 	Error("impossible to close template");
  660:     FsmClose(&ctx->bund->ipcp.fsm);
  661:     return (0);
  662: }
  663: 
  664: /*
  665:  * IpcpFailure()
  666:  */
  667: 
  668: static void
  669: IpcpFailure(Fsm fp, enum fsmfail reason)
  670: {
  671:     Bund 	b = (Bund)fp->arg;
  672:     RecordLinkUpDownReason(b, NULL, 0, STR_PROTO_ERR, STR_IPCP_FAILED, FsmFailureStr(reason));
  673: }
  674: 
  675: /*
  676:  * IpcpDecodeConfig()
  677:  */
  678: 
  679: static void
  680: IpcpDecodeConfig(Fsm fp, FsmOption list, int num, int mode)
  681: {
  682:     Bund 	b = (Bund)fp->arg;
  683:   IpcpState		const ipcp = &b->ipcp;
  684:   struct in_addr	*wantip, *peerip;
  685:   int			k;
  686: 
  687:   /* Decode each config option */
  688:   for (k = 0; k < num; k++) {
  689:     FsmOption	const opt = &list[k];
  690:     FsmOptInfo	const oi = FsmFindOptInfo(gIpcpConfOpts, opt->type);
  691: 
  692:     if (!oi) {
  693:       Log(LG_IPCP, ("[%s]   UNKNOWN[%d] len=%d", b->name, opt->type, opt->len));
  694:       if (mode == MODE_REQ)
  695: 	FsmRej(fp, opt);
  696:       continue;
  697:     }
  698:     if (!oi->supported) {
  699:       Log(LG_IPCP, ("[%s]   %s", b->name, oi->name));
  700:       if (mode == MODE_REQ) {
  701: 	Log(LG_IPCP, ("[%s]     Not supported", b->name));
  702: 	FsmRej(fp, opt);
  703:       }
  704:       continue;
  705:     }
  706:     if (opt->len < oi->minLen + 2 || opt->len > oi->maxLen + 2) {
  707:       Log(LG_IPCP, ("[%s]   %s", b->name, oi->name));
  708:       if (mode == MODE_REQ) {
  709: 	Log(LG_IPCP, ("[%s]     bogus len=%d", b->name, opt->len));
  710: 	FsmRej(fp, opt);
  711:       }
  712:       continue;
  713:     }
  714:     switch (opt->type) {
  715:       case TY_IPADDR:
  716: 	{
  717: 	  struct in_addr	ip;
  718: 	  struct u_addr		tmp;
  719: 
  720: 	  memcpy(&ip, opt->data, 4);
  721: 	  in_addrtou_addr(&ip, &tmp);
  722: 	  Log(LG_IPCP, ("[%s]   %s %s", b->name, oi->name, inet_ntoa(ip)));
  723: 	  switch (mode) {
  724: 	    case MODE_REQ:
  725: 	      if (!IpAddrInRange(&ipcp->peer_allow, &tmp) || !ip.s_addr) {
  726: 		if (ipcp->peer_addr.s_addr == 0)
  727: 		  Log(LG_IPCP, ("[%s]     no IP address available for peer!", b->name));
  728: 		if (Enabled(&ipcp->conf.options, IPCP_CONF_PRETENDIP)) {
  729: 		  Log(LG_IPCP, ("[%s]     pretending that %s is OK, will ignore",
  730: 		      b->name, inet_ntoa(ip)));
  731: 		  ipcp->peer_addr = ip;
  732: 		  FsmAck(fp, opt);
  733: 		  break;
  734: 		}
  735: 		memcpy(opt->data, &ipcp->peer_addr, 4);
  736: 		Log(LG_IPCP, ("[%s]     NAKing with %s", b->name, inet_ntoa(ipcp->peer_addr)));
  737: 		FsmNak(fp, opt);
  738: 		break;
  739: 	      }
  740: 	      Log(LG_IPCP, ("[%s]     %s is OK", b->name, inet_ntoa(ip)));
  741: 	      ipcp->peer_addr = ip;
  742: 	      FsmAck(fp, opt);
  743: 	      break;
  744: 	    case MODE_NAK:
  745: 	      {
  746: 		if (IpAddrInRange(&ipcp->self_allow, &tmp)) {
  747: 		  Log(LG_IPCP, ("[%s]     %s is OK", b->name, inet_ntoa(ip)));
  748: 		  ipcp->want_addr = ip;
  749: 		} else if (Enabled(&ipcp->conf.options, IPCP_CONF_PRETENDIP)) {
  750: 		  Log(LG_IPCP, ("[%s]     pretending that %s is OK, will ignore",
  751: 		      b->name, inet_ntoa(ip)));
  752: 		  ipcp->want_addr = ip;
  753: 		} else
  754: 		  Log(LG_IPCP, ("[%s]     %s is unacceptable", b->name, inet_ntoa(ip)));
  755: 	      }
  756: 	      break;
  757: 	    case MODE_REJ:
  758: 	      IPCP_PEER_REJ(ipcp, opt->type);
  759: 	      if (ipcp->want_addr.s_addr == 0)
  760: 		Log(LG_IPCP, ("[%s]     Problem: I need an IP address!", b->name));
  761: 	      break;
  762: 	  }
  763: 	}
  764: 	break;
  765: 
  766: #ifdef USE_NG_VJC
  767:       case TY_COMPPROTO:
  768: 	{
  769: 	  struct ipcpvjcomp	vj;
  770: 
  771: 	  memcpy(&vj, opt->data, sizeof(vj));
  772: 	  Log(LG_IPCP, ("[%s]   %s %s, %d comp. channels, %s comp-cid",
  773: 	    b->name, oi->name, ProtoName(ntohs(vj.proto)),
  774: 	    vj.maxchan + 1, vj.compcid ? "allow" : "no"));
  775: 	  switch (mode) {
  776: 	    case MODE_REQ:
  777: 	      if (!Acceptable(&ipcp->conf.options, IPCP_CONF_VJCOMP) && 
  778: 	    	  !b->params.vjc_enable) {
  779: 		FsmRej(fp, opt);
  780: 		break;
  781: 	      }
  782: 	      if (ntohs(vj.proto) == PROTO_VJCOMP
  783: 		  && vj.maxchan <= IPCP_VJCOMP_MAX_MAXCHAN
  784: 		  && vj.maxchan >= IPCP_VJCOMP_MIN_MAXCHAN) {
  785: 		ipcp->peer_comp = vj;
  786: 		FsmAck(fp, opt);
  787: 		break;
  788: 	      }
  789: 	      vj.proto = htons(PROTO_VJCOMP);
  790: 	      vj.maxchan = IPCP_VJCOMP_MAX_MAXCHAN;
  791: 	      vj.compcid = 0;
  792: 	      memcpy(opt->data, &vj, sizeof(vj));
  793: 	      FsmNak(fp, opt);
  794: 	      break;
  795: 	    case MODE_NAK:
  796: 	      if (ntohs(vj.proto) != PROTO_VJCOMP) {
  797: 		Log(LG_IPCP, ("[%s]     Can't accept proto 0x%04x",
  798: 		  b->name, (u_short) ntohs(vj.proto)));
  799: 		break;
  800: 	      }
  801: 	      if (vj.maxchan != ipcp->want_comp.maxchan) {
  802: 		if (vj.maxchan <= IPCP_VJCOMP_MAX_MAXCHAN
  803: 		    && vj.maxchan >= IPCP_VJCOMP_MIN_MAXCHAN) {
  804: 		  Log(LG_IPCP, ("[%s]     Adjusting # compression channels", b->name));
  805: 		  ipcp->want_comp.maxchan = vj.maxchan;
  806: 		} else {
  807: 		  Log(LG_IPCP, ("[%s]     Can't handle %d maxchan", b->name, vj.maxchan));
  808: 		}
  809: 	      }
  810: 	      if (vj.compcid) {
  811: 		Log(LG_IPCP, ("[%s]     Can't accept comp-cid", b->name));
  812: 		break;
  813: 	      }
  814: 	      break;
  815: 	    case MODE_REJ:
  816: 	      IPCP_PEER_REJ(ipcp, opt->type);
  817: 	      ipcp->want_comp.proto = 0;
  818: 	      break;
  819: 	  }
  820: 	}
  821: 	break;
  822: #endif /* USE_NG_VJC */
  823: 
  824:       case TY_PRIMARYDNS:
  825:         if (b->params.peer_dns[0].s_addr != 0)
  826: 	    peerip = &b->params.peer_dns[0];
  827: 	else
  828: 	    peerip = &ipcp->conf.peer_dns[0];
  829: 	wantip = &ipcp->want_dns[0];
  830: 	goto doDnsNbns;
  831:       case TY_PRIMARYNBNS:
  832:         if (b->params.peer_nbns[0].s_addr != 0)
  833: 	    peerip = &b->params.peer_nbns[0];
  834: 	else
  835: 	    peerip = &ipcp->conf.peer_nbns[0];
  836: 	wantip = &ipcp->want_nbns[0];
  837: 	goto doDnsNbns;
  838:       case TY_SECONDARYDNS:
  839:         if (b->params.peer_dns[1].s_addr != 0)
  840: 	    peerip = &b->params.peer_dns[1];
  841: 	else
  842: 	    peerip = &ipcp->conf.peer_dns[1];
  843: 	wantip = &ipcp->want_dns[1];
  844: 	goto doDnsNbns;
  845:       case TY_SECONDARYNBNS:
  846:         if (b->params.peer_nbns[1].s_addr != 0)
  847: 	    peerip = &b->params.peer_nbns[1];
  848: 	else
  849: 	    peerip = &ipcp->conf.peer_nbns[1];
  850: 	wantip = &ipcp->want_nbns[1];
  851: doDnsNbns:
  852: 	{
  853: 	  struct in_addr	hisip;
  854: 
  855: 	  memcpy(&hisip, opt->data, 4);
  856: 	  Log(LG_IPCP, ("[%s]   %s %s", b->name, oi->name, inet_ntoa(hisip)));
  857: 	  switch (mode) {
  858: 	    case MODE_REQ:
  859: 	      if (hisip.s_addr == 0) {		/* he's asking for one */
  860: 		if (peerip->s_addr == 0) {	/* we don't got one */
  861: 		  FsmRej(fp, opt);
  862: 		  break;
  863: 		}
  864: 		Log(LG_IPCP, ("[%s]     NAKing with %s", b->name, inet_ntoa(*peerip)));
  865: 		memcpy(opt->data, peerip, sizeof(*peerip));
  866: 		FsmNak(fp, opt);		/* we got one for him */
  867: 		break;
  868: 	      }
  869: 	      FsmAck(fp, opt);			/* he knows what he wants */
  870: 	      break;
  871: 	    case MODE_NAK:	/* we asked for his server, he's telling us */
  872: 	      *wantip = hisip;
  873: 	      break;
  874: 	    case MODE_REJ:	/* we asked for his server, he's ignorant */
  875: 	      IPCP_PEER_REJ(ipcp, opt->type);
  876: 	      break;
  877: 	  }
  878: 	}
  879: 	break;
  880: 
  881:       default:
  882: 	assert(0);
  883:     }
  884:   }
  885: }
  886: 
  887: /*
  888:  * IpcpInput()
  889:  *
  890:  * Deal with an incoming IPCP packet
  891:  */
  892: 
  893: void
  894: IpcpInput(Bund b, Mbuf bp)
  895: {
  896:     FsmInput(&b->ipcp.fsm, bp);
  897: }
  898: 
  899: #ifdef USE_NG_VJC
  900: static int
  901: IpcpNgInitVJ(Bund b)
  902: {
  903:   struct ngm_mkpeer	mp;
  904:   struct ngm_connect	cn;
  905:   char path[NG_PATHSIZ];
  906:   struct ngm_name	nm;
  907: 
  908:   /* Add a VJ compression node */
  909:   snprintf(path, sizeof(path), "[%x]:", b->nodeID);
  910:   strcpy(mp.type, NG_VJC_NODE_TYPE);
  911:   strcpy(mp.ourhook, NG_PPP_HOOK_VJC_IP);
  912:   strcpy(mp.peerhook, NG_VJC_HOOK_IP);
  913:   if (NgSendMsg(gLinksCsock, path,
  914:       NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
  915:     Perror("[%s] can't create %s node at \"%s\"->\"%s\"",
  916:       b->name, NG_VJC_NODE_TYPE, path, mp.ourhook);
  917:     goto fail;
  918:   }
  919: 
  920:   /* Give it a name */
  921:   strlcat(path, NG_PPP_HOOK_VJC_IP, sizeof(path));
  922:   snprintf(nm.name, sizeof(nm.name), "mpd%d-%s-vjc", gPid, b->name);
  923:   if (NgSendMsg(gLinksCsock, path,
  924:       NGM_GENERIC_COOKIE, NGM_NAME, &nm, sizeof(nm)) < 0) {
  925:     Perror("[%s] can't name %s node", b->name, NG_VJC_NODE_TYPE);
  926:     goto fail;
  927:   }
  928: 
  929:   /* Connect the other three hooks between the ppp and vjc nodes */
  930:   snprintf(path, sizeof(path), "[%x]:", b->nodeID);
  931:   strcpy(cn.path, NG_PPP_HOOK_VJC_IP);
  932:   strcpy(cn.ourhook, NG_PPP_HOOK_VJC_COMP);
  933:   strcpy(cn.peerhook, NG_VJC_HOOK_VJCOMP);
  934:   if (NgSendMsg(gLinksCsock, path,
  935:       NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) {
  936:     Perror("[%s] can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
  937:       b->name, path, cn.ourhook, cn.path, cn.peerhook);
  938:     goto fail;
  939:   }
  940:   strcpy(cn.ourhook, NG_PPP_HOOK_VJC_UNCOMP);
  941:   strcpy(cn.peerhook, NG_VJC_HOOK_VJUNCOMP);
  942:   if (NgSendMsg(gLinksCsock, path,
  943:       NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) {
  944:     Perror("[%s] can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
  945:       b->name, path, cn.ourhook, cn.path, cn.peerhook);
  946:     goto fail;
  947:   }
  948:   strcpy(cn.ourhook, NG_PPP_HOOK_VJC_VJIP);
  949:   strcpy(cn.peerhook, NG_VJC_HOOK_VJIP);
  950:   if (NgSendMsg(gLinksCsock, path,
  951:       NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) {
  952:     Perror("[%s] can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
  953:       b->name, path, cn.ourhook, cn.path, cn.peerhook);
  954:     goto fail;
  955:   }
  956: 
  957:     return 0;
  958: fail:
  959:     return -1;
  960: }
  961: 
  962: static void
  963: IpcpNgShutdownVJ(Bund b)
  964: {
  965:     char	path[NG_PATHSIZ];
  966: 
  967:     snprintf(path, sizeof(path), "[%x]:%s", b->nodeID, NG_PPP_HOOK_VJC_IP);
  968:     NgFuncShutdownNode(gLinksCsock, b->name, path);
  969: }
  970: #endif /* USE_NG_VJC */
  971: 
  972: /*
  973:  * IpcpSetCommand()
  974:  */
  975: 
  976: static int
  977: IpcpSetCommand(Context ctx, int ac, char *av[], void *arg)
  978: {
  979:   IpcpState		const ipcp = &ctx->bund->ipcp;
  980:   struct in_addr	*ips;
  981: 
  982:   if (ac == 0)
  983:     return(-1);
  984:   switch ((intptr_t)arg) {
  985:     case SET_RANGES:
  986:       {
  987: 	struct u_range	self_new_allow;
  988: 	struct u_range	peer_new_allow;
  989: 	int pos = 0, self_new_pool = -1, peer_new_pool = -1;
  990: 
  991: 	/* Parse args */
  992: 	if (ac < 2)
  993: 	    return (-1);
  994: 	if (strcmp(av[pos], "ippool") == 0) {
  995: 	    self_new_pool = pos+1;
  996: 	    pos+=2;
  997: 	} else {
  998: 	    if (!ParseRange(av[pos], &self_new_allow, ALLOW_IPV4))
  999: 		return(-1);
 1000: 	    pos++;
 1001: 	}
 1002: 	if (pos >= ac)
 1003: 	    return (-1);
 1004: 	if (strcmp(av[pos], "ippool") == 0) {
 1005: 	    if ((pos + 1) >= ac)
 1006: 		return (-1);
 1007: 	    peer_new_pool = pos+1;
 1008: 	    pos+=2;
 1009: 	} else {
 1010: 	    if (!ParseRange(av[pos], &peer_new_allow, ALLOW_IPV4))
 1011: 		return(-1);
 1012: 	    pos++;
 1013: 	}
 1014: 	if (pos != ac)
 1015: 	    return (-1);
 1016: 
 1017: 	if (self_new_pool >= 0)
 1018: 	    strlcpy(ipcp->conf.self_ippool, av[self_new_pool], sizeof(ipcp->conf.self_ippool));
 1019: 	else
 1020: 	    ipcp->conf.self_ippool[0] = 0;
 1021: 	if (peer_new_pool >= 0)
 1022: 	    strlcpy(ipcp->conf.ippool, av[peer_new_pool], sizeof(ipcp->conf.ippool));
 1023: 	else
 1024: 	    ipcp->conf.ippool[0] = 0;
 1025: 	ipcp->conf.self_allow = self_new_allow;
 1026: 	ipcp->conf.peer_allow = peer_new_allow;
 1027: 
 1028:       }
 1029:       break;
 1030: 
 1031:     case SET_DNS:
 1032:       ips = ipcp->conf.peer_dns;
 1033:       goto getPrimSec;
 1034:       break;
 1035:     case SET_NBNS:
 1036:       ips = ipcp->conf.peer_nbns;
 1037: getPrimSec:
 1038:       if (!inet_aton(av[0], &ips[0]))
 1039: 	Error("invalid IP address: \'%s\'", av[0]);
 1040:       ips[1].s_addr = 0;
 1041:       if (ac > 1 && !inet_aton(av[1], &ips[1]))
 1042: 	Error("invalid IP address: \'%s\'", av[1]);
 1043:       break;
 1044: 
 1045:     case SET_ACCEPT:
 1046:       AcceptCommand(ac, av, &ipcp->conf.options, gConfList);
 1047:       break;
 1048: 
 1049:     case SET_DENY:
 1050:       DenyCommand(ac, av, &ipcp->conf.options, gConfList);
 1051:       break;
 1052: 
 1053:     case SET_ENABLE:
 1054:       EnableCommand(ac, av, &ipcp->conf.options, gConfList);
 1055:       break;
 1056: 
 1057:     case SET_DISABLE:
 1058:       DisableCommand(ac, av, &ipcp->conf.options, gConfList);
 1059:       break;
 1060: 
 1061:     case SET_YES:
 1062:       YesCommand(ac, av, &ipcp->conf.options, gConfList);
 1063:       break;
 1064: 
 1065:     case SET_NO:
 1066:       NoCommand(ac, av, &ipcp->conf.options, gConfList);
 1067:       break;
 1068: 
 1069:     default:
 1070:       assert(0);
 1071:   }
 1072:   return(0);
 1073: }
 1074: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>