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 + -
显示快捷键?