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

📄 ifppp.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 2 页
字号:
         return (0);       /* OK return - this is not an error */
      }
   }

   /* Insert PPP_IP type at front of IP packet */
   pkt->nb_prot -= 2;      /* space for PPP_IP header */
   if (pkt->nb_prot < pkt->nb_buff)
   {
      dtrap("ifppp 5\n");    /* there should always be room to prepend MAC header */
      panic("ppp_pkt_output: no MAC prepend space");
   }
   pkt->nb_plen += 2;      /* for PPP_IP header */

   /* build PPP_IP header at pkt->nb_prot */
   ppp_putshort((u_char*)pkt->nb_prot, PPP_IP);

   /* see if we need to start the PPP link for IPCP: */
   if(mppp->states[IPCP_STATE] != ST_OPENED)
      ppp_open(mppp, IPCP_STATE);

   /* lastly, add the packet to the send queue and spin send logic */
   
#ifdef PPP_MULTILINK
   /* see if we need to fragment the packet over a multilink bundle */
   if((mppp->ml_numlinks > 1) &&   /* does this bundle have multiple links. */
      (pkt->nb_plen > mppp->ml_frag_size))   /* and packet is big? */
   {
      err = pppml_sendpkt(mppp, pkt);     /* hand over to ML code */
      return err;
   }
#endif /* PPP_MULTILINK */

   putq(&mppp->dataq, (qp)pkt);  /* add to data packet send queue */

   /* spin the dataq send logic */
   err = ppp_allpktsend(mppp);
   return err;
}


/* FUNCTION: ppp_ifclose()
 * 
 * net iface close routine, called from netclose. A full graceful
 * PPP shutdown is probably optimistic, so it just tries to disconnect 
 * the line device. This should eventually trigger the FSM shutdown events.
 *
 * PARAM1: int iface
 *
 * RETURNS: 
 */


int
ppp_ifclose(int iface)
{
   M_PPP mppp;
   mppp = (M_PPP)nets[iface]->n_local;
   if(mppp && (mppp->line.ln_state == LN_CONNECTED))
      mppp->line.ln_disconnect(&mppp->line);
   return 0;
}


/* FUNCTION: ppp_mstats()
 *
 * PPP link statistics routine. This called from the MAC stats routine below
 * as well as from pppmenu.c
 *
 * PARAM1: void * pio
 * PARAM2: M_PPP mppp
 *
 * RETURNS: void
 */

#ifndef NO_CONPRINTF
extern char * fsmstate[];   /* strings for state names */
#endif

