Branch data Line data Source code
1 : : #include <sys/socket.h>
2 : : #include <arpa/inet.h>
3 : : #include <unistd.h>
4 : : #include <string.h>
5 : : #include <wait.h>
6 : : #include <stdlib.h>
7 : :
8 : : #include "types.h"
9 : : #include "util.h"
10 : : #include "list.h"
11 : : #include "files.h"
12 : : #include "netfilter.h"
13 : : #include "sockets.h"
14 : : #include "sk-inet.h"
15 : :
16 : : static char buf[512];
17 : :
18 : : /*
19 : : * Need to configure simple netfilter rules for blocking connections
20 : : * ANy brave soul to write it using xtables-devel?
21 : : */
22 : :
23 : : static const char *nf_conn_cmd = "%s -t filter %s INPUT --protocol tcp "
24 : : "--source %s --sport %d --destination %s --dport %d -j DROP";
25 : :
26 : : static char iptable_cmd_ipv4[] = "iptables";
27 : : static char iptable_cmd_ipv6[] = "ip6tables";
28 : :
29 : 16 : static int nf_connection_switch_raw(int family, u32 *src_addr, u16 src_port, u32 *dst_addr, u16 dst_port, int lock)
30 : : {
31 : : char sip[INET_ADDR_LEN], dip[INET_ADDR_LEN];
32 : : char *cmd;
33 : : int ret;
34 : :
35 [ + - + ]: 16 : switch (family) {
36 : : case AF_INET:
37 : : cmd = iptable_cmd_ipv4;
38 : : break;
39 : : case AF_INET6:
40 : 8 : cmd = iptable_cmd_ipv6;
41 : 8 : break;
42 : : default:
43 : 0 : pr_err("Unknown socket family %d\n", family);
44 : : return -1;
45 : : };
46 : :
47 [ + - - + ]: 32 : if (!inet_ntop(family, (void *)src_addr, sip, INET_ADDR_LEN) ||
48 : 16 : !inet_ntop(family, (void *)dst_addr, dip, INET_ADDR_LEN)) {
49 : 0 : pr_perror("nf: Can't translate ip addr\n");
50 : : return -1;
51 : : }
52 : :
53 [ + + ]: 16 : snprintf(buf, sizeof(buf), nf_conn_cmd, cmd, lock ? "-A" : "-D",
54 : : dip, (int)dst_port, sip, (int)src_port);
55 : :
56 : 16 : pr_debug("\tRunning iptables [%s]\n", buf);
57 : 16 : ret = system(buf);
58 [ + - ][ - + ]: 16 : if (ret < 0 || !WIFEXITED(ret) || WEXITSTATUS(ret)) {
[ + - ]
59 : 0 : pr_perror("Iptables configuration failed");
60 : : return -1;
61 : : }
62 : :
63 [ + + ]: 16 : pr_info("%s %s:%d - %s:%d connection\n", lock ? "Locked" : "Unlocked",
64 : : sip, (int)src_port, dip, (int)dst_port);
65 : : return 0;
66 : : }
67 : :
68 : 8 : static int nf_connection_switch(struct inet_sk_desc *sk, int lock)
69 : : {
70 : 8 : return nf_connection_switch_raw(sk->sd.family,
71 : 16 : sk->src_addr, sk->src_port,
72 : 16 : sk->dst_addr, sk->dst_port, lock);
73 : : }
74 : :
75 : 8 : int nf_lock_connection(struct inet_sk_desc *sk)
76 : : {
77 : 8 : return nf_connection_switch(sk, 1);
78 : : }
79 : :
80 : 0 : int nf_unlock_connection(struct inet_sk_desc *sk)
81 : : {
82 : 0 : return nf_connection_switch(sk, 0);
83 : : }
84 : :
85 : 8 : int nf_unlock_connection_info(struct inet_sk_info *si)
86 : : {
87 : 8 : return nf_connection_switch_raw(si->ie->family,
88 : 16 : si->ie->src_addr, si->ie->src_port,
89 : 16 : si->ie->dst_addr, si->ie->dst_port, 0);
90 : 32 : }
|