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