fb39f5f7db0dec35182c43092a67dc5ab39518ed
[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 char const *cvs_id = "$Id: snoopctl.c,v 1.2 2004-11-18 05:44:36 bodea Exp $";
9
10 int plugin_api_version = PLUGIN_API_VERSION;
11 static struct pluginfuncs *p = 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 static int iam_master = 0;
20
21 int plugin_init(struct pluginfuncs *funcs)
22 {
23 if (!funcs)
24 return 0;
25
26 p = funcs;
27 return 1;
28 }
29
30 int plugin_become_master(void)
31 {
32 iam_master = 1;
33 return PLUGIN_RET_OK;
34 }
35
36 int plugin_control(struct param_control *data)
37 {
38 sessionidt session;
39 sessiont *s = 0;
40 int flag;
41 char *end;
42
43 if (data->argc < 1)
44 return PLUGIN_RET_OK;
45
46 if (strcmp(data->argv[0], "snoop") && strcmp(data->argv[0], "unsnoop"))
47 return PLUGIN_RET_OK; // not for us
48
49 flag = data->argv[0][0] != 'u';
50
51 if (!iam_master)
52 {
53 data->response = NSCTL_RES_ERR;
54 data->additional = "must be run on the cluster master";
55 return PLUGIN_RET_STOP;
56 }
57
58 if (flag)
59 {
60 if (data->argc != 4)
61 {
62 data->response = NSCTL_RES_ERR;
63 data->additional = "requires username or session id and host, port";
64 return PLUGIN_RET_STOP;
65 }
66 }
67 else
68 {
69 if (data->argc != 2)
70 {
71 data->response = NSCTL_RES_ERR;
72 data->additional = "requires username or session id";
73 return PLUGIN_RET_STOP;
74 }
75 }
76
77 if (!(session = strtol(data->argv[1], &end, 10)) || *end)
78 session = p->get_session_by_username(data->argv[1]);
79
80 if (session)
81 s = p->get_session_by_id(session);
82
83 if (!s || !s->ip)
84 {
85 data->response = NSCTL_RES_ERR;
86 data->additional = "session not found";
87 return PLUGIN_RET_STOP;
88 }
89
90 if (flag)
91 {
92 ipt ip = inet_addr(data->argv[2]);
93 u16 port = atoi(data->argv[3]);
94
95 if (!ip || ip == INADDR_NONE)
96 {
97 data->response = NSCTL_RES_ERR;
98 data->additional = "invalid ip address";
99 return PLUGIN_RET_STOP;
100 }
101
102 if (!port)
103 {
104 data->response = NSCTL_RES_ERR;
105 data->additional = "invalid port";
106 return PLUGIN_RET_STOP;
107 }
108
109 if (ip == s->snoop_ip && port == s->snoop_port)
110 {
111 data->response = NSCTL_RES_ERR;
112 data->additional = "already intercepted";
113 return PLUGIN_RET_STOP;
114 }
115
116 s->snoop_ip = ip;
117 s->snoop_port = port;
118 }
119 else
120 {
121 if (!s->snoop_ip)
122 {
123 data->response = NSCTL_RES_ERR;
124 data->additional = "not intercepted";
125 return PLUGIN_RET_STOP;
126 }
127
128 s->snoop_ip = 0;
129 s->snoop_port = 0;
130 }
131
132 p->session_changed(session);
133
134 data->response = NSCTL_RES_OK;
135 data->additional = 0;
136
137 return PLUGIN_RET_STOP;
138 }