Update changelog
[l2tpns.git] / snoopctl.c
1 #include <string.h>
2 #include <linux/rtnetlink.h>
3 #include <netinet/ip6.h>
4
5 #include "dhcp6.h"
6 #include "l2tpns.h"
7 #include "plugin.h"
8 #include "control.h"
9
10 /* snoop control */
11
12 int plugin_api_version = PLUGIN_API_VERSION;
13 static struct pluginfuncs *f = 0;
14
15 char *plugin_control_help[] = {
16 " snoop USER|SID IP PORT Intercept user traffic",
17 " unsnoop USER|SID Stop intercepting user",
18 0
19 };
20
21 int plugin_control(struct param_control *data)
22 {
23 sessionidt session;
24 sessiont *s = 0;
25 int flag;
26 char *end;
27
28 if (data->argc < 1)
29 return PLUGIN_RET_OK;
30
31 if (strcmp(data->argv[0], "snoop") && strcmp(data->argv[0], "unsnoop"))
32 return PLUGIN_RET_OK; // not for us
33
34 if (!data->iam_master)
35 return PLUGIN_RET_NOTMASTER;
36
37 flag = data->argv[0][0] != 'u';
38
39 if (flag)
40 {
41 if (data->argc != 4)
42 {
43 data->response = NSCTL_RES_ERR;
44 data->additional = "requires username or session id and host, port";
45 return PLUGIN_RET_STOP;
46 }
47 }
48 else
49 {
50 if (data->argc != 2)
51 {
52 data->response = NSCTL_RES_ERR;
53 data->additional = "requires username or session id";
54 return PLUGIN_RET_STOP;
55 }
56 }
57
58 if (!(session = strtol(data->argv[1], &end, 10)) || *end)
59 session = f->get_session_by_username(data->argv[1]);
60
61 if (session)
62 s = f->get_session_by_id(session);
63
64 if (!s || !s->ip)
65 {
66 data->response = NSCTL_RES_ERR;
67 data->additional = "session not found";
68 return PLUGIN_RET_STOP;
69 }
70
71 if (flag)
72 {
73 in_addr_t ip = inet_addr(data->argv[2]);
74 uint16_t port = atoi(data->argv[3]);
75
76 if (!ip || ip == INADDR_NONE)
77 {
78 data->response = NSCTL_RES_ERR;
79 data->additional = "invalid ip address";
80 return PLUGIN_RET_STOP;
81 }
82
83 if (!port)
84 {
85 data->response = NSCTL_RES_ERR;
86 data->additional = "invalid port";
87 return PLUGIN_RET_STOP;
88 }
89
90 if (ip == s->snoop_ip && port == s->snoop_port)
91 {
92 data->response = NSCTL_RES_ERR;
93 data->additional = "already intercepted";
94 return PLUGIN_RET_STOP;
95 }
96
97 s->snoop_ip = ip;
98 s->snoop_port = port;
99 }
100 else
101 {
102 if (!s->snoop_ip)
103 {
104 data->response = NSCTL_RES_ERR;
105 data->additional = "not intercepted";
106 return PLUGIN_RET_STOP;
107 }
108
109 s->snoop_ip = 0;
110 s->snoop_port = 0;
111 }
112
113 f->session_changed(session);
114
115 data->response = NSCTL_RES_OK;
116 data->additional = 0;
117
118 return PLUGIN_RET_STOP;
119 }
120
121 int plugin_init(struct pluginfuncs *funcs)
122 {
123 return ((f = funcs)) ? 1 : 0;
124 }