rawiptst.c

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

C
1,299
字号
         while (len > 0);

         /* if tester is sending, and it's time to do the next send...
          */
         if ((tester->sending) &&
             ((tester->sendsdone == 0) ||
              (cticks - tester->lastsendtime > tester->senddelay)))
         {
            dptr = raw_tester_buf;

            if (hdrincl)
            {
               /* XXX fill in the IP header */
               pip = (struct ip *)dptr;
               dptr += sizeof(struct ip);
            }

            /* fill the buffer out to the send length with data:
             * sequence 0, 1, 2, ..., 255, 0, 1, 2, ..., 255 until
             * we reach the send length
             * (note that if we built the IP header above its
             * size is included in the send length!)
             */
            donedata = 0;
            while (dptr - raw_tester_buf < tester->sendlen)
            {
               *dptr++ = (char)((donedata++) & 0xff);
            }

            /* send the buffer 
             */
            if (tester->conn && (tester->sendtoaddr == 0))
            {
               e = send(tester->sock, raw_tester_buf, tester->sendlen, 0);
               if (e < 0)
               {
                  ns_printf(tester->pio,
                            "raw_testerq_poll: [%d] send error %d\n",
                            tester->id, t_errno(tester->sock));
                  tester->senderr = t_errno(tester->sock);
                  tester->sending = 0;
                  continue;
               }
            }
            else
            {
               addr.sin_family = AF_INET;
               addr.sin_port = 0;
               addr.sin_addr.s_addr = tester->sendtoaddr;
               e = sendto(tester->sock, raw_tester_buf, tester->sendlen, 0,
                          (struct sockaddr *)&addr, &addrlen);
               if (e < 0)
               {
                  ns_printf(tester->pio,
                            "raw_testerq_poll: [%d] sendto error %d (to %u.%u.%u.%u)\n",
                            tester->id, t_errno(tester->sock),
                            PUSH_IPADDR(tester->sendtoaddr));
                  tester->senderr = t_errno(tester->sock);
                  tester->sending = 0;
                  continue;
               }
            }
            tester->lastsendtime = cticks;
            tester->sendsdone++;

            /* if we're done, stop sending
             */
            if (tester->sendcount && tester->sendsdone >= tester->sendcount)
            {
               tester->sending = 0;
            }
         }

      }
      
   }

   /* unlock the receiver queue */
   raw_testerq_unlock();
}


/* FUNCTION: raw_ristart()
 *
 * Starts (creates) a new raw IP tester.
 *
 * PARAM1: void * pio; IN- ptr to GEN_IO object for command-line output
 *
 * RETURNS: an integer indicating success or failure; 
 *          zero indicates success; values <0 indicate failure
 */
int
raw_ristart(void * pio)
{
   char * arg2;
   int prot;
   unsigned id;

   arg2 = nextarg(((GEN_IO)pio)->inbuf);
   if (!arg2 || !*arg2)
   {
      ns_printf(pio, "requires IP protocol ID\n");
      return -1;
   }
   prot = atoi(arg2);
   if ((prot < 0) || (prot > 255))
   {
      ns_printf(pio, "IP protocol ID must be between 0 and 255 inclusive\n");
      return -1;
   }

   id = raw_tester_new(pio, prot);
   if (id < 0)
   {
      ns_printf(pio, "unable to create new tester: error %d\n", id);
      return -1;
   }
   ns_printf(pio, "started new tester [%d]\n", id);
   return 0;
}

/* FUNCTION: raw_ridelete()
 *
 * Deletes a raw IP tester.
 *
 * PARAM1: void * pio; IN- ptr to GEN_IO object for command-line output
 *
 * RETURNS: an integer indicating success or failure; 
 *          zero indicates success; values <0 indicate failure
 */
