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

schweikert / fping / 24923853954

25 Apr 2026 05:42AM UTC coverage: 88.0% (-0.09%) from 88.091%
24923853954

push

github

gsnw-sebast
Fixes the indentation of the blocks

5 of 5 new or added lines in 1 file covered. (100.0%)

151 existing lines in 3 files now uncovered.

1672 of 1900 relevant lines covered (88.0%)

344.84 hits per line

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

86.96
/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
#include "flags.h"
36

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

50
char* ping_buffer_ipv4 = 0;
51
size_t ping_pkt_size_ipv4;
52

53
/* Interface index for outgoing packets (0 = not set, use routing table) */
54
static int outgoing_iface_idx_ipv4 = 0;
55

56
/* Source address for outgoing packets (used to populate ipi_spec_dst) */
57
static struct in_addr outgoing_src_addr_ipv4;
58
static int outgoing_src_addr_set_ipv4 = 0;
59

60
int open_ping_socket_ipv4(int *socktype)
881✔
61
{
62
    struct protoent* proto;
63
    int s;
64

65
    /* confirm that ICMP is available on this machine */
66
    if ((proto = getprotobyname("icmp")) == NULL)
881✔
UNCOV
67
        crash_and_burn("icmp: unknown protocol");
×
68

69
    /* create raw socket for ICMP calls (ping) */
70
    *socktype = SOCK_RAW;
881✔
71
    s = socket(AF_INET, *socktype, proto->p_proto);
881✔
72
    if (s < 0) {
881✔
73
        /* try non-privileged icmp (works on Mac OSX without privileges, for example) */
74
        *socktype = SOCK_DGRAM;
12✔
75
        s = socket(AF_INET, *socktype, proto->p_proto);
12✔
76
        if (s < 0) {
12✔
UNCOV
77
            return -1;
×
78
        }
79
    }
80

81
    /* Make sure that we use non-blocking IO */
82
    {
83
        int flags;
84

85
        if ((flags = fcntl(s, F_GETFL, 0)) < 0)
881✔
UNCOV
86
            perror("fcntl");
×
87

88
        if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0)
881✔
UNCOV
89
            perror("fcntl");
×
90
    }
91

92
    return s;
881✔
93
}
239✔
94

95
void socket_set_outgoing_iface_ipv4(int s, const char *iface_name)
4✔
96
{
97
    unsigned int idx = if_nametoindex(iface_name);
4✔
98
    if (idx == 0) {
4✔
UNCOV
99
        fprintf(stderr, "fping: unknown interface '%s'\n", iface_name);
×
UNCOV
100
        exit(1);
×
101
    }
102
    outgoing_iface_idx_ipv4 = (int)idx;
4✔
103

104
    int on = 1;
4✔
105
    if (setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on)) < 0) {
4✔
UNCOV
106
        perror("setsockopt IP_PKTINFO");
×
UNCOV
107
        exit(1);
×
108
    }
109
}
4✔
110

111
void init_ping_buffer_ipv4(size_t ping_data_size)
392✔
112
{
113
    /* allocate ping buffer */
114
    ping_pkt_size_ipv4 = ping_data_size + ICMP_MINLEN;
392✔
115
    ping_buffer_ipv4 = (char*)calloc(1, ping_pkt_size_ipv4);
392✔
116
    if (!ping_buffer_ipv4)
392✔
UNCOV
117
        crash_and_burn("can't malloc ping packet");
×
118
}
392✔
119

120
void socket_set_src_addr_ipv4(int s, struct in_addr* src_addr, int *ident)
18✔
121
{
122
    struct sockaddr_in sa;
123
    socklen_t len = sizeof(sa);
18✔
124

125
    /* Remember source address so we can set ipi_spec_dst in sendmsg() */
126
    outgoing_src_addr_ipv4 = *src_addr;
18✔
127
    outgoing_src_addr_set_ipv4 = 1;
18✔
128

129
    memset(&sa, 0, len);
18✔
130
    sa.sin_family = AF_INET;
18✔
131
    sa.sin_addr = *src_addr;
18✔
132
    if (bind(s, (struct sockaddr*)&sa, len) < 0)
18✔
133
        errno_crash_and_burn("cannot bind source address");
3✔
134

135
    if (ident) {
16✔
136
        memset(&sa, 0, len);
12✔
137
        if (getsockname(s, (struct sockaddr *)&sa, &len) < 0)
12✔
UNCOV
138
            errno_crash_and_burn("can't get ICMP socket identity");
×
139

140
        if (sa.sin_port)
12✔
141
            *ident = sa.sin_port;
12✔
142
    }
143
}
16✔
144

