IPv6 load-balancing
[l2tpns.git] / autosnoop.c
1 #include <string.h>
2 #include <linux/rtnetlink.h>
3 #include <netinet/ip6.h>
4 #include "dhcp6.h"
5
6 #include "l2tpns.h"
7 #include "plugin.h"
8
9 /* set up intercept based on RADIUS reply */
10
11 int plugin_api_version = PLUGIN_API_VERSION;
12 static struct pluginfuncs *f = 0;
13
14 int plugin_radius_response(struct param_radius_response *data)
15 {
16 if (!strcmp(data->key, "intercept"))
17 {
18 char *p;
19 data->s->snoop_ip = 0;
20 data->s->snoop_port = 0;
21 if ((p = strchr(data->value, ':')))
22 {
23 *p++ = 0;
24 if (*data->value)
25 data->s->snoop_ip = inet_addr(data->value);
26
27 if (data->s->snoop_ip == INADDR_NONE)
28 data->s->snoop_ip = 0;
29
30 if (*p)
31 data->s->snoop_port = atoi(p);
32
33 f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
34 " Intercepting user to %s:%d\n",
35 f->fmtaddr(data->s->snoop_ip, 0), data->s->snoop_port);
36 }
37 else
38 {
39 f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
40 " Not Intercepting user (reply string should"
41 " be intercept=ip:port)\n");
42 }
43 }
44
45 return PLUGIN_RET_OK;
46 }
47
48 int plugin_radius_reset(struct param_radius_reset *data)
49 {
50 data->s->snoop_ip = 0;
51 data->s->snoop_port = 0;
52 return PLUGIN_RET_OK;
53 }
54
55 int plugin_radius_account(struct param_radius_account *data)
56 {
57 if (data->s->snoop_ip && data->s->snoop_port)
58 {
59 uint8_t *p = *data->packet;
60
61 *p = 26; // vendor-specific
62 *(uint32_t *) (p + 2) = htonl(9); // Cisco
63 p[6] = 1; // Cisco-AVPair
64 p[7] = 2 + sprintf((char *) p + 8, "intercept=%s:%d",
65 f->fmtaddr(data->s->snoop_ip, 0), data->s->snoop_port);
66
67 p[1] = p[7] + 6;
68 *data->packet += p[1];
69 }
70
71 return PLUGIN_RET_OK;
72 }
73
74 int plugin_init(struct pluginfuncs *funcs)
75 {
76 return ((f = funcs)) ? 1 : 0;
77 }