void
ppp_mstats(void * pio, M_PPP mppp)
{
   ns_printf(pio, "PPP stats for link %lx:\n", mppp);

#ifndef NO_CONPRINTF
   ns_printf(pio, "states: LCP:%s, IPCP:%s \n", 
	   fsmstate[mppp->states[LCP_STATE]],
	   fsmstate[mppp->states[IPCP_STATE]]);
#else
   ns_printf(pio, "states: LCP:%u, IPCP:%u \n", 
	   mppp->state[LCP_STATE],
	   mppp->state[IPCP_STATE]);
#endif
   
   ns_printf(pio, "pkts (bytes);  in:%lu(%lu), out:%lu(%lu)\n",
      mppp->pkts_in, mppp->bytes_in, mppp->pkts_out, mppp->bytes_out);
   ns_printf(pio, "flags; PPP:%04x, SC:%04x; errors: fsm:%d, io:%d\n",
      mppp->pppflags, mppp->sc_flags, mppp->bad_fcs, mppp->io_errors);
   ns_printf(pio, "output queues (max,current): ctrl(%u,%u), data(%u,%u)\n", 
	   mppp->fastq.q_max, mppp->fastq.q_len, 
	   mppp->dataq.q_max, mppp->dataq.q_len);
   ns_printf(pio, "timers set:%d cleared:%d fired:%d replaced:%d\n",
      mppp->tmr_sets, mppp->tmr_cleared, mppp->tmr_fired, mppp->tmr_replaced);
   ns_printf(pio, "asynmaps; ours: %lx, his:%lx \n",
      mppp->my_asyncmap, mppp->his_asyncmap);
   ns_printf(pio, "MRUs; ours: %d, his:%d \n",
      mppp->lcp_gotoptions.mru, mppp->lcp_hisoptions.mru);
   ns_printf(pio, "Negotiated Auth; his: CHAP:%s PAP:%s  ours: CHAP:%s PAP:%s\n",
      mppp->lcp_hisoptions.neg_chap?"YES":"NO", 
      mppp->lcp_hisoptions.neg_upap?"YES":"NO",
      mppp->lcp_gotoptions.neg_chap?"YES":"NO", 
      mppp->lcp_gotoptions.neg_upap?"YES":"NO");
   ns_printf(pio, "Negotiated VJ: us:%s him:%s\n", 
      (mppp->sc_flags & SC_COMP_TCP)?"YES":"NO",
      (mppp->ipcp_gotoptions.neg_vj)?"YES":"NO");

#ifdef PPP_IDENTIFY
   if(mppp->identity[0] != 0)
      ns_printf(pio, "His Identity: %s\n", mppp->identity);
#endif   /* PPP_IDENTIFY */

#ifndef SL_NO_STATS
#ifdef PPP_VJC
   ns_printf(pio, "VJ send stats; pkts %ld, comp. %ld, searches %ld, misses %ld\n", 
      mppp->sc_comp.sls_packets,
      mppp->sc_comp.sls_compressed,
      mppp->sc_comp.sls_searches,
      mppp->sc_comp.sls_misses);

   ns_printf(pio, "VJ recv stats; uncomp. %ld, comp. %ld, err %ld, tossed %ld\n", 
      mppp->sc_comp.sls_uncompressedin,
      mppp->sc_comp.sls_compressedin,
      mppp->sc_comp.sls_errorin,
      mppp->sc_comp.sls_tossed);
#endif   /* PPP_VJC */
#endif   /* not SL_NO_STATS */


#ifdef PPP_MULTILINK
   if(mppp->pppflags & ML_IPCP)     /* bundle master? */
   {
      int   i;
      ns_printf(pio, "ML bundle type %d, data:", mppp->ml_conf.endp_class);
      for(i = 0; i <  mppp->ml_conf.endp_length; i++)
         ns_printf(pio, "%02X ", mppp->ml_conf.endp_desc[i] );
      ns_printf(pio, "\n");
   }
   ns_printf(pio, "ML frag thresh:%d; sent:%lu rcvd:%lu err:%lu drop:%lu tmo:%lu\n",
      mppp->ml_frag_size, mppp->mf_txfrags, mppp->mf_rxfrags,
      mppp->mf_errors, mppp->mf_drops, mppp->mf_tmo);
#endif   /* PPP_MULTILINK */

   switch (mppp->line.lower_type)
   {
#ifdef USE_PPPOE
   case LN_PPPOE:
      poe_stats(pio, mppp);
      break;
#endif   /* USE_PPPOE */

#ifdef USE_MODEM
   case LN_ATMODEM:
      /* modem code currently only supports stats for first unit */
      if(mppp->line.lower_unit == 0)
         dialer_status(pio);
      else
         ns_printf(pio, "Modem unit %d\n", mppp->line.lower_unit);
      break;
#endif   /* USE_MODEM */

#ifdef USE_COMPORT
   case LN_UART:
      uart_stats(pio, mppp->line.lower_unit);
      break;
#endif   /* USE_COMPORT */

#ifdef LB_XOVER
   case LN_LBXOVER:
      ns_printf(pio, "type %d, loopback-crosover\n");
      break;
#endif   /* LB_XOVER */

   default:
      ns_printf(pio, "unknown type: %d\n", mppp->line.lower_type);
      break;
   }

}

/* FUNCTION: ppp_stats()
 * 
 * Entry point for the MAC driver stats routine. This just extracts the
 * mppp object and calls the mppp-ish stats routine
 *
 * PARAM1: void * pio
 * PARAM2: int iface
 *
 * RETURNS: 
 */

void
ppp_stats(void * pio, int iface)
{
   M_PPP    mppp;

   mppp = (M_PPP)nets[iface]->n_local;

   ppp_mstats(pio, mppp);
}


/* FUNCTION: ppp_pktdemux()
 *
 * Handle received PPP packets.
 *
 * PARAM1: none
 *
 * RETURNS: void
 */

/* Only needed IF we are using packet oriented PPP links in this build */
#ifdef PPP_PACKETS

