rttest.c

来自「在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LE」· C语言 代码 · 共 732 行 · 第 1/2 页

C
732
字号
 * 
 * Menu routine to generate the stream of test packets into the IP or
 * NAT code.
 *
 * PARAM1: void * pio
 *
 * RETURNS: 0 if OK or an ENP error code
 */

int
nt_send(void * pio)
{
   int      count;      /* number of test packets to generate */
   u_long   timer;      /* speed timer for statstics */
   u_long   pkts;       /* local counters for speed test */
   u_long   bytes;
   u_long   timeout;    /* timeout for stuck systems */
   PACKET   master;
   PACKET   tmp;
   struct ethhdr *   eth;
   struct ip *       pip;
   struct tcphdr *   ptcp;
   int      ipid  =  0; /* IP header ID for sent packets */
   char *   arg   =  nextarg( ((GEN_IO)pio)->inbuf );
   struct arptabent *   arp;

   count = atol(arg);
   if (count < 1)
   {
      ns_printf(pio, "usage: rtsend|ntsend count (count is number >1)\n");
      return -1;
   }

   if (deflength > 1506)
   {
      ns_printf(pio, "oversize length (%d) - max test length is 1506\n",
       deflength);
      return -1;
   }
   if (nt_ifp == NULL)
   {
      ns_printf(pio, "Create device with rstart first.\n");
      return -1;
   }

   /* make ARP table entries for both target IP addresses - the one 
    * on the loopback iface, and this one. We test for arp creation,
    * but don't waste message on it since it's fantisticly unlikely.
    */
   arp = make_arp_entry(nt_destaddr, nets[lb_index]);
   if (arp == NULL)
      return ENP_RESOURCE;
   MEMCPY(arp->t_phy_addr, "LPBACK", 6);
   arp = make_arp_entry(nt_srcaddr, nt_ifp);
   if (arp == NULL)
      return ENP_RESOURCE;
   MEMCPY(arp->t_phy_addr, nat_mac, 6);

   ns_printf(pio, "%s test: starting send of %ld pkts, %d bytes each...",
    (rttest == TESTIP)?"Route":"NAT", count, deflength);

   /* build template send packet */
   master = pk_alloc(deflength);
   if (master == NULL)
   {
      dprintf("Can't get a buffer for %d bytes\n", deflength);
      return -1;
   }

   eth = (struct ethhdr*)(master->nb_buff + ETHHDR_BIAS);
   eth->e_type = htons(0x0800);     /* put IP packet type in header & pkt */

   master->nb_prot = master->nb_buff + sizeof(struct ip) + ETHHDR_SIZE;
   master->nb_plen = deflength - (sizeof(struct ip) + ETHHDR_SIZE);
   ip_bldhead(master, ipid, ntprot, 0);
   pip = (struct ip *)master->nb_prot;

   pip->ip_src = nt_srcaddr;
   pip->ip_dest = nt_destaddr;

   /* set the port numbers as though pkt is TCP. This will also work 
    * for UDP since UDPs port numbers happen to be at the same offsets.
    */
   ptcp = (struct tcphdr *)(pip + 1);
   ptcp->th_dport = htons(80);
   ptcp->th_sport = htons(1200);

   master->nb_prot += ETHHDR_SIZE;  /* ignore ether header */

   if (rttest != TESTIP)
   {
   }

   /* record starting counts in the iface MIB */
   pkts = nt_ifp->n_mib->ifOutUcastPkts;
   bytes = nt_ifp->n_mib->ifOutOctets;

   timer = cticks;      /* note start time */
   while (count--)
   {
      timeout = cticks + TPS;
      while (bigfreeq.q_len < (bigfreeq.q_max/4))
      {
         tk_yield();
         if (timeout < cticks)
         {
            ns_printf(pio, "timeout waiting for buffers, Aborting...\n");
            break;
         }
      }

      tmp = pk_alloc(deflength);
      if (tmp == NULL)
      {
         ns_printf(pio, "error - ran out of buffers!!! Aborting...\n");
         break;
      }

      MEMCPY(tmp->nb_buff, master->nb_buff, 54);

      tmp->type = 0x0800;
      tmp->nb_prot = tmp->nb_buff + ETHHDR_SIZE;
      tmp->nb_plen = master->nb_plen;
      pip = (struct ip *)tmp->nb_prot;
      pip->ip_id = ipid++;
      pip->ip_chksum = 0;
      pip->ip_chksum = ~cksum(pip, ip_hlen(pip) >> 1);

      /* packet is ready. We want it to look like it came from a 
       * private net and is to be NAT routed to the modified MAC 
       * loopback driver, which will swap the IP addersses and port
       * and send it back for a return trip to us. To do this we
       * simple insert it in the reced queue
       */
      tmp->net = nt_ifp;
      putq(&rcvdq, (qp)tmp);
      SignalPktDemux();
   }

   /* conver start time and count to delta time and counts */
   timer = cticks - timer;
   pkts = nt_ifp->n_mib->ifOutUcastPkts - pkts;
   bytes = nt_ifp->n_mib->ifOutOctets - bytes;

   /* pretty-print results */
   ns_printf(pio, "\nDone, %ld and %ld/%d seconds.\n", timer/TPS, timer % TPS, TPS);

   if (timer > 0) /* avoid divide by zero, CPUs hate that... */
   {
      ns_printf(pio, "speed %ld pkts/sec round trip, %ld bytes/sec\n", 
       (pkts/timer) * TPS,
       (bytes/timer) * TPS);
      ns_printf(pio, "or %ld pkts/sec one way.\n", 
       (pkts/timer) * TPS * 2);
   }
   return 0;
}



