home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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;
- }
-