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