File: ssmping.cpp

package info (click to toggle)
dbeacon 0.4.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 396 kB
  • sloc: cpp: 2,346; perl: 1,549; makefile: 42; sh: 21
file content (79 lines) | stat: -rw-r--r-- 1,653 bytes parent folder | download | duplicates (2)
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
/*
 * Copyright 2005-2010, Hugo Santos <hugo@fivebits.net>
 * Distributed under the terms of the MIT License.
 */

#include "dbeacon.h"
#include "address.h"
#include "msocket.h"

#include <assert.h>
#include <stdio.h>
#include <unistd.h>

enum {
	SSMPING_REQUEST = 'Q',
	SSMPING_ANSWER = 'A'
};

static const size_t maxSSMPingMessage = 1000;

static const char *SSMPingV6ResponseChannel = "ff3e::4321:1234";
static const char *SSMPingV4ResponseChannel = "232.43.211.234";

static address SSMPingV6Addr(AF_INET6), SSMPingV4Addr(AF_INET);

static int ssmPingSocket = -1;

static void handle_ssmping(int s, const Message &msg)
{
	if (msg.buffer[0] != SSMPING_REQUEST || msg.len > maxSSMPingMessage)
		return;

	if (verbose > 1) {
		char tmp[64];
		info("Got SSM Ping Request from %s",
			msg.from.to_string(tmp, sizeof(tmp)));
	}

	msg.buffer[0] = SSMPING_ANSWER;

	if (SendTo(s, msg.buffer, msg.len, msg.to, msg.from) < 0)
		return;

	address mcastDest(msg.from.family() == AF_INET6 ?
			SSMPingV6Addr : SSMPingV4Addr);
	mcastDest.set_port(msg.from.port());

	SendTo(s, msg.buffer, msg.len, msg.to, mcastDest);
}

int SetupSSMPing() {
	address addr(beaconUnicastAddr.family());

	if (!addr.set_port(4321))
		return -1;

	ssmPingSocket = SetupSocket(addr, true, false);
	if (ssmPingSocket < 0)
		return -1;

	if (!SetHops(ssmPingSocket, addr, 64)) {
		close(ssmPingSocket);
		return -1;
	}

	if (!RequireToAddress(ssmPingSocket, addr)) {
		close(ssmPingSocket);
		return -1;
	}

	assert(SSMPingV4Addr.set_addr(SSMPingV4ResponseChannel));
	assert(SSMPingV6Addr.set_addr(SSMPingV6ResponseChannel));

	ListenTo(ssmPingSocket, handle_ssmping);

	return 0;
}