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

📄 upap.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
字号:
/*
 * FILENAME: upap.c
 *
 * Copyright 1997 - 2001 By InterNiche Technologies Inc. All rights reserved
 *
 * User/Password Authentication Protocol.
 *
 * MODULE: PPP
 *
 * ROUTINES: upap_init(), upap_authwithpeer(), upap_authpeer(), 
 * ROUTINES: upap_timeout(), upap_reqtimeout(), upap_lowerup(), 
 * ROUTINES: upap_lowerdown(), upap_protrej(), upap_input(), upap_rauthreq(), 
 * ROUTINES: upap_rauthack(), upap_rauthnak(), upap_sauthreq(), upap_sresp(), 
 *
 * PORTABLE: yes
 */

/* Additional Copyrights: */

/* Portions Copyright 1996 by NetPort Software 
 * Portions 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.
 */

#include "ppp_port.h"

#ifdef PAP_SUPPORT   /* whole file can be ifdeffed out */

#include "mppp.h"

/* UPAP Header length -  op + id + (short)len */
#define  UPAP_HEADERLEN    4


static void upap_timeout (M_PPP mppp, long);
static void upap_reqtimeout (M_PPP mppp, long);

static void upap_rauthreq (upap_state *, u_char *, int id, unshort len);
static void upap_rauthack (upap_state *, u_char *, unshort len);
static void upap_rauthnak (upap_state *, u_char *, unshort len);
static void upap_sauthreq (upap_state *);
static void upap_sresp (upap_state *, int, int, char *, int);


auth_funcs upap_authtable = 
{
   upap_init,
   upap_authwithpeer,
   upap_authpeer,
   upap_lowerup,
   upap_lowerdown,
   upap_input,
   upap_protrej,   
};


#ifndef NO_CONPRINTF
char * upap_code[] =
{
   "foo",
   "AUTHREQ",
   "AUTHACK",
   "AUTHNAK",
};
#endif

/* FUNCTION: upap_init()
 *
 * upap_init - Initialize a UPAP unit.
 * 
 * PARAM1: M_PPP mppp
 *
 * RETURNS: void
 */

void
upap_init(M_PPP mppp)
{
   upap_state * u = &mppp->upap;

   u->mppp = mppp;
   u->us_user = NULL;
   u->us_userlen = 0;
   u->us_passwd = NULL;
   u->us_passwdlen = 0;
   u->us_clientstate = UPAPCS_INITIAL;
   u->us_serverstate = UPAPSS_INITIAL;
   u->us_id = 0;
   u->us_timeouttime = UPAP_DEFTIMEOUT;
   u->us_maxtransmits = 10;
   u->us_reqtimeout = UPAP_DEFREQTIME;
}


/* FUNCTION: upap_authwithpeer()
 *
 * Authenticate us with our peer (start client).
 * Set new state and send authenticate's.
 *
 * 
 * PARAM1: M_PPP mppp
 *
 * RETURNS: void
 */

void
upap_authwithpeer(M_PPP mppp)
{
   upap_state *u = &mppp->upap;

   /* Save the username and password we're given */
   u->us_user = mppp->username;
   u->us_userlen = strlen(mppp->username);
   u->us_passwd = mppp->password;
   u->us_passwdlen = strlen(mppp->password);
   u->us_transmits = 0;

   /* Lower layer up yet? */
   if (u->us_clientstate == UPAPCS_INITIAL ||
       u->us_clientstate == UPAPCS_PENDING) 
   {
      u->us_clientstate = UPAPCS_PENDING;
      return;
   }

   upap_sauthreq(u);         /* Start protocol */
}


/* FUNCTION: upap_authpeer()
 *
 * upap_authpeer - Authenticate our peer (start server). Sets new 
 * state. 
 *
 * 
 * PARAM1: M_PPP mppp
 *
 * RETURNS: 
 */

void
upap_authpeer(M_PPP mppp)
{
   upap_state *u = &mppp->upap;

   /* Lower layer up yet? */
   if (u->us_serverstate == UPAPSS_INITIAL ||
       u->us_serverstate == UPAPSS_PENDING) 
   {
      u->us_serverstate = UPAPSS_PENDING;
      return;
   }

   u->us_serverstate = UPAPSS_LISTEN;
   if (u->us_reqtimeout > 0)
      ppp_settimer(mppp, upap_reqtimeout, u->us_reqtimeout, 0);
}


