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

📄 minimal-ppp.c

📁 ppp协议实现源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * A minimal implementation of PPP tunneled over UDP.  This implements * just LCP and IPCP, and then only a subset of each of those.  This * is not supported and probably shouldn't be used for much more than * simple experiments with PPP.  If you need a real version of PPP, * see Paul Mackerras' ppp-2.3.  If you do try to use this, don't say * I didn't warn you. * * This code may be used for any purpose as long as the author's * copyright is cited in any source code distributed.  This code * is also available electronically from the author's web site. * * http://people.ne.mediaone.net/carlson/ppp * * http://www.workingcode.com/ppp * * Copyright 1997 by James Carlson and Working Code */#include <stdio.h>#include <stdlib.h>#include <memory.h>#include <unistd.h>#include <strings.h>#include <time.h>#include <ctype.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/time.h>#ifdef _AIX#include <sys/select.h>#endif#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <signal.h>#include <errno.h>#define MAX_TERMINATE 2#define MAX_CONFIGURE 10#define MAX_FAILURE 5#define INITIAL_TIMEOUT 2#define MAX_TIMEOUT 8#define DEFAULT_MRU 1500#define MAX_WAIT 40		/* Maximum wait time for PPP to come up. */#define Dim(x)	(sizeof(x)/sizeof(*(x)))int remote_ip_base = 0x0A000000;int remote_ip_mask = 0xFF000000;char *myname;int showpackets = 0, debugphases = 0, debugstates = 0, debugactions = 0;int showraw = 0, debugtimer = 0;voidusage(void){    fprintf(stderr,"\nUsage:\n\t%s [-adpstv] <peer-IP> [<peer-port> [<local-port>]]\n\n",	    myname);    fprintf(stderr,"\t-a\tShow state machine actions\n");    fprintf(stderr,"\t-d\tShow raw data\n");    fprintf(stderr,"\t-p\tShow link phases\n");    fprintf(stderr,"\t-s\tShow XCP states\n");    fprintf(stderr,"\t-t\tShow timer actions\n");    fprintf(stderr,"\t-v\tShow negotiation packets\n");    exit(1);}/* Look up UDP port number. */intresolve_port(char *port_name){    struct servent *sp;    char *cp;    int pnum;    if (port_name != NULL) {	sp = getservbyname(port_name,"udp");	if (sp == NULL) {	    pnum = strtol(port_name,&cp,0);	    if (pnum <= 0 || pnum > 65535 || port_name == cp || *cp != '\0') {		fprintf(stderr,"Illegal port name/number '%s'\n",port_name);		return -1;	    }	    pnum = htons(pnum);	} else	    pnum = sp->s_port;    } else	pnum = htons(5001);    return pnum;}/* Set up connected UDP socket. */intset_up_tunnel(char **argv){    struct sockaddr_in sin,bsin;    struct hostent *hp;    int sock = -1,nlen;    char *host_name;    host_name = *argv++;    if (host_name == NULL) {	fprintf(stderr,"Must specify a peer name or IP address.\n");	return -1;    }    memset(&sin,0,sizeof(sin));    memset(&bsin,0,sizeof(bsin));    sin.sin_port = resolve_port(*argv);    bsin.sin_port = resolve_port(*argv?argv[1]:NULL);    hp = gethostbyname(host_name);    if (hp == NULL) {	sin.sin_family = AF_INET;	if ((sin.sin_addr.s_addr = inet_addr(host_name)) ==	    (unsigned long)-1) {	    (void)fprintf(stderr,			  "%s:  Host \"%s\" not found.\n",			  myname,host_name);	    return -1;	}    } else {	memcpy((char *)&sin.sin_addr,(char *)hp->h_addr,hp->h_length);	sin.sin_family = hp->h_addrtype;    }    sock = socket(AF_INET,SOCK_DGRAM,0);    if (sock < 0) {	perror("socket");	return -1;    }    nlen = 1;    if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&nlen,sizeof(nlen)) ==	-1) {	perror("setsockopt");	close(sock);	return -1;    }    bsin.sin_family = AF_INET;    bsin.sin_addr.s_addr = INADDR_ANY;    if (bind(sock,(struct sockaddr *)&bsin,sizeof(bsin)) == -1) {	perror("bind");	close(sock);	return -1;    }    nlen = sizeof(bsin);    if (getsockname(sock,(struct sockaddr *)&bsin,&nlen) == -1) {	perror("getsockname");	close(sock);	return -1;    }    if (connect(sock,(struct sockaddr *)&sin,sizeof(sin)) == -1) {	perror("connect");	close(sock);	return -1;    }    printf("Tunnel from %s:%d to ",inet_ntoa(bsin.sin_addr),	   ntohs(bsin.sin_port));    printf("%s:%d.\n",inet_ntoa(sin.sin_addr),ntohs(sin.sin_port));    return sock;}/* Handle fatal negotiation timeout. */voidalarm_handle(dummy)int dummy;{    fprintf(stderr,"PPP failed to negotiate in prescribed time; shutting down.\n");    exit(1);}/* Standard link phases */enum ppp_phase {    phDead, phEstablish, phAuthenticate, phNetwork, phTerminate};const char *ph_str[] = {    "Dead", "Establish", "Authenticate", "Network", "Terminate"};/* Standard set of events */enum ppp_event {    evUp = 0, evDown, evOpen, evClose, evTOp, evTOm,    evRCRp, evRCRm, evRCA, evRCN, evRTR, evRTA,    evRUC, evRXJp, evRXJm, evRXR};const char *ev_str[] = {    "Up", "Down", "Open", "Close", "TO+", "TO-",    "RCR+", "RCR-", "RCA", "RCN", "RTR", "RTA",    "RUC", "RXJ+", "RXJ-", "RXR"};/* Standard negotiation states */enum xcp_state {    stInitial = 0, stStarting, stClosed, stStopped, stClosing, stStopping,    stReqSent, stAckRcvd, stAckSent, stOpened,    stNoChange};const char *st_str[] = {    "Initial", "Starting", "Closed", "Stopped", "Closing", "Stopping",    "Req-Sent", "Ack-Rcvd", "Ack-Sent", "Opened",    "No-Change"};/* Standard set of actions */enum xcp_action {    acNull, acIrc, acScr, acTls, acTlf, acStr, acSta, acSca, acScn, acScj,    acTld, acTlu, acZrc, acSer};const char *ac_str[] = {    "Null", "irc", "scr", "tls", "tlf", "str", "sta", "sca", "scn", "scj",    "tld", "tlu", "zrc", "ser"};/* Dispatch table from RFC 1661 */const struct ppp_dispatch {    enum xcp_state next;    enum xcp_action act[3];} ppp_dispatch[10][16] = {    { /* stInitial */	/* evUp */    { stClosed, { acNull, acNull, acNull } },	/* evDown */  { stNoChange, { acNull, acNull, acNull } },	/* evOpen */  { stStarting, { acTls, acNull, acNull } },	/* evClose */ { stClosed, { acNull, acNull, acNull } },	/* evTOp */   { stNoChange, { acNull, acNull, acNull } },	/* evTOm */   { stNoChange, { acNull, acNull, acNull } },	/* evRCRp */  { stNoChange, { acNull, acNull, acNull } },	/* evRCRm */  { stNoChange, { acNull, acNull, acNull } },	/* evRCA */   { stNoChange, { acNull, acNull, acNull } },	/* evRCN */   { stNoChange, { acNull, acNull, acNull } },	/* evRTR */   { stNoChange, { acNull, acNull, acNull } },	/* evRTA */   { stNoChange, { acNull, acNull, acNull } },	/* evRUC */   { stNoChange, { acNull, acNull, acNull } },	/* evRXJp */  { stNoChange, { acNull, acNull, acNull } },	/* evRXJm */  { stNoChange, { acNull, acNull, acNull } },	/* evRXR */   { stNoChange, { acNull, acNull, acNull } },    },    { /* stStarting */	/* evUp */    { stReqSent, { acIrc, acScr, acNull } },	/* evDown */  { stNoChange, { acNull, acNull, acNull } },	/* evOpen */  { stStarting, { acNull, acNull, acNull } },	/* evClose */ { stInitial, { acTlf, acNull, acNull } },	/* evTOp */   { stNoChange, { acNull, acNull, acNull } },	/* evTOm */   { stNoChange, { acNull, acNull, acNull } },	/* evRCRp */  { stNoChange, { acNull, acNull, acNull } },	/* evRCRm */  { stNoChange, { acNull, acNull, acNull } },	/* evRCA */   { stNoChange, { acNull, acNull, acNull } },	/* evRCN */   { stNoChange, { acNull, acNull, acNull } },	/* evRTR */   { stNoChange, { acNull, acNull, acNull } },	/* evRTA */   { stNoChange, { acNull, acNull, acNull } },	/* evRUC */   { stNoChange, { acNull, acNull, acNull } },	/* evRXJp */  { stNoChange, { acNull, acNull, acNull } },	/* evRXJm */  { stNoChange, { acNull, acNull, acNull } },	/* evRXR */   { stNoChange, { acNull, acNull, acNull } },    },    { /* stClosed */	/* evUp */    { stNoChange, { acNull, acNull, acNull } },	/* evDown */  { stInitial, { acNull, acNull, acNull } },	/* evOpen */  { stReqSent, { acIrc, acScr, acNull } },	/* evClose */ { stClosed, { acNull, acNull, acNull } },	/* evTOp */   { stNoChange, { acNull, acNull, acNull } },	/* evTOm */   { stNoChange, { acNull, acNull, acNull } },	/* evRCRp */  { stClosed, { acSta, acNull, acNull } },	/* evRCRm */  { stClosed, { acSta, acNull, acNull } },	/* evRCA */   { stClosed, { acSta, acNull, acNull } },	/* evRCN */   { stClosed, { acSta, acNull, acNull } },	/* evRTR */   { stClosed, { acSta, acNull, acNull } },	/* evRTA */   { stClosed, { acNull, acNull, acNull } },	/* evRUC */   { stClosed, { acScj, acNull, acNull } },	/* evRXJp */  { stClosed, { acNull, acNull, acNull } },	/* evRXJm */  { stClosed, { acTlf, acNull, acNull } },	/* evRXR */   { stClosed, { acNull, acNull, acNull } },    },    { /* stStopped */	/* evUp */    { stNoChange, { acNull, acNull, acNull } },	/* evDown */  { stStarting, { acTls, acNull, acNull } },	/* evOpen */  { stStopped, { acNull, acNull, acNull } },	/* evClose */ { stClosed, { acNull, acNull, acNull } },	/* evTOp */   { stNoChange, { acNull, acNull, acNull } },	/* evTOm */   { stNoChange, { acNull, acNull, acNull } },	/* evRCRp */  { stAckSent, { acIrc, acScr, acSca } },	/* evRCRm */  { stReqSent, { acIrc, acScr, acScn } },	/* evRCA */   { stStopped, { acSta, acNull, acNull } },	/* evRCN */   { stStopped, { acSta, acNull, acNull } },	/* evRTR */   { stStopped, { acSta, acNull, acNull } },	/* evRTA */   { stStopped, { acNull, acNull, acNull } },	/* evRUC */   { stStopped, { acScj, acNull, acNull } },	/* evRXJp */  { stStopped, { acNull, acNull, acNull } },	/* evRXJm */  { stStopped, { acTlf, acNull, acNull } },	/* evRXR */   { stStopped, { acNull, acNull, acNull } },    },    { /* stClosing */	/* evUp */    { stNoChange, { acNull, acNull, acNull } },	/* evDown */  { stInitial, { acNull, acNull, acNull } },	/* evOpen */  { stStopping, { acNull, acNull, acNull } },	/* evClose */ { stClosing, { acNull, acNull, acNull } },	/* evTOp */   { stClosing, { acStr, acNull, acNull } },	/* evTOm */   { stClosed, { acTlf, acNull, acNull } },	/* evRCRp */  { stClosing, { acNull, acNull, acNull } },	/* evRCRm */  { stClosing, { acNull, acNull, acNull } },	/* evRCA */   { stClosing, { acNull, acNull, acNull } },	/* evRCN */   { stClosing, { acNull, acNull, acNull } },	/* evRTR */   { stClosing, { acSta, acNull, acNull } },	/* evRTA */   { stClosed, { acTlf, acNull, acNull } },	/* evRUC */   { stClosing, { acScj, acNull, acNull } },	/* evRXJp */  { stClosing, { acNull, acNull, acNull } },	/* evRXJm */  { stClosed, { acTlf, acNull, acNull } },	/* evRXR */   { stClosing, { acNull, acNull, acNull } },    },    { /* stStopping */	/* evUp */    { stNoChange, { acNull, acNull, acNull } },	/* evDown */  { stInitial, { acNull, acNull, acNull } },	/* evOpen */  { stStopping, { acNull, acNull, acNull } },	/* evClose */ { stClosing, { acNull, acNull, acNull } },	/* evTOp */   { stStopping, { acStr, acNull, acNull } },	/* evTOm */   { stStopped, { acTlf, acNull, acNull } },	/* evRCRp */  { stStopping, { acNull, acNull, acNull } },	/* evRCRm */  { stStopping, { acNull, acNull, acNull } },	/* evRCA */   { stStopping, { acNull, acNull, acNull } },	/* evRCN */   { stStopping, { acNull, acNull, acNull } },	/* evRTR */   { stStopping, { acSta, acNull, acNull } },	/* evRTA */   { stStopped, { acTlf, acNull, acNull } },	/* evRUC */   { stStopping, { acScj, acNull, acNull } },	/* evRXJp */  { stStopping, { acNull, acNull, acNull } },	/* evRXJm */  { stStopped, { acTlf, acNull, acNull } },	/* evRXR */   { stStopping, { acNull, acNull, acNull } },    },    { /* stReqSent */	/* evUp */    { stNoChange, { acNull, acNull, acNull } },	/* evDown */  { stStarting, { acNull, acNull, acNull } },	/* evOpen */  { stReqSent, { acNull, acNull, acNull } },	/* evClose */ { stClosing, { acIrc, acStr, acNull } },	/* evTOp */   { stReqSent, { acScr, acNull, acNull } },	/* evTOm */   { stStopped, { acTlf, acNull, acNull } },	/* evRCRp */  { stAckSent, { acSca, acNull, acNull } },	/* evRCRm */  { stReqSent, { acScn, acNull, acNull } },	/* evRCA */   { stAckRcvd, { acIrc, acNull, acNull } },	/* evRCN */   { stReqSent, { acIrc, acScr, acNull } },	/* evRTR */   { stReqSent, { acSta, acNull, acNull } },	/* evRTA */   { stReqSent, { acNull, acNull, acNull } },	/* evRUC */   { stReqSent, { acScj, acNull, acNull } },	/* evRXJp */  { stReqSent, { acNull, acNull, acNull } },	/* evRXJm */  { stStopped, { acTlf, acNull, acNull } },	/* evRXR */   { stReqSent, { acNull, acNull, acNull } },    },    { /* stAckRcvd */	/* evUp */    { stNoChange, { acNull, acNull, acNull } },	/* evDown */  { stStarting, { acNull, acNull, acNull } },	/* evOpen */  { stAckRcvd, { acNull, acNull, acNull } },	/* evClose */ { stClosing, { acIrc, acStr, acNull } },	/* evTOp */   { stReqSent, { acScr, acNull, acNull } },	/* evTOm */   { stStopped, { acTlf, acNull, acNull } },	/* evRCRp */  { stOpened, { acSca, acTlu, acNull } },	/* evRCRm */  { stAckRcvd, { acScn, acNull, acNull } },	/* evRCA */   { stReqSent, { acScr, acNull, acNull } },	/* evRCN */   { stReqSent, { acScr, acNull, acNull } },	/* evRTR */   { stReqSent, { acSta, acNull, acNull } },	/* evRTA */   { stReqSent, { acNull, acNull, acNull } },	/* evRUC */   { stAckRcvd, { acScj, acNull, acNull } },	/* evRXJp */  { stReqSent, { acNull, acNull, acNull } },	/* evRXJm */  { stStopped, { acTlf, acNull, acNull } },	/* evRXR */   { stAckRcvd, { acNull, acNull, acNull } },    },    { /* stAckSent */	/* evUp */    { stNoChange, { acNull, acNull, acNull } },	/* evDown */  { stStarting, { acNull, acNull, acNull } },	/* evOpen */  { stAckSent, { acNull, acNull, acNull } },	/* evClose */ { stClosing, { acIrc, acStr, acNull } },	/* evTOp */   { stAckSent, { acScr, acNull, acNull } },	/* evTOm */   { stStopped, { acTlf, acNull, acNull } },	/* evRCRp */  { stAckSent, { acSca, acNull, acNull } },	/* evRCRm */  { stReqSent, { acScn, acNull, acNull } },	/* evRCA */   { stOpened, { acIrc, acTlu, acNull } },	/* evRCN */   { stAckSent, { acIrc, acScr, acNull } },	/* evRTR */   { stReqSent, { acSta, acNull, acNull } },	/* evRTA */   { stAckSent, { acNull, acNull, acNull } },	/* evRUC */   { stAckSent, { acScj, acNull, acNull } },	/* evRXJp */  { stAckSent, { acNull, acNull, acNull } },	/* evRXJm */  { stStopped, { acTlf, acNull, acNull } },	/* evRXR */   { stAckSent, { acNull, acNull, acNull } },    },    { /* stOpened */	/* evUp */    { stNoChange, { acNull, acNull, acNull } },	/* evDown */  { stStarting, { acTld, acNull, acNull } },	/* evOpen */  { stOpened, { acNull, acNull, acNull } },	/* evClose */ { stClosing, { acTld, acIrc, acStr } },	/* evTOp */   { stNoChange, { acNull, acNull, acNull } },	/* evTOm */   { stNoChange, { acNull, acNull, acNull } },	/* evRCRp */  { stAckSent, { acTld, acScr, acSca } },	/* evRCRm */  { stReqSent, { acTld, acScr, acScn } },	/* evRCA */   { stReqSent, { acTld, acScr, acNull } },	/* evRCN */   { stReqSent, { acTld, acScr, acNull } },	/* evRTR */   { stStopping, { acTld, acZrc, acSta } },	/* evRTA */   { stReqSent, { acTld, acScr, acNull } },	/* evRUC */   { stOpened, { acScj, acNull, acNull } },	/* evRXJp */  { stOpened, { acNull, acNull, acNull } },	/* evRXJm */  { stStopping, { acTld, acIrc, acStr } },	/* evRXR */   { stOpened, { acSer, acNull, acNull } },    }};/* Standard message code numbers */#define CODE_CONF_REQ	1#define CODE_CONF_ACK	2#define CODE_CONF_NAK	3#define CODE_CONF_REJ	4#define CODE_TERM_REQ	5#define CODE_TERM_ACK	6#define CODE_CODE_REJ	7#define CODE_PROTO_REJ	8#define CODE_ECHO_REQ	9#define CODE_ECHO_REP	10#define CODE_DISCARD_REQ	11const char *code_str[] = {    "Vendor", "Configure-Request", "Configure-Ack", "Configure-Nak",    "Configure-Reject", "Terminate-Request", "Terminate-Ack", "Code-Reject",    "Protocol-Reject", "Echo-Request", "Echo-Reply", "Discard-Request"};#define PROT_LCP	0xC021#define PROT_IPCP	0x8021struct ppp_xcp;struct ppp_state;/* Basic information about an option. */struct xcp_type {    const char *name;		/* Printable name */    short type;			/* option number (-1 to end) */    short flag;			/* set to ignore default value */    unsigned char minlen;	/* minimum overall length */    unsigned char maxlen;	/* maximum overall length */    int default_value;		/* default */    void (*validate_req)(struct ppp_state *state,			 struct ppp_xcp *xcp,			 const struct xcp_type *tp,			 const unsigned char *buf,			 int len);    void (*validate_nak)(struct ppp_state *state,			 struct ppp_xcp *xcp,			 const struct xcp_type *tp,			 const unsigned char *buf,			 int len);    void (*show)(const struct ppp_state *state,		 const struct ppp_xcp *xcp,		 const struct xcp_type *tp,		 const unsigned char *buf,		 int len);};const struct xcp_type lcp_types[] = {    { NULL, -1, 0, 0, 0, 0, NULL, NULL, NULL }};void ipcp_addr_req(struct ppp_state *state,		   struct ppp_xcp *xcp,		   const struct xcp_type *tp,		   const unsigned char *buf,		   int len);void ipcp_addr_nak(struct ppp_state *state,		   struct ppp_xcp *xcp,		   const struct xcp_type *tp,		   const unsigned char *buf,		   int len);void ipcp_addr_show(const struct ppp_state *state,		    const struct ppp_xcp *xcp,		    const struct xcp_type *tp,		    const unsigned char *buf,		    int len);const struct xcp_type ipcp_types[] = {    { "IP-Address", 3, 1, 6, 6, 0, ipcp_addr_req, ipcp_addr_nak,      ipcp_addr_show },    { NULL, -1, 0, 0, 0, 0, NULL, NULL, NULL }};struct option_state {    int my_value;			/* sent in Configure-Request */    int peer_value;			/* last received */    enum { osUsable, osUnusable } state;	/* flag for rejects */};struct ppp_xcp {    const char *name;			/* name of control protocol */    enum xcp_state state;		/* state machine */    int restart;			/* standard restart count */    time_t restart_point;		/* standard restart timer */    int naks_sent;			/* consecutive naks sent */    void (*deliver)(struct ppp_state *state,	/* handler */		    struct ppp_xcp *xcp);    const struct xcp_type *types;	/* option types supported here */    struct option_state *opts;		/* current negotiation state */    unsigned short proto;		/* PPP protocol ID */    unsigned char ident;		/* current ID number */};enum parse_state { psOK, psNak, psRej, psBad };struct ppp_state {    enum ppp_phase phase;		/* link phase */    enum parse_state parse_state;	/* request parsing state */    int sock;				/* connection to physical layer */    int timeout_period;			/* value for restart timer */    int mlen;				/* packet length */    unsigned long mymagic,hismagic;	/* magic numbers (for echo) */    unsigned char *bp,*up;		/* pointers to packet buffers */    struct ppp_xcp xcps[2];		/* installed XCPs */    unsigned char inbuffer[1600],upbuf[1500];};#define XCP_LCP 0#define XCP_IPCP 1void send_event(struct ppp_state *state, struct ppp_xcp *xcp,		enum ppp_event event);void change_phase(struct ppp_state *state, enum ppp_phase phase);/* Display contents of buffer */voidbuffer_print(const char *verb, const unsigned char *buf, int len){    int i,j;    struct tm *tm;    time_t now;    now = time(NULL);    tm = localtime(&now);    printf("%02d:%02d %s %d bytes:\n",tm->tm_min,tm->tm_sec,verb,len);    for (i = 0; i < len; i += 16) {

⌨️ 快捷键说明

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