home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HAM Radio 1
/
HamRadio.cdr
/
misc
/
src0131
/
ppppap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-11-10
|
22KB
|
954 lines
/*
* PPPPAP.C -- Password Authenticate Protocol for PPP
*
* 12-89 -- Katie Stevens (dkstevens@ucdavis.edu)
* UC Davis, Computing Services
* PPP.09 05-90 [ks] add authentication phase
* PPP.10 06-90 [ks] improve keybd input of PAP password
* make ppp open/close/reset work properly
* PPP.14 08-90 [ks] change PAP to PPP for consistency with RFC1172
* PPP.15 09-90 [ks] update to KA9Q NOS v900828
*/
#include <stdio.h>
#include "global.h"
#include "files.h"
#include "mbuf.h"
#include "proc.h"
#include "iface.h"
#include "socket.h"
#include "ppp.h"
#include "slip.h"
#include "session.h"
#include "ftpserv.h"
/* Counter for PPP id field */
extern unsigned char Pppid;
/* PPP tracing */
extern int Ppptrace;
static void pap_open __ARGS((struct slip *sp));
static int pap_authen __ARGS((char *peerid, char *pass));
void pap_input __ARGS((int mustask, void *v1, void *v2));
static void pap_pwdlookup __ARGS((struct lcpctl *lcpiop));
static int pap_sendreq __ARGS((struct slip *sp));
static struct mbuf *pap_makereq __ARGS((struct lcpctl *lcpiop));
static void pap_rcvack __ARGS((struct slip *sp, struct cnfhdr *rcnf,
struct mbuf *data));
static void pap_rcvnak __ARGS((struct slip *sp, struct cnfhdr *rcnf,
struct mbuf *data));
static void pap_rcvreq __ARGS((struct slip *sp, struct cnfhdr *rcnf,
struct mbuf *data));
static void pap_shutdown __ARGS((struct slip *sp));
static int pap_chkack __ARGS((struct slip *sp, struct cnfhdr *ackcnf,
struct mbuf *data));
static int pap_chknak __ARGS((struct slip *sp, struct cnfhdr *nakcnf,
struct mbuf *data));
static void pap_chkreq __ARGS((struct slip *sp, struct cnfhdr *reqcnf,
struct mbuf *data));
static void pap_timeout __ARGS((void *vp));
static void pap_timer __ARGS((struct slip *sp));
static int pap_sendreply __ARGS((struct slip *sp, char code,
unsigned char id, struct mbuf *data));
/* Possible PAP states */
static char *PAPStates[] = {
"Closed",
"Listen",
"Req Sent",
"Req Rcvd",
"Open",
};
/* Possible PAP packet types */
static char *PAPCodes[] = {
NULLCHAR,
"Auth Req",
"Auth Ack",
"Auth Nak",
};
/****************************************************************************/
/* Initialize Password Auth Protocol state machine for config exchange */
int
pap_start(sp)
struct slip *sp;
{
struct pppctl *pppiop;
struct lcpctl *lcpiop;
if (Ppptrace > 5)
log(-1, "pap_start()");
pppiop = sp->pppio;
lcpiop = &(pppiop->lcpio);
/* Ready for PAP phase */
pppiop->state = PPP_PAP;
pap_reset(pppiop);
/* Just finished LCP negotiation; prepare for PAP negotiation */
if (lcpiop->lclparm.auth_type == PAP_AUTH_TYPE) {
/* We asked remote to send AUTH_REQ; wait for that packet */
lcpiop->pap_state = PAP_LISTEN;
return 0;
}
/* Remote host asked us to send AUTH_REQ */
lcpiop->pap_state = PAP_CLOSED;
/* We need to send AUTH_REQ to remote host */
/* Get the peer ID and password we will send */
if ((lcpiop->pap_user == NULLCHAR)||(lcpiop->pap_pass == NULLCHAR)) {
pap_getpass(sp,0);
pwait(&(lcpiop->pap_user));
if ((lcpiop->pap_user == NULLCHAR) ||
(lcpiop->pap_pass == NULLCHAR))
return -1;
}
return(pap_sendreq(sp));
}
/*******************************************/
/* Initialize our PAP configuration options */
void
pap_init(sp)
struct slip *sp;
{
struct pppctl *pppiop;
struct lcpctl *lcpiop;
if (Ppptrace > 5)
log(-1, "pap_init()");
pppiop = sp->pppio;
lcpiop = &(pppiop->lcpio);
/* PAP layer closed; dont know local peerID/password values */
lcpiop->pap_state = PAP_CLOSED;
lcpiop->pap_user = NULLCHAR;
lcpiop->pap_pass = NULLCHAR;
return;
}
/* IP Control configuration negotiation complete */
static void
pap_open(sp)
struct slip *sp;
{
struct pppctl *pppiop;
struct lcpctl *lcpiop;
pppiop = sp->pppio;
lcpiop = &(pppiop->lcpio);
/* Mark PAP as completed */
if (Ppptrace)
log(-1,"%s: PPP/PAP: peer ID verified %s",
sp->iface->name,lcpiop->pap_user);
lcpiop->pap_state = PAP_OPEN;
/* Ready for IPCP negotiation phase */
ipcp_start(sp);
return;
}
/* Reset PAP configuration options for initial request */
int
pap_reset(pppiop)
struct pppctl *pppiop;
{
struct lcpctl *lcpiop;
if (Ppptrace > 5)
log(-1, "pap_reset()");
lcpiop = &(pppiop->lcpio);
lcpiop->pap_state = PAP_CLOSED;
lcpiop->ack_retry = 0;
return 0;
}
/*******************************************/
/* Verify peer ID and password sent by remote host with PAP AUTH_REQ */
static int
pap_authen(peerid,pass)
char *peerid;
char *pass;
{
int privs;
char *path;
int anony = 0;
/* Use same login as FTP server */
path = mallocw(128);
privs = userlogin(peerid,pass,&path,128,&anony);
free(path);
/* Check privs for this peer ID */
if (privs == -1) {
if (Ppptrace > 2)
log(-1,
"PAP peerID/password incorrect or not found: %s",
peerid);
return -1;
}
if ((privs & PPP_ACCESS_PRIV) == 0) {
if (Ppptrace > 2)
log(-1,"PAP no permission for PPP access: %s",peerid);
return -1;
}
return 0;
}
/* Get peerID and password to send to remote host with PAP AUTH_REQ */
int
pap_getpass(sp,mustask)
struct slip *sp;
int mustask;
{
struct pppctl *pppiop;
struct lcpctl *lcpiop;
pppiop = sp->pppio;
lcpiop = &(pppiop->lcpio);
if (mustask) {
if (lcpiop->pap_user != NULLCHAR) {
free(lcpiop->pap_user);
lcpiop->pap_user = NULLCHAR;
}
if (lcpiop->pap_pass != NULLCHAR) {
free(lcpiop->pap_pass);
lcpiop->pap_pass = NULLCHAR;
}
} else if ((lcpiop->pap_user != NULLCHAR)
&&(lcpiop->pap_pass == NULLCHAR)) {
pap_pwdlookup(lcpiop);
}
if ((lcpiop->pap_user == NULLCHAR)||(lcpiop->pap_pass == NULLCHAR)) {
newproc("PAP Input",256,pap_input,mustask,
(void *)sp->iface,
(void *)lcpiop,0);
}
return 0;
}
void
pap_input(mustask, v1, v2)
int mustask;
void *v1;
void *v2;
{
struct iface *iface;
struct lcpctl *lcpiop;
char buf[21];
struct session *sp;
iface = (struct iface *)v1;
lcpiop = (struct lcpctl *)v2;
/* Allocate a session control block */
if((sp = newsession("PPP/PAP Auth",PPPPASS)) == NULLSESSION){
tprintf("Too many sessions\n");
return;
}
if (mustask)
tprintf("\n%s: PPP/PAP Password Authentication Failed; enter peer ID and password again\n",
iface->name);
else
tprintf("\n%s: PPP/PAP Password Authentication Required\n",
iface->name);
tprintf("%s: PPP/PAP Peer ID: ",iface->name);
usflush(sp->output);
/* Only ask for the peer ID if it is unknown */
if (lcpiop->pap_user == NULLCHAR) {
recvline(sp->input,buf,20);
/* Send the command only if the user response
* was non-null
*/
if (buf[0] == '\n')
lcpiop->pap_user = NULLCHAR;
else {
rip(buf);
lcpiop->pap_user = mallocw(strlen(buf)+1);
strcpy(lcpiop->pap_user,buf);
}
} else {
tprintf("%s\n",lcpiop->pap_user);
}
/* Always ask for the password */
/* turn off echo */
sp->ttystate.echo = 0;
tprintf("%s: PPP/PAP Password: ",iface->name);
usflush(sp->output);
recvline(sp->input,buf,20);
tprintf("\n");
/* Turn echo back on */
sp->ttystate.echo = 1;
/* Save the password only if the user response was non-null */
if (buf[0] == '\n')
lcpiop->pap_pass = NULLCHAR;
else {
rip(buf);
lcpiop->pap_pass = mallocw(strlen(buf)+1);
strcpy(lcpiop->pap_pass,buf);
}
if (sp != NULLSESSION)
freesession(sp);
psignal(&(lcpiop->pap_user),0);
return;
}
/* Check the FTP userfile for this peer ID; get password if available */
static void
pap_pwdlookup(lcpiop)
struct lcpctl *lcpiop;
{
char *buf;
char *cp, *cp1;
char *svp;
FILE *fp;
int perm;
if((fp = fopen(Userfile,READ_TEXT)) == NULLFILE)
/* Userfile doesn't exist */
return;
/* Locate user name in password file */
buf = mallocw(128);
while(fgets(buf,128,fp),!feof(fp)){
if(buf[0] == '#')
continue; /* Comment */
if((cp = strchr(buf,' ')) == NULLCHAR)
/* Bogus entry */
continue;
*cp++ = '\0'; /* Now points to password */
svp = cp; /* Save ptr to password */
if(stricmp(lcpiop->pap_user,buf) == 0)
break; /* Found peer ID */
}
if(feof(fp)){
/* Peer ID not found in file */
fclose(fp);
free(buf);
return;
}
fclose(fp);
/* Look for space after password field in file */
if((cp1 = strchr(cp,' ')) == NULLCHAR) {
/* Invalid file entry */
free(buf);
return;
}
*cp1++ = '\0'; /* Now points to path field */
if((cp = strchr(cp1,' ')) == NULLCHAR) {
/* Permission field missing */
free(buf);
return;
}
*cp++ = '\0'; /* now points to permission field */
perm = atoi(cp);
/* Check permissions for this peer ID */
if ((perm & PPP_PWD_LOOKUP) == 0) {
/* Not in ftpuser file for password lookup */
free(buf);
return;
}
/* Save the password from this userfile record */
lcpiop->pap_pass = malloc(strlen(svp)+1);
strcpy(lcpiop->pap_pass,svp);
return;
}
/****************************************************************************/
/* Send our PAP configuration request */
static int
pap_sendreq(sp)
struct slip *sp;
{
struct pppctl *pppiop;
struct lcpctl *lcpiop;
struct mbuf *bp;
if (Ppptrace > 5)
log(-1,"pap_sendreq()");
pppiop = sp->pppio;
lcpiop = &(pppiop->lcpio);
/* Get a packet with our configuration request */
bp = pap_makereq(lcpiop);
/* Start timer against wait for reply to our config request */
pap_timer(sp);
/* Send PAP configuration request to remote host */
pppiop->state = PPP_PAP;
if (lcpiop->pap_state != PAP_REQ_SENT)
lcpiop->pap_state = PAP_REQ_SENT;
return(pap_sendreply(sp, AUTH_REQ, 0, bp));
}
/*******************************************/
static struct mbuf *
pap_makereq(lcpiop)
struct lcpctl *lcpiop;
{
register char *cp;
struct mbuf *req_bp = NULLBUF;
int len;
if (Ppptrace > 5)
log(-1," pap_makereq() peer ID: %s",lcpiop->pap_user);
/* Get buffer for authenticate request packet */
len = strlen(lcpiop->pap_user)+strlen(lcpiop->pap_pass)+2;
if ((req_bp = alloc_mbuf(len)) == NULLBUF)
return NULLBUF;
/* Load peer ID and password for authenticate packet */
cp = req_bp->data;
*cp++ = (char)strlen(lcpiop->pap_user);
memcpy(cp, lcpiop->pap_user, strlen(lcpiop->pap_user));
cp += strlen(lcpiop->pap_user);
*cp++ = (char)strlen(lcpiop->pap_pass);
memcpy(cp, lcpiop->pap_pass, strlen(lcpiop->pap_pass));
req_bp->cnt += len;
/* Return our config request */
return(req_bp);
}
/****************************************************************************/
/* Remote host ACKed our configuration request */
static void
pap_rcvack(sp, rcnf, data)
struct slip *sp;
struct cnfhdr *rcnf;
struct mbuf *data;
{
struct pppctl *pppiop;
struct lcpctl *lcpiop;
if (Ppptrace > 5)
log(-1, "pap_rcvack()");
pppiop = sp->pppio;
lcpiop = &(pppiop->lcpio);
stop_timer(&lcpiop->lcp_tm);
switch(lcpiop->pap_state) {
case PAP_REQ_SENT:
/* Make sure ACK is proper */
if (pap_chkack(sp, rcnf, data) != -1) {
/* Remote host accepted our request */
pap_open(sp);
break;
}
/* Still need to settle request from remote host */
pap_timer(sp);
break;
case PAP_REQ_RCVD:
case PAP_CLOSED:
case PAP_LISTEN:
case PAP_OPEN:
default:
/* Confusion; shutdown the connection */
free_p(data);
pap_shutdown(sp);
break;
}
return;
}
/* Remote host NAKed our configuration request */
static void
pap_rcvnak(sp, rcnf, data)
struct slip *sp;
struct cnfhdr *rcnf;
struct mbuf *data;
{
struct pppctl *pppiop;
struct lcpctl *lcpiop;
if (Ppptrace > 5)
log(-1, "pap_rcvnak()");
pppiop = sp->pppio;
lcpiop = &(pppiop->lcpio);
stop_timer(&lcpiop->lcp_tm);
switch(lcpiop->pap_state) {
case PAP_REQ_SENT:
/* Remote host NAKd our AUTH_REQ */
if (pap_chknak(sp, rcnf, data) == -1) {
/* Bad NAK packet */
/* Wait for another; resend request on timeout */
pap_timer(sp);
break;
}
/* Must have sent a bad peer ID or password */
/* Get the password again */
pap_getpass(sp,1);
pwait(&(lcpiop->pap_user));
if (lcpiop->pap_pass == NULLCHAR)
/* No password entered, close PPP link */
pap_shutdown(sp);
else
/* Send AUTH_REQ again with new password */
pap_sendreq(sp);
break;
case PAP_REQ_RCVD:
case PAP_OPEN:
case PAP_CLOSED:
case PAP_LISTEN:
default:
/* Confusion; shutdown the connection */
free_p(data);
pap_shutdown(sp);
break;
}
return;
}
/* Process configuration request sent by remote host */
static void
pap_rcvreq(sp, rcnf, data)
struct slip *sp;
struct cnfhdr *rcnf;
struct mbuf *data;
{
struct pppctl *pppiop;
struct lcpctl *lcpiop;
if (Ppptrace > 5)
log(-1, "pap_rcvreq()");
pppiop = sp->pppio;
lcpiop = &(pppiop->lcpio);
switch(lcpiop->pap_state) {
case PAP_LISTEN: /* Normal event */
case PAP_REQ_RCVD: /* Normal event */
/* Evaluate configuration request from remote host */
pap_chkreq(sp, rcnf, data);
break;
case PAP_CLOSED:
case PAP_REQ_SENT:
case PAP_OPEN:
default:
/* We are closed; dont accept any connections */
free_p(data);
pap_shutdown(sp);
break;
}
return;
}
/* PAP failure, abandon PAP attempt; shutdown LCP layer */
static void
pap_shutdown(sp)
struct slip *sp;
{
struct pppctl *pppiop;
if (Ppptrace > 5)
log(-1, "pap_shutdown()");
pppiop = sp->pppio;
if (Ppptrace > 1)
log(-1,"%s: PPP/PAP: Failed; close PPP connection",sp->iface->name);
pap_reset(pppiop);
/* Shut the link down completely */
lcp_shutdown(sp);
return;
}
/*******************************************/
/* Process configuration ACK send by remote host */
static int
pap_chkack(sp, ackcnf, data)
struct slip *sp;
struct cnfhdr *ackcnf;
struct mbuf *data;
{
int ackerr = 0;
struct pppctl *pppiop;
struct lcpctl *lcpiop;
char *pap_msg;
int len;
if (Ppptrace > 5)
log(-1,"pap_chkack()");
pppiop = sp->pppio;
lcpiop = &(pppiop->lcpio);
/* PAP ID field must match last request we sent */
if (ackcnf->id != lcpiop->lastid) {
if (Ppptrace > 5)
log(-1,"improper PAP ACK; bad ID");
free_p(data);
return -1;
}
if ((Ppptrace > 1) && (len_p(data) != 0)) {
/* Log ASCII message from remote host, if any */
len = pullchar(&data);
pap_msg = mallocw(len+1);
len = dqdata(data,pap_msg,len);
pap_msg[len] = '\0';
log(-1,"%s: PPP/PAP: ACK msg: %s",sp->iface->name,pap_msg);
free(pap_msg);
} else {
free_p(data);
}
if (ackerr) {
/* Error in configuration ACK */
if (Ppptrace > 5)
log(-1,"improper PAP ACK");
return -1;
}
/* ACK is acceptable */
if (Ppptrace > 5)
log(-1,"valid PAP ACK");
return 0;
}
/* Process configuration NAK send by remote host */
static int
pap_chknak(sp, nakcnf, data)
struct slip *sp;
struct cnfhdr *nakcnf;
struct mbuf *data;
{
int nakerr = 0;
struct pppctl *pppiop;
struct lcpctl *lcpiop;
int len;
char *pap_msg;
if (Ppptrace > 5)
log(-1,"pap_chknak()");
pppiop = sp->pppio;
lcpiop = &(pppiop->lcpio);
/* PAP ID field must match last request we sent */
if (nakcnf->id != lcpiop->lastid) {
if (Ppptrace > 1)
log(-1,"improper PAP NAK; bad ID");
free_p(data);
return -1;
}
if ((Ppptrace > 1) && (len_p(data) != 0)) {
/* Log ASCII message from remote host, if any */
len = pullchar(&data);
pap_msg = mallocw(len+1);
len = dqdata(data,pap_msg,len);
pap_msg[len] = '\0';
log(-1,"%s: PPP/PAP: NAK msg: %s",sp->iface->name,pap_msg);
free(pap_msg);
} else {
free_p(data);
}
if (nakerr) {
/* Error in configuration NAK */
if (Ppptrace > 5)
log(-1,"improper PAP NAK");
return -1;
}
/* NAK packet was properly constructed */
if (Ppptrace > 5)
log(-1,"valid PAP NAK");
return 0;
}
/* Check IP Control options requested by the remote host */
static void
pap_chkreq(sp, reqcnf, data)
struct slip *sp;
struct cnfhdr *reqcnf;
struct mbuf *data;
{
struct pppctl *pppiop;
struct lcpctl *lcpiop;
int ilen,ulen,plen;
char cnf_accept = CONFIG_ACK; /* Overall reply to request */
struct mbuf *reply_bp = NULLBUF; /* Actual reply packet */
char userpass[48]; /* Storage for peerID/pass */
char *pap_msg = NULLCHAR; /* Message for remote host */
if (Ppptrace > 5)
log(-1, "pap_chkreq()");
pppiop = sp->pppio;
lcpiop = &(pppiop->lcpio);
lcpiop->pap_state = PAP_REQ_RCVD;
/* Make sure length in PAP config header is realistic */
ilen = len_p(data);
if (ilen < reqcnf->len)
reqcnf->len = ilen;
/* Extract peerID/password sent by remote host */
plen = dqdata(data,userpass,48);
ulen = (int)userpass[0];
if (ulen >= 48) {
strcpy(userpass,"foo");
} else {
++ulen;
plen = (int)userpass[ulen];
userpass[ulen] = '\0';
++ulen;
plen += ulen;
if (plen >= 48)
plen = 47;
userpass[plen] = '\0';
}
if (Ppptrace > 5)
log(-1,"PAP peer ID: %s",&(userpass[1]));
/* Verify peerID/pass sent by remote host */
if (lcpiop->pap_user != NULLCHAR) {
free(lcpiop->pap_user);
lcpiop->pap_user = NULLCHAR;
}
if (pap_authen(&(userpass[1]),&(userpass[ulen])) == -1) {
cnf_accept = AUTH_NAK;
pap_msg = " Invalid peer ID or password";
} else {
cnf_accept = AUTH_ACK;
pap_msg = " Welcome to the Internet";
lcpiop->pap_user = mallocw(strlen(&(userpass[1]))+1);
strcpy(lcpiop->pap_user,&(userpass[1]));
}
ilen = strlen(pap_msg);
reply_bp = qdata(pap_msg,ilen);
reply_bp->data[0] = (char)(ilen - 1);
/* Send ACK/NAK to remote host */
if (cnf_accept == AUTH_ACK) {
if (Ppptrace > 1)
log(-1, "%s: PPP/PAP: peerID (%s) from remote host has been verified",
sp->iface->name,&(userpass[1]));
/* Accept configuration requested by remote host */
pap_sendreply(sp, AUTH_ACK, reqcnf->id, reply_bp);
/* PPP data link now ready for next phase */
pap_open(sp);
} else {
/* NAK config request made by remote host */
if (Ppptrace)
log(-1,"%s: PPP/PAP: invalid peerID (%s) from remote host",
sp->iface->name,&(userpass[1]));
pap_sendreply(sp, AUTH_NAK, reqcnf->id, reply_bp);
if (++lcpiop->ack_retry > PAP_FAIL_MAX) {
/* Shut the link down after too many failed auth */
if (Ppptrace)
log(-1,"%s: PPP/PAP: Failed; too many failed attempts; close PPP link",
sp->iface->name);
pap_shutdown(sp);
} else {
if (Ppptrace > 1)
log(-1,"%s: PPP/PAP: not verified; wait for another attempt",
sp->iface->name);
}
}
return;
}
/****************************************************************************/
/* Timeout while waiting for reply from remote host */
static void
pap_timeout(vp)
void *vp;
{
struct slip *sp;
struct pppctl *pppiop;
struct lcpctl *lcpiop;
if (Ppptrace > 1)
log(-1, "pap_timeout()");
/* Load pointers to interface that timed-out */
sp = (struct slip *)vp;
pppiop = sp->pppio;
lcpiop = &(pppiop->lcpio);
/* Attempt to get things going again */
switch(lcpiop->pap_state) {
case PAP_REQ_SENT:
/* Timeout waiting for ACK to our request */
if (++lcpiop->ack_retry > PAP_RETRY_MAX) {
/* Remote host doesnt seem to be listening */
pap_shutdown(sp);
break;
}
/* Resend the request */
pap_sendreq(sp);
break;
case PAP_REQ_RCVD:
case PAP_CLOSED:
case PAP_LISTEN:
case PAP_OPEN:
default:
/* Confusion; shutdown the connection */
pap_shutdown(sp);
break;
}
return;
}
/* Set a timer in case an expected event does not occur */
static void
pap_timer(sp)
struct slip *sp;
{
struct pppctl *pppiop;
struct lcpctl *lcpiop;
struct timer *t;
if (Ppptrace > 5)
log(-1,"pap_timer()");
pppiop = sp->pppio;
lcpiop = &(pppiop->lcpio);
t = &(lcpiop->lcp_tm);
t->func = (void (*)())pap_timeout;
t->arg = (void *)sp;
start_timer(t);
return;
}
/****************************************************************************/
/* Send an PAP packet to the remote host */
static int
pap_sendreply(sp,code,id,data)
struct slip *sp;
char code;
unsigned char id;
struct mbuf *data;
{
struct iface *iface;
struct cnfhdr hdr;
/* Load PAP header values */
hdr.code = code;
switch(code) {
case AUTH_REQ:
/* Save ID field for match aginst replies from remote host */
sp->pppio->lcpio.lastid = Pppid;
/* Use a unique ID field value */
hdr.id = Pppid++;
break;
case AUTH_ACK:
case AUTH_NAK:
/* Use ID sent by remote host */
hdr.id = id;
break;
default:
/* Shouldnt happen */
if (Ppptrace)
log(-1, "%s: PPP/PAP: bogus code: %x\n",
sp->iface->name, code);
return -1;
}
hdr.len = len_p(data) + CNF_HDRLEN;
/* Prepend PAP header to packet data */
if ((data = htoncnf(&hdr,data)) == NULLBUF)
return -1;
if (Ppptrace > 1)
log(-1, "%s: PPP/PAP Send: current state: %s PAP option: %s id: %d len: %d",
sp->iface->name,
PAPStates[sp->pppio->lcpio.pap_state],
PAPCodes[code],hdr.id,hdr.len);
/* Send PAP packet to remote host */
sp->pppio->sndpap++;
iface = sp->iface;
return( (*iface->output)
(iface, NULLCHAR, NULLCHAR, PPP_PAP_TYPE, data) );
}
/* Process incoming PAP packet */
void
papproc(iface,bp)
struct iface *iface;
struct mbuf *bp;
{
struct slip *sp;
struct cnfhdr hdr;
sp = &Slip[iface->xdev];
/* Extract PAP header */
ntohcnf(&hdr, &bp);
hdr.len -= CNF_HDRLEN; /* Length includes envelope */
trim_mbuf(&bp, hdr.len); /* Trim off FCS bytes */
if (Ppptrace > 1)
log(-1, "%s: PPP/PAP Recv: current state: %s PAP option: %s id: %d len: %d",
iface->name,
PAPStates[sp->pppio->lcpio.pap_state],
PAPCodes[hdr.code], hdr.id, hdr.len);
/* Process PAP packet data */
switch(hdr.code) {
case AUTH_REQ: /* Request of remote host */
pap_rcvreq(sp, &hdr, bp);
break;
case AUTH_ACK: /* Remote accepted our req */
pap_rcvack(sp, &hdr, bp);
break;
case AUTH_NAK: /* Remote declined our req */
pap_rcvnak(sp, &hdr, bp);
break;
default:
if (Ppptrace)
log(-1,"%s: PPP/PAP: Unknown packet type: %x; dropping packet",
sp->iface->name,hdr.code);
free_p(bp);
break;
}
return;
}