/* FUNCTION: upap_timeout()
 *
 * Retransmission timer for sending auth-reqs expired.
 * 
 * PARAM1: void * arg
 *
 * RETURNS: void
 */

static void
upap_timeout(M_PPP mppp, long arg)
{
   upap_state *u = &mppp->upap;
   USE_ARG(arg);

   if (u->us_clientstate != UPAPCS_AUTHREQ)
      return;

   if (u->us_transmits >= u->us_maxtransmits) 
   {
      /* give up in disgust */
      //ConPrintf("link %lx: No response to PAP authenticate-requests", mppp);
      u->us_clientstate = UPAPCS_BADAUTH;
      ppp_auth_failed(mppp, 1);
      return;
   }

   upap_sauthreq(u);       /* Send Authenticate-Request */
}


/* FUNCTION: upap_reqtimeout()
 *
 * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
 * 
 * PARAM1: void * arg
 *
 * RETURNS: void
 */

static void
upap_reqtimeout(M_PPP mppp, long arg)
{
   upap_state *u = &mppp->upap;
   USE_ARG(arg);

   if (u->us_serverstate != UPAPSS_LISTEN)
   {
      dtrap("upap 0\n");
      return;           /* huh?? */
   }

   ppp_auth_failed(mppp, 1);
   u->us_serverstate = UPAPSS_BADAUTH;
}



/* FUNCTION: upap_lowerup()
 *
 * The lower layer is up. Start authenticating if pending. 
 *
 * 
 * PARAM1: M_PPP mppp
 *
 * RETURNS: 
 */

void
upap_lowerup(M_PPP mppp)
{
   upap_state * u = &mppp->upap;

   if (u->us_clientstate == UPAPCS_INITIAL)
      u->us_clientstate = UPAPCS_CLOSED;
   else if (u->us_clientstate == UPAPCS_PENDING) 
   {
      upap_sauthreq(u);    /* send an auth-request */
   }

   if (u->us_serverstate == UPAPSS_INITIAL)
      u->us_serverstate = UPAPSS_CLOSED;
   else if (u->us_serverstate == UPAPSS_PENDING) 
   {
      u->us_serverstate = UPAPSS_LISTEN;
      if (u->us_reqtimeout > 0)
         ppp_settimer(mppp, upap_reqtimeout, u->us_reqtimeout, 0);
   }
}


/* FUNCTION: upap_lowerdown()
 *
 * The lower layer is down. Cancel all timeouts. 
 *
 * 
 * PARAM1: M_PPP mppp
 *
 * RETURNS: void
 */

void
upap_lowerdown(M_PPP mppp)
{
   upap_state * u = &mppp->upap;

   if((u->us_clientstate == UPAPCS_AUTHREQ) ||     /* Timeout pending? */
      (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0))
   {
      ppp_cleartimer(mppp);   /* Cancel timeout */
   }
   u->us_clientstate = UPAPCS_INITIAL;
   u->us_serverstate = UPAPSS_INITIAL;
}


/* FUNCTION: upap_protrej()
 *
 * upap_protrej - Peer doesn't speak this protocol. This shouldn't 
 * happen. In any case, pretend lower layer went down. 
 *
 * 
 * PARAM1: M_PPP mppp
 *
 * RETURNS: void
 */

void
upap_protrej(M_PPP mppp)
{
   upap_state *u = &mppp->upap;

   if (u->us_clientstate == UPAPCS_AUTHREQ) 
   {
     // ConPrintf("PAP authentication failed due to protocol-reject");
      ppp_auth_failed(mppp, 0);
   }
   if (u->us_serverstate == UPAPSS_LISTEN) 
   {
      //ConPrintf("PAP authentication of peer failed (protocol-reject)");
      ppp_auth_failed(mppp, 1);
   }
   upap_lowerdown(mppp);
}


/* FUNCTION: upap_input()
 *
 * Input UPAP packet.
 * 
 * PARAM1: M_PPP mppp         - link
 * PARAM2: u_char * inpacket  - starts with opcode AFTER upap prot field
 * PARAM3: int l              - number of bytes in inpacket
 *
 * RETURNS: 
 */