int
raw_ridelete(void * pio)
{
   char * arg2;
   long lid;
   unsigned id;
   int e;

   arg2 = nextarg(((GEN_IO)pio)->inbuf);
   if (!arg2 || !*arg2)
   {
      ns_printf(pio, "requires raw IP tester ID\n");
      return -1;
   }
   lid = atol(arg2);
   id = (unsigned)lid;
   if (((long)id) != lid)
   {
      ns_printf(pio, "invalid ID %ld\n", lid);
      return -1;
   }

   raw_testerq_lock();
   e = raw_tester_delid(id);
   raw_testerq_unlock();
   if (e < 0)
   {
      ns_printf(pio, "unable to delete tester [%d]: error %d\n", id, e);
      return -1;
   }
   ns_printf(pio, "deleted tester [%d]\n", id);
   return 0;
}

/* FUNCTION: raw_rilist()
 *
 * Displays a list of raw IP testers with state information for each.
 *
 * PARAM1: void * pio; IN- ptr to GEN_IO object for command-line output
 *
 * RETURNS: an integer indicating success or failure; 
 *          zero indicates success; values <0 indicate failure
 */
int
raw_rilist(void * pio)
{
   char * arg2;
   long lid;
   unsigned id;
   unsigned listall;
   struct raw_tester * tester;

   /* figure out whether we're supposed to list a specified ID
    * or all IDs: all IDs is indicated by the absence of the ID
    * argument
    */
   arg2 = nextarg(((GEN_IO)pio)->inbuf);
   if (!arg2 || !*arg2)
   {
      listall = 1;
#ifdef MUTE_WARNS
      id = 0;
#endif /* MUTE_WARNS */
   }
   else
   {
      listall = 0;
      lid = atol(arg2);
      id = (unsigned)lid;
      if (((long)id) != lid)
      {
         ns_printf(pio, "invalid ID %ld\n", lid);
         return -1;
      }
   }

   /* at this point, either listall should be 1 (meaning all IDs
    * are to be listed) or listall should be 0 and id should be the
    * ID to be listed
    */

   /* lock the queue */
   raw_testerq_lock();

   /* if no testers, say as much; else list appropriately */
   if (raw_testerq == NULL)
   {
      ns_printf(pio, "no raw testers\n");
   }
   else
   {
      for (tester = raw_testerq; tester != NULL; tester = tester->next)
      {
         if (listall || tester->id == id)
         {
            ns_printf(pio, "ID %u%c,%ssending (%ld/%ld, err %d)\n",
                      tester->id, 
                      ((pio == tester->pio) ? '*' : ' '),
                      ((tester->sending) ? " " : " not "),
                      tester->sendsdone,
                      tester->sendcount,
                      tester->senderr);
         }
      }
   }

   /* unlock the queue */
   raw_testerq_unlock();

   /* and return success */
   return 0;
}

/* FUNCTION: raw_risend()
 *
 * Tells a tester to begin sending.
 *
 * PARAM1: void * pio; IN- ptr to GEN_IO object for command-line output
 *
 * RETURNS: an integer indicating success or failure; 
 *          zero indicates success; values <0 indicate failure
 */