/* FUNCTION: rt_setprot()
 * 
 * Menu routine to set type type of test packet - TCP or UDP.
 * 
 * PARAM1: void * pio
 *
 * RETURNS: 0 if OK or an ENP error code
 */

int
rt_setprot(void * pio)
{
   int   newprot;
   char *   arg   =  nextarg(cbuf);

   newprot = atoi(arg);

   if (newprot == 6)
      ns_printf(pio, "setting Nat test prot to TCP\n");
   else if(newprot == 17)
      ns_printf(pio, "setting Nat test prot to UDP\n");
   else
   {
      ns_printf(pio, "protocol must be 6 (TCP) or 17 (UDP)\n");
      return -1;
   }

   ntprot = (u_char)newprot;
   return 0;
}



/* FUNCTION: rt_statistics()
 * 
 * Menu routine to dump or clear stats.
 * 
 * PARAM1: void * pio
 *
 * RETURNS: 0 if OK or an ENP error code
 */

int
rt_statistics(void * pio)
{
   char *   arg   =  nextarg(cbuf);

   if (arg && (*arg == '0'))
   {
      ns_printf(pio, "Clearing NAT test stats to zero\n");
      ntstat.udp_pkts_sent = 0;
      ntstat.udp_bytes_sent = 0;
      ntstat.tcp_pkts_sent = 0;
      ntstat.tcp_bytes_sent = 0;
      ntstat.udp_pkts_recv = 0;
      ntstat.udp_bytes_recv = 0;
      ntstat.tcp_pkts_recv = 0;
      ntstat.tcp_bytes_recv = 0;
      ntstat.other_pkts = 0;
      return 0;
   }

   ns_printf(pio, "TCP sent; pkts: %ld bytes: %ld\n",
    ntstat.tcp_pkts_sent,
    ntstat.tcp_bytes_sent);
   ns_printf(pio, "TCP recv; pkts: %ld bytes: %ld\n",
    ntstat.tcp_pkts_recv,
    ntstat.tcp_bytes_recv);
   ns_printf(pio, "UDP sent; pkts: %ld bytes: %ld\n",
    ntstat.udp_pkts_sent,
    ntstat.udp_bytes_sent);
   ns_printf(pio, "UDP recv; pkts: %ld bytes: %ld\n",
    ntstat.udp_pkts_recv,
    ntstat.udp_bytes_recv);

   ns_printf(pio, "Other pkts received %ld\n", ntstat.other_pkts);


   return 0;
}



