aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2018-01-25 20:50:59 +0100
committerHarald Welte <laforge@gnumonks.org>2018-01-26 18:20:22 +0000
commit5b1ef9589ccb2507af06f6a65c341fe0f7564ab4 (patch)
tree719ccb3c911e37979962ddd184972615efbf8d00
parent7d54ed48e78e9666217865f4586c26c6ec896fe6 (diff)
ggsn: Validate packet src addr from MS
-rw-r--r--ggsn/ggsn.c19
-rw-r--r--gtp/gtp.c1
2 files changed, 19 insertions, 1 deletions
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c
index 7954d5e..6645d4c 100644
--- a/ggsn/ggsn.c
+++ b/ggsn/ggsn.c
@@ -736,7 +736,9 @@ static int encaps_tun(struct pdp_t *pdp, void *pack, unsigned len)
struct ip6_hdr *ip6h = (struct ip6_hdr *)pack;
struct tun_t *tun = (struct tun_t *)pdp->ipif;
struct apn_ctx *apn = tun->priv;
+ char straddr[INET6_ADDRSTRLEN];
struct ippoolm_t *peer;
+ uint8_t pref_offset;
OSMO_ASSERT(tun);
OSMO_ASSERT(apn);
@@ -752,6 +754,16 @@ static int encaps_tun(struct pdp_t *pdp, void *pack, unsigned len)
return -1;
}
+ /* Validate packet comes from IPaddr assigned to the pdp ctx.
+ If packet is a LL addr, then EUA is in the lower 64 bits,
+ otherwise it's used as the 64 prefix */
+ pref_offset = IN6_IS_ADDR_LINKLOCAL(&ip6h->ip6_src) ? 8 : 0;
+ if (memcmp(((uint8_t*)&ip6h->ip6_src) + pref_offset, &peer->addr.v6, 8)) {
+ LOGPPDP(LOGL_ERROR, pdp, "Packet from MS using unassigned src IPv6: %s\n",
+ inet_ntop(AF_INET6, &ip6h->ip6_src, straddr, sizeof(straddr)));
+ return -1;
+ }
+
/* daddr: all-routers multicast addr */
if (IN6_ARE_ADDR_EQUAL(&ip6h->ip6_dst, &all_router_mcast_addr))
return handle_router_mcast(pdp->gsn, pdp, &peer->addr.v6,
@@ -764,6 +776,13 @@ static int encaps_tun(struct pdp_t *pdp, void *pack, unsigned len)
osmo_hexdump(pack, len));
return -1;
}
+
+ /* Validate packet comes from IPaddr assigned to the pdp ctx */
+ if (memcmp(&iph->saddr, &peer->addr.v4, sizeof(peer->addr.v4))) {
+ LOGPPDP(LOGL_ERROR, pdp, "Packet from MS using unassigned src IPv4: %s\n",
+ inet_ntop(AF_INET, &iph->saddr, straddr, sizeof(straddr)));
+ return -1;
+ }
break;
default:
LOGPPDP(LOGL_ERROR, pdp, "Packet from MS is neither IPv4 nor IPv6: %s\n",
diff --git a/gtp/gtp.c b/gtp/gtp.c
index 2abc32e..42e84a7 100644
--- a/gtp/gtp.c
+++ b/gtp/gtp.c
@@ -2698,7 +2698,6 @@ static int gtp_gpdu_ind(struct gsn_t *gsn, uint8_t version,
int hlen;
- /* Need to include code to verify packet src and dest addresses */
struct pdp_t *pdp;
switch (version) {