int
raw_risend(void * pio)
{
   char * arg2;
   char * arg3;
   char * arg4;
   long lid;
   unsigned id;
   struct raw_tester * tester;
   unsigned long hostaddr;
   unsigned hostaddrfound;
   long sendcount;
   int e;

   /* get first argument: tester ID (required) 
    */
   arg2 = nextarg(((GEN_IO)pio)->inbuf);
   if (!arg2 || !*arg2)
   {
      ns_printf(pio, "requires raw IP tester ID\n");
      return -1;
   }
   lid = atol(arg2);
   id = (unsigned)lid;
   if (((long)id) != lid)
   {
      ns_printf(pio, "invalid ID %ld\n", lid);
      return -1;
   }

   /* get optional second and third arguments:
    *   host address to which to send 
    *     defaults to activehost for un-connected testers
    *     defaults to connected address for connected testers
    *   send count
    *     defaults to 1
    *     0 means send forever (or until otherwise stopped)
    */
   hostaddrfound = 0;
   hostaddr = activehost;
   sendcount = 1;
   arg3 = nextarg(arg2);
   arg4 = nextarg(arg3);
   if (*arg4)
   {
      /* there's a third argument, so make sure the second argument
       * (presumed at this point to be a host address) is null-terminated
       */
      arg2 = arg3;
      while (*arg2 > ' ') 
         arg2++;
      *arg2 = 0;
   }

   /* the second argument (arg3) is either a host address (name or 
    * IP address) or it's a send count
    * so we look at it to see if it's all digits -- 
    * if it's not, then we guess it's a host address
    * if it is, then we guess it's a send count
    */
   if (arg3 && *arg3)
   {
      arg2 = arg3;
      while (*arg2 > ' ')
      {
         if (*arg2 > '9' || *arg2 < '0')
         {
            e = in_reshost(arg3, &hostaddr, RH_VERBOSE | RH_BLOCK);
            if (e)
            {
               ns_printf(pio, "Unable to resolve host name \"%s\"\n", arg3);
               return -1;
            }
            hostaddrfound = 1;
            break;
         }
         arg2++;
      }
      if (*arg2 <= ' ')
      {
         sendcount = atol(arg3);
         if ((sendcount == 0) && (*arg3 != '0'))
            sendcount = -1;
      }
   }

   /* if there's a third argument,
    * assume it's a send count
    */
   if (arg4 && *arg4)
   {
      sendcount = atol(arg4);
      if ((sendcount == 0) && (*arg4 != '0'))
         sendcount = -1;
   }

   /* make sure we the host address makes sense
    */
   if (hostaddrfound && (hostaddr == 0))
   {
      ns_printf(pio, 
                "specify valid host address, or use default host address\n");
      return -1;
   }

   /* make sure the send count makes sense
    */
   if (sendcount < 0)
   {
      ns_printf(pio, 
                "last argument must be send count (>= 1)\n");
      ns_printf(pio,
                "or 0 to send without limit; default is 1.\n");
      return -1;
   }

   /* lock the queue */
   raw_testerq_lock();

   /* look for the tester */
   tester = raw_tester_findid(id);
   if (tester == NULL)
   {
      ns_printf(pio, "ID [%d] not found\n", id);
      raw_testerq_unlock();
      return -1;
   }

   /* if the tester is already sending, we will stop this action
    */
   if (tester->sending)
   {
      ns_printf(pio, "Terminating previous send on ID [%d]\n", id);
      tester->sending = 0;
   }

   /* set the tester up to send:
    * take sendcount from argument
    * take sendlen and senddelay from globals deflength and pingdelay
    *   (same as used by ping)
    * if hostaddr argument present, use it as sendtoaddr;
    * else let sendtoaddr default:
    *   if the socket is connected, to the connected address;
    *   else to global activehost (same as used by ping)
    */
   tester->sendcount = sendcount;
   tester->sendsdone = 0;
   tester->senderr = 0;
   if (deflength > sizeof(raw_tester_buf))
   {
      ns_printf(pio, "Send length limited to %d bytes\n",
                id, sizeof(raw_tester_buf));
      tester->sendlen = sizeof(raw_tester_buf);
   }
   else
      tester->sendlen = deflength;
   tester->senddelay = pingdelay;
   if (hostaddrfound)
      tester->sendtoaddr = hostaddr;
   else
   {
      if (tester->conn)
         tester->sendtoaddr = 0;
      else
         tester->sendtoaddr = activehost;
   }
   tester->sending = 1;

   /* unlock the queue */
   raw_testerq_unlock();

   /* poll once to get things going */
   raw_testerq_poll();

   /* and return success */
   return 0;
}

/* FUNCTION: raw_rihalt()
 *
 * Tells a tester to stop sending.

⌨️ 快捷键说明

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