• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

schweikert / fping / 11777176665

11 Nov 2024 10:58AM UTC coverage: 87.637% (-0.1%) from 87.762%
11777176665

push

github

gsnw-sebast
Update CHANGELOG.md for ICMP Timestamp

1276 of 1456 relevant lines covered (87.64%)

256.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.23
/src/socket4.c
1
/*
2
 * fping: fast-ping, file-ping, favorite-ping, funky-ping
3
 *
4
 *   Ping a list of target hosts in a round robin fashion.
5
 *   A better ping overall.
6
 *
7
 * fping website:  http://www.fping.org
8
 *
9
 * Current maintainer of fping: David Schweikert
10
 * Please send suggestions and patches to: david@schweikert.ch
11
 *
12
 *
13
 * Original author:  Roland Schemers  <schemers@stanford.edu>
14
 * IPv6 Support:     Jeroen Massar    <jeroen@unfix.org / jeroen@ipng.nl>
15
 * Improved main loop: David Schweikert <david@schweikert.ch>
16
 * Debian Merge, TOS settings: Tobi Oetiker <tobi@oetiker.ch>
17
 * Bugfixes, byte order & senseful seq.-numbers: Stephan Fuhrmann (stephan.fuhrmann AT 1und1.de)
18
 *
19
 *
20
 * Redistribution and use in source and binary forms are permitted
21
 * provided that the above copyright notice and this paragraph are
22
 * duplicated in all such forms and that any documentation,
23
 * advertising materials, and other materials related to such
24
 * distribution and use acknowledge that the software was developed
25
 * by Stanford University.  The name of the University may not be used
26
 * to endorse or promote products derived from this software without
27
 * specific prior written permission.
28
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
29
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
30
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
31
 */
32

33
#include "config.h"
34
#include "fping.h"
35

36
#include <fcntl.h>
37
#include <netdb.h>
38
#include <netinet/in.h>
39
#include <netinet/in_systm.h>
40
#include <netinet/ip.h>
41
#include <netinet/ip_icmp.h>
42
#include <stdio.h>
43
#include <stdlib.h>
44
#include <string.h>
45
#include <sys/socket.h>
46
#include <time.h>
47

48
char* ping_buffer_ipv4 = 0;
49
size_t ping_pkt_size_ipv4;
50

51
int open_ping_socket_ipv4(int *socktype)
444✔
52
{
53
    struct protoent* proto;
54
    int s;
55

56
    /* confirm that ICMP is available on this machine */
57
    if ((proto = getprotobyname("icmp")) == NULL)
444✔
58
        crash_and_burn("icmp: unknown protocol");
×
59

60
    /* create raw socket for ICMP calls (ping) */
61
    *socktype = SOCK_RAW;
444✔
62
    s = socket(AF_INET, *socktype, proto->p_proto);
444✔
63
    if (s < 0) {
444✔
64
        /* try non-privileged icmp (works on Mac OSX without privileges, for example) */
65
        *socktype = SOCK_DGRAM;
10✔
66
        s = socket(AF_INET, *socktype, proto->p_proto);
10✔
67
        if (s < 0) {
10✔
68
            return -1;
×
69
        }
70
    }
71

72
    /* Make sure that we use non-blocking IO */
73
    {
74
        int flags;
75

76
        if ((flags = fcntl(s, F_GETFL, 0)) < 0)
444✔
77
            perror("fcntl");
×
78

79
        if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0)
444✔
80
            perror("fcntl");
×
81
    }
82

83
    return s;
444✔
84
}
128✔
85

86
void init_ping_buffer_ipv4(size_t ping_data_size)
223✔
87
{
88
    /* allocate ping buffer */
89
    ping_pkt_size_ipv4 = ping_data_size + ICMP_MINLEN;
223✔
90
    ping_buffer_ipv4 = (char*)calloc(1, ping_pkt_size_ipv4);
223✔
91
    if (!ping_buffer_ipv4)
223✔
92
        crash_and_burn("can't malloc ping packet");
×
93
}
223✔
94

95
void socket_set_src_addr_ipv4(int s, struct in_addr* src_addr, int *ident)
16✔
96
{
97
    struct sockaddr_in sa;
98
    socklen_t len = sizeof(sa);
16✔
99

100
    memset(&sa, 0, len);
16✔
101
    sa.sin_family = AF_INET;
16✔
102
    sa.sin_addr = *src_addr;
16✔
103
    if (bind(s, (struct sockaddr*)&sa, len) < 0)
16✔
104
        errno_crash_and_burn("cannot bind source address");
3✔
105

106
    if (ident) {
14✔
107
        memset(&sa, 0, len);
10✔
108
        if (getsockname(s, (struct sockaddr *)&sa, &len) < 0)
10✔
109
            errno_crash_and_burn("can't get ICMP socket identity");
×
110

111
        if (sa.sin_port)
10✔
112
            *ident = sa.sin_port;
10✔
113
    }
114
}
14✔
115

116
unsigned short calcsum(unsigned short* buffer, int length)
552✔
117
{
118
    unsigned long sum;
119

120
    /* initialize sum to zero and loop until length (in words) is 0 */
121
    for (sum = 0; length > 1; length -= 2) /* sizeof() returns number of bytes, we're interested in number of words */
19,632✔
122
        sum += *buffer++; /* add 1 word of buffer to sum and proceed to the next */
19,080✔
123

124
    /* we may have an extra byte */
125
    if (length == 1)
552✔
126
        sum += (char)*buffer;
×
127

128
    sum = (sum >> 16) + (sum & 0xFFFF); /* add high 16 to low 16 */
552✔
129
    sum += (sum >> 16); /* add carry */
552✔
130
    return ~sum;
552✔
131
}
132

133
int socket_sendto_ping_ipv4(int s, struct sockaddr* saddr, socklen_t saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr, uint8_t icmp_proto)
552✔
134
{
135
    struct icmp* icp;
136
    struct timespec tsorig;
137
    long tsorig_ms;
138
    int n;
139

140
    icp = (struct icmp*)ping_buffer_ipv4;
552✔
141

142
    icp->icmp_type = icmp_proto;
552✔
143
    if(icmp_proto == ICMP_TSTAMP) {
552✔
144
        clock_gettime(CLOCK_REALTIME, &tsorig);
6✔
145
        tsorig_ms = (tsorig.tv_sec % (24*60*60)) * 1000 + tsorig.tv_nsec / 1000000;
6✔
146
        icp->icmp_otime = htonl(tsorig_ms);
6✔
147
        icp->icmp_rtime = 0;
6✔
148
        icp->icmp_ttime = 0;
6✔
149
    }
150
    icp->icmp_code = 0;
552✔
151
    icp->icmp_cksum = 0;
552✔
152
    icp->icmp_seq = htons(icmp_seq_nr);
552✔
153
    icp->icmp_id = icmp_id_nr;
552✔
154

155
    if (random_data_flag) {
552✔
156
        for (n = ((char*)&icp->icmp_data - (char*)icp); n < ping_pkt_size_ipv4; ++n) {
513✔
157
            ping_buffer_ipv4[n] = random() & 0xFF;
504✔
158
        }
168✔
159
    }
3✔
160

161
    icp->icmp_cksum = calcsum((unsigned short*)icp, ping_pkt_size_ipv4);
552✔
162

163
    n = sendto(s, icp, ping_pkt_size_ipv4, 0, saddr, saddr_len);
552✔
164

165
    return n;
552✔
166
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc