blob: 45e1b318945224f3d5275a68b9dfcaa31528c5eb [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001
2#include "headers.h"
3#include "runner.h"
4#include "util.h"
5#include "zpingp.h"
6#include "settings.h"
7#include <net/if.h>
8#include <netinet/ip_icmp.h>
9#include "softap_api.h"
10
11
12#define LOG_EMERG 0 /* system is unusable */
13#define LOG_ALERT 1 /* action must be taken immediately */
14#define LOG_CRIT 2 /* critical conditions */
15#define LOG_ERR 3 /* error conditions */
16#define LOG_WARNING 4 /* warning conditions */
17#define LOG_NOTICE 5 /* normal but significant condition */
18#define LOG_INFO 6 /* informational */
19#define LOG_DEBUG 7
20
21#define DEFAULT_IP_ICMP_SIZE 1500
22#define DEFAULT_ICMP_SIZE 1480
23#define DEFAULT_ICMP_DATA_SIZE 1472
24
25#define IPHDR_MINLEN 20
26
27#define DEV_NAME_LEN 32
28#define MAX_MARK_NUM 45
29
30u_int16_t id = 0;
31u_int16_t last_seq_send = 0;
32u_int16_t last_seq_recv = 0;
33
34u_int16_t send_num = 0;
35u_int16_t recv_num = 0;
36
37int pingcount = 100;
38
39int16_t myid = 0; // 0x7777
40
41int delayoutput = 0;
42int lostoutput = 0;
43
44int maxwaitnum = 0;
45
46u_int32_t labels[MAX_MARK_NUM];
47int lost_count[MAX_MARK_NUM];
48
49enum {
50 DEFDATALEN = 56,
51 MAXIPLEN = 60,
52 MAXICMPLEN = 76,
53 MAXPACKET = 65468,
54 MAX_DUP_CHK = (8 * 128),
55 MAXWAIT = 10,
56 PINGINTERVAL = 1, /* 1 second */
57};
58
59zping_print_t label_string[] = {
60 {CLINET_RECV, "CLINET_RECV"},
61 {CLINET_SEND, "CLIENT_SEND"},
62 {SERVER_RECV, "SERVER_RECV"},
63 {SERVER_SEND, "SERVER_SEND"},
64
65 {AP_USB_IN, "AP_USB_IN"},
66 {AP_USB_OUT, "AP_USB_OUT"},
67 {AP_PS_IN, "AP_PS_IN"},
68 {AP_PS_OUT, "AP_PS_OUT"},
69 {AP_WIFI_WAN_IN, "AP_WIFI_WAN_IN"},
70 {AP_WIFI_WAN_OUT, "AP_WIFI_WAN_OUT"},
71 {AP_WIFI_LAN_IN, "AP_WIFI_LAN_IN"},
72 {AP_WIFI_LAN_OUT, "AP_WIFI_LAN_OUT"},
73 {AP_ETH_WAN_IN, "AP_ETH_WAN_IN"},
74 {AP_ETH_WAN_OUT, "AP_ETH_WAN_OUT"},
75 {AP_ETH_LAN_IN, "AP_ETH_LAN_IN"},
76 {AP_ETH_LAN_OUT, "AP_ETH_LAN_OUT"},
77 {AP_PS_EXT1_IN, "AP_PS_EXT1_IN"},
78 {AP_PS_EXT1_OUT, "AP_PS_EXT1_OUT"},
79 {AP_PS_EXT2_IN, "AP_PS_EXT2_IN"},
80 {AP_PS_EXT2_OUT, "AP_PS_EXT2_OUT"},
81 {AP_PS_EXT3_IN, "AP_PS_EXT3_IN"},
82 {AP_PS_EXT3_OUT, "AP_PS_EXT3_OUT"},
83 {AP_PS_EXT4_IN, "AP_PS_EXT4_IN"},
84 {AP_PS_EXT4_OUT, "AP_PS_EXT4_OUT"},
85
86 {CP_ETH1_IN, "CP_ETH1_IN"},
87 {CP_ETH1_OUT, "CP_ETH1_OUT"},
88 {CP_ETH2_IN, "CP_ETH2_IN"},
89 {CP_ETH2_OUT, "CP_ETH2_OUT"},
90 {CP_ETH3_IN, "CP_ETH3_IN"},
91 {CP_ETH3_OUT, "CP_ETH3_OUT"},
92 {CP_ETH4_IN, "CP_ETH4_IN"},
93 {CP_ETH4_OUT, "CP_ETH4_OUT"},
94 {CP_PS1_IN, "CP_PS1_IN"},
95 {CP_PS1_OUT, "CP_PS1_OUT"},
96 {CP_PS2_IN, "CP_PS2_IN"},
97 {CP_PS2_OUT, "CP_PS2_OUT"},
98 {CP_PS3_IN, "CP_PS3_IN"},
99 {CP_PS3_OUT, "CP_PS3_OUT"},
100 {CP_PS4_IN, "CP_PS4_IN"},
101 {CP_PS4_OUT, "CP_PS4_OUT"},
102 {CP_CTRM1_IN, "CP_CTRM1_IN"},
103 {CP_CTRM1_OUT, "CP_CTRM1_OUT"},
104 {CP_CTRM2_IN, "CP_CTRM2_IN"},
105 {CP_CTRM2_OUT, "CP_CTRM2_OUT"},
106 {CP_CTRM3_IN, "CP_CTRM3_IN"},
107 {CP_CTRM3_OUT, "CP_CTRM3_OUT"},
108 {CP_CTRM4_IN, "CP_CTRM4_IN"},
109 {CP_CTRM4_OUT, "CP_CTRM4_OUT"},
110
111 {LABEL_NULL, 0}
112};
113
114static void init_and_reset(zping_settings_t *zping_settings)
115{
116 id = 0;
117 last_seq_send = 0;
118 last_seq_recv = 0;
119
120 send_num = 0;
121 recv_num = 0;
122
123 pingcount = zping_settings->pingcount;
124
125 myid = zping_settings->set_id; // 0x7777
126}
127
128static int in_cksum(unsigned short *buf, int sz)
129{
130 int nleft = sz;
131 int sum = 0;
132 unsigned short *w = buf;
133 unsigned short ans = 0;
134
135 while (nleft > 1) {
136 sum += *w++;
137 nleft -= 2;
138 }
139
140 if (nleft == 1) {
141 *(unsigned char *)(&ans) = *(unsigned char *) w;
142 sum += ans;
143 }
144
145 sum = (sum >> 16) + (sum & 0xFFFF);
146 sum += (sum >> 16);
147 ans = ~sum;
148 return ans;
149}
150
151static const char *icmp_type_name(int id)
152{
153 switch (id) {
154 case ICMP_ECHOREPLY:
155 return "Echo Reply";
156 case ICMP_DEST_UNREACH:
157 return "Destination Unreachable";
158 case ICMP_SOURCE_QUENCH:
159 return "Source Quench";
160 case ICMP_REDIRECT:
161 return "Redirect (change route)";
162 case ICMP_ECHO:
163 return "Echo Request";
164 case ICMP_TIME_EXCEEDED:
165 return "Time Exceeded";
166 case ICMP_PARAMETERPROB:
167 return "Parameter Problem";
168 case ICMP_TIMESTAMP:
169 return "Timestamp Request";
170 case ICMP_TIMESTAMPREPLY:
171 return "Timestamp Reply";
172 case ICMP_INFO_REQUEST:
173 return "Information Request";
174 case ICMP_INFO_REPLY:
175 return "Information Reply";
176 case ICMP_ADDRESS:
177 return "Address Mask Request";
178 case ICMP_ADDRESSREPLY:
179 return "Address Mask Reply";
180 default:
181 return "unknown ICMP type";
182 }
183}
184
185char *translate_label(u_int32_t label, char *label_str, int len)
186{
187 if (label_str == NULL)
188 return NULL;
189
190 if (len < DEV_NAME_LEN)
191 return NULL;
192
193 memset(label_str, 0, len);
194
195 int i = 0;
196
197 while (1) {
198 if (label_string[i].label == LABEL_NULL)
199 break;
200 if (label == label_string[i].label) {
201 strcpy(label_str, label_string[i].name);
202 break;
203 }
204 i++;
205 }
206 return label_str;
207}
208
209static int analyse_each_zping_reply(char *buf, u_int16_t recv_seq, const u_int16_t id)
210{
211 zping_hdr_t *zping_hdr;
212 zping_item_t *zping_item, *zping_item_first, *zping_items;
213 zping_pktlost_item_t *zping_pktlost_item, *zping_pktlost_item_first, *zping_pktlost_items;
214 int i, j, lost_count_all = 0;
215 char name[32] = {0};
216 //int i, left, right;
217 //char label_str[DEV_NAME_LEN];
218 //char label_str_temp[DEV_NAME_LEN];
219 //zping_item_t *zping_items;
220 int32_t interval_secs, interval_usecs, prev_interval_secs, prev_interval_usecs, temp_secs, temp_usecs;
221 u_int32_t prev_secs, prev_usecs, first_secs, first_usecs;
222 u_int16_t prev_label = 0xffff;
223 prev_secs = prev_usecs = first_secs = first_usecs = -1;
224 int string_for_label = 0;
225 //u_int32_t prev_label = 0;
226
227 interval_secs = interval_usecs = prev_interval_secs = prev_interval_usecs = temp_secs = temp_usecs = -1;
228
229 if (buf == NULL)
230 return 0;
231
232 zping_hdr = (zping_hdr_t *)buf;
233
234 //zping_print(LOG_ALERT, "\n");
235 //zping_print(LOG_ALERT, "item_count:%d, item_index:%d, seq:%d\n",
236 //zping_hdr->item_count, zping_hdr->item_index, recv_seq);
237
238 if (id == 0) {
239 zping_pktlost_items = (zping_pktlost_item_t *)malloc(zping_hdr->item_index * sizeof(zping_pktlost_item_t));
240 } else {
241 zping_items = (zping_item_t *)malloc(zping_hdr->item_index * sizeof(zping_item_t));
242 }
243
244 if (delayoutput) {
245 if (id == 0) {
246 for (i = 0; i < zping_hdr->item_index; i++) {
247 zping_pktlost_item = (zping_pktlost_item_t *)(buf + sizeof(zping_hdr_t) + sizeof(zping_pktlost_item_t) * i);
248
249 zping_print(LOG_ALERT, " last_seq:%d, label:%d \t", zping_pktlost_item->last_seq, zping_pktlost_item->label);//translate_label(zping_item->label, label_str, 16),
250
251 zping_pktlost_items[i].label = zping_pktlost_item->label;
252 zping_pktlost_items[i].last_seq = zping_pktlost_item->last_seq;
253 }
254 zping_print(LOG_ALERT, "\n");
255 } else {
256 for (i = 0; i < zping_hdr->item_index; i++) {
257 zping_item = (zping_item_t *)(buf + sizeof(zping_hdr_t) + sizeof(zping_item_t) * i);
258
259 for (string_for_label = 0; label_string[string_for_label].label != LABEL_NULL; string_for_label++) {
260 if (label_string[string_for_label].label == zping_item->label)
261 {
262 strcpy(name,label_string[string_for_label].name);
263 break;
264 }
265 }
266
267 zping_print(LOG_ALERT, "node:%d, %s label: %d, last_seq:%ld \n secs:%ld, usecs:%ld \n",
268 i, name, zping_item->label,zping_item->last_seq, zping_item->secs, zping_item->usecs);
269
270 zping_items[i].label = zping_item->label;
271 zping_items[i].last_seq = zping_item->last_seq;
272 zping_items[i].secs = zping_item->secs;
273 zping_items[i].usecs = zping_item->usecs;
274
275 if (prev_label != 0xffff)
276 {
277 zping_print(LOG_ALERT, " delay: secs %d usecs %d \n",
278 zping_item->secs - prev_secs, zping_item->usecs - prev_usecs);
279 }
280
281
282 prev_secs = zping_item->secs;
283 prev_usecs = zping_item->usecs;
284 prev_label = zping_item->label;
285 if (first_secs == -1)
286 {
287 first_secs = zping_item->secs;
288 first_usecs = zping_item->usecs;
289 }
290 }
291 if (zping_hdr->item_index > 1) {
292 zping_print(LOG_ALERT, "whole time interval:%d secs %d usecs \n \n",
293 zping_item->secs - first_secs, zping_item->usecs - first_usecs);
294 }
295 }
296 }
297
298 if (lostoutput) {
299 if (id == 0) {
300 zping_pktlost_item_first = (zping_pktlost_item_t *)(buf + sizeof(zping_hdr_t));
301 if (send_num - zping_pktlost_item_first->last_seq > 1) {
302 return -1;
303 }
304 prev_label = zping_pktlost_item_first->label;
305 labels[0] = zping_pktlost_item_first->label;
306 for (i = 1; i < zping_hdr->item_index; i++) {
307 zping_pktlost_item = (zping_pktlost_item_t *)(buf + sizeof(zping_hdr_t) + sizeof(zping_pktlost_item_t) * i);
308
309 labels[i] = zping_pktlost_item->label;
310
311 //zping_print(LOG_ALERT, "label:%d, send_num:%d, zping_item->last_seq:%d\n", zping_item->label, send_num, zping_item->last_seq);
312 if (send_num - zping_pktlost_item->last_seq > 1) {
313 zping_print(LOG_ALERT, "node :%d, between label %d and label %d \n",
314 i, prev_label, zping_pktlost_item->label);
315
316 lost_count[i]++;
317 if (i > 0) {
318 for (j = 1; j < zping_hdr->item_index; j++) {
319 lost_count_all += lost_count[j];
320 }
321 zping_print(LOG_ALERT, "statistics: ");
322 for (j = 1; j < zping_hdr->item_index; j++) {
323 if (lost_count[j] > 0) {
324 zping_print(LOG_ALERT, "between label %d and label %d, lost count:%d, ", labels[j - 1], labels[j], lost_count[j]);
325 zping_print(LOG_ALERT, " label %d : %s label %d : %s\n",labels[j - 1],label_string[labels[j - 1]].name,labels[j],label_string[labels[j]].name);
326 }
327 }
328 zping_print(LOG_ALERT, "lost count all:%d\n", lost_count_all);
329 }
330
331 break;
332 }
333 prev_label = zping_pktlost_item->label;
334 }
335 } else {
336 zping_item_first = (zping_item_t *)(buf + sizeof(zping_hdr_t));
337 if (send_num - zping_item_first->last_seq > 1) {
338 return -1;
339 }
340 prev_label = zping_item_first->label;
341 labels[0] = zping_item_first->label;
342 for (i = 1; i < zping_hdr->item_index; i++) {
343 zping_item = (zping_item_t *)(buf + sizeof(zping_hdr_t) + sizeof(zping_item_t) * i);
344
345 labels[i] = zping_item->label;
346
347 //zping_print(LOG_ALERT, "label:%d, send_num:%d, zping_item->last_seq:%d\n", zping_item->label, send_num, zping_item->last_seq);
348 if (send_num - zping_item->last_seq > 1) {
349 zping_print(LOG_ALERT, "node:%d, between label %d and label %d, seq lost between %d and %d\n", i, prev_label, zping_item->label, zping_item->last_seq, send_num);
350
351 lost_count[i]++;
352 if (i > 0) {
353 for (j = 1; j < zping_hdr->item_index; j++) {
354 lost_count_all += lost_count[j];
355 }
356 zping_print(LOG_ALERT, "statistics: ");
357 for (j = 1; j < zping_hdr->item_index; j++) {
358 if (lost_count[j] > 0) {
359 zping_print(LOG_ALERT, "between label %d and label %d, lost count:%d, ", labels[j - 1], labels[j], lost_count[j]);
360 }
361 }
362 zping_print(LOG_ALERT, "lost count all:%d\n", lost_count_all);
363 }
364
365 break;
366 }
367 prev_label = zping_item->label;
368 }
369 }
370 }
371
372 if (id == 0) {
373 free(zping_pktlost_items);
374 } else {
375 free(zping_items);
376 }
377 return 1;
378}
379
380int zping_hdr_init(char *buffer, int len, u_int16_t itemcount, u_int16_t id)
381{
382 zping_hdr_t *zping_hdr;
383 int item_size = 0;
384 if (len < sizeof(zping_hdr_t))
385 return 0;
386 zping_hdr = (zping_hdr_t*)buffer;
387
388 zping_hdr->id = id;
389 zping_hdr->item_count = itemcount;
390 zping_hdr->item_index = 0;
391 zping_hdr->item_index_padding = 0xFFFF;
392 zping_hdr->flags = 0;
393 zping_hdr->flags_padding = 0xFFFF;
394
395 item_size = id == 0 ? sizeof(zping_pktlost_item_t) : sizeof(zping_item_t);
396 if (len - sizeof(zping_hdr_t) < zping_hdr->item_count * item_size)
397 return 0;
398
399 return 1;
400}
401
402void init_all_items(char *buffer, u_int16_t itemcount, const u_int16_t id)
403{
404 int i;
405 zping_item_t *zping_item;
406 zping_pktlost_item_t *zping_pktlost_item;
407
408 if (id == 0) {
409 for (i = 0; i < itemcount; i++) {
410 zping_pktlost_item = (zping_pktlost_item_t *)(buffer + sizeof(zping_hdr_t) + sizeof(zping_pktlost_item_t) * i);
411 zping_pktlost_item->label = 0x0;
412 zping_pktlost_item->label_padding = 0xFFFF;
413 zping_pktlost_item->last_seq = 0x0;
414 zping_pktlost_item->last_seq_padding = 0xFFFF;
415 }
416 return;
417 }
418
419 for (i = 0; i < itemcount; i++) {
420 zping_item = (zping_item_t *)(buffer + sizeof(zping_hdr_t) + sizeof(zping_item_t) * i);
421 zping_item->label = 0x0;
422 zping_item->label_padding = 0xFFFF;
423 zping_item->secs = 0x0;
424 zping_item->secs_padding = 0xFFFFFFFF;
425 zping_item->usecs = 0x0;
426 zping_item->usecs_padding = 0xFFFFFFFF;
427 zping_item->last_seq = 0x0;
428 zping_item->last_seq_padding = 0xFFFF;
429 }
430}
431
432int get_current_item_index(char *buffer)
433{
434 zping_hdr_t *zping_hdr = (zping_hdr_t*)buffer;
435 return zping_hdr->item_index;
436}
437void get_uniform_time(unsigned long * sec ,unsigned long * usec )
438{
439 unsigned long long time_usec = get_time_us();
440 *usec = (unsigned long)time_usec;
441 *sec = (unsigned long)((unsigned long)time_usec/1000000);
442}
443
444int set_send_zping_item(char *buffer, int index, const u_int16_t id)
445{
446 struct timeval tv;
447 zping_hdr_t *zping_hdr = (zping_hdr_t*)buffer;
448 zping_pktlost_item_t *zping_pktlost_item;
449 zping_item_t *zping_item;
450
451 if (id == 0) {
452 zping_pktlost_item = (zping_pktlost_item_t *)(buffer + sizeof(zping_hdr_t) + sizeof(zping_pktlost_item_t) * (index - 1));
453 zping_pktlost_item->label = CLINET_SEND;
454 zping_pktlost_item->label_padding = 0xFFFF;
455 zping_pktlost_item->last_seq = last_seq_send;
456 } else {
457 zping_item = (zping_item_t *)(buffer + sizeof(zping_hdr_t) + sizeof(zping_item_t) * (index - 1));
458 zping_item->label = CLINET_SEND;
459 zping_item->label_padding = 0xFFFF;
460 zping_item->secs_padding = 0xFFFFFFFF;
461 zping_item->usecs_padding = 0xFFFFFFFF;
462 //gettimeofday(&tv, NULL);
463 //zping_item->secs = tv.tv_sec;
464 //zping_item->usecs = tv.tv_usec;
465 get_uniform_time(&zping_item->secs,&zping_item->usecs);
466 zping_item->last_seq = last_seq_send;
467 }
468
469 zping_hdr->item_index++;
470 return 1;
471}
472
473int set_recv_zping_item(char *buffer, int index, const u_int16_t id)
474{
475 struct timeval tv;
476 zping_hdr_t *zping_hdr = (zping_hdr_t*)buffer;
477 zping_pktlost_item_t *zping_pktlost_item;
478 zping_item_t *zping_item;
479 if (id == 0) {
480 zping_pktlost_item = (zping_pktlost_item_t *)(buffer + sizeof(zping_hdr_t) + sizeof(zping_pktlost_item_t) * (index - 1));
481 zping_pktlost_item->label_padding = 0xFFFF;
482 zping_pktlost_item->last_seq = last_seq_recv;
483 } else {
484 zping_item = (zping_item_t *)(buffer + sizeof(zping_hdr_t) + sizeof(zping_item_t) * (index - 1));
485 zping_item->label = CLINET_RECV;
486 zping_item->label_padding = 0xFFFF;
487 zping_item->secs_padding = 0xFFFFFFFF;
488 zping_item->usecs_padding = 0xFFFFFFFF;
489
490 //gettimeofday(&tv, NULL);
491 //zping_item->secs = tv.tv_sec;
492 //zping_item->usecs = tv.tv_usec;
493 get_uniform_time(&zping_item->secs,&zping_item->usecs);
494 zping_item->last_seq = last_seq_recv;
495 }
496 zping_hdr->item_index++;
497 return 1;
498}
499
500static int unpack4(char *buf, int sz, struct sockaddr_in *from, const u_int16_t id)
501{
502 //zping_print(LOG_ALERT, "unpack4 enter\n");
503 struct icmp *icmppkt;
504 struct iphdr *iphdr;
505 u_int16_t recv_seq;
506
507 iphdr = (struct iphdr *) buf;
508 icmppkt = (struct icmp *)(buf + (iphdr->ihl << 2));
509
510 set_recv_zping_item(icmppkt->icmp_data, get_current_item_index(icmppkt->icmp_data) + 1, id);
511 recv_seq = ntohs(icmppkt->icmp_seq);
512
513 recv_num++;
514
515 return analyse_each_zping_reply(icmppkt->icmp_data, recv_seq, id);
516 /*
517 if (sz >= ICMP_MINLEN + sizeof(uint32_t)) // todo
518 tp = (uint32_t *) icmppkt->icmp_data;
519 unpack_tail(sz, tp,
520 inet_ntoa(*(struct in_addr *) &from->sin_addr.s_addr),
521 recv_seq, iphdr->ttl);
522 */
523 //return 1;
524}
525
526static int zping_validate(char *buf, int sz, int send_icmp_data_size)
527{
528 struct icmp *icmppkt;
529 struct iphdr *iphdr;
530 int hlen;
531
532 /* discard if too short */
533 if (sz < (IPHDR_MINLEN + ICMP_MINLEN + send_icmp_data_size))
534 return 0;
535
536 /* check IP header */
537 iphdr = (struct iphdr *) buf;
538 hlen = iphdr->ihl << 2;
539 sz -= hlen;
540 icmppkt = (struct icmp *)(buf + hlen);
541 if (ntohs(icmppkt->icmp_id) != myid)
542 return 0; /* not our ping */
543
544 if (icmppkt->icmp_type == ICMP_ECHOREPLY) {
545
546 } else if (icmppkt->icmp_type != ICMP_ECHO) {
547 zping_print(LOG_ALERT, "warning: got ICMP %d (%s)",
548 icmppkt->icmp_type,
549 icmp_type_name(icmppkt->icmp_type));
550 return 0;
551 }
552 return 1;
553}
554
555void sendping4(zping_settings_t *zping_settings)
556{
557
558}
559
560void ping4(zping_settings_t *zping_settings)
561{
562 struct sockaddr_in pingaddr;
563 int ret;
564 int data_size, icmp_size;
565 int pingsock;
566 int sockopt;
567 struct timeval tv, start_tv, end_tv;
568
569 struct icmp *icmp_pkt;
570 char packet[DEFAULT_IP_ICMP_SIZE];
571 char *icmp_data_zping;
572
573 struct sockaddr_in from;
574 socklen_t fromlen = sizeof(from);
575 int c;
576 int n = 1;
577 int mark = 0;
578 int recv_wait_num = 0;
579
580 memset(lost_count, 0, MAX_MARK_NUM * sizeof(int));
581 memset(labels, 0, MAX_MARK_NUM * sizeof(int));
582
583 data_size = zping_settings->size;
584
585 pingsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); /* 1 == ICMP */
586 FAIL_errno(pingsock < 0, "sock creat failed");
587
588 /* set recv buf (needed if we can get lots of responses: flood ping,
589 * broadcast ping etc) */
590 sockopt = (DEFDATALEN * 2) + 7 * 1024; /* giving it a bit of extra room */
591 setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt));
592
593 tv.tv_sec = zping_settings->timeout == 0 ? 4 : zping_settings->timeout;
594 tv.tv_usec = 0;
595 setsockopt(pingsock, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(struct timeval));
596
597another_round:
598 init_and_reset(zping_settings);
599// zping_print(LOG_ALERT, "\nround %d starts\n", n++);
600 while (1) {
601 if (pingcount != 0 && send_num >= pingcount) {
602 goto out;
603 }
604
605 icmp_size = data_size + ICMP_MINLEN;
606
607 icmp_pkt = (struct icmp *) packet;
608 memset(icmp_pkt, 0, icmp_size);
609 icmp_pkt->icmp_type = ICMP_ECHO;
610 icmp_pkt->icmp_seq = htons(send_num); /* don't ++ here, it can be a macro */
611 icmp_pkt->icmp_id = htons(myid); // no need to do htons if it's 0x7777
612 //icmp_pkt->icmp_cksum = in_cksum((unsigned short *)icmp_pkt, icmp_size);
613
614 icmp_data_zping = (char *)(icmp_pkt->icmp_data);
615
616 zping_hdr_init(icmp_data_zping, data_size, zping_settings->itemcount, zping_settings->set_id);
617
618 init_all_items(icmp_data_zping, zping_settings->itemcount, zping_settings->set_id);
619
620 //gettimeofday(&tv, NULL);
621
622 set_send_zping_item(icmp_data_zping, 1, zping_settings->set_id);
623
624 icmp_pkt->icmp_cksum = in_cksum((unsigned short *)icmp_pkt, icmp_size);
625
626 gettimeofday(&start_tv, NULL);
627
628 ret = sendto(pingsock, icmp_pkt, icmp_size, 0,
629 (struct sockaddr *)&zping_settings->zping_sockaddr, sizeof(zping_settings->zping_sockaddr));
630
631 if (mark == 0) {
632 system("cat /proc/uptime 1>/dev/console 2>&1");
633 mark = 1;
634 }
635 FAIL_errno(ret < 0, "sock sendto failed");
636//zping_print(LOG_ALERT, "ping4 sendto\n");
637
638
639recv_reply:
640 /* listen for replies */
641 while (1) {
642
643 memset(icmp_pkt, 0, icmp_size);
644 c = recvfrom(pingsock, packet, DEFAULT_IP_ICMP_SIZE, 0, (struct sockaddr *)&from, &fromlen);
645 //zping_print(LOG_ALERT, "try recvfrom\n");
646 if (c < 0) {
647 //zping_print(LOG_ALERT, "recvfrom error\n");
648 if (errno == EINTR)
649 continue;
650 else {
651 //FAIL_errno(1, "sock recvfrom failed");
652 zping_print(LOG_ALERT, "recvfrom error errno=%d \n",errno);
653 WARN_errno(1, "sock recvfrom failed");
654 recv_wait_num++;
655 if (recv_wait_num >= maxwaitnum)
656 break;
657 //goto out;
658 }
659 } else {
660 //zping_print(LOG_ALERT, "recvfrom received something len:%d\n", c);
661
662 if (zping_validate(packet, c, data_size) == 0) {
663 zping_print(LOG_ALERT, "recvfrom received something we don't need\n");
664 continue;
665 } else {
666 if (mark == 1) {
667 system("cat /proc/uptime 1>/dev/console 2>&1");
668 mark = 2;
669 }
670 ret = unpack4(packet, c, &from, zping_settings->set_id);
671 if (ret == -1) {
672 continue;
673 } else {
674 last_seq_recv = send_num;
675 break;
676 }
677 }
678 /*
679 if(c < icmp_size)
680 {
681 zping_print(LOG_ALERT, "recvfrom len < icmp_size");
682 goto out; // think more
683 }
684
685 if(unpack4(packet, c, &from, data_size))
686 {
687 break;
688 }
689 */
690 }
691
692 }
693
694 last_seq_send = send_num;
695 send_num++;
696
697 if (pingcount != 0 && send_num > pingcount) {
698 break;
699 } else {
700 gettimeofday(&end_tv, NULL);
701 if (end_tv.tv_sec - start_tv.tv_sec < zping_settings->interval) {
702 sleep(zping_settings->interval - end_tv.tv_sec + start_tv.tv_sec);
703 }
704 }
705 }
706
707out:
708
709 if (zping_settings->unstopped) {
710 goto another_round;
711 }
712
713
714 close(pingsock);
715 pingsock = -1;
716}
717
718static void ping(zping_settings_t *zping_settings)
719{
720 zping_print(LOG_ALERT, "PING %s", zping_settings->address_str);
721 zping_print(LOG_ALERT, ": %d data bytes\n", zping_settings->size);
722
723 ping4(zping_settings); // ping6 is to be on the way if needed
724}
725
726void start_run(zping_settings_t *zping_settings)
727{
728 delayoutput = zping_settings->delayoutput;
729 lostoutput = zping_settings->lostoutput;
730 maxwaitnum = zping_settings->maxwaitnum;
731 ping(zping_settings);
732}