diff options
Diffstat (limited to 'ggsn')
-rw-r--r-- | ggsn/ggsn.c | 37 | ||||
-rw-r--r-- | ggsn/gtp-kernel.c | 15 | ||||
-rw-r--r-- | ggsn/gtp-kernel.h | 4 |
3 files changed, 30 insertions, 26 deletions
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c index 168e907..0d0e569 100644 --- a/ggsn/ggsn.c +++ b/ggsn/ggsn.c @@ -56,6 +56,7 @@ #include "../lib/tun.h" #include "../lib/ippool.h" #include "../lib/syserr.h" +#include "../lib/in46_addr.h" #include "../gtp/pdp.h" #include "../gtp/gtp.h" #include "cmdline.h" @@ -65,7 +66,8 @@ int end = 0; int maxfd = 0; /* For select() */ struct in_addr listen_; -struct in_addr netaddr, destaddr, net, mask; /* Network interface */ +struct in_addr netaddr, destaddr, net; /* Network interface */ +size_t prefixlen; struct in_addr dns1, dns2; /* PCO DNS address */ char *ipup, *ipdown; /* Filename of scripts */ int debug; /* Print debug output */ @@ -135,9 +137,12 @@ int daemon(int nochdir, int noclose) static bool send_trap(const struct gsn_t *gsn, const struct pdp_t *pdp, const struct ippoolm_t *member, const char *var) { + char addrbuf[256]; char val[NAMESIZE]; - snprintf(val, sizeof(val), "%" PRIu64 ",%s", pdp->imsi, inet_ntoa(member->addr)); + const char *addrstr = in46a_ntop(&member->addr, addrbuf, sizeof(addrbuf)); + + snprintf(val, sizeof(val), "%" PRIu64 ",%s", pdp->imsi, addrstr); if (ctrl_cmd_send_trap(gsn->ctrl, var, val) < 0) { LOGP(DGGSN, LOGL_ERROR, "Failed to create and send TRAP for IMSI %" PRIu64 " [%s].\n", pdp->imsi, var); @@ -168,7 +173,7 @@ int delete_context(struct pdp_t *pdp) int create_context_ind(struct pdp_t *pdp) { - struct in_addr addr; + struct in46_addr addr; struct ippoolm_t *member; DEBUGP(DGGSN, "Received create PDP context request\n"); @@ -183,8 +188,8 @@ int create_context_ind(struct pdp_t *pdp) memcpy(pdp->qos_neg.v, pdp->qos_req.v, pdp->qos_req.l); /* TODO */ pdp->qos_neg.l = pdp->qos_req.l; - if (pdp_euaton(&pdp->eua, &addr)) { - addr.s_addr = 0; /* Request dynamic */ + if (pdp_euaton(&pdp->eua, &addr.v4)) { + addr.v4.s_addr = 0; /* Request dynamic */ } if (ippool_newip(ippool, &member, &addr, 0)) { @@ -192,7 +197,7 @@ int create_context_ind(struct pdp_t *pdp) return 0; /* Allready in use, or no more available */ } - pdp_ntoeua(&member->addr, &pdp->eua); + pdp_ntoeua(&member->addr.v4, &pdp->eua); pdp->peer = member; pdp->ipif = tun; /* TODO */ member->peer = pdp; @@ -215,10 +220,18 @@ int create_context_ind(struct pdp_t *pdp) int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len) { struct ippoolm_t *ipm; - struct in_addr dst; + struct in46_addr dst; struct tun_packet_t *iph = (struct tun_packet_t *)pack; - dst.s_addr = iph->dst; + if (iph->ver == 4) { + if (len < sizeof(*iph) || len < 4*iph->ihl) + return -1; + dst.len = 4; + dst.v4.s_addr = iph->dst; + } else { + LOGP(DGGSN, LOGL_NOTICE, "non-IPv4 packet received from tun\n"); + return -1; + } DEBUGP(DGGSN, "Received packet from tun!\n"); @@ -383,12 +396,14 @@ int main(int argc, char **argv) /* net */ /* Store net as in_addr net and mask */ if (args_info.net_arg) { - if (ippool_aton(&net, &mask, args_info.net_arg, 0)) { + struct in46_addr in46; + if (ippool_aton(&in46, &prefixlen, args_info.net_arg, 0)) { SYS_ERR(DGGSN, LOGL_ERROR, 0, "Invalid network address: %s!", args_info.net_arg); exit(1); } + net.s_addr = in46.v4.s_addr; netaddr.s_addr = htonl(ntohl(net.s_addr) + 1); destaddr.s_addr = htonl(ntohl(net.s_addr) + 1); } else { @@ -547,7 +562,7 @@ int main(int argc, char **argv) maxfd = gsn->fd1u; /* use GTP kernel module for data packet encapsulation */ - if (gtp_kernel_init(gsn, &net, &mask, &args_info) < 0) + if (gtp_kernel_init(gsn, &net, prefixlen, &args_info) < 0) goto err; gtp_set_cb_data_ind(gsn, encaps_tun); @@ -572,7 +587,7 @@ int main(int argc, char **argv) } DEBUGP(DGGSN, "Setting tun IP address\n"); - if (tun_setaddr(tun, &netaddr, &destaddr, &mask)) { + if (tun_setaddr(tun, &netaddr, &destaddr, &prefixlen)) { SYS_ERR(DGGSN, LOGL_ERROR, 0, "Failed to set tun IP address"); exit(1); } diff --git a/ggsn/gtp-kernel.c b/ggsn/gtp-kernel.c index dbe5a9f..458ac27 100644 --- a/ggsn/gtp-kernel.c +++ b/ggsn/gtp-kernel.c @@ -70,17 +70,6 @@ static void pdp_debug(struct pdp_t *pdp) printf("\n"); } -static int mask2prefix(struct in_addr *mask) -{ - uint32_t tmp = ntohl(mask->s_addr); - int k; - - for (k=0; tmp > 0; k++) - tmp = (tmp << 1); - - return k; -} - static struct { int genl_id; struct mnl_socket *nl; @@ -91,7 +80,7 @@ static struct { #define GTP_DEVNAME "gtp0" int gtp_kernel_init(struct gsn_t *gsn, struct in_addr *net, - struct in_addr *mask, + size_t prefixlen, struct gengetopt_args_info *args_info) { if (!args_info->gtp_linux_given) @@ -126,7 +115,7 @@ int gtp_kernel_init(struct gsn_t *gsn, struct in_addr *net, DEBUGP(DGGSN, "Setting route to reach %s via %s\n", args_info->net_arg, GTP_DEVNAME); - if (gtp_dev_config(GTP_DEVNAME, net, mask2prefix(mask)) < 0) { + if (gtp_dev_config(GTP_DEVNAME, net, prefixlen) < 0) { SYS_ERR(DGGSN, LOGL_ERROR, 0, "Cannot add route to reach network %s\n", args_info->net_arg); diff --git a/ggsn/gtp-kernel.h b/ggsn/gtp-kernel.h index 83280a0..b3b29e3 100644 --- a/ggsn/gtp-kernel.h +++ b/ggsn/gtp-kernel.h @@ -8,7 +8,7 @@ extern char *ipup; #ifdef GTP_KERNEL int gtp_kernel_init(struct gsn_t *gsn, struct in_addr *net, - struct in_addr *mask, + size_t prefixlen, struct gengetopt_args_info *args_info); void gtp_kernel_stop(void); @@ -19,7 +19,7 @@ int gtp_kernel_enabled(void); #else static inline int gtp_kernel_init(struct gsn_t *gsn, struct in_addr *net, - struct in_addr *mask, + size_t prefixlen, struct gengetopt_args_info *args_info) { if (args_info->gtp_linux_given) { |