void
ppp_pktdemux()
{
   PACKET pkt;
   M_PPP mppp;

   while(ppp_rcvdq.q_len)
   {
      pkt = (PACKET)getq(&ppp_rcvdq);

#ifdef PPP_MULTILINK
      /* for multilink we have to get exactly to right link, not just the
       * right interface 
       */
      mppp = (M_PPP)(pkt->link);
#else
      /* non-multilink ports have only one link per iface */
      mppp = (M_PPP)(pkt->net->n_local);
#endif

#ifdef NPDEBUG
      if(mppp->ifp != pkt->net)
         panic("ppp demux");
#endif
      ppp_inpkt(mppp, pkt);
   }
}
#endif   /* PPP_PACKETS */

static int pt_reentry = 0;



/* FUNCTION: ppp_timeisup()
 *
 * PPP periodic timer, called from misclib/timeouts.c and used to
 * drive timeouts of various sorts.
 *
 * PARAM1: none
 *
 * RETURNS: void
 */


void
ppp_timeisup(void)
{
   M_PPP mppp;

   if (pt_reentry)   /* this happens a lot on slow DOS devices */
      return;     /* prevent re-entry of this routine */
   pt_reentry++;

   /* loop through the sessions and see if it's time for a retry */
   for(mppp = ppp_list; mppp; mppp = mppp->next)
   {
      if((mppp->tmo_tick != 0) && 
         (mppp->tmo_tick <= cticks))
      {
         //ConPrintf("ppp timeout (link %p), trys left: %d\n", 
            //mppp, mppp->retrys);
         mppp->tmo_tick = 0;     /* clear timer */
         mppp->tmr_fired++;
         mppp->tmo_func(mppp, (long)(mppp->tmo_parm) );
      }
      /* also see if we can start a delayed send */
      if(((mppp->dataq.q_len) || (mppp->fastq.q_len)) &&
         ((mppp->pppflags & PPP_SENDING) == 0))
      {
         ppp_allpktsend(mppp);
      }
#ifdef PPP_MULTILINK
      /* see if a multilink fragment reassembly has timed out. Limit
       * this test to multilink units which currently actually have 
       * multiple links.
       */
      if(mppp->ml_numlinks > 1)
      {
         int i;
         for(i = 0; i < MAX_ML_FRAGS; i++)      /* loop thru reasm list */
         {
            if(mppp->reasms[i].pkt == NULL)     /* no entry */
               continue;
            if(mppp->reasms[i].tmo <= cticks)   /* check RU time */
            {
               pppml_delfrag(&mppp->reasms[i]); /* clear reasmbly info */
               mppp->mf_tmo++;
            }
         }
      }
#endif   /* PPP_MULTILINK */
   }

#ifdef USE_PPPOE
   poe_check();      /* PPPOE needs a timer too */
#endif

#ifdef PPP_PACKETS
   ppp_pktdemux();
#endif   /* PPP_PACKETS */

   pt_reentry--;
}

/* FUNCTION: ppp_settimer()
 *
 * Set timer to call func() in count number of seconds.
 * 
 * PARAM1: mppp                        - ppp link for timer
 * PARAM2: void (*func)(M_PPP, long)   - routine to call on expiry
 * PARAM3: int seconds                 - timer value
 * PARAM4: long arg                    - arg to func() callback
 *
 * RETURNS: void
 */

void
ppp_settimer(M_PPP mppp, void (*func)(M_PPP, long), int secs, long arg)
{
   /* count times we over-write a running timer with a new one */
   if(mppp->tmo_tick != 0)
      mppp->tmr_replaced++;

   ENTER_CRIT_SECTION(mppp);  /* keep it from firing while we set up */
   mppp->tmo_tick = cticks + (secs * (u_long)TPS);
   mppp->tmo_parm = arg;
   mppp->tmo_func = func;
   mppp->tmr_sets++;
   EXIT_CRIT_SECTION(mppp);

}

/* FUNCTION: ppp_cleartimer()
 *
 * Clear a mppp timer.
 * 
 * PARAM1: mppp - ppp link
 *
 * RETURNS: 
 */

void
ppp_cleartimer(M_PPP mppp)
{
   if(mppp->tmo_tick)
   {
      mppp->tmr_cleared++;
      mppp->tmo_tick = 0;
   }
}

#if defined(CHAP_SUPPORT) || defined(PAP_SUPPORT)

/* FUNCTION: ppp_auth_failed()
 * 
 * called if CHAP or PAP authorization fails
 *
 * PARAM1: M_PPP mppp
 * PARAM2: int who  - 0 == we failed, 1 == peer failed
 *
 * RETURNS: void
 */