/* FUNCTION: rt_startup()
 * 
 * Menu routine to create the dynamic device which generates the IP or
 * NAT test traffic.
 * 
 * PARAM1: void * pio
 *
 * RETURNS: 0 if OK or an ENP error code
 */

int
rt_startup(void * pio)
{
   int      err;
   NET      tmp;
   ip_addr  tmpip;
   struct niconfig_0 cfg;

   if (nt_ifp != NULL)
   {
      ns_printf(pio, "rt test aaalready has device\n");
      return 0;
   }

   err = ni_create(&tmp, rtcreate_device, "rt0", NULL);
   if (err || (tmp != nt_ifp))
   {
      ns_printf(pio, "rt test:error %d creating test device\n", err);
      return -1;
   }

   /* set up the new ifaces IP address and subnet mask */
   cfg.n_ipaddr = htonl(0xc0a40001);
   cfg.snmask = htonl(0xFFFF0000);
   err = ni_set_config(tmp, &cfg);
   if (err)
   {
      ns_printf(pio, "rt test device config error %d\n", err);
      return -1;
   }

   /* make a source address on the local net */
   tmpip = htonl(nt_ifp->n_ipaddr);       /* start with out local address */
   tmpip++;          /* add 1 - make it not our address */
   nt_srcaddr = htonl(tmpip);

   nt_destaddr = htonl(0x7f000002);       /* set dest addr */

   /* verify there is a loopback iface & keep it's index */
   for (lb_index = 0; lb_index < (int)ifNumber; lb_index++)
   {
      if (nets[lb_index]->n_ipaddr == htonl(0x7f000001))
         break;
   }
   if (lb_index >= (int)ifNumber)
   {
      dprintf("NAT test: Error; need loopback interface\n");
      return ENP_LOGIC;
   }

#ifdef NATRT
   /*
    * Set NAT up with this device as the private net and the
    * loopback device as a public net.
    */
   save_nat_inet = natrt_nvparms.nat_inet;      /* Save nvparms entries */
   save_nat_localnet = natrt_nvparms.nat_localnet;
   /* stuff the indexes into nvparms structure */
   natrt_nvparms.nat_inet = lb_index;
   natrt_nvparms.nat_localnet = rt_index;
   nat_re_init();       /* restart NAT with test ifaces */
#endif   /* NATRT */

   ns_printf(pio, "rt test device ready.\n   device IP %u.%u.%u.%u.\n",
    PUSH_IPADDR(nt_ifp->n_ipaddr) );
   ns_printf(pio, "   Pkt source address: %u.%u.%u.%u\n",
    PUSH_IPADDR(nt_srcaddr));
   ns_printf(pio, "   dest address: %u.%u.%u.%u\n",
    PUSH_IPADDR(nt_destaddr));

   return 0;
}



/* FUNCTION: rt_done()
 * 
 * Menu routine to delete the dynamic device which generates the IP or
 * NAT test traffic.
 * 
 * PARAM1: void * pio
 *
 * RETURNS: 0 if OK or an ENP error code
 */

int
rt_done(void * pio)
{
   int   err;

#ifdef NATRT
   /* Restore the original NAT device proior ot installing this test */
   /* stuff the indexes into nvparms structure */
   natrt_nvparms.nat_inet = lb_index;
   natrt_nvparms.nat_localnet = rt_index;
   nat_re_init();       /* restart NAT with original ifaces */
#endif   /* NATRT */

   err = ni_delete(nt_ifp);
   if (err)
   {
      ns_printf(pio, "rt test device delete error %d\n", err);
      return -1;
   }
   nt_ifp = NULL;
   return 0;
}

#endif   /* ROUTE_TEST */



⌨️ 快捷键说明

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