diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-01-05 17:45:25 +0100 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-01-05 17:45:28 +0100 |
commit | ffd6e37eb537d93ce0e60793c14c149cfc76214e (patch) | |
tree | af7b7149b038fce8919278816310056882a81a65 | |
parent | 44bde6b85a0ceb4041ca7fd91d47614a446fbb91 (diff) |
Move struct apn_ctx and APN related definitions to its own file
This allows further shrinking of gprs_sgsn.{c,h} and also being able to
use GSM_APN_LENGTH on different headers easily (needed by follow-up
patch).
Change-Id: Id225ed8b84e1376f4a30f17dd4b153b6b1a6efa8
-rw-r--r-- | include/osmocom/sgsn/Makefile.am | 1 | ||||
-rw-r--r-- | include/osmocom/sgsn/apn.h | 22 | ||||
-rw-r--r-- | include/osmocom/sgsn/gprs_sgsn.h | 16 | ||||
-rw-r--r-- | include/osmocom/sgsn/gprs_subscriber.h | 2 | ||||
-rw-r--r-- | src/sgsn/Makefile.am | 1 | ||||
-rw-r--r-- | src/sgsn/apn.c | 126 | ||||
-rw-r--r-- | src/sgsn/gprs_sgsn.c | 98 | ||||
-rw-r--r-- | tests/sgsn/Makefile.am | 1 |
8 files changed, 154 insertions, 113 deletions
diff --git a/include/osmocom/sgsn/Makefile.am b/include/osmocom/sgsn/Makefile.am index fc4f5978c..4d43c6dde 100644 --- a/include/osmocom/sgsn/Makefile.am +++ b/include/osmocom/sgsn/Makefile.am @@ -1,4 +1,5 @@ noinst_HEADERS = \ + apn.h \ common.h \ crc24.h \ debug.h \ diff --git a/include/osmocom/sgsn/apn.h b/include/osmocom/sgsn/apn.h new file mode 100644 index 000000000..adf62e21f --- /dev/null +++ b/include/osmocom/sgsn/apn.h @@ -0,0 +1,22 @@ +#pragma once + +#include <osmocom/core/linuxlist.h> + +struct sgsn_ggsn_ctx; + +#define GSM_APN_LENGTH 102 + +extern struct llist_head sgsn_apn_ctxts; + +struct apn_ctx { + struct llist_head list; + struct sgsn_ggsn_ctx *ggsn; + char *name; + char *imsi_prefix; + char *description; +}; + +struct apn_ctx *sgsn_apn_ctx_find_alloc(const char *name, const char *imsi_prefix); +void sgsn_apn_ctx_free(struct apn_ctx *actx); +struct apn_ctx *sgsn_apn_ctx_by_name(const char *name, const char *imsi_prefix); +struct apn_ctx *sgsn_apn_ctx_match(const char *name, const char *imsi_prefix); diff --git a/include/osmocom/sgsn/gprs_sgsn.h b/include/osmocom/sgsn/gprs_sgsn.h index 541d854ae..6d51b303e 100644 --- a/include/osmocom/sgsn/gprs_sgsn.h +++ b/include/osmocom/sgsn/gprs_sgsn.h @@ -14,10 +14,10 @@ #include <osmocom/gsm/protocol/gsm_23_003.h> #include <osmocom/crypt/auth.h> +#include <osmocom/sgsn/apn.h> #include <osmocom/sgsn/gprs_subscriber.h> #define GSM_EXTENSION_LENGTH 15 -#define GSM_APN_LENGTH 102 struct gprs_llc_lle; struct ctrl_handle; @@ -362,21 +362,7 @@ struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm, void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp); void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp); -struct apn_ctx { - struct llist_head list; - struct sgsn_ggsn_ctx *ggsn; - char *name; - char *imsi_prefix; - char *description; -}; - -struct apn_ctx *sgsn_apn_ctx_find_alloc(const char *name, const char *imsi_prefix); -void sgsn_apn_ctx_free(struct apn_ctx *actx); -struct apn_ctx *sgsn_apn_ctx_by_name(const char *name, const char *imsi_prefix); -struct apn_ctx *sgsn_apn_ctx_match(const char *name, const char *imsi_prefix); - extern struct llist_head sgsn_mm_ctxts; -extern struct llist_head sgsn_apn_ctxts; extern struct llist_head sgsn_pdp_ctxts; uint32_t sgsn_alloc_ptmsi(void); diff --git a/include/osmocom/sgsn/gprs_subscriber.h b/include/osmocom/sgsn/gprs_subscriber.h index a961c4581..2e53bdf26 100644 --- a/include/osmocom/sgsn/gprs_subscriber.h +++ b/include/osmocom/sgsn/gprs_subscriber.h @@ -6,6 +6,8 @@ #include <osmocom/core/linuxlist.h> #include <osmocom/gsm/protocol/gsm_23_003.h> +#include <osmocom/sgsn/apn.h> + struct sgsn_instance; struct sgsn_mm_ctx; diff --git a/src/sgsn/Makefile.am b/src/sgsn/Makefile.am index 638eaccd6..ba752ad95 100644 --- a/src/sgsn/Makefile.am +++ b/src/sgsn/Makefile.am @@ -40,6 +40,7 @@ bin_PROGRAMS = \ $(NULL) osmo_sgsn_SOURCES = \ + apn.c \ gprs_bssgp.c \ gprs_gmm_attach.c \ gprs_gmm.c \ diff --git a/src/sgsn/apn.c b/src/sgsn/apn.c new file mode 100644 index 000000000..d6d537204 --- /dev/null +++ b/src/sgsn/apn.c @@ -0,0 +1,126 @@ +/* APN contexts */ + +/* (C) 2009-2015 by Harald Welte <laforge@gnumonks.org> + * (C) 2010 by On-Waves + * (C) 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <string.h> +#include <talloc.h> + +#include <osmocom/sgsn/apn.h> + +extern void *tall_sgsn_ctx; + +LLIST_HEAD(sgsn_apn_ctxts); + +static struct apn_ctx *sgsn_apn_ctx_alloc(const char *ap_name, const char *imsi_prefix) +{ + struct apn_ctx *actx; + + actx = talloc_zero(tall_sgsn_ctx, struct apn_ctx); + if (!actx) + return NULL; + actx->name = talloc_strdup(actx, ap_name); + actx->imsi_prefix = talloc_strdup(actx, imsi_prefix); + + llist_add_tail(&actx->list, &sgsn_apn_ctxts); + + return actx; +} + +void sgsn_apn_ctx_free(struct apn_ctx *actx) +{ + llist_del(&actx->list); + talloc_free(actx); +} + +struct apn_ctx *sgsn_apn_ctx_match(const char *name, const char *imsi) +{ + struct apn_ctx *actx; + struct apn_ctx *found_actx = NULL; + size_t imsi_prio = 0; + size_t name_prio = 0; + size_t name_req_len = strlen(name); + + llist_for_each_entry(actx, &sgsn_apn_ctxts, list) { + size_t name_ref_len, imsi_ref_len; + const char *name_ref_start, *name_match_start; + + imsi_ref_len = strlen(actx->imsi_prefix); + if (strncmp(actx->imsi_prefix, imsi, imsi_ref_len) != 0) + continue; + + if (imsi_ref_len < imsi_prio) + continue; + + /* IMSI matches */ + + name_ref_start = &actx->name[0]; + if (name_ref_start[0] == '*') { + /* Suffix match */ + name_ref_start += 1; + name_ref_len = strlen(name_ref_start); + if (name_ref_len > name_req_len) + continue; + } else { + name_ref_len = strlen(name_ref_start); + if (name_ref_len != name_req_len) + continue; + } + + name_match_start = name + (name_req_len - name_ref_len); + if (strcasecmp(name_match_start, name_ref_start) != 0) + continue; + + /* IMSI and name match */ + + if (imsi_ref_len == imsi_prio && name_ref_len < name_prio) + /* Lower priority, skip */ + continue; + + imsi_prio = imsi_ref_len; + name_prio = name_ref_len; + found_actx = actx; + } + return found_actx; +} + +struct apn_ctx *sgsn_apn_ctx_by_name(const char *name, const char *imsi_prefix) +{ + struct apn_ctx *actx; + + llist_for_each_entry(actx, &sgsn_apn_ctxts, list) { + if (strcasecmp(name, actx->name) == 0 && + strcasecmp(imsi_prefix, actx->imsi_prefix) == 0) + return actx; + } + return NULL; +} + +struct apn_ctx *sgsn_apn_ctx_find_alloc(const char *name, const char *imsi_prefix) +{ + struct apn_ctx *actx; + + actx = sgsn_apn_ctx_by_name(name, imsi_prefix); + if (!actx) + actx = sgsn_apn_ctx_alloc(name, imsi_prefix); + + return actx; +} diff --git a/src/sgsn/gprs_sgsn.c b/src/sgsn/gprs_sgsn.c index ea0786282..cdfa02955 100644 --- a/src/sgsn/gprs_sgsn.c +++ b/src/sgsn/gprs_sgsn.c @@ -64,7 +64,6 @@ extern void *tall_sgsn_ctx; extern struct osmo_tdef sgsn_T_defs[]; LLIST_HEAD(sgsn_mm_ctxts); -LLIST_HEAD(sgsn_apn_ctxts); LLIST_HEAD(sgsn_pdp_ctxts); const struct value_string sgsn_ran_type_names[] = { @@ -533,103 +532,6 @@ void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp) talloc_free(pdp); } -/* APN contexts */ - -static struct apn_ctx *sgsn_apn_ctx_alloc(const char *ap_name, const char *imsi_prefix) -{ - struct apn_ctx *actx; - - actx = talloc_zero(tall_sgsn_ctx, struct apn_ctx); - if (!actx) - return NULL; - actx->name = talloc_strdup(actx, ap_name); - actx->imsi_prefix = talloc_strdup(actx, imsi_prefix); - - llist_add_tail(&actx->list, &sgsn_apn_ctxts); - - return actx; -} - -void sgsn_apn_ctx_free(struct apn_ctx *actx) -{ - llist_del(&actx->list); - talloc_free(actx); -} - -struct apn_ctx *sgsn_apn_ctx_match(const char *name, const char *imsi) -{ - struct apn_ctx *actx; - struct apn_ctx *found_actx = NULL; - size_t imsi_prio = 0; - size_t name_prio = 0; - size_t name_req_len = strlen(name); - - llist_for_each_entry(actx, &sgsn_apn_ctxts, list) { - size_t name_ref_len, imsi_ref_len; - const char *name_ref_start, *name_match_start; - - imsi_ref_len = strlen(actx->imsi_prefix); - if (strncmp(actx->imsi_prefix, imsi, imsi_ref_len) != 0) - continue; - - if (imsi_ref_len < imsi_prio) - continue; - - /* IMSI matches */ - - name_ref_start = &actx->name[0]; - if (name_ref_start[0] == '*') { - /* Suffix match */ - name_ref_start += 1; - name_ref_len = strlen(name_ref_start); - if (name_ref_len > name_req_len) - continue; - } else { - name_ref_len = strlen(name_ref_start); - if (name_ref_len != name_req_len) - continue; - } - - name_match_start = name + (name_req_len - name_ref_len); - if (strcasecmp(name_match_start, name_ref_start) != 0) - continue; - - /* IMSI and name match */ - - if (imsi_ref_len == imsi_prio && name_ref_len < name_prio) - /* Lower priority, skip */ - continue; - - imsi_prio = imsi_ref_len; - name_prio = name_ref_len; - found_actx = actx; - } - return found_actx; -} - -struct apn_ctx *sgsn_apn_ctx_by_name(const char *name, const char *imsi_prefix) -{ - struct apn_ctx *actx; - - llist_for_each_entry(actx, &sgsn_apn_ctxts, list) { - if (strcasecmp(name, actx->name) == 0 && - strcasecmp(imsi_prefix, actx->imsi_prefix) == 0) - return actx; - } - return NULL; -} - -struct apn_ctx *sgsn_apn_ctx_find_alloc(const char *name, const char *imsi_prefix) -{ - struct apn_ctx *actx; - - actx = sgsn_apn_ctx_by_name(name, imsi_prefix); - if (!actx) - actx = sgsn_apn_ctx_alloc(name, imsi_prefix); - - return actx; -} - uint32_t sgsn_alloc_ptmsi(void) { struct sgsn_mm_ctx *mm; diff --git a/tests/sgsn/Makefile.am b/tests/sgsn/Makefile.am index 8deec2462..853d8f1b9 100644 --- a/tests/sgsn/Makefile.am +++ b/tests/sgsn/Makefile.am @@ -48,6 +48,7 @@ sgsn_test_LDFLAGS = \ $(NULL) sgsn_test_LDADD = \ + $(top_builddir)/src/sgsn/apn.o \ $(top_builddir)/src/sgsn/gprs_bssgp.o \ $(top_builddir)/src/sgsn/gprs_llc.o \ $(top_builddir)/src/sgsn/gprs_ns.o \ |