-
Notifications
You must be signed in to change notification settings - Fork 0
/
ssmping.c
80 lines (66 loc) · 2.59 KB
/
ssmping.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/*
* Copyright (C) 2005 Stig Venaas <[email protected]>
* $Id: ssmping.c,v 1.22 2005/11/29 16:27:26 sv Exp $
*
* Contributions:
* Solaris support by Alexander Gall <[email protected]>
* Initial Windows support by Nick Lamb <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*/
#include "ssmping.h"
extern int optind;
extern char *optarg;
int main(int argc, char **argv) {
int family, count, ver, us, ms;
char *pingee, *group, source[INET6_ADDRSTRLEN];
uint16_t size;
uint32_t intface;
struct sockaddr_storage name, ucaddr, mcaddr, grpaddr;
size_t namelen;
#ifdef WIN32
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
WSAStartup(wVersionRequested, &wsaData);
/* lots of complicated Win32 error checking expected - sigh - */
#endif
parseargs(argc, argv, SSMMODE, &family, &ver, &size, &intface, &count, &pingee, &group, NULL, NULL, NULL);
if (names2addrsocks(&us, &ms, pingee, group, "4321", &family, &ucaddr, &mcaddr))
errx("name2addrsocks failed");
prep_sock(family, us);
prep_sock(family, ms);
setvbuf(stdout, NULL, _IONBF, 0);
findsrc((struct sockaddr *)&name, (struct sockaddr *)&ucaddr);
namelen = SOCKADDR_SIZE(name);
setport((struct sockaddr *)&name, 0);
if (bind(us, (struct sockaddr *)&name, namelen) < 0)
errx("bind");
if (connect(us, (struct sockaddr *)&ucaddr, namelen) < 0)
errx("connect");
if (getsockname(us, (struct sockaddr *)&name, &namelen) == -1)
errx("getsockname");
grpaddr = name;
setaddr(&grpaddr, group ? &mcaddr : NULL, "ff3e::4321:1234", "232.43.211.234");
#ifdef WIN32
{
struct sockaddr_storage any = name;
setaddr(&any, NULL, "::", "0.0.0.0");
if (bind(ms, (struct sockaddr *)&any, namelen) < 0)
errx("bind [ANY]");
}
#else
if (bind(ms, (struct sockaddr *)&grpaddr, namelen) < 0)
errx("bind [multicast]");
#endif
/* using name to specify interface is wrong, only problem for old API */
joinchannel(ms, (struct sockaddr *)&ucaddr,
(struct sockaddr *)&grpaddr, intface, (struct sockaddr *)&name);
strcpy(source, addr2string((struct sockaddr *)&ucaddr, namelen));
printf("ssmping joined (S,G) = (%s,%s)\n", source,
addr2string((struct sockaddr *)&grpaddr, namelen));
printf("pinging S from %s\n", addr2string((struct sockaddr *)&name, namelen));
return doit(ver, size, count, us, ms, &ucaddr, &grpaddr, source);
}