void
upap_input(M_PPP mppp, u_char * inpacket, int l)
{
   upap_state * u = &mppp->upap;
   u_char * inp;
   u_char   code, id;
   unshort  len;

   /* Parse header (code, id and length). If packet too short, drop it. */
   inp = inpacket;
   if (l < UPAP_HEADERLEN) 
   {
     // ConPrintf("upap_input: rcvd short header.");
      return;
   }
   code = *inp++;    /* get opcode (authreq, authack) */
   id = *inp++;
   len = ppp_getshort(inp);
   inp += 2;
   if (len < UPAP_HEADERLEN) 
   {
      //ConPrintf("upap_input link %lx: runt, len: %d.",mppp, len);
      return;
   }
  // ConPrintf("upap_input link %lx: code: %s, id %d, len %d\n",
     //    mppp, upap_code[code], id, len);
   len -= 4;      /* deduct the 4 bytes we advanced inp by */

   if(code > UPAP_AUTHNAK)
   {
      /* Need code reject? */
      //ConPrintf("upap_input: unknown code %d\n", code);
      return;
   }

   /* Action depends on code. */
   switch (code) 
   {
   case UPAP_AUTHREQ:
      upap_rauthreq(u, inp, id, len);
      break;
   case UPAP_AUTHACK:
      upap_rauthack(u, inp, len);
      break;
   case UPAP_AUTHNAK:
      upap_rauthnak(u, inp, len);
      break;
   }

   return;
}


/* FUNCTION: upap_rauthreq()
 *
 * Receive Authenticate.
 * 
 * PARAM1: upap_state *u
 * PARAM2: u_char *inp
 * PARAM3: int id
 * PARAM4: int len
 *
 * RETURNS: void
 */

static void
upap_rauthreq(upap_state * u, 
     u_char *  inp,
     int       id,
     unshort    len)
{
   u_char   ruserlen,   rpasswdlen;
   char *   ruser, * rpasswd;
   int   retcode;
   char *   msg;
   int   msglen;

   if (u->us_serverstate < UPAPSS_LISTEN)
      return;

   /* If we receive a duplicate authenticate-request, we are supposed 
    * to return the same status as for the first request.
    */
   if (u->us_serverstate == UPAPSS_OPEN) 
   {
      upap_sresp(u, UPAP_AUTHACK, id, "", 0);   /* return auth-ack */
      return;
   }
   if (u->us_serverstate == UPAPSS_BADAUTH) 
   {
      upap_sresp(u, UPAP_AUTHNAK, id, "", 0);   /* return auth-nak */
      return;
   }

   /* Parse user/passwd. */
   if (len < sizeof (u_char)) 
   {
      //ConPrintf("upap_rauth: rcvd short packet.");
      return;
   }

   /* Subtract the length of the user name from the total length. */
   ruserlen = *inp++;
   len -= (unshort)ruserlen + 2; /* add size of 2 chars */
   if (len & (unshort)0x8000)    /* see if len tried to go negative */
   {
      //ConPrintf("upap_rauth: rcvd short packet.");
      return;
   }
   ruser = (char *) inp;
   inp += ruserlen;
   rpasswdlen = *inp++;
   if (len < rpasswdlen) 
   {
     // ConPrintf("upap_rauth: rcvd short packet.");
      return;
   }
   rpasswd = (char *) inp;

   if (u->us_reqtimeout > 0)  /* Don't need UPAP timer anymore */
      ppp_cleartimer(u->mppp);

   /* Check the username and password given. */
   retcode = check_passwd(u->mppp, ruser, ruserlen, rpasswd,
      rpasswdlen, &msg, &msglen);

   upap_sresp(u, retcode, id, msg, msglen);

   if (retcode == UPAP_AUTHACK) 
   {
      ppp_lowerup(u->mppp, IPCP_STATE);
   }
   else 
   {
      u->us_serverstate = UPAPSS_BADAUTH;
      ppp_auth_failed(u->mppp, 1);
   }
   return;
}


/* FUNCTION: upap_rauthack()
 *
 * upap_rauthack - Receive Authenticate-Ack.
 * 
 * PARAM1: upap_state *u
 * PARAM2: u_char *inp
 * PARAM3: int id
 * PARAM4: int len
 *
 * RETURNS: void
 */

