From edcba4e307fc6d8cf3de5d22982b1317178e7433 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 17 Jun 2012 23:34:34 +0800 Subject: use new external libosmogb (part of libosmocore.git) This removes the libgb (GPRS NS/BSSGP) code from the openbsc.git repository and uses the new version from libosmocore.git instead. --- openbsc/src/libgb/gprs_ns_frgre.c | 310 -------------------------------------- 1 file changed, 310 deletions(-) delete mode 100644 openbsc/src/libgb/gprs_ns_frgre.c (limited to 'openbsc/src/libgb/gprs_ns_frgre.c') diff --git a/openbsc/src/libgb/gprs_ns_frgre.c b/openbsc/src/libgb/gprs_ns_frgre.c deleted file mode 100644 index be5f0f6c7..000000000 --- a/openbsc/src/libgb/gprs_ns_frgre.c +++ /dev/null @@ -1,310 +0,0 @@ -/* GPRS Networks Service (NS) messages on the Gb interface - * 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05) */ - -/* NS-over-FR-over-GRE implementation */ - -/* (C) 2009-2010 by Harald Welte - * - * 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 . - * - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "common_vty.h" - -#define GRE_PTYPE_FR 0x6559 -#define GRE_PTYPE_IPv4 0x0800 -#define GRE_PTYPE_KAR 0x0000 /* keepalive response */ - -struct gre_hdr { - uint16_t flags; - uint16_t ptype; -} __attribute__ ((packed)); - -/* IPv4 messages inside the GRE tunnel might be GRE keepalives */ -static int handle_rx_gre_ipv4(struct osmo_fd *bfd, struct msgb *msg, - struct iphdr *iph, struct gre_hdr *greh) -{ - struct gprs_ns_inst *nsi = bfd->data; - int gre_payload_len; - struct iphdr *inner_iph; - struct gre_hdr *inner_greh; - struct sockaddr_in daddr; - struct in_addr ia; - - gre_payload_len = msg->len - (iph->ihl*4 + sizeof(*greh)); - - inner_iph = (struct iphdr *) ((uint8_t *)greh + sizeof(*greh)); - - if (gre_payload_len < inner_iph->ihl*4 + sizeof(*inner_greh)) { - LOGP(DNS, LOGL_ERROR, "GRE keepalive too short\n"); - return -EIO; - } - - if (inner_iph->saddr != iph->daddr || - inner_iph->daddr != iph->saddr) { - LOGP(DNS, LOGL_ERROR, - "GRE keepalive with wrong tunnel addresses\n"); - return -EIO; - } - - if (inner_iph->protocol != IPPROTO_GRE) { - LOGP(DNS, LOGL_ERROR, "GRE keepalive with wrong protocol\n"); - return -EIO; - } - - inner_greh = (struct gre_hdr *) ((uint8_t *)inner_iph + iph->ihl*4); - if (inner_greh->ptype != htons(GRE_PTYPE_KAR)) { - LOGP(DNS, LOGL_ERROR, "GRE keepalive inner GRE type != 0\n"); - return -EIO; - } - - /* Actually send the response back */ - - daddr.sin_family = AF_INET; - daddr.sin_addr.s_addr = inner_iph->daddr; - daddr.sin_port = IPPROTO_GRE; - - ia.s_addr = iph->saddr; - LOGP(DNS, LOGL_DEBUG, "GRE keepalive from %s, responding\n", - inet_ntoa(ia)); - - return sendto(nsi->frgre.fd.fd, inner_greh, - gre_payload_len - inner_iph->ihl*4, 0, - (struct sockaddr *)&daddr, sizeof(daddr)); -} - -static struct msgb *read_nsfrgre_msg(struct osmo_fd *bfd, int *error, - struct sockaddr_in *saddr) -{ - struct msgb *msg = msgb_alloc(NS_ALLOC_SIZE, "Gb/NS/FR/GRE Rx"); - int ret = 0; - socklen_t saddr_len = sizeof(*saddr); - struct iphdr *iph; - struct gre_hdr *greh; - uint8_t *frh; - uint16_t dlci; - - if (!msg) { - *error = -ENOMEM; - return NULL; - } - - ret = recvfrom(bfd->fd, msg->data, NS_ALLOC_SIZE, 0, - (struct sockaddr *)saddr, &saddr_len); - if (ret < 0) { - LOGP(DNS, LOGL_ERROR, "recv error %s during NS-FR-GRE recv\n", - strerror(errno)); - *error = ret; - goto out_err; - } else if (ret == 0) { - *error = ret; - goto out_err; - } - - msgb_put(msg, ret); - - if (msg->len < sizeof(*iph) + sizeof(*greh) + 2) { - LOGP(DNS, LOGL_ERROR, "Short IP packet: %u bytes\n", msg->len); - *error = -EIO; - goto out_err; - } - - iph = (struct iphdr *) msg->data; - if (msg->len < (iph->ihl*4 + sizeof(*greh) + 2)) { - LOGP(DNS, LOGL_ERROR, "Short IP packet: %u bytes\n", msg->len); - *error = -EIO; - goto out_err; - } - - greh = (struct gre_hdr *) (msg->data + iph->ihl*4); - if (greh->flags) { - LOGP(DNS, LOGL_NOTICE, "Unknown GRE flags 0x%04x\n", - ntohs(greh->flags)); - } - - switch (ntohs(greh->ptype)) { - case GRE_PTYPE_IPv4: - /* IPv4 messages might be GRE keepalives */ - *error = handle_rx_gre_ipv4(bfd, msg, iph, greh); - goto out_err; - break; - case GRE_PTYPE_FR: - /* continue as usual */ - break; - default: - LOGP(DNS, LOGL_NOTICE, "Unknown GRE protocol 0x%04x != FR\n", - ntohs(greh->ptype)); - *error = -EIO; - goto out_err; - break; - } - - if (msg->len < sizeof(*greh) + 2) { - LOGP(DNS, LOGL_ERROR, "Short FR header: %u bytes\n", msg->len); - *error = -EIO; - goto out_err; - } - - frh = (uint8_t *)greh + sizeof(*greh); - if (frh[0] & 0x01) { - LOGP(DNS, LOGL_NOTICE, "Unsupported single-byte FR address\n"); - *error = -EIO; - goto out_err; - } - dlci = ((frh[0] & 0xfc) << 2); - if ((frh[1] & 0x0f) != 0x01) { - LOGP(DNS, LOGL_NOTICE, "Unknown second FR octet 0x%02x\n", - frh[1]); - *error = -EIO; - goto out_err; - } - dlci |= (frh[1] >> 4); - - msg->l2h = frh+2; - - /* Store DLCI in NETWORK BYTEORDER in sockaddr port member */ - saddr->sin_port = htons(dlci); - - return msg; - -out_err: - msgb_free(msg); - return NULL; -} - -int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg, - struct sockaddr_in *saddr, enum gprs_ns_ll ll); - -static int handle_nsfrgre_read(struct osmo_fd *bfd) -{ - int rc; - struct sockaddr_in saddr; - struct gprs_ns_inst *nsi = bfd->data; - struct msgb *msg; - uint16_t dlci; - - msg = read_nsfrgre_msg(bfd, &rc, &saddr); - if (!msg) - return rc; - - dlci = ntohs(saddr.sin_port); - if (dlci == 0 || dlci == 1023) { - LOGP(DNS, LOGL_INFO, "Received FR on LMI DLCI %u - ignoring\n", - dlci); - rc = 0; - goto out; - } - - rc = gprs_ns_rcvmsg(nsi, msg, &saddr, GPRS_NS_LL_FR_GRE); -out: - msgb_free(msg); - - return rc; -} - -static int handle_nsfrgre_write(struct osmo_fd *bfd) -{ - /* FIXME: actually send the data here instead of nsip_sendmsg() */ - return -EIO; -} - -int gprs_ns_frgre_sendmsg(struct gprs_nsvc *nsvc, struct msgb *msg) -{ - int rc; - struct gprs_ns_inst *nsi = nsvc->nsi; - struct sockaddr_in daddr; - uint16_t dlci = ntohs(nsvc->frgre.bts_addr.sin_port); - uint8_t *frh; - struct gre_hdr *greh; - - /* Build socket address for the packet destionation */ - daddr.sin_family = AF_INET; - daddr.sin_addr = nsvc->frgre.bts_addr.sin_addr; - daddr.sin_port = IPPROTO_GRE; - - /* Prepend the FR header */ - frh = msgb_push(msg, 2); - frh[0] = (dlci >> 2) & 0xfc; - frh[1] = ((dlci & 0xf)<<4) | 0x01; - - /* Prepend the GRE header */ - greh = (struct gre_hdr *) msgb_push(msg, sizeof(*greh)); - greh->flags = 0; - greh->ptype = htons(GRE_PTYPE_FR); - - rc = sendto(nsi->frgre.fd.fd, msg->data, msg->len, 0, - (struct sockaddr *)&daddr, sizeof(daddr)); - - msgb_free(msg); - - return rc; -} - -static int nsfrgre_fd_cb(struct osmo_fd *bfd, unsigned int what) -{ - int rc = 0; - - if (what & BSC_FD_READ) - rc = handle_nsfrgre_read(bfd); - if (what & BSC_FD_WRITE) - rc = handle_nsfrgre_write(bfd); - - return rc; -} - -int gprs_ns_frgre_listen(struct gprs_ns_inst *nsi) -{ - struct in_addr in; - int rc; - - in.s_addr = htonl(nsi->frgre.local_ip); - - /* Make sure we close any existing socket before changing it */ - if (nsi->frgre.fd.fd) - close(nsi->frgre.fd.fd); - - if (!nsi->frgre.enabled) - return 0; - - nsi->frgre.fd.cb = nsfrgre_fd_cb; - nsi->frgre.fd.data = nsi; - rc = osmo_sock_init_ofd(&nsi->frgre.fd, AF_INET, SOCK_RAW, - IPPROTO_GRE, inet_ntoa(in), 0, - OSMO_SOCK_F_BIND); - if (rc < 0) { - LOGP(DNS, LOGL_ERROR, "Error creating GRE socket (%s)\n", - strerror(errno)); - return rc; - } - nsi->frgre.fd.data = nsi; - - return rc; -} -- cgit v1.2.3