void
ppp_auth_failed(M_PPP mppp, int who)
{
   /* put this on both the console and the log */
   dprintf("link %p Auth FAILURE: %s failed authentication\n", mppp,
      who?"peer":"we");
   //ConPrintf("link %p Auth FAILURE: %s failed authentication\n", mppp,
      //who?"peer":"we");

   ppp_close(mppp, LCP_STATE);   /* kill LCP layer */
}
#endif /* defined(CHAP_SUPPORT) || defined(PAP_SUPPORT) */


/* FUNCTION: ppp_set_ipaddr()
 *
 * Check the IP address field in the outgoing packet. It
 * it is all zeros,then insert our IP Address.
 *
 * This is needed in the case when ppp_pkt_output() is called, the
 * link is not connected, and has no assigned IP address. In this case
 * ppp_pkt_output() queues the packet until an IP address is assigned
 * either via IPCP or DHCP. The queued packet has a source IP address
 * of zero, which won't get it very far, so this routine patches
 * up the packet with the correct IP address.
 * 
 * PARAM1: PACKET pkt
 *
 * RETURNS: void
 */

extern   u_short tcp_cksum(struct ip *);

#ifndef IPPROTO_TCP
#define IPPROTO_TCP 6
#endif

void
ppp_set_ipaddr(PACKET pkt)
{
   struct ip * pip;
   /* struct tcphdr * tcpp; */

   /* Assign our new IP address and update the IPHEADER_CHECKSUM */
   /* Assign only if the SRC IP address in original packet is zero */

   /* IP header follows 2 bytes of PPP header */
   pip = (struct ip*)(pkt->nb_prot + 2);

   if ( pip->ip_src == 0 )
   {
      //ConPrintf("Updating Src IP\n");
      pip->ip_src = pkt->net->n_ipaddr;
      pip->ip_chksum = IPXSUM;        /* clear checksum field for summing */
      pip->ip_chksum = ~cksum(pip, 10);
   }
   else  /* address was already set */
      return;

   /* If it's a TCP packet, we need to adjust the TCP checksum too */
   if (pip->ip_prot == IPPROTO_TCP)
   {
      struct tcphdr *   tcpp; /* tcp header */
      unsigned hlen = (pip->ip_ver_ihl & 0x0F); /* length of IP header */
      unsigned long deltasum;    /* checksum workspace */
      int   loops =  0;

      hlen <<= 2; /* convert length of iP header to bytes */
      tcpp = (struct tcphdr *)((char*)pip+hlen);
      deltasum = (u_short)~(tcpp->th_sum);
      deltasum += (u_short)(pip->ip_src & 0x0000FFFF);
      deltasum += (u_short)(pip->ip_src >> 16);
      while (deltasum & 0xFFFF0000) /* carry bits need to be wrapped? */
      {
         hlen = (unsigned)(deltasum >> 16);  /* get # carry bits */
         deltasum &= 0x0000FFFF; /* clear carry bits in sum */
         deltasum += hlen;    /* add carry bits back in */
         if (loops++ > 2)  /* should never loop more than twice */
         {
            dtrap("ifppp 6\n");
            break;   /* send packet anyway, TCP will probably retry */
         }
      }
      tcpp->th_sum = ~((u_short)deltasum);
#ifdef NPDEBUG /* doublecheck sum if debugging, omit test later -JB- */
      if (tcpp->th_sum != tcp_cksum(pip))
      {
         dprintf("inser_ip_addr: delta cksum bug, was:%x good:%x \n",
          tcpp->th_sum, tcp_cksum(pip));
      }
#endif
   }
   else if(pip->ip_prot == UDP_PROT)
   {
      /* Adjust the UDP check sum */
      struct udp *   pup;
      struct ph   php;
      unsigned hlen = (pip->ip_ver_ihl & 0x0F);    /* length of IP header */

      hlen <<= 2; /* convert length of iP header to bytes */
      pup = (struct udp*)((char*)pip+hlen);

#ifdef NO_UDP_CKSUM
      pup->ud_cksum = 0;
#else
      php.ph_src  = pip->ip_src;
      php.ph_dest = pip->ip_dest;
      php.ph_zero = 0;
      php.ph_prot = UDP_PROT;
      php.ph_len  = pup->ud_len;
      pup->ud_cksum = cksum(&php, sizeof(struct ph)>>1);
      pup->ud_cksum = ~cksum(pup, (htons(pup->ud_len)+1)>>1);
#endif
   }
}

#endif   /* USE_PPP */



⌨️ 快捷键说明

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