static void
upap_rauthack(upap_state * u, 
     u_char * inp,
     unshort  len)
{
   u_char   msglen;
   char *   msg;

   if (u->us_clientstate != UPAPCS_AUTHREQ)  /* XXX */
   {
      //ConPrintf("upap_rauthack: rx pkt in state %d\n", u->us_clientstate);
      return;
   }

   /* Parse message. */

   msglen = *inp++;
   len -= sizeof (u_char);
   if (len < (unshort)msglen) 
   {
      //ConPrintf("upap_rauthack: runt, len: %d.", len);
      return;
   }
   msg = (char *) inp;
   //ConPrintf(msg);

   u->us_clientstate = UPAPCS_OPEN;
   if (u->us_reqtimeout > 0)  /* Don't need UPAP timer anymore */
      ppp_cleartimer(u->mppp);

   ppp_lowerup(u->mppp, IPCP_STATE);   /* let upper layer know auth OK */

   return;
}


/* FUNCTION: upap_rauthnak()
 *
 * Receive Authenticate-Nakk.
 * 
 * PARAM1: upap_state *u
 * PARAM2: u_char *inp
 * PARAM3: int id
 * PARAM4: int len
 *
 * RETURNS: 
 */

static void
upap_rauthnak(upap_state * u, 
     u_char *  inp,
     unshort   len)
{
   u_char   msglen;
   char *   msg;

   if (u->us_clientstate != UPAPCS_AUTHREQ)  /* XXX */
   {
      dtrap("upap 1\n");
      return;
   }

   /* Parse message. */
   msglen = *inp++;
   len -= sizeof (u_char);
   if (len < msglen) 
   {
      //ConPrintf("upap_rauthnak: runt, len %d\n", len);
      return;
   }
   msg = (char *) inp;
   //ConPrintf(msg);

   u->us_clientstate = UPAPCS_BADAUTH;

   //ConPrintf("Link %lx: PAP auth failed\n", u->mppp);
   ppp_auth_failed(u->mppp, 0);
}


/* FUNCTION: upap_sauthreq()
 *
 *  Send an Authenticate-Request.
 * 
 * PARAM1: upap_state *u
 *
 * RETURNS: 
 */

static void
upap_sauthreq(upap_state * u)
{
   u_char * outp;
   unshort  outlen;

   /* 2 len bytes + 2 prot bytes */
   outlen = (unshort)(UPAP_HEADERLEN + 2 +
      u->us_userlen + u->us_passwdlen);

   if(outlen > MAX_CILEN)
      panic("upap overflow 1");

   outp = u->mppp->lastci;

   /* build a UPAP header in the send buffer */
   outp = ppp_putshort(outp, PPP_UPAP);

   *outp++ = UPAP_AUTHREQ;
   *outp++ = (++u->us_id);
   outp = ppp_putshort(outp, outlen);
   *outp++ = (u_char)u->us_userlen;
   MEMCPY(outp, u->us_user, u->us_userlen);
   outp += u->us_userlen;
   *outp++ = (u_char)u->us_passwdlen;
   MEMCPY(outp, u->us_passwd, u->us_passwdlen);

   ppp_sendctl(u->mppp, AUTH_STATE, 0, u->mppp->lastci, outlen + 2, 0);

   //ConPrintf("upap_sauth: Sent id %d.", u->us_id);

   ppp_settimer(u->mppp, upap_timeout, u->us_timeouttime, 0);
   ++u->us_transmits;
   u->us_clientstate = UPAPCS_AUTHREQ;
}


/* FUNCTION: upap_sresp()
 *
 * upap_sresp - Send a response (ack or nak).
 * 
 * PARAM1: upap_state *u
 * PARAM2: int code
 * PARAM3: int id
 * PARAM4: char *msg
 * PARAM5: int msglen
 *
 * RETURNS: 
 */

static void
upap_sresp(upap_state * u, 
     int   code,
     int   id,
     char *   msg,
     int   msglen)
{
   u_char * outp;
   unshort  outlen;

   outlen = (unshort)(UPAP_HEADERLEN + 1 + msglen);
   if(outlen > MAX_CILEN)
      panic("upap overflow 1");

   outp = u->mppp->lastci;

   outp = ppp_putshort(outp, PPP_UPAP);

   *outp++ = (u_char)code;
   *outp++ = (u_char)id;
   outp = ppp_putshort(outp, outlen);
   *outp++ = (u_char)msglen;
   MEMCPY(outp, msg, msglen);

   ppp_sendctl(u->mppp, AUTH_STATE, 0, u->mppp->lastci, outlen + 2, 0);

   //ConPrintf("upap_sresp: Sent code %d, id %d.", code, id);
}

#endif   /* PAP_SUPPORT  whole file can be ifdeffed out */
/* end of file upap.c */



⌨️ 快捷键说明

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