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

📄 ipcp.c

📁 Unix/Linux NAPT协议解析源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * ipcp.c - PPP IP 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. */#ifndef lintstatic char rcsid[] = "$Id: ipcp.c,v 1.19 1995/06/01 01:30:38 paulus Exp $";#endif/* * TODO: */#include <stdio.h>#include <string.h>#include <syslog.h>#include <sys/types.h>#include "pppd.h"#include "fsm.h"#include "ipcp.h"#include "pathnames.h"/* global vars */ipcp_options ipcp_wantoptions[NUM_PPP];	/* Options that we want to request */ipcp_options ipcp_gotoptions[NUM_PPP];	/* Options that peer ack'd */ipcp_options ipcp_allowoptions[NUM_PPP];	/* Options we allow peer to request */ipcp_options ipcp_hisoptions[NUM_PPP];	/* Options that we ack'd *//* local vars */static int cis_received[NUM_PPP];		/* # Conf-Reqs received *//* * Callbacks for fsm code.  (CI = Configuration Information) */static void ipcp_resetci __P((fsm *));	/* Reset our CI */static int  ipcp_cilen __P((fsm *));	        /* Return length of our CI */static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */static int  ipcp_ackci __P((fsm *, u_char *, int));	/* Peer ack'd our CI */static int  ipcp_nakci __P((fsm *, u_char *, int));	/* Peer nak'd our CI */static int  ipcp_rejci __P((fsm *, u_char *, int));	/* Peer rej'd our CI */static int  ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */static void ipcp_up __P((fsm *));		/* We're UP */static void ipcp_down __P((fsm *));		/* We're DOWN */static void ipcp_script __P((fsm *, char *)); /* Run an up/down script */fsm ipcp_fsm[NUM_PPP];		/* IPCP fsm structure */static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */    ipcp_resetci,		/* Reset our Configuration Information */    ipcp_cilen,			/* Length of our Configuration Information */    ipcp_addci,			/* Add our Configuration Information */    ipcp_ackci,			/* ACK our Configuration Information */    ipcp_nakci,			/* NAK our Configuration Information */    ipcp_rejci,			/* Reject our Configuration Information */    ipcp_reqci,			/* Request peer's Configuration Information */    ipcp_up,			/* Called when fsm reaches OPENED state */    ipcp_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 */    NULL,			/* Called when Protocol-Reject received */    NULL,			/* Retransmission is necessary */    NULL,			/* Called to handle protocol-specific codes */    "IPCP"			/* String name of protocol */};/* * Lengths of configuration options. */#define CILEN_VOID	2#define CILEN_COMPRESS	4	/* min length for compression protocol opt. */#define CILEN_VJ	6	/* length for RFC1332 Van-Jacobson opt. */#define CILEN_ADDR	6	/* new-style single address option */#define CILEN_ADDRS	10	/* old-style dual address option */#define CODENAME(x)	((x) == CONFACK ? "ACK" : \			 (x) == CONFNAK ? "NAK" : "REJ")/* * Make a string representation of a network IP address. */char *ip_ntoa(ipaddr)u_int32_t ipaddr;{    static char b[64];    ipaddr = ntohl(ipaddr);    sprintf(b, "%d.%d.%d.%d",	    (u_char)(ipaddr >> 24),	    (u_char)(ipaddr >> 16),	    (u_char)(ipaddr >> 8),	    (u_char)(ipaddr));    return b;}/* * ipcp_init - Initialize IPCP. */voidipcp_init(unit)    int unit;{    fsm *f = &ipcp_fsm[unit];    ipcp_options *wo = &ipcp_wantoptions[unit];    ipcp_options *ao = &ipcp_allowoptions[unit];    f->unit = unit;    f->protocol = PPP_IPCP;    f->callbacks = &ipcp_callbacks;    fsm_init(&ipcp_fsm[unit]);    wo->neg_addr = 1;    wo->old_addrs = 0;    wo->ouraddr = 0;    wo->hisaddr = 0;#ifdef USE_MS_DNS    wo->dnsaddr[0] =    wo->dnsaddr[1] = 0;    wo->winsaddr[0] =    wo->winsaddr[1] = 0;#endif    wo->neg_vj = 1;    wo->old_vj = 0;    wo->vj_protocol = IPCP_VJ_COMP;    wo->maxslotindex = MAX_STATES - 1; /* really max index */    wo->cflag = 1;    /* max slots and slot-id compression are currently hardwired in */    /* ppp_if.c to 16 and 1, this needs to be changed (among other */    /* things) gmc */    ao->neg_addr = 1;    ao->neg_vj = 1;    ao->maxslotindex = MAX_STATES - 1;    ao->cflag = 1;    /*     * XXX These control whether the user may use the proxyarp     * and defaultroute options.     */    ao->proxy_arp = 1;    ao->default_route = 1;}/* * ipcp_open - IPCP is allowed to come up. */voidipcp_open(unit)    int unit;{    fsm_open(&ipcp_fsm[unit]);}/* * ipcp_close - Take IPCP down. */voidipcp_close(unit)    int unit;{    fsm_close(&ipcp_fsm[unit]);}/* * ipcp_lowerup - The lower layer is up. */voidipcp_lowerup(unit)    int unit;{    fsm_lowerup(&ipcp_fsm[unit]);}/* * ipcp_lowerdown - The lower layer is down. */voidipcp_lowerdown(unit)    int unit;{    fsm_lowerdown(&ipcp_fsm[unit]);}/* * ipcp_input - Input IPCP packet. */voidipcp_input(unit, p, len)    int unit;    u_char *p;    int len;{    fsm_input(&ipcp_fsm[unit], p, len);}/* * ipcp_protrej - A Protocol-Reject was received for IPCP. * * Pretend the lower layer went down, so we shut up. */voidipcp_protrej(unit)    int unit;{    fsm_lowerdown(&ipcp_fsm[unit]);}/* * ipcp_resetci - Reset our CI. */static voidipcp_resetci(f)    fsm *f;{    ipcp_options *wo = &ipcp_wantoptions[f->unit];    wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;    if (wo->ouraddr == 0)	wo->accept_local = 1;    if (wo->hisaddr == 0)	wo->accept_remote = 1;    ipcp_gotoptions[f->unit] = *wo;    cis_received[f->unit] = 0;}/* * ipcp_cilen - Return length of our CI. */static intipcp_cilen(f)    fsm *f;{    ipcp_options *go = &ipcp_gotoptions[f->unit];#define LENCIVJ(neg, old)	(neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)#define LENCIADDR(neg, old)	(neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)    return (LENCIADDR(go->neg_addr, go->old_addrs) +	    LENCIVJ(go->neg_vj, go->old_vj));}/* * ipcp_addci - Add our desired CIs to a packet. */static voidipcp_addci(f, ucp, lenp)    fsm *f;    u_char *ucp;    int *lenp;{    ipcp_options *wo = &ipcp_wantoptions[f->unit];    ipcp_options *go = &ipcp_gotoptions[f->unit];    ipcp_options *ho = &ipcp_hisoptions[f->unit];    int len = *lenp;#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \    if (neg) { \	int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \	if (len >= vjlen) { \	    PUTCHAR(opt, ucp); \	    PUTCHAR(vjlen, ucp); \	    PUTSHORT(val, ucp); \	    if (!old) { \		PUTCHAR(maxslotindex, ucp); \		PUTCHAR(cflag, ucp); \	    } \	    len -= vjlen; \	} else \	    neg = 0; \    }#define ADDCIADDR(opt, neg, old, val1, val2) \    if (neg) { \	int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \	if (len >= addrlen) { \	    u_int32_t l; \	    PUTCHAR(opt, ucp); \	    PUTCHAR(addrlen, ucp); \	    l = ntohl(val1); \	    PUTLONG(l, ucp); \	    if (old) { \		l = ntohl(val2); \		PUTLONG(l, ucp); \	    } \	    len -= addrlen; \	} else \	    neg = 0; \    }    /*     * First see if we want to change our options to the old     * forms because we have received old forms from the peer.     */    if (wo->neg_addr && !go->neg_addr && !go->old_addrs) {	/* use the old style of address negotiation */	go->neg_addr = 1;	go->old_addrs = 1;    }    if (wo->neg_vj && !go->neg_vj && !go->old_vj) {	/* try an older style of VJ negotiation */	if (cis_received[f->unit] == 0) {	    /* keep trying the new style until we see some CI from the peer */	    go->neg_vj = 1;	} else {	    /* use the old style only if the peer did */	    if (ho->neg_vj && ho->old_vj) {		go->neg_vj = 1;		go->old_vj = 1;		go->vj_protocol = ho->vj_protocol;	    }	}    }    ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,	      go->old_addrs, go->ouraddr, go->hisaddr);    ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,	    go->maxslotindex, go->cflag);    *lenp -= len;}/* * ipcp_ackci - Ack our CIs. * * Returns: *	0 - Ack was bad. *	1 - Ack was good. */static intipcp_ackci(f, p, len)    fsm *f;    u_char *p;    int len;{    ipcp_options *go = &ipcp_gotoptions[f->unit];    u_short cilen, citype, cishort;    u_int32_t cilong;    u_char cimaxslotindex, cicflag;    /*     * 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.     */#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \    if (neg) { \	int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \	if ((len -= vjlen) < 0) \	    goto bad; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != vjlen || \	    citype != opt)  \	    goto bad; \	GETSHORT(cishort, p); \	if (cishort != val) \	    goto bad; \	if (!old) { \	    GETCHAR(cimaxslotindex, p); \	    if (cimaxslotindex != maxslotindex) \		goto bad; \	    GETCHAR(cicflag, p); \	    if (cicflag != cflag) \		goto bad; \	} \    }#define ACKCIADDR(opt, neg, old, val1, val2) \    if (neg) { \	int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \	u_int32_t l; \	if ((len -= addrlen) < 0) \	    goto bad; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != addrlen || \	    citype != opt) \	    goto bad; \	GETLONG(l, p); \	cilong = htonl(l); \	if (val1 != cilong) \	    goto bad; \	if (old) { \	    GETLONG(l, p); \	    cilong = htonl(l); \	    if (val2 != cilong) \		goto bad; \	} \    }    ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,	      go->old_addrs, go->ouraddr, go->hisaddr);    ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,	    go->maxslotindex, go->cflag);    /*     * If there are any remaining CIs, then this packet is bad.     */    if (len != 0)

⌨️ 快捷键说明

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