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

📄 ipxcp.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 3 页
字号:
}/* * 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;/* * Start with these default values */    *go = *wo;}/* * ipxcp_cilen - Return length of our CI. */static intipxcp_cilen(f)    fsm *f;{    int len;    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;    /* RFC says that defaults should not be included. */    if (go->neg_router && to_external(go->router) != RIP_SAP)        len += CILEN_PROTOCOL;    return (len);}/* * ipxcp_addci - Add our desired CIs to a packet. */static voidipxcp_addci(f, ucp, lenp)    fsm *f;    u_char *ucp;    int *lenp;{/* * Add the options to the record. */    if (go->neg_nn) {	PUTCHAR (IPX_NETWORK_NUMBER, ucp);	PUTCHAR (CILEN_NETN, ucp);	PUTLONG (go->our_network, ucp);    }    if (go->neg_node) {	int indx;	PUTCHAR (IPX_NODE_NUMBER, ucp);	PUTCHAR (CILEN_NODEN, ucp);	for (indx = 0; indx < sizeof (go->our_node); ++indx)	    PUTCHAR (go->our_node[indx], ucp);    }    if (go->neg_name) {	int cilen = strlen (go->name);	int indx;	PUTCHAR (IPX_ROUTER_NAME, ucp);	PUTCHAR (CILEN_NAME + cilen - 1, ucp);	for (indx = 0; indx < cilen; ++indx)	    PUTCHAR (go->name [indx], ucp);    }    if (go->neg_router) {        short external = to_external (go->router);	if (external != RIP_SAP) {	    PUTCHAR  (IPX_ROUTER_PROTOCOL, ucp);	    PUTCHAR  (CILEN_PROTOCOL,      ucp);	    PUTSHORT (external,            ucp);	}    }}/* * ipxcp_ackci - Ack our CIs. * * Returns: *	0 - Ack was bad. *	1 - Ack was good. */static intipxcp_ackci(f, p, len)    fsm *f;    u_char *p;    int len;{    u_short cilen, citype, cishort;    u_char cichar;    u_int32_t cilong;#define ACKCIVOID(opt, neg) \    if (neg) { \	if ((len -= CILEN_VOID) < 0) \	    break; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != CILEN_VOID || \	    citype != opt) \	    break; \    }#define ACKCICOMPLETE(opt,neg)	ACKCIVOID(opt, neg)#define ACKCICHARS(opt, neg, val, cnt) \    if (neg) { \	int indx, count = cnt; \	len -= (count + 2); \	if (len < 0) \	    break; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != (count + 2) || \	    citype != opt) \	    break; \	for (indx = 0; indx < count; ++indx) {\	    GETCHAR(cichar, p); \	    if (cichar != ((u_char *) &val)[indx]) \	       break; \	}\	if (indx != count) \	    break; \    }#define ACKCINODE(opt,neg,val) ACKCICHARS(opt,neg,val,sizeof(val))#define ACKCINAME(opt,neg,val) ACKCICHARS(opt,neg,val,strlen(val))#define ACKCINETWORK(opt, neg, val) \    if (neg) { \	if ((len -= CILEN_NETN) < 0) \	    break; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != CILEN_NETN || \	    citype != opt) \	    break; \	GETLONG(cilong, p); \	if (cilong != val) \	    break; \    }#define ACKCIPROTO(opt, neg, val) \    if (neg) { \	if (len < 2) \	    break; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != CILEN_PROTOCOL || citype != opt) \	    break; \	len -= cilen; \	if (len < 0) \	    break; \	GETSHORT(cishort, p); \	if (cishort != to_external (val) || cishort == RIP_SAP) \	    break; \      }/* * Process the ACK frame in the order in which the frame was assembled */    do {	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);	if (len > 0)		ACKCIPROTO    (IPX_ROUTER_PROTOCOL, go->neg_router, go->router);/* * This is the end of the record. */	if (len == 0)	    return (1);    } while (0);/* * The frame is invalid */    IPXCPDEBUG(("ipxcp_ackci: received bad Ack!"));    return (0);}/* * ipxcp_nakci - Peer has sent a NAK for some of our CIs. * This should not modify any state if the Nak is bad * or if IPXCP is in the OPENED state. * * Returns: *	0 - Nak was bad. *	1 - Nak was good. */static intipxcp_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;    u_int32_t l;    ipxcp_options no;		/* options we've seen Naks for */    ipxcp_options try;		/* options to request next time */    BZERO(&no, sizeof(no));    try = *go;    while (len >= CILEN_VOID) {	GETCHAR (citype, p);	GETCHAR (cilen,	 p);	len -= cilen;	if (cilen < CILEN_VOID || len < 0)	    goto bad;	next = &p [cilen - CILEN_VOID];	switch (citype) {	case IPX_NETWORK_NUMBER:	    if (!go->neg_nn || no.neg_nn || (cilen != CILEN_NETN))		goto bad;	    no.neg_nn = 1;	    GETLONG(l, p);	    if (treat_as_reject)		try.neg_nn = 0;	    else if (l && ao->accept_network)		try.our_network = l;	    break;	case IPX_NODE_NUMBER:	    if (!go->neg_node || no.neg_node || (cilen != CILEN_NODEN))		goto bad;	    no.neg_node = 1;	    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;	    /* This has never been sent. Ignore the NAK frame */	case IPX_COMPRESSION_PROTOCOL:	    goto bad;	case IPX_ROUTER_PROTOCOL:	    if (!go->neg_router || (cilen < CILEN_PROTOCOL))		goto bad;	    GETSHORT (s, p);	    if (s > 15)         /* This is just bad, but ignore for now. */	        break;	    s = BIT(s);	    if (no.router & s)  /* duplicate NAKs are always bad */		goto bad;	    if (no.router == 0) /* Reset on first NAK only */		try.router = 0;	    no.router      |= s;	    try.router     |= s;	    try.neg_router  = 1;	    break;	    /* These, according to the RFC, must never be NAKed. */	case IPX_ROUTER_NAME:	case IPX_COMPLETE:	    goto bad;	    /* These are for options which we have not seen. */	default:	    break;	}	p = next;    }    /*     * Do not permit the peer to force a router protocol which we do not     * support. However, default to the condition that will accept "NONE".     */    try.router &= (ao->router | BIT(IPX_NONE));    if (try.router == 0 && ao->router != 0)	try.router = BIT(IPX_NONE);    if (try.router != 0)        try.neg_router = 1;        /*     * 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;    return 1;bad:    IPXCPDEBUG(("ipxcp_nakci: received bad Nak!"));    return 0;}/* * ipxcp_rejci - Reject some of our CIs. */static intipxcp_rejci(f, p, len)    fsm *f;    u_char *p;    int len;{    u_short cilen, citype, cishort;    u_char cichar;    u_int32_t cilong;    ipxcp_options try;		/* options to request next time */#define REJCINETWORK(opt, neg, val) \    if (neg && p[0] == opt) { \	if ((len -= CILEN_NETN) < 0) \	    break; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != CILEN_NETN || \	    citype != opt) \	    break; \	GETLONG(cilong, p); \	if (cilong != val) \	    break; \	neg = 0; \    }#define REJCICHARS(opt, neg, val, cnt) \    if (neg && p[0] == opt) { \	int indx, count = cnt; \	len -= (count + 2); \	if (len < 0) \	    break; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != (count + 2) || \	    citype != opt) \	    break; \	for (indx = 0; indx < count; ++indx) {\	    GETCHAR(cichar, p); \	    if (cichar != ((u_char *) &val)[indx]) \	       break; \	}\	if (indx != count) \	    break; \	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 REJCIVOID(opt, neg) \    if (neg && p[0] == opt) { \	if ((len -= CILEN_VOID) < 0) \	    break; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != CILEN_VOID || citype != opt) \	    break; \	neg = 0; \    }/* a reject for RIP/SAP is invalid since we don't send it and you can't   reject something which is not sent. (You can NAK, but you can't REJ.) */#define REJCIPROTO(opt, neg, val, bit) \    if (neg && p[0] == opt) { \	if ((len -= CILEN_PROTOCOL) < 0) \	    break; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != CILEN_PROTOCOL) \	    break; \	GETSHORT(cishort, p); \	if (cishort != to_external (val) || cishort == RIP_SAP) \	    break; \	neg = 0; \    }/* * Any Rejected CIs must be in exactly the same order that we sent. * Check packet length and CI length at each step. * If we find any deviations, then this packet is bad. */    try = *go;    do {	REJCINETWORK (IPX_NETWORK_NUMBER,  try.neg_nn,	   try.our_network);	REJCINODE    (IPX_NODE_NUMBER,	   try.neg_node,   try.our_node);	REJCINAME    (IPX_ROUTER_NAME,	   try.neg_name,   try.name);	REJCIPROTO   (IPX_ROUTER_PROTOCOL, try.neg_router, try.router, 0);/* * This is the end of the record. */	if (len == 0) {	    if (f->state != OPENED)		*go = try;	    return (1);	}    } while (0);/* * The frame is invalid at this point. */    IPXCPDEBUG(("ipxcp_rejci: received bad Reject!"));    return 0;}/* * ipxcp_reqci - Check the peer's requested CIs and send appropriate response. * * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified * appropriately.  If reject_if_disagree is non-zero, doesn't return * CONFNAK; returns CONFREJ if it can't return CONFACK. */static intipxcp_reqci(f, inp, len, reject_if_disagree)    fsm *f;    u_char *inp;		/* Requested CIs */    int *len;			/* Length of requested CIs */    int reject_if_disagree;{    u_char *cip, *next;		/* Pointer to current and next CIs */    u_short cilen, citype;	/* Parsed len, type */    u_short cishort;		/* Parsed short value */    u_int32_t cinetwork;	/* Parsed address values */    int rc = CONFACK;		/* Final packet return code */    int orc;			/* Individual option return code */    u_char *p;			/* Pointer to next char to parse */    u_char *ucp = inp;		/* Pointer to current output char */    int l = *len;		/* Length left */    /*     * Reset all his options.     */    BZERO(ho, sizeof(*ho));        /*     * Process all his options.     */    next = inp;    while (l) {	orc = CONFACK;			/* Assume success */	cip = p = next;			/* Remember begining of CI */	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(("ipxcp_reqci: bad CI length!"));	    orc = CONFREJ;		/* Reject bad CI */	    cilen = l;			/* Reject till end of packet */	    l = 0;			/* Don't loop again */	    goto endswitch;	}	GETCHAR(citype, p);		/* Parse CI type */	GETCHAR(cilen, p);		/* Parse CI length */	l -= cilen;			/* Adjust remaining length */	next += cilen;			/* Step to next CI */	switch (citype) {		/* Check CI type *//* * The network number must match. Choose the larger of the two. */	case IPX_NETWORK_NUMBER:	    /* if we wont negotiate the network number or the length is wrong	       then reject the option */	    if ( !ao->neg_nn || cilen != CILEN_NETN ) {		orc = CONFREJ;		break;			    }	    GETLONG(cinetwork, p);	    /* If the network numbers match then acknowledge them. */	    if (cinetwork != 0) {		ho->his_network = cinetwork;		ho->neg_nn	= 1;		if (wo->our_network == cinetwork)		    break;/* * If the network number is not given or we don't accept their change or * the network number is too small then NAK it. */		if (! ao->accept_network || cinetwork < wo->our_network) {		    DECPTR (sizeof (u_int32_t), p);		    PUTLONG (wo->our_network, p);		    orc = CONFNAK;		}		break;	    }/* * The peer sent '0' for the network. Give it ours if we have one. */	    if (go->our_network != 0) {		DECPTR (sizeof (u_int32_t), p);

⌨️ 快捷键说明

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