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