blob: 6ca22373ee4ff69e2e5e830c63897bb6bce5f5ed [file] [log] [blame]
Holger Hans Peter Freyther6a97b8d2010-06-15 18:45:26 +08001/*
2 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
Holger Hans Peter Freytherdf6143a2010-06-15 18:46:56 +08003 * (C) 2010 by On-Waves
Holger Hans Peter Freyther6a97b8d2010-06-15 18:45:26 +08004 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 */
21
22#ifndef BSC_NAT_H
23#define BSC_NAT_H
24
Holger Hans Peter Freytherf7d33352010-06-15 18:50:26 +080025#include "mgcp.h"
26
Holger Hans Peter Freyther6a97b8d2010-06-15 18:45:26 +080027#include <sys/types.h>
Holger Hans Peter Freyther9f8f3d02010-02-07 13:08:09 +010028
Holger Hans Peter Freyther6c45f2e2010-06-15 19:06:18 +080029#include <osmocore/select.h>
30#include <osmocore/msgb.h>
31#include <osmocore/timer.h>
Holger Hans Peter Freythered07a3f2010-06-15 18:47:10 +080032#include <osmocore/write_queue.h>
Holger Hans Peter Freytherb2c38eb2010-06-17 18:16:00 +080033#include <osmocore/rate_ctr.h>
Holger Hans Peter Freytherd4702862010-04-12 12:17:09 +020034#include <osmocore/statistics.h>
Holger Hans Peter Freyther6a97b8d2010-06-15 18:45:26 +080035
Holger Hans Peter Freytherc16cf272010-04-13 09:24:37 +020036#include <regex.h>
37
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +010038#define DIR_BSC 1
39#define DIR_MSC 2
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080040
Holger Hans Peter Freytherd131b792010-03-31 07:30:58 +020041#define NAT_IPAC_PROTO_MGCP 0xfc
Holger Hans Peter Freytherf7d33352010-06-15 18:50:26 +080042
Holger Hans Peter Freytherc2b31ed2010-07-31 05:17:17 +080043struct sccp_connections;
44struct bsc_nat_parsed;
Holger Hans Peter Freytheraa698242010-06-15 18:46:19 +080045struct bsc_nat;
46
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +080047enum {
48 NAT_CON_TYPE_NONE,
49 NAT_CON_TYPE_LU,
50 NAT_CON_TYPE_CM_SERV_REQ,
51 NAT_CON_TYPE_PAG_RESP,
Holger Hans Peter Freytherb71c23b2010-05-16 20:43:52 +080052 NAT_CON_TYPE_LOCAL_REJECT,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +080053 NAT_CON_TYPE_OTHER,
54};
55
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080056/*
Holger Hans Peter Freyther9f8f3d02010-02-07 13:08:09 +010057 * Per BSC data structure
58 */
59struct bsc_connection {
60 struct llist_head list_entry;
61
62 /* do we know anything about this BSC? */
63 int authenticated;
64
65 /* the fd we use to communicate */
Holger Hans Peter Freythered07a3f2010-06-15 18:47:10 +080066 struct write_queue write_queue;
Holger Hans Peter Freyther9a85ef32010-06-15 18:46:11 +080067
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +020068 /* the BSS associated */
69 struct bsc_config *cfg;
Holger Hans Peter Freyther9a85ef32010-06-15 18:46:11 +080070
71 /* a timeout node */
72 struct timer_list id_timeout;
Holger Hans Peter Freytheraa698242010-06-15 18:46:19 +080073
Holger Hans Peter Freyther906c15e2010-05-02 19:28:59 +080074 /* pong timeout */
75 struct timer_list ping_timeout;
76 struct timer_list pong_timeout;
77
Holger Hans Peter Freytheraa698242010-06-15 18:46:19 +080078 /* a back pointer */
79 struct bsc_nat *nat;
Holger Hans Peter Freyther9f8f3d02010-02-07 13:08:09 +010080};
81
Holger Hans Peter Freyther9a85ef32010-06-15 18:46:11 +080082/**
Holger Hans Peter Freytherd4702862010-04-12 12:17:09 +020083 * Stats per BSC
84 */
85struct bsc_config_stats {
Holger Hans Peter Freytherb2c38eb2010-06-17 18:16:00 +080086 struct rate_ctr_group *ctrg;
87};
Holger Hans Peter Freytherd4702862010-04-12 12:17:09 +020088
Holger Hans Peter Freytherb2c38eb2010-06-17 18:16:00 +080089enum bsc_cfg_ctr {
90 BCFG_CTR_SCCP_CONN,
91 BCFG_CTR_SCCP_CALLS,
92 BCFG_CTR_NET_RECONN,
Holger Hans Peter Freyther8330c1c2010-06-17 18:29:42 +080093 BCFG_CTR_DROPPED_SCCP,
94 BCFG_CTR_DROPPED_CALLS,
Holger Hans Peter Freytherd4702862010-04-12 12:17:09 +020095};
96
97/**
Holger Hans Peter Freyther9a85ef32010-06-15 18:46:11 +080098 * One BSC entry in the config
99 */
100struct bsc_config {
101 struct llist_head entry;
102
103 char *token;
104 unsigned int lac;
105 int nr;
106
Holger Hans Peter Freytherb6061012010-05-14 22:06:28 +0800107 char *description;
108
Holger Hans Peter Freytherc16cf272010-04-13 09:24:37 +0200109 /* imsi white and blacklist */
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800110 char *acc_lst_name;
Holger Hans Peter Freytherc16cf272010-04-13 09:24:37 +0200111
Holger Hans Peter Freyther62e58432010-04-21 19:05:14 +0800112 int forbid_paging;
113
Holger Hans Peter Freytherc16cf272010-04-13 09:24:37 +0200114 /* backpointer */
Holger Hans Peter Freyther9a85ef32010-06-15 18:46:11 +0800115 struct bsc_nat *nat;
Holger Hans Peter Freytherd4702862010-04-12 12:17:09 +0200116
117 struct bsc_config_stats stats;
Holger Hans Peter Freyther9a85ef32010-06-15 18:46:11 +0800118};
119
120/**
Holger Hans Peter Freythera0df82d2010-04-01 08:21:33 +0200121 * BSCs point of view of endpoints
122 */
123struct bsc_endpoint {
124 /* the pending transaction id */
125 char *transaction_id;
126 /* the bsc we are talking to */
127 struct bsc_connection *bsc;
128};
129
130/**
Holger Hans Peter Freytherd4702862010-04-12 12:17:09 +0200131 * Statistic for the nat.
132 */
133struct bsc_nat_statistics {
134 struct {
135 struct counter *conn;
136 struct counter *calls;
137 } sccp;
138
139 struct {
140 struct counter *reconn;
141 struct counter *auth_fail;
142 } bsc;
143
144 struct {
145 struct counter *reconn;
146 } msc;
147};
148
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800149struct bsc_nat_acc_lst {
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800150 struct llist_head list;
151
152 /* the name of the list */
153 const char *name;
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800154 struct llist_head fltr_list;
155};
156
157struct bsc_nat_acc_lst_entry {
158 struct llist_head list;
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800159
160 /* the filter */
161 char *imsi_allow;
162 regex_t imsi_allow_re;
163 char *imsi_deny;
164 regex_t imsi_deny_re;
165};
166
Holger Hans Peter Freytherd4702862010-04-12 12:17:09 +0200167/**
Holger Hans Peter Freyther9a85ef32010-06-15 18:46:11 +0800168 * the structure of the "nat" network
169 */
170struct bsc_nat {
171 /* active SCCP connections that need patching */
172 struct llist_head sccp_connections;
173
174 /* active BSC connections that need patching */
175 struct llist_head bsc_connections;
176
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800177 /* access lists */
178 struct llist_head access_lists;
179
Holger Hans Peter Freyther9a85ef32010-06-15 18:46:11 +0800180 /* known BSC's */
181 struct llist_head bsc_configs;
182 int num_bsc;
Holger Hans Peter Freyther6b771072010-07-27 19:21:53 +0800183 int bsc_ip_dscp;
Holger Hans Peter Freytherf7d33352010-06-15 18:50:26 +0800184
185 /* MGCP config */
186 struct mgcp_config *mgcp_cfg;
Holger Hans Peter Freythera7f80182010-03-31 13:02:22 +0200187 struct write_queue mgcp_queue;
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800188 uint8_t mgcp_msg[4096];
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200189 int mgcp_length;
Holger Hans Peter Freythera0df82d2010-04-01 08:21:33 +0200190
Holger Hans Peter Freytherb7527612010-04-07 11:20:36 +0200191 /* msc things */
Holger Hans Peter Freythera88742c2010-06-15 18:51:04 +0800192 char *msc_ip;
Holger Hans Peter Freyther81395532010-04-17 07:48:45 +0200193 int msc_port;
Holger Hans Peter Freytheraad82ce2010-05-11 19:07:39 +0800194 struct bsc_msc_connection *msc_con;
Holger Hans Peter Freythere635dab2010-05-15 00:14:58 +0800195 char *token;
Holger Hans Peter Freytherb7527612010-04-07 11:20:36 +0200196
Holger Hans Peter Freytherda35a8d2010-05-05 16:57:38 +0800197 /* timeouts */
198 int auth_timeout;
199 int ping_timeout;
200 int pong_timeout;
201
Holger Hans Peter Freythera0df82d2010-04-01 08:21:33 +0200202 struct bsc_endpoint *bsc_endpoints;
Holger Hans Peter Freytherd4702862010-04-12 12:17:09 +0200203
Holger Hans Peter Freytherc16cf272010-04-13 09:24:37 +0200204 /* filter */
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800205 char *acc_lst_name;
Holger Hans Peter Freytherc16cf272010-04-13 09:24:37 +0200206
Holger Hans Peter Freytherd4702862010-04-12 12:17:09 +0200207 /* statistics */
208 struct bsc_nat_statistics stats;
Holger Hans Peter Freyther9a85ef32010-06-15 18:46:11 +0800209};
210
211/* create and init the structures */
212struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token, unsigned int lac);
213struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num);
Holger Hans Peter Freytherdcf8a7d2010-06-15 18:48:01 +0800214struct bsc_nat *bsc_nat_alloc(void);
215struct bsc_connection *bsc_connection_alloc(struct bsc_nat *nat);
Holger Hans Peter Freythera88742c2010-06-15 18:51:04 +0800216void bsc_nat_set_msc_ip(struct bsc_nat *bsc, const char *ip);
Holger Hans Peter Freyther9a85ef32010-06-15 18:46:11 +0800217
Holger Hans Peter Freyther23fe7be2010-03-30 10:45:48 +0200218void sccp_connection_destroy(struct sccp_connections *);
Holger Hans Peter Freyther2f9dcf02010-04-27 13:21:39 +0800219void bsc_close_connection(struct bsc_connection *);
Holger Hans Peter Freyther9f8f3d02010-02-07 13:08:09 +0100220
Holger Hans Peter Freyther234d3122010-05-16 02:06:11 +0800221const char *bsc_con_type_to_string(int type);
222
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800223/**
224 * parse the given message into the above structure
225 */
226struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg);
227
Holger Hans Peter Freyther6a97b8d2010-06-15 18:45:26 +0800228/**
229 * filter based on IP Access header in both directions
230 */
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100231int bsc_nat_filter_ipa(int direction, struct msgb *msg, struct bsc_nat_parsed *parsed);
Holger Hans Peter Freyther9a85ef32010-06-15 18:46:11 +0800232int bsc_nat_vty_init(struct bsc_nat *nat);
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200233struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg, int *_lac);
Holger Hans Peter Freyther6a97b8d2010-06-15 18:45:26 +0800234
Holger Hans Peter Freyther0ab6bab2010-06-15 18:47:49 +0800235/**
Holger Hans Peter Freytherb4af5c92010-05-14 03:39:56 +0800236 * Content filtering.
237 */
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800238int bsc_nat_filter_sccp_cr(struct bsc_connection *bsc, struct msgb *msg,
239 struct bsc_nat_parsed *, int *con_type);
Holger Hans Peter Freytherb4af5c92010-05-14 03:39:56 +0800240
241/**
Holger Hans Peter Freyther0ab6bab2010-06-15 18:47:49 +0800242 * SCCP patching and handling
243 */
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800244struct sccp_connections *create_sccp_src_ref(struct bsc_connection *bsc, struct bsc_nat_parsed *parsed);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800245int update_sccp_src_ref(struct sccp_connections *sccp, struct bsc_nat_parsed *parsed);
Holger Hans Peter Freyther0ab6bab2010-06-15 18:47:49 +0800246void remove_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800247struct sccp_connections *patch_sccp_src_ref_to_bsc(struct msgb *, struct bsc_nat_parsed *, struct bsc_nat *);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800248struct sccp_connections *patch_sccp_src_ref_to_msc(struct msgb *, struct bsc_nat_parsed *, struct bsc_connection *);
Holger Hans Peter Freyther0ab6bab2010-06-15 18:47:49 +0800249
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800250/**
251 * MGCP/Audio handling
252 */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800253int bsc_write_mgcp(struct bsc_connection *bsc, const uint8_t *data, unsigned int length);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800254int bsc_mgcp_assign(struct sccp_connections *, struct msgb *msg);
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800255void bsc_mgcp_init(struct sccp_connections *);
256void bsc_mgcp_dlcx(struct sccp_connections *);
Holger Hans Peter Freyther241e1302010-03-31 09:16:56 +0200257void bsc_mgcp_free_endpoints(struct bsc_nat *nat);
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800258int bsc_mgcp_nat_init(struct bsc_nat *nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800259
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800260struct sccp_connections *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200261struct msgb *bsc_mgcp_rewrite(char *input, int length, const char *ip, int port);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200262void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg);
263
Holger Hans Peter Freyther26a43892010-04-05 23:09:27 +0200264void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200265int bsc_mgcp_parse_response(const char *str, int *code, char transaction[60]);
Holger Hans Peter Freyther46340132010-08-06 08:26:54 +0800266uint32_t bsc_mgcp_extract_ci(const char *resp);
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200267
Holger Hans Peter Freyther2896df72010-04-08 10:24:57 +0200268
269int bsc_write(struct bsc_connection *bsc, struct msgb *msg, int id);
270
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800271/* IMSI allow/deny handling */
Holger Hans Peter Freyther12dc89a2010-05-14 18:38:29 +0800272void bsc_parse_reg(void *ctx, regex_t *reg, char **imsi, int argc, const char **argv);
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800273struct bsc_nat_acc_lst *bsc_nat_acc_lst_find(struct bsc_nat *nat, const char *name);
274struct bsc_nat_acc_lst *bsc_nat_acc_lst_get(struct bsc_nat *nat, const char *name);
275void bsc_nat_acc_lst_delete(struct bsc_nat_acc_lst *lst);
Holger Hans Peter Freyther12dc89a2010-05-14 18:38:29 +0800276
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800277struct bsc_nat_acc_lst_entry *bsc_nat_acc_lst_entry_create(struct bsc_nat_acc_lst *);
278
Holger Hans Peter Freyther20ee3122010-07-05 14:39:44 +0800279int bsc_nat_msc_is_connected(struct bsc_nat *nat);
280
Holger Hans Peter Freyther6a97b8d2010-06-15 18:45:26 +0800281#endif