File: ssmping.c

package info (click to toggle)
ssmping 0.9.1-4
  • links: PTS
  • area: main
  • in suites: bookworm, bullseye, sid, trixie
  • size: 216 kB
  • sloc: ansic: 1,692; makefile: 91
file content (82 lines) | stat: -rw-r--r-- 2,681 bytes parent folder | download
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
81
82
/*
 * Copyright (C) 2005  Stig Venaas <venaas@uninett.no>
 * $Id: ssmping.c,v 1.22 2005/11/29 16:27:26 sv Exp $
 *
 * Contributions:
 * Solaris support by Alexander Gall <gall@switch.ch>
 * Initial Windows support by Nick Lamb <njl@ecs.soton.ac.uk>
 *
 * 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.
 */

#define _GNU_SOURCE 1

#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;
    socklen_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);
}