52
52
53
53
#define ICMP_IOBUFFER_SIZE (x ) (sizeof(struct icmp_hdr_s) + (x))
54
54
55
+ /****************************************************************************
56
+ * Private Types
57
+ ****************************************************************************/
58
+
59
+ /* Data needed for ping, reduce stack usage. */
60
+
61
+ struct ping_priv_s
62
+ {
63
+ struct sockaddr_in destaddr ;
64
+ struct sockaddr_in fromaddr ;
65
+ struct icmp_hdr_s outhdr ;
66
+ struct pollfd recvfd ;
67
+ socklen_t addrlen ;
68
+ clock_t kickoff ;
69
+ clock_t start ;
70
+ ssize_t nsent ;
71
+ ssize_t nrecvd ;
72
+ long elapsed ;
73
+ bool retry ;
74
+ int sockfd ;
75
+ };
76
+
55
77
/****************************************************************************
56
78
* Private Data
57
79
****************************************************************************/
@@ -107,14 +129,14 @@ static int ping_gethostip(FAR const char *hostname, FAR struct in_addr *dest)
107
129
#ifdef CONFIG_LIBC_NETDB
108
130
/* Netdb DNS client support is enabled */
109
131
110
- FAR struct addrinfo hint ;
111
132
FAR struct addrinfo * info ;
112
133
FAR struct sockaddr_in * addr ;
134
+ static const struct addrinfo s_hint =
135
+ {
136
+ .ai_family = AF_INET
137
+ };
113
138
114
- memset (& hint , 0 , sizeof (hint ));
115
- hint .ai_family = AF_INET ;
116
-
117
- if (getaddrinfo (hostname , NULL , & hint , & info ) != OK )
139
+ if (getaddrinfo (hostname , NULL , & s_hint , & info ) != OK )
118
140
{
119
141
return ERROR ;
120
142
}
@@ -166,21 +188,10 @@ static void icmp_callback(FAR struct ping_result_s *result,
166
188
void icmp_ping (FAR const struct ping_info_s * info )
167
189
{
168
190
struct ping_result_s result ;
169
- struct sockaddr_in destaddr ;
170
- struct sockaddr_in fromaddr ;
171
- struct icmp_hdr_s outhdr ;
191
+ FAR struct ping_priv_s * priv ;
172
192
FAR struct icmp_hdr_s * inhdr ;
173
- struct pollfd recvfd ;
174
193
FAR uint8_t * iobuffer ;
175
194
FAR uint8_t * ptr ;
176
- long elapsed ;
177
- clock_t kickoff ;
178
- clock_t start ;
179
- socklen_t addrlen ;
180
- ssize_t nsent ;
181
- ssize_t nrecvd ;
182
- bool retry ;
183
- int sockfd ;
184
195
int ret ;
185
196
int ch ;
186
197
int i ;
@@ -200,34 +211,36 @@ void icmp_ping(FAR const struct ping_info_s *info)
200
211
return ;
201
212
}
202
213
203
- /* Allocate memory to hold ping buffer */
214
+ /* Allocate memory to hold private data and ping buffer */
204
215
205
- iobuffer = ( FAR uint8_t * ) malloc ( result .outsize );
206
- if (iobuffer == NULL )
216
+ priv = malloc ( sizeof ( * priv ) + result .outsize );
217
+ if (priv == NULL )
207
218
{
208
219
icmp_callback (& result , ICMP_E_MEMORY , 0 );
209
220
return ;
210
221
}
211
222
212
- sockfd = socket (AF_INET , SOCK_DGRAM , IPPROTO_ICMP );
213
- if (sockfd < 0 )
223
+ iobuffer = (FAR uint8_t * )(priv + 1 );
224
+
225
+ priv -> sockfd = socket (AF_INET , SOCK_DGRAM , IPPROTO_ICMP );
226
+ if (priv -> sockfd < 0 )
214
227
{
215
228
icmp_callback (& result , ICMP_E_SOCKET , errno );
216
- free (iobuffer );
229
+ free (priv );
217
230
return ;
218
231
}
219
232
220
- kickoff = clock ();
233
+ priv -> kickoff = clock ();
221
234
222
- memset (& destaddr , 0 , sizeof (struct sockaddr_in ));
223
- destaddr .sin_family = AF_INET ;
224
- destaddr .sin_port = 0 ;
225
- destaddr .sin_addr .s_addr = result .dest .s_addr ;
235
+ memset (& priv -> destaddr , 0 , sizeof (struct sockaddr_in ));
236
+ priv -> destaddr .sin_family = AF_INET ;
237
+ priv -> destaddr .sin_port = 0 ;
238
+ priv -> destaddr .sin_addr .s_addr = result .dest .s_addr ;
226
239
227
- memset (& outhdr , 0 , sizeof (struct icmp_hdr_s ));
228
- outhdr .type = ICMP_ECHO_REQUEST ;
229
- outhdr .id = htons (result .id );
230
- outhdr .seqno = htons (result .seqno );
240
+ memset (& priv -> outhdr , 0 , sizeof (struct icmp_hdr_s ));
241
+ priv -> outhdr .type = ICMP_ECHO_REQUEST ;
242
+ priv -> outhdr .id = htons (result .id );
243
+ priv -> outhdr .seqno = htons (result .seqno );
231
244
232
245
icmp_callback (& result , ICMP_I_BEGIN , 0 );
233
246
@@ -240,7 +253,7 @@ void icmp_ping(FAR const struct ping_info_s *info)
240
253
241
254
/* Copy the ICMP header into the I/O buffer */
242
255
243
- memcpy (iobuffer , & outhdr , sizeof (struct icmp_hdr_s ));
256
+ memcpy (iobuffer , & priv -> outhdr , sizeof (struct icmp_hdr_s ));
244
257
245
258
/* Add some easily verifiable payload data */
246
259
@@ -256,33 +269,33 @@ void icmp_ping(FAR const struct ping_info_s *info)
256
269
}
257
270
}
258
271
259
- start = clock ();
260
- nsent = sendto (sockfd , iobuffer , result .outsize , 0 ,
261
- (FAR struct sockaddr * )& destaddr ,
262
- sizeof (struct sockaddr_in ));
263
- if (nsent < 0 )
272
+ priv -> start = clock ();
273
+ priv -> nsent = sendto (priv -> sockfd , iobuffer , result .outsize , 0 ,
274
+ (FAR struct sockaddr * )& priv -> destaddr ,
275
+ sizeof (struct sockaddr_in ));
276
+ if (priv -> nsent < 0 )
264
277
{
265
278
icmp_callback (& result , ICMP_E_SENDTO , errno );
266
279
goto done ;
267
280
}
268
- else if (nsent != result .outsize )
281
+ else if (priv -> nsent != result .outsize )
269
282
{
270
- icmp_callback (& result , ICMP_E_SENDSMALL , nsent );
283
+ icmp_callback (& result , ICMP_E_SENDSMALL , priv -> nsent );
271
284
goto done ;
272
285
}
273
286
274
287
result .nrequests ++ ;
275
288
276
- elapsed = 0 ;
289
+ priv -> elapsed = 0 ;
277
290
do
278
291
{
279
- retry = false;
280
-
281
- recvfd .fd = sockfd ;
282
- recvfd .events = POLLIN ;
283
- recvfd .revents = 0 ;
292
+ priv -> retry = false;
293
+ priv -> recvfd .fd = priv -> sockfd ;
294
+ priv -> recvfd .events = POLLIN ;
295
+ priv -> recvfd .revents = 0 ;
284
296
285
- ret = poll (& recvfd , 1 , info -> timeout - elapsed / USEC_PER_MSEC );
297
+ ret = poll (& priv -> recvfd , 1 ,
298
+ info -> timeout - priv -> elapsed / USEC_PER_MSEC );
286
299
if (ret < 0 )
287
300
{
288
301
icmp_callback (& result , ICMP_E_POLL , errno );
@@ -296,57 +309,58 @@ void icmp_ping(FAR const struct ping_info_s *info)
296
309
297
310
/* Get the ICMP response (ignoring the sender) */
298
311
299
- addrlen = sizeof (struct sockaddr_in );
300
- nrecvd = recvfrom (sockfd , iobuffer , result .outsize , 0 ,
301
- (FAR struct sockaddr * )& fromaddr , & addrlen );
302
- if (nrecvd < 0 )
312
+ priv -> addrlen = sizeof (struct sockaddr_in );
313
+ priv -> nrecvd = recvfrom (priv -> sockfd , iobuffer ,
314
+ result .outsize , 0 ,
315
+ (FAR struct sockaddr * )& priv -> fromaddr ,
316
+ & priv -> addrlen );
317
+ if (priv -> nrecvd < 0 )
303
318
{
304
319
icmp_callback (& result , ICMP_E_RECVFROM , errno );
305
320
goto done ;
306
321
}
307
- else if (nrecvd < sizeof (struct icmp_hdr_s ))
322
+ else if (priv -> nrecvd < sizeof (struct icmp_hdr_s ))
308
323
{
309
- icmp_callback (& result , ICMP_E_RECVSMALL , nrecvd );
324
+ icmp_callback (& result , ICMP_E_RECVSMALL , priv -> nrecvd );
310
325
goto done ;
311
326
}
312
327
313
- elapsed = TICK2USEC (clock () - start );
314
- inhdr = (FAR struct icmp_hdr_s * )iobuffer ;
328
+ priv -> elapsed = TICK2USEC (clock () - priv -> start );
329
+ inhdr = (FAR struct icmp_hdr_s * )iobuffer ;
315
330
316
331
if (inhdr -> type == ICMP_ECHO_REPLY )
317
332
{
318
333
#ifndef CONFIG_SIM_NETUSRSOCK
319
334
if (ntohs (inhdr -> id ) != result .id )
320
335
{
321
336
icmp_callback (& result , ICMP_W_IDDIFF , ntohs (inhdr -> id ));
322
- retry = true;
337
+ priv -> retry = true;
323
338
}
324
339
else
325
340
#endif
326
341
if (ntohs (inhdr -> seqno ) > result .seqno )
327
342
{
328
343
icmp_callback (& result , ICMP_W_SEQNOBIG ,
329
344
ntohs (inhdr -> seqno ));
330
- retry = true;
345
+ priv -> retry = true;
331
346
}
332
347
else if (ntohs (inhdr -> seqno ) < result .seqno )
333
348
{
334
349
icmp_callback (& result , ICMP_W_SEQNOSMALL ,
335
350
ntohs (inhdr -> seqno ));
336
- retry = true;
351
+ priv -> retry = true;
337
352
}
338
353
else
339
354
{
340
355
bool verified = true;
341
- long pktdelay = elapsed ;
342
356
343
- icmp_callback (& result , ICMP_I_ROUNDTRIP , pktdelay );
357
+ icmp_callback (& result , ICMP_I_ROUNDTRIP , priv -> elapsed );
344
358
345
359
/* Verify the payload data */
346
360
347
- if (nrecvd != result .outsize )
361
+ if (priv -> nrecvd != result .outsize )
348
362
{
349
- icmp_callback (& result , ICMP_W_RECVBIG , nrecvd );
363
+ icmp_callback (& result , ICMP_W_RECVBIG , priv -> nrecvd );
350
364
verified = false;
351
365
}
352
366
else
@@ -383,20 +397,20 @@ void icmp_ping(FAR const struct ping_info_s *info)
383
397
icmp_callback (& result , ICMP_W_TYPE , inhdr -> type );
384
398
}
385
399
}
386
- while (retry && info -> delay > elapsed / USEC_PER_MSEC &&
387
- info -> timeout > elapsed / USEC_PER_MSEC );
400
+ while (priv -> retry && info -> delay > priv -> elapsed / USEC_PER_MSEC &&
401
+ info -> timeout > priv -> elapsed / USEC_PER_MSEC );
388
402
389
403
/* Wait if necessary to preserved the requested ping rate */
390
404
391
- elapsed = TICK2MSEC (clock () - start );
392
- if (elapsed < info -> delay )
405
+ priv -> elapsed = TICK2MSEC (clock () - priv -> start );
406
+ if (priv -> elapsed < info -> delay )
393
407
{
394
408
struct timespec rqt ;
395
409
unsigned int remaining ;
396
410
unsigned int sec ;
397
411
unsigned int frac ; /* In deciseconds */
398
412
399
- remaining = info -> delay - elapsed ;
413
+ remaining = info -> delay - priv -> elapsed ;
400
414
sec = remaining / MSEC_PER_SEC ;
401
415
frac = remaining - MSEC_PER_SEC * sec ;
402
416
@@ -406,11 +420,11 @@ void icmp_ping(FAR const struct ping_info_s *info)
406
420
nanosleep (& rqt , NULL );
407
421
}
408
422
409
- outhdr .seqno = htons (++ result .seqno );
423
+ priv -> outhdr .seqno = htons (++ result .seqno );
410
424
}
411
425
412
426
done :
413
- icmp_callback (& result , ICMP_I_FINISH , TICK2USEC (clock () - kickoff ));
414
- close (sockfd );
415
- free (iobuffer );
427
+ icmp_callback (& result , ICMP_I_FINISH , TICK2USEC (clock () - priv -> kickoff ));
428
+ close (priv -> sockfd );
429
+ free (priv );
416
430
}
0 commit comments