145
unsigned short calcsum(unsigned short* buffer, int length)
916✔
146
{
147
    unsigned long sum;
148

149
    /* initialize sum to zero and loop until length (in words) is 0 */
150
    for (sum = 0; length > 1; length -= 2) /* sizeof() returns number of bytes, we're interested in number of words */
31,248✔
151
        sum += *buffer++; /* add 1 word of buffer to sum and proceed to the next */
30,332✔
152

153
    /* we may have an extra byte */
154
    if (length == 1)
916✔
UNCOV
155
        sum += (char)*buffer;
×
156

157
    sum = (sum >> 16) + (sum & 0xFFFF); /* add high 16 to low 16 */
916✔
158
    sum += (sum >> 16); /* add carry */
916✔
159
    return ~sum;
916✔
160
}
161

162
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)
916✔
163
{
164
    struct icmp* icp;
165
    struct timespec tsorig;
166
    long tsorig_ms;
167
    int n;
168

169
    icp = (struct icmp*)ping_buffer_ipv4;
916✔
170

171
    icp->icmp_type = icmp_proto;
916✔
172
    if(icmp_proto == ICMP_TSTAMP) {
916✔
173
        clock_gettime(CLOCK_REALTIME, &tsorig);
18✔
174
        tsorig_ms = (tsorig.tv_sec % (24*60*60)) * 1000 + tsorig.tv_nsec / 1000000;
18✔
175
        icp->icmp_otime = htonl(tsorig_ms);
18✔
176
        icp->icmp_rtime = 0;
18✔
177
        icp->icmp_ttime = 0;
18✔
178
    }
179
    icp->icmp_code = 0;
916✔
180
    icp->icmp_cksum = 0;
916✔
181
    icp->icmp_seq = htons(icmp_seq_nr);
916✔
182
    icp->icmp_id = icmp_id_nr;
916✔
183

184
    if (opt_random_data_on) {
916✔
185
        for (n = ((char*)&icp->icmp_data - (char*)icp); n < ping_pkt_size_ipv4; ++n) {
513✔
186
            ping_buffer_ipv4[n] = random() & 0xFF;
504✔
187
        }
168✔
188
    }
3✔
189

190
    icp->icmp_cksum = calcsum((unsigned short*)icp, ping_pkt_size_ipv4);
916✔
191

192
    if (outgoing_iface_idx_ipv4 > 0) {
916✔
193
        struct iovec iov = {
2✔
194
            .iov_base = icp,
195
            .iov_len  = ping_pkt_size_ipv4
196
        };
197

198
        char cmsg_buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
199
        memset(cmsg_buf, 0, sizeof(cmsg_buf));
2✔
200

201
        struct msghdr msg = {
2✔
202
            .msg_name       = saddr,
203
            .msg_namelen    = saddr_len,
204
            .msg_iov        = &iov,
205
            .msg_iovlen     = 1,
206
            .msg_control    = cmsg_buf,
207
            .msg_controllen = sizeof(cmsg_buf),
208
            .msg_flags      = 0
209
        };
210

211
        struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
2✔
212
        cmsg->cmsg_level = IPPROTO_IP;
2✔
213
        cmsg->cmsg_type  = IP_PKTINFO;
2✔
214
        cmsg->cmsg_len   = CMSG_LEN(sizeof(struct in_pktinfo));
2✔
215

216
        struct in_pktinfo *pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg);
2✔
217
        memset(pktinfo, 0, sizeof(*pktinfo));
2✔
218
        pktinfo->ipi_ifindex = outgoing_iface_idx_ipv4;
2✔
219
        if (outgoing_src_addr_set_ipv4) {
2✔
UNCOV
220
            pktinfo->ipi_spec_dst = outgoing_src_addr_ipv4;
×
221
        }
222

223
        n = sendmsg(s, &msg, 0);
2✔
224
    } else {
225
        n = sendto(s, icp, ping_pkt_size_ipv4, 0, saddr, saddr_len);
914✔
226
    }
227

228
    return n;
916✔
229
}
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