?? ppp.c
字號:
#include <string.h>
#include "net.h"
#include "local.h"
#include "support.h"
#ifndef PPP
#error Please do not undefine PPP in local.h
#endif
#include "ppp.h"
#if DIALD
#include "dialapi.h"
#endif
extern struct NET nets[];
extern struct CONNECT connblo[];
extern struct NETCONF netconf[];
extern PTABLE ussIPTable;
extern PTABLE ussTCPTable;
extern PTABLE ussUDPTable;
extern PTABLE ussLQRPTable;
static int ioctl(void *handle, enum ioctlreq request, void *arg, size_t size);
struct Ihdr { /* Internet header */
char message_header[MESSH_SZ];
char link_header[LHDRSZ];
unsigned char verlen; /* header version, length in 32 bit words */
unsigned char tservice; /* type of service */
unsigned short tlen; /* total packet length including header */
unsigned short frid; /* ID for fragmentation */
unsigned short fragm; /* fragment flags, offset */
unsigned char time; /* time to live (hops) */
unsigned char prot; /* protocol */
unsigned short chksum; /* header checksum */
unsigned char from[Iid_SZ]; /* source name */
unsigned char to[Iid_SZ]; /* destination name */
};
#define IP_H(mb) ((struct Ihdr *)mb)
#define NOMIPHDRSZ 20
struct Thdr { /* TCP header */
char message_header[MESSH_SZ];
char link_header[LHDRSZ];
char ip_header[NOMIPHDRSZ];
unsigned short myport; /* source port */
unsigned short herport; /* dest port */
unsigned NLONG seqno[4 / sizeof(NLONG)]; /* sequence number */
unsigned NLONG ackno[4 / sizeof(NLONG)]; /* acknowledgement number */
unsigned char hdrlen; /* tcp header length in high 4 bits */
unsigned char flags; /* message flags, see below */
unsigned short window; /* window */
unsigned short chksum; /* checksum */
unsigned short urgp; /* urgent pointer */
};
#define TCP_H(mb) ((struct Thdr *)mb)
struct Uhdr { /* UDP header */
char message_header[MESSH_SZ];
char link_header[LHDRSZ];
char ip_header[NOMIPHDRSZ];
unsigned short myport; /* source port */
unsigned short herport; /* dest port */
unsigned short tlen;
unsigned short chksum; /* checksum */
};
#define UDP_H(mb) ((struct Uhdr *)mb)
#define IP_TCP 6
#define IP_UDP 17
/* table for fast checksum sequence calculation */
static const unsigned short fcstab[256] = {
0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf,
0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7,
0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e,
0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876,
0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd,
0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5,
0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c,
0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974,
0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb,
0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3,
0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a,
0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72,
0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9,
0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1,
0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738,
0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70,
0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7,
0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff,
0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036,
0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e,
0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,
0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,
0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,
0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,
0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,
0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,
0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
};
static const char pppterm[]={5,0,0,10,0,0,0,0,0,0};
unsigned char ppp_hstat[NNETS];
/*
** * * * * * *
** ussGetPasswd() Get password from user id
**
** char *ussGetPasswd(int n, char ul, char *u);
**
** PARAMETERS:
** (in) int n A network interface index
** (in) char ul Length of user ID
** (in) char *u Pointer to user ID
**
** RETURNS:
** char *passwd Success
** 0 Failure
**
** DESCRIPTION:
** This function is an internal function for PPP to see if a password
** exists for a given userid.
**
*/
char *ussGetPasswd(int netno, char ul, char *uid)
{
char *pw;
struct NET *netp;
netp = &nets[netno];
if (strncmp(uid, netp->hw.userid, ul) == 0)
pw = netp->hw.passwd;
else
pw = 0;
return pw;
}
/*
** * * * * * *
** pppDQ() Dequeue any lingering messages in PPP future queue
**
** static void pppDQ(netno)
**
** PARAMETERS:
** (in) int netno A network interface index
**
** DESCRIPTION:
** This function is an internal function for PPP that dequeues any
** remaining messages in the PPP future queue so that the upper
** layers may deal with them (as if they were sent but no replies
** have been received).
**
** * * * * * *
*/
#if DBUFFER
static void pppDQ(int netno)
{
MESS *mess;
struct NET *netp;
int i1, i2;
netp = &nets[netno];
i1 = 0;
/* Empty future queue for future links */
while (!QUEUE_EMPTY(netp, future)) {
QUEUE_OUT(netp, future, mess);
mess->offset = boTXDONE; /* Message is "sent" */
if (mess->id <= bWACK) {
if (mess->id == bRELEASE) {
mess->id = bALLOC;
Nrelbuf(mess);
}
}
else {
WAITNOMORE(SIG_WN(netno));
}
i1++;
}
#if NTRACE >= 5
if (i1)
Nprintf("PPP: %d Datagram%c tossed from future queue!\n",
i1, ((i1 == 1)?'!':'s'));
#endif
netp->hw.opt8 = 0;
}
#else
#define pppDQ(netno) (nets[netno].hw.opt8 = 0)
#endif
/*
** * * * * * *
** pppWrite() Internal write for negotiation protocols
**
** static int pppWrite(MESS *mess);
**
** PARAMETERS:
** (in/out) mess Pointer to a buffer to write out interface
**
** DESCRIPTION:
** This function is an internal function for PPP that will create
** the appropriate framing and write a message out the link.
**
** * * * * * *
*/
static int pppWrite(MESS *mess)
{
int i1;
unsigned short us1;
unsigned char *cp;
struct NET *netp;
#if NTRACE > 2 && PPP_DEBUG
pppDebug(0, mess); /* Print out packet */
#endif
netp = &nets[mess->netno];
/* The '- 2' skips the PPP protocol field */
cp = (unsigned char *)mess + MESSH_SZ + LHDRSZ - 2;
PH(mess)->MACtype = 0; /* No compression for WRAP driver */
/* Make async framing */
if (netp->ifType == 23) {
/* Add AHDLC framing */
*--cp = 0x03; /* Control */
*--cp = 0xff; /* Address */
/* Set driver offset */
PH(mess)->poffset = cp - (unsigned char *)mess;
i1 = mess->mlen - PH(mess)->poffset;
/* Calculate and append AHDLC checksum */
us1 = 0xffff;
while (i1--)
us1 = (us1 >> 8) ^ fcstab[(us1 ^ *cp++) & 0xff];
us1 ^= 0xffff;
cp[1] = us1 >> 8;
cp[0] = us1;
}
#ifdef MIB2
netp->ifOutOctets += mess->mlen - PH(mess)->poffset + 2;
netp->ifOutUcastPkts++;
#endif
us1 = mess->id;
/* Write out the packet by calling the driver */
i1 = netp->protoc[1]->writE(mess->netno, mess);
if (i1 != 0 || us1 <= bWACK)
return i1;
WAITFOR(mess->offset == boTXDONE, SIG_WN(mess->netno), netp->tout, i1);
return 1;
}
/*
** * * * * * *
** pppStart() Internal function to make PPP ready for negotiations
**
** static void pppStart(int netno);
**
** PARAMETERS:
** (in) netno A yfnet network number
** (in) apflag Active/Passive flag (1/0)
**
** DESCRIPTION:
** This function will set PPP's data to initial values for negotiations.
** It neither checks nor changes the state. The apflag is there because
** active links usually do not request authentication, but passive ones
** usually do.
**
** * * * * * *
*/
static void pppStart(int netno, int apflag)
{
struct NET *netp;
netp = &nets[netno];
netp->state = 0;
#if NTRACE >= 3
Nprintf("PPP: Starting on network %d\n", netno);
#endif
#ifdef LQRP
memset(netp->lastins, 0, 44); /* OutLQRs, InLQRs, InGoodOctets also */
#endif
/* Options used in first configure request for LCP */
netp->hw.locopts = 0
#if PPP_MRU
+ 0x02
#endif
#if ASYNC
+ 0x04
#endif
#if REQAUTH
+ (apflag ? 0 : 0x08)
#endif
#if QUALITY
+ 0x10
#endif
#if MAGICNUM
+ 0x20
#endif
#if COMPRESSION & 1
+ 0x0180
#endif
;
netp->hw.remopts = 0;
#if MP
mpStart(netno);
#endif
#if VJ
TXslots[netno] = RXslots[netno] = MAXSLOTS-1;
TXixcomp[netno] = 1;
#endif
/* What authentication did host request if passive? */
if (!apflag) {
#if REQAUTH == PROTpap
netp->hw.opt4 = AUTHhpap;
#elif REQAUTH == PROTchap && AUTH_ALG == CHAPalg_MD5
netp->hw.opt4 = AUTHhchp;
#elif REQAUTH == PROTchap && AUTH_ALG == CHAPalg_MD4
netp->hw.opt4 = AUTHhmsc;
#else
netp->hw.opt4 = 0;
#endif
}
#if ASYNC
netp->hw.ul1 = 0; /* Escape no characters if possible */
#endif
netp->hw.opt1 = netp->hw.opt2 = netp->hw.opt6 = netp->hw.opt8 = 0;
netp->hw.opt7 = MAXCONF; /* Initialize restart counter */
netp->hw.timems = TimeMS(); /* Initialize timer */
netp->hw.idle_time = netp->hw.echo_time = netp->hw.timems;
}
/*
** * * * * * *
** pppNegotiate() Internal packet writing function.
**
** static void pppNegotiate(MESS *mess);
**
** PARAMETERS:
** (in/out) mess A buffer to write with
**
** DESCRIPTION:
** This function will check the state and create any necessary
** packet to negotiate with.
**
** * * * * * *
*/
static void pppNegotiate(MESS *mess)
{
int i1;
unsigned char *cp, *cp2;
struct NET *netp;
netp = &nets[mess->netno];
if (netp->state != PPPclsd && netp->state != PPPopen) {
cp = (unsigned char *)mess + MESSH_SZ + LHDRSZ;
cp2 = cp + 4;
if (netp->state == PPPclsng) {
Nmemcpy((char *)mess+MESSH_SZ+LHDRSZ, pppterm, sizeof(pppterm));
PH(mess)->protocol = NC2(PROTlcp);
cp2 = cp + sizeof(pppterm);
goto write;
}
else if ((netp->state & LCPopen) == LCPopen) {
#if AUTHENT & 1
/* If peer requested PAP, we send Auth-req */
if (netp->hw.opt4 & AUTHppap) {
if(netp->hw.opt4 & AUTHpwat)
return;
netp->hw.opt4 |= AUTHpwat;
PH(mess)->protocol = NC2(PROTpap);
*cp = PAPauth_req;
cp[2] = 0;
*cp2 = (unsigned char)strlen(netp->hw.userid);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -