-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathigmp-keep-alive-server.c
157 lines (133 loc) · 4.28 KB
/
igmp-keep-alive-server.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/* [isd] igmp-keep-alive-server v0.1
* =================================
* Idea spawned by Kim Daniel @BF-SD7
* Code by [email protected] - ievil/isd
*/
#include <getopt.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <syslog.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include <netdb.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <termios.h>
#include <sys/poll.h>
#include <syslog.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/ether.h>
#include <linux/if_packet.h>
char arg_interface[128];
void usage(char * binname) {
printf("Usage: %s [-i interface]\n", binname);
printf(" Default interface: lo\n");
exit(1);
}
int main (int argc, char *argv[])
{
time_t now, current, last;
int fork_pid, real_pid, i, status;
int sockfd, sockmc, mcast_dport, payload_len;
struct sockaddr_in mcast_dst;
struct sockaddr_in mcast_srv;
struct ip_mreq mcast_req;
char *mcast_ip;
unsigned char mcast_ttl;
char *payload;
//, done, upd_error;
now = time(NULL);
real_pid = getpid();
strcpy(arg_interface, "eth0");
mcast_ip = "239.0.0.1";
mcast_dport = 1911;
mcast_ttl = 1;
payload = "Keep-Alive";
payload_len = strlen(payload);
openlog("igmp-keep-alive-server",LOG_PID, LOG_LOCAL5);
syslog(LOG_NOTICE,"System starting up... initing... time: %li pid: %d!", now, real_pid);
for (i=1;i<argc-1;++i) {
if (!strcmp(argv[i], "-i")) {
++i;
strncpy(arg_interface, argv[i], sizeof(arg_interface));
} else {
usage(argv[0]);
}
}
fork_pid=fork();
if (fork_pid<0) {
printf("Error sending process to background.");
syslog(LOG_CRIT, "System not forked successfully ... bailing.. system panic!");
exit(1);
}
if (fork_pid) { exit(0); }
close(0); close(1); close (2);
// done = 1;
// upd_error = 0;
last = 0;
if ((sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
syslog(LOG_CRIT, "Unable to open socket fd ... bailing.. system panic!");
exit(1);
}
if ((sockmc = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) == -1) {
syslog(LOG_CRIT, "Unable to open socket fd ... bailing.. system panic!");
exit(1);
}
memset(&mcast_dst, 0, sizeof(mcast_dst));
memset(&mcast_req, 0, sizeof(struct ip_mreq));
mcast_dst.sin_family = AF_INET;
mcast_dst.sin_addr.s_addr = inet_addr(mcast_ip);
mcast_dst.sin_port = htons(mcast_dport);
mcast_srv.sin_family = PF_INET;
mcast_srv.sin_port = htons(mcast_dport);
mcast_srv.sin_addr.s_addr = htonl(INADDR_ANY);
status = bind(sockmc, (struct sockaddr *)&mcast_srv, sizeof(struct sockaddr_in));
if ( status < 0 ) {
syslog(LOG_CRIT, "Unable to bind mcast server ... bailing.. system panic!");
exit(1);
}
mcast_req.imr_multiaddr.s_addr = inet_addr("239.0.0.1");
mcast_req.imr_interface.s_addr = INADDR_ANY;
status = setsockopt(sockmc, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mcast_req, sizeof(struct ip_mreq));
if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, (void *) &mcast_ttl, sizeof(mcast_ttl)) < 0) {
syslog(LOG_CRIT, "Unable to set socket options ... bailing.. system panic!");
exit(1);
}
syslog(LOG_NOTICE, "System forked successfully, starting igmp keep alive server on %s.", arg_interface);
do {
current = time(NULL);
if ( last+120 < current ) {
syslog(LOG_NOTICE, "Sending IGMP Join for %s.", mcast_ip);
status = setsockopt(sockmc, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mcast_req, sizeof(struct ip_mreq));
// if ( status < 0 )
// syslog(LOG_CRIT, "Failed to send IGMP Join ... bailing.. system panic!");
syslog(LOG_NOTICE, "Sending IGMP Keep Alive to %s.", mcast_ip);
last = time(NULL);
if (sendto(sockfd, payload, payload_len, 0, (struct sockaddr *) &mcast_dst, sizeof(mcast_dst)) != payload_len) {
syslog(LOG_CRIT, "Failed to send ... bailing.. system panic!");
exit(1);
}
sleep(120);
}
} while(1);
shutdown(sockmc, 2);
close(sockmc);
exit(0);
return 0; /* Keep some compilers happy */
}