mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-ggsn.git
synced 2025-11-03 13:43:25 +00:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
561a9bc77c | ||
|
|
7ae1177e04 | ||
|
|
57585767dc | ||
|
|
488972b442 | ||
|
|
08239ccac3 | ||
|
|
fbc56063c5 | ||
|
|
c1598e0eb4 | ||
|
|
519a2e401d | ||
|
|
fbef527222 | ||
|
|
68f5b086ad | ||
|
|
3cb3423a59 | ||
|
|
bad5eeba0f | ||
|
|
1dd16fa12f | ||
|
|
3372625ad9 | ||
|
|
1f9cc2674f | ||
|
|
4abe361f33 | ||
|
|
bb0655d5aa | ||
|
|
4e6fe42731 | ||
|
|
19a506b705 | ||
|
|
ea6c02ac1f | ||
|
|
ec357c5377 | ||
|
|
768d6d5be9 | ||
|
|
fa91a10498 | ||
|
|
6929391ecf | ||
|
|
9baac03927 | ||
|
|
9bd2711f39 | ||
|
|
b17fe7bfe9 | ||
|
|
0917ce4e22 | ||
|
|
2a0d37cb1d | ||
|
|
f3d541e353 | ||
|
|
8d976444b8 | ||
|
|
77734ac81b | ||
|
|
848ec697e2 | ||
|
|
6a2e82542d | ||
|
|
a625bdd136 | ||
|
|
08bb5182a4 | ||
|
|
4963d1c2ea | ||
|
|
37daa5d003 | ||
|
|
c4c4d90b85 | ||
|
|
59f1539ece | ||
|
|
eff88c08e7 | ||
|
|
92ac7249f9 | ||
|
|
5cf6b75dc9 | ||
|
|
4aa2e417c9 |
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
open_collective: osmocom
|
||||
13
Makefile.am
13
Makefile.am
@@ -1,5 +1,15 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
SUBDIRS = lib gtp ggsn sgsnemu doc contrib utils tests
|
||||
SUBDIRS = \
|
||||
include \
|
||||
lib \
|
||||
gtp \
|
||||
ggsn \
|
||||
sgsnemu \
|
||||
doc \
|
||||
contrib \
|
||||
utils \
|
||||
tests \
|
||||
$(NULL)
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libgtp.pc
|
||||
@@ -15,7 +25,6 @@ EXTRA_DIST = \
|
||||
README.FreeBSD \
|
||||
README.MacOSX \
|
||||
README.md \
|
||||
contrib/osmo-ggsn.spec.in \
|
||||
debian \
|
||||
git-version-gen \
|
||||
$(NULL)
|
||||
|
||||
165
README.md
165
README.md
@@ -5,15 +5,14 @@ This repository contains a C-language implementation of a GGSN (Gateway
|
||||
GPRS Support Node), a core network element of ETSI/3GPP cellular
|
||||
networks such as GPRS, EDGE, UMTS or HSPA.
|
||||
|
||||
OsmoGGSN is part of the [Osmocom](https://osmocom.org/) Open Source
|
||||
Mobile Communications projects and the successor to OpenGGSN.
|
||||
OpenGGSN was developed until 2004 by Mondru AB.
|
||||
**OsmoGGSN** is part of the [Osmocom](https://osmocom.org/) Open Source
|
||||
Mobile Communications projects and the successor to OpenGGSN (which was
|
||||
developed until 2004 by Mondru AB).
|
||||
|
||||
Homepage
|
||||
--------
|
||||
|
||||
The official homepage of the project is
|
||||
https://osmocom.org/projects/openggsn/wiki
|
||||
The official homepage of the project is <https://osmocom.org/projects/openggsn/wiki>.
|
||||
|
||||
GIT Repository
|
||||
--------------
|
||||
@@ -27,35 +26,50 @@ There is a web interface at <https://gitea.osmocom.org/cellular-infrastructure/o
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
There currently is no other documentation other than the wiki on the
|
||||
homepage. It would be great if somebody would work towards a user
|
||||
manual that can become part of the osmo-gsm-manuals project.
|
||||
The user manual and VTY reference are optionally built in PDF form
|
||||
as part of the build process. Pre-rendered versions are available here:
|
||||
|
||||
* [osmo-ggsn user manual](https://ftp.osmocom.org/docs/osmo-ggsn/master/osmoggsn-usermanual.pdf)
|
||||
* [osmo-ggsn VTY reference](https://ftp.osmocom.org/docs/osmo-ggsn/master/osmoggsn-vty-reference.pdf)
|
||||
|
||||
Forum
|
||||
-----
|
||||
|
||||
We welcome any pySim related discussions in the
|
||||
[Cellular Network Infrastructure -> 2G/3G Core Network](https://discourse.osmocom.org/c/cni/2g-3g-cn/)
|
||||
section of the osmocom discourse (web based Forum).
|
||||
|
||||
Mailing List
|
||||
------------
|
||||
|
||||
Discussions related to OsmoGGSN are happening on the
|
||||
osmocom-net-gprs@lists.osmocom.org mailing list, please see
|
||||
https://lists.osmocom.org/mailman/listinfo/osmocom-net-gprs for
|
||||
<https://lists.osmocom.org/mailman/listinfo/osmocom-net-gprs> for
|
||||
subscription options and the list archive.
|
||||
|
||||
Please observe the [Osmocom Mailing List
|
||||
Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
|
||||
Please observe the [Osmocom Mailing List Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
|
||||
when posting.
|
||||
|
||||
Issue Tracker
|
||||
-------------
|
||||
|
||||
We use the [issue tracker of the osmo-ggsn project on osmocom.org](https://osmocom.org/projects/openggsn/issues) for
|
||||
tracking the state of bug reports and feature requests. Feel free to submit any issues you may find, or help
|
||||
us out by resolving existing issues.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Our coding standards are described at
|
||||
https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards
|
||||
<https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards>
|
||||
|
||||
We us a gerrit based patch submission/review process for managing
|
||||
We use a Gerrit based patch submission/review process for managing
|
||||
contributions. Please see
|
||||
https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit for
|
||||
<https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit> for
|
||||
more details
|
||||
|
||||
The current patch queue for OsmoGGSN can be seen at
|
||||
https://gerrit.osmocom.org/#/q/project:osmo-ggsn+status:open
|
||||
<https://gerrit.osmocom.org/#/q/project:osmo-ggsn+status:open>
|
||||
|
||||
|
||||
QuickStart
|
||||
@@ -75,61 +89,33 @@ The tun driver is required for proper operation of openggsn. For Linux
|
||||
kernels later than 2.4.7 the driver is typically included, but might
|
||||
need to be configured for automatic loading:
|
||||
|
||||
1. Add the following line to /etc/modules.conf: alias char-major-10-200 tun
|
||||
2. depmod -a
|
||||
1. Add the following line to `/etc/modules.conf`: `alias char-major-10-200 tun`
|
||||
2. `depmod -a`
|
||||
|
||||
|
||||
Installation from binary
|
||||
------------------------
|
||||
|
||||
OsmoGGSN is built for common versions of Debian and Ubuntu as part of
|
||||
OsmoGGSN is built for common versions of Debian, Ubuntu and other distributions part of
|
||||
the [Osmocom Nightly Builds](https://osmocom.org/projects/cellular-infrastructure/wiki/Nightly_Builds)
|
||||
project. If you don't want to do development, it is suggested to simply
|
||||
use those binary packages, rather than building yourself from source.
|
||||
and [Osmocom Latest Builds](https://osmocom.org/projects/cellular-infrastructure/wiki/Latest_Builds).
|
||||
If you don't want to do development, it is suggested to simply use those binary packages, rather than building
|
||||
yourself from source.
|
||||
|
||||
|
||||
Installation from source
|
||||
------------------------
|
||||
|
||||
1. ./configure
|
||||
2. make
|
||||
3. make install
|
||||
```
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
```
|
||||
|
||||
You need to be root in order to install the package, but not in order
|
||||
to compile.
|
||||
|
||||
|
||||
Running
|
||||
-------
|
||||
|
||||
*sgsnemu*
|
||||
Start the emulator as root using the command:
|
||||
|
||||
sgsnemu -l 10.0.0.50 -r 10.0.0.40 --createif --defaultroute
|
||||
|
||||
This will cause the sgsn emulator to bind to local address 10.0.0.50
|
||||
and connect to the ggsn found at 10.0.0.40. It will first send off an
|
||||
ECHO_REQUEST message. After this it will attempt to establish a pdp
|
||||
context. If successful it will create a local interface and set up
|
||||
routing. Now you should be able to ping through the connection. Use a
|
||||
network analysator such as ethereal to monitor the traffic.
|
||||
|
||||
sgsnemu -h will show a list of available options.
|
||||
|
||||
sgsnemu -c sgsnemu.conf will use sgsnemu.conf as a configuration
|
||||
file. A sample file is provided in examples/sgsnemu.conf.
|
||||
|
||||
*ggsn*
|
||||
Edit the configuration file ggsn.conf found under openggsn/examples.
|
||||
Start the ggsn as root using the command:
|
||||
|
||||
ggsn --fg -c examples/ggsn.conf -l 10.0.0.40 --statedir ./
|
||||
|
||||
This will run the ggsn in foreground using the local interface
|
||||
10.0.0.40. If you don't have a GSM network available for testing you
|
||||
can use sgsnemu to test the GGSN.
|
||||
|
||||
|
||||
Support
|
||||
-------
|
||||
|
||||
@@ -144,9 +130,10 @@ OsmoGGSN is an open source implementation of GPRS Support Nodes
|
||||
version 1.
|
||||
|
||||
OsmoGGSN provides 3 components:
|
||||
* gtplib
|
||||
* osmo-ggsn
|
||||
* sgsnemu
|
||||
|
||||
* *libgtp*, a shared library for the GTPv1C protocol
|
||||
* *osmo-ggsn*, the GGSN itself
|
||||
* *sgsnemu*, a SGSN emulator
|
||||
|
||||
*gtplib*
|
||||
This library contains all functionality relating to the GTP
|
||||
@@ -182,10 +169,10 @@ Both osmo-ggsn and sgsnemu uses the tun package. You need at least tun
|
||||
version 1.1. With Linux tun is normally included from kernel version
|
||||
2.4.7. To configure automatic loading:
|
||||
|
||||
1. Add the following line to /etc/modules.conf: alias char-major-10-200 tun
|
||||
2. depmod -a
|
||||
1. Add the following line to `/etc/modules.conf`: `alias char-major-10-200 tun`
|
||||
2. `depmod -a`
|
||||
|
||||
Alternatively you can execute "modprobe tun" on the commandline.
|
||||
Alternatively you can execute `modprobe tun` on the commandline.
|
||||
|
||||
Gengetopt
|
||||
---------
|
||||
@@ -195,11 +182,13 @@ cmdline.ggo source file. You need at least gengetopt version 2.8. If
|
||||
you are just going to compile the programs you don't need gengetopt.
|
||||
|
||||
To use gengetopt for the sgsnemu do the following:
|
||||
```
|
||||
cd sgsnemu
|
||||
gengetopt < cmdline.ggo --conf-parser
|
||||
```
|
||||
|
||||
For more information about gengetopt see
|
||||
http://www.gnu.org/software/gengetopt/gengetopt.html
|
||||
<http://www.gnu.org/software/gengetopt/gengetopt.html>
|
||||
|
||||
|
||||
Compilation and Installation
|
||||
@@ -213,27 +202,21 @@ Running osmo-ggsn
|
||||
|
||||
Use osmo-ggsn -h for a list of available options. All options available on
|
||||
the command line can also be given in a configuration file. See
|
||||
examples/osmo-ggsn.cfg for the format of this file.
|
||||
`doc/examples/osmo-ggsn.cfg` for the format of this file.
|
||||
|
||||
Start osmo-ggsn as root using the command:
|
||||
|
||||
osmo-ggsn -c examples/osmo-ggsn.cfg
|
||||
`osmo-ggsn -c doc/examples/osmo-ggsn.cfg`
|
||||
|
||||
First a tun network interface will be created. In the above example
|
||||
the network interface address is 192.168.0.0 and the mask is
|
||||
255.255.255.0. You can check that this interface is up by using
|
||||
ifconfig.
|
||||
First, a tun network interface will be created for each configured apn.
|
||||
|
||||
After tun has been successfully established the ggsn will wait for GTP
|
||||
create PDP context requests on the local interface
|
||||
10.0.0.40. Currently all requests are accepted, and no password,
|
||||
username or APN validation is performed.
|
||||
create PDP context requests on the configured `gtp bind-ip` address.
|
||||
Currently all requests are accepted, and no password, username validation is performed.
|
||||
|
||||
When receiving a create PDP context request a dynamic IP address will
|
||||
be allocated from the address pool determined by --dynip. In the above
|
||||
example the first allocated address will be 192.168.0.1, followed by
|
||||
192.168.0.2 and so on. The request is confirmed by sending a create
|
||||
PDP context response message to the peer (SGSN).
|
||||
When receiving a create PDP context request for a given APN, a dynamic IP address will
|
||||
be allocated from the address pool defined in the config file section for that apn.
|
||||
The request is confirmed by sending a create PDP context response message to the peer (SGSN).
|
||||
|
||||
Now IP packets will be forwarded between the tun network interface and
|
||||
the established GTP tunnel. In order to allow users to access the
|
||||
@@ -241,22 +224,22 @@ external network routing needs to be set up. If private addresses are
|
||||
used you need to configure network address translation. See the Linux
|
||||
Networking HOWTO for details.
|
||||
|
||||
Remember to enable routing:
|
||||
Remember to enable routing:
|
||||
|
||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
`echo 1 > /proc/sys/net/ipv4/ip_forward`
|
||||
|
||||
If you installed using a binary RPM package it is possible to start
|
||||
osmo-ggsn by using the Sys 5 script:
|
||||
If you're using systemd and did `make install` or installed from a bianry package,
|
||||
you can start osmo-ggsn by using the included systemd service/unit file:
|
||||
|
||||
/etc/init.d/osmo-ggsn start
|
||||
`systemctl start osmo-ggsn`
|
||||
|
||||
|
||||
Running sgsnemu
|
||||
===============
|
||||
|
||||
Use sgsnemu -h for a list of available options. All options available
|
||||
Use `sgsnemu -h` for a list of available options. All options available
|
||||
on the command line can also be given in a configuration file. See
|
||||
examples/sgsnemu.conf for the format of this file.
|
||||
`doc/examples/sgsnemu.conf` for the format of this file.
|
||||
|
||||
If you want to test a GRX roaming connection you will need to do the
|
||||
following:
|
||||
@@ -269,11 +252,11 @@ subnet mask and default route. See the Linux Networking HOWTO for
|
||||
details.
|
||||
4. Launch sgsnemu with something like:
|
||||
|
||||
sgsnemu --listen 10.0.0.50 --remote 10.0.0.40 --dns 10.20.38.51 --timelimit 10 --contexts 0
|
||||
`sgsnemu --listen 10.0.0.50 --remote 10.0.0.40 --dns 10.20.38.51 --timelimit 10 --contexts 0`
|
||||
|
||||
sgsnemu will print something like the following on the screen:
|
||||
|
||||
|
||||
```
|
||||
Using DNS server: 10.20.38.51 (10.20.38.51)
|
||||
Local IP address is: 10.0.0.50 (10.0.0.50)
|
||||
Remote IP address is: 10.0.0.40 (10.0.0.40)
|
||||
@@ -289,6 +272,7 @@ sgsnemu will print something like the following on the screen:
|
||||
Waiting for response from ggsn........
|
||||
|
||||
Received echo response. Cause value: 0
|
||||
```
|
||||
|
||||
This is quite good. It means that you managed to send off an echo
|
||||
request to a remote GGSN, and it was friendly enough to answer you. If
|
||||
@@ -306,10 +290,11 @@ testing. Also note that you are establishing a connection to the Gi
|
||||
network, so please be carefull not to route internet traffic onto the
|
||||
GPRS core network! Assuming you know what you are doing:
|
||||
|
||||
sgsnemu --listen 10.0.0.50 --remote 10.0.0.40 --dns 10.20.38.51 --timelimit 10 --contexts 1 --apn internet --imsi 240011234567890 --msisdn 46702123456 --createif --defaultroute
|
||||
`sgsnemu --listen 10.0.0.50 --remote 10.0.0.40 --dns 10.20.38.51 --timelimit 10 --contexts 1 --apn internet --imsi 240011234567890 --msisdn 46702123456 --createif --defaultroute`
|
||||
|
||||
sgsnemu will print something like the following on the screen:
|
||||
|
||||
```
|
||||
Using DNS server: 10.20.38.51 (10.20.38.51)
|
||||
Local IP address is: 10.0.0.50 (10.0.0.50)
|
||||
Remote IP address is: 10.0.0.40 (10.0.0.40)
|
||||
@@ -330,7 +315,7 @@ sgsnemu will print something like the following on the screen:
|
||||
Setting up interface and routing
|
||||
/sbin/ifconfig tun0 192.168.0.1
|
||||
/sbin/route add -net 192.168.0.0 netmask 255.255.255.0 gw 192.168.0.1
|
||||
|
||||
```
|
||||
|
||||
Now a context is established to the remote GGSN. The IP address of the
|
||||
context is 192.168.0.1. You should be able to ping a known address on
|
||||
@@ -344,13 +329,13 @@ do this is to use policy routing. Also note that you are effectively
|
||||
connecting the same computer to both the Gn and Gi network, so please
|
||||
be carefull not to route internet traffic onto the GPRS core network
|
||||
and please protect yourself against hackers! For this reason it is
|
||||
advised to always use --contexts 0 when testing a live network.
|
||||
advised to always use `--contexts 0` when testing a live network.
|
||||
|
||||
After --timelimit seconds the PDP context is disconnected with the
|
||||
After `--timelimit seconds` the PDP context is disconnected with the
|
||||
following messages from sgsnemu:
|
||||
|
||||
|
||||
```
|
||||
Disconnecting PDP context #0
|
||||
Received delete PDP context response. Cause value: 128
|
||||
Deleting tun interface
|
||||
|
||||
```
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install
|
||||
# according to https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
|
||||
# In short:
|
||||
# according to https://osmocom.org/projects/cellular-infrastructure/wiki/Make_a_new_release
|
||||
# In short: https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
|
||||
# LIBVERSION=c:r:a
|
||||
# If the library source code has changed at all since the last update, then increment revision: c:r + 1:a.
|
||||
# If any interfaces have been added, removed, or changed since the last update: c + 1:0:0.
|
||||
# If any interfaces have been added, removed, or changed since the last update: c + 1:0:a.
|
||||
# If any interfaces have been added since the last public release: c:r:a + 1.
|
||||
# If any interfaces have been removed or changed since the last public release: c:r:0.
|
||||
#library what description / commit summary line
|
||||
#library what description / commit summary line
|
||||
|
||||
12
configure.ac
12
configure.ac
@@ -71,7 +71,7 @@ AC_ARG_ENABLE([gtp-linux],
|
||||
[enable_gtp_linux="$enableval"], [enable_gtp_linux="no"])
|
||||
|
||||
AS_IF([test "x$enable_gtp_linux" = "xyes"], [
|
||||
PKG_CHECK_MODULES([LIBGTPNL], [libgtpnl >= 1.2.0])
|
||||
PKG_CHECK_MODULES([LIBGTPNL], [libgtpnl >= 1.3.0])
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([ENABLE_GTP_KERNEL], [test "$enable_gtp_linux" = "yes"])
|
||||
@@ -154,9 +154,9 @@ adl_FUNC_GETOPT_LONG
|
||||
|
||||
AM_INIT_AUTOMAKE([foreign])
|
||||
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.10.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.10.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.10.0)
|
||||
|
||||
AC_ARG_ENABLE(sanitize,
|
||||
[AS_HELP_STRING(
|
||||
@@ -262,10 +262,12 @@ AC_CONFIG_FILES([Makefile
|
||||
doc/manuals/Makefile
|
||||
contrib/Makefile
|
||||
contrib/systemd/Makefile
|
||||
contrib/osmo-ggsn.spec
|
||||
tests/Makefile
|
||||
tests/lib/Makefile
|
||||
tests/gtp/Makefile
|
||||
include/Makefile
|
||||
include/osmocom/Makefile
|
||||
include/osmocom/gtp/Makefile
|
||||
libgtp.pc])
|
||||
AC_OUTPUT
|
||||
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# osmo-ggsn This shell script takes care of starting and stopping
|
||||
# osmo-ggsn.
|
||||
#
|
||||
# chkconfig: - 65 35
|
||||
# description: osmo-ggsn is a Gateway GPRS Support Node.
|
||||
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
# Source networking configuration.
|
||||
. /etc/sysconfig/network
|
||||
|
||||
if [ -f /etc/sysconfig/osmo-ggsn ]; then
|
||||
. /etc/sysconfig/osmo-ggsn
|
||||
fi
|
||||
|
||||
# Check that networking is up.
|
||||
[ ${NETWORKING} = "no" ] && exit 0
|
||||
|
||||
[ -f /usr/bin/osmo-ggsn ] || exit 0
|
||||
[ -f /etc/osmo-ggsn.cfg ] || exit 0
|
||||
|
||||
RETVAL=0
|
||||
prog="osmo-ggsn"
|
||||
|
||||
start() {
|
||||
# Start daemons.
|
||||
echo -n $"Starting $prog: "
|
||||
|
||||
# Load tun module
|
||||
/sbin/modprobe tun >/dev/null 2>&1
|
||||
|
||||
# Enable routing of packets: WARNING!!!
|
||||
# Users should enable this explicitly
|
||||
# echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
|
||||
# Check for runtime directory of nonvolatile data
|
||||
if [ ! -d /var/lib/osmo-ggsn ]; then
|
||||
mkdir /var/lib/osmo-ggsn
|
||||
fi
|
||||
|
||||
# Check for GTP restart counter
|
||||
if [ ! -d /var/lib/osmo-ggsn/gsn_restart ]; then
|
||||
echo 0 > /var/lib/osmo-ggsn/gsn_restart
|
||||
fi
|
||||
|
||||
|
||||
daemon /usr/bin/osmo-ggsn
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/osmo-ggsn
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
stop() {
|
||||
# Stop daemons.
|
||||
echo -n $"Shutting down $prog: "
|
||||
killproc osmo-ggsn
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL = 0 ] && rm -f /var/lock/subsys/osmo-ggsn /var/run/osmo-ggsn.pid
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
restart|reload)
|
||||
stop
|
||||
start
|
||||
RETVAL=$?
|
||||
;;
|
||||
condrestart)
|
||||
if [ -f /var/lock/subsys/osmo-ggsn ] ; then
|
||||
stop
|
||||
start
|
||||
RETVAL=$?
|
||||
fi
|
||||
;;
|
||||
status)
|
||||
status osmo-ggsn
|
||||
RETVAL=$?
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit $RETVAL
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
#
|
||||
# spec file for package osmo-ggsn
|
||||
#
|
||||
# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
# upon. The license for this file, and modifications and additions to the
|
||||
# file, is the same license as for the pristine package itself (unless the
|
||||
# license for the pristine package is not an Open Source License, in which
|
||||
# case the license is the MIT License). An "Open Source License" is a
|
||||
# license that conforms to the Open Source Definition (Version 1.9)
|
||||
# published by the Open Source Initiative.
|
||||
|
||||
## Disable LTO for now since it breaks compilation of the tests
|
||||
## https://osmocom.org/issues/4114
|
||||
%define _lto_cflags %{nil}
|
||||
|
||||
Name: osmo-ggsn
|
||||
Version: @VERSION@
|
||||
Release: 0
|
||||
Summary: GPRS Support Node
|
||||
License: GPL-2.0-only AND LGPL-2.1-or-later
|
||||
Group: Productivity/Telephony/Servers
|
||||
URL: https://osmocom.org/projects/openggsn
|
||||
Source: %{name}-%{version}.tar.xz
|
||||
BuildRequires: libtool >= 2
|
||||
BuildRequires: pkgconfig >= 0.20
|
||||
%if 0%{?suse_version}
|
||||
BuildRequires: systemd-rpm-macros
|
||||
%endif
|
||||
BuildRequires: pkgconfig(libgtpnl) >= 1.2.0
|
||||
BuildRequires: pkgconfig(libosmocore) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmovty) >= 1.8.0
|
||||
Obsoletes: openggsn
|
||||
%{?systemd_requires}
|
||||
|
||||
%description
|
||||
Osmo-GGSN is a C-language implementation of a GGSN (Gateway GPRS
|
||||
Support Node), a core network element of ETSI/3GPP cellular networks
|
||||
such as GPRS, EDGE, UMTS or HSPA.
|
||||
|
||||
%package -n libgtp6
|
||||
Summary: Library implementing GTP between SGSN and GGSN
|
||||
License: GPL-2.0-only
|
||||
Group: System/Libraries
|
||||
|
||||
%description -n libgtp6
|
||||
libgtp implements the GPRS Tunneling Protocol between SGSN and GGSN.
|
||||
|
||||
%package -n libgtp-devel
|
||||
Summary: Development files for the GTP library
|
||||
License: GPL-2.0-only
|
||||
Group: Development/Libraries/C and C++
|
||||
Requires: libgtp6 = %{version}
|
||||
|
||||
%description -n libgtp-devel
|
||||
libgtp implements the GPRS Tunneling Protocol between SGSN and GGSN.
|
||||
|
||||
This subpackage contains libraries and header files for developing
|
||||
applications that want to make use of libgtp.
|
||||
|
||||
%package -n gtp-echo-responder
|
||||
Summary: Small program answering GTP ECHO Request with GTP ECHO Response
|
||||
License: MIT
|
||||
Group: System/Libraries
|
||||
|
||||
%description -n gtp-echo-responder
|
||||
Small program answering GTP ECHO Request with GTP ECHO Response for both GTPCv1
|
||||
and GTPCv2.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
echo "%{version}" >.tarball-version
|
||||
autoreconf -fi
|
||||
%configure \
|
||||
--enable-gtp-linux \
|
||||
--disable-static \
|
||||
--docdir="%{_docdir}/%{name}" \
|
||||
--with-systemdsystemunitdir=%{_unitdir} \
|
||||
--includedir="%{_includedir}/%{name}"
|
||||
make %{?_smp_mflags} V=1
|
||||
|
||||
%install
|
||||
%make_install
|
||||
find %{buildroot} -type f -name "*.la" -delete -print
|
||||
|
||||
%check
|
||||
make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
||||
|
||||
%if 0%{?suse_version}
|
||||
%pre
|
||||
%service_add_pre %{name}.service
|
||||
|
||||
%post
|
||||
%service_add_post %{name}.service
|
||||
|
||||
%preun
|
||||
%service_del_preun %{name}.service
|
||||
|
||||
%postun
|
||||
%service_del_postun %{name}.service
|
||||
%endif
|
||||
|
||||
%post -n libgtp6 -p /sbin/ldconfig
|
||||
%postun -n libgtp6 -p /sbin/ldconfig
|
||||
|
||||
%files
|
||||
%license COPYING
|
||||
%doc AUTHORS README.md
|
||||
%{_bindir}/osmo-ggsn
|
||||
%{_bindir}/sgsnemu
|
||||
%{_mandir}/man8/osmo-ggsn.8%{?ext_man}
|
||||
%{_mandir}/man8/sgsnemu.8%{?ext_man}
|
||||
%{_unitdir}/%{name}.service
|
||||
%dir %{_docdir}/%{name}/examples
|
||||
%{_docdir}/%{name}/examples/osmo-ggsn-kernel-gtp.cfg
|
||||
%{_docdir}/%{name}/examples/osmo-ggsn.cfg
|
||||
%{_docdir}/%{name}/examples/sgsnemu.conf
|
||||
%dir %{_sysconfdir}/osmocom
|
||||
%config(noreplace) %{_sysconfdir}/osmocom/osmo-ggsn.cfg
|
||||
|
||||
%files -n libgtp6
|
||||
%{_libdir}/libgtp.so.6*
|
||||
|
||||
%files -n libgtp-devel
|
||||
%{_includedir}/%{name}/
|
||||
%{_libdir}/libgtp.so
|
||||
%{_libdir}/pkgconfig/libgtp.pc
|
||||
|
||||
%files -n gtp-echo-responder
|
||||
%{_bindir}/gtp-echo-responder
|
||||
|
||||
%changelog
|
||||
@@ -1,6 +1,7 @@
|
||||
[Unit]
|
||||
Description=OsmoGGSN
|
||||
After=networking.service
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
@@ -10,6 +11,10 @@ WorkingDirectory=%S/osmocom
|
||||
ExecStart=/usr/bin/osmo-ggsn -c /etc/osmocom/osmo-ggsn.cfg
|
||||
RestartSec=2
|
||||
RestartPreventExitStatus=1
|
||||
User=osmocom
|
||||
Group=osmocom
|
||||
# For setting up the gtp0/tun0 devices
|
||||
AmbientCapabilities=CAP_NET_ADMIN
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
68
debian/changelog
vendored
68
debian/changelog
vendored
@@ -1,3 +1,71 @@
|
||||
osmo-ggsn (1.12.0) unstable; urgency=medium
|
||||
|
||||
[ Daniel Willmann ]
|
||||
* libgtp: Remove defines for reserved causes in gtp.h
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* pco: Improve IPCP spec reference documentation
|
||||
|
||||
[ Oliver Smith ]
|
||||
* Fix a typo
|
||||
* gtp_new: deduplicate create_and_bind_socket code
|
||||
* kernel-gtp: support IPv6 on outer layer
|
||||
* kernel-gtp: support IPv6 on inner layer
|
||||
* Revert "kernel-gtp: support IPv6 on outer layer"
|
||||
* Cosmetic: Makefile.am: make SUBDIRS diff friendly
|
||||
* Cosmetic: AM_CFLAGS: make diff friendly
|
||||
* Cosmetic: {lib,gtp}/Makefile.am: diff friendly
|
||||
* lib/gtp-kernel.c: initialize ret with 0
|
||||
* lib/gtp-kernel.c: check rc of in46a_from_eua
|
||||
* doc: fix typo ndoe -> node
|
||||
* Add clear error for kernel not supporting IPv6
|
||||
* contrib: remove rpm spec file
|
||||
* libgtp: move includes to osmocom/include/gtp
|
||||
* gtp/gsn_internal.h: new file
|
||||
* gtp/gtp.c: move gtp_create_context_resp down
|
||||
* gtp: remove unused conversion functions
|
||||
* gtp: move conversion functions up
|
||||
* gtp/gtp_internal.h: new file
|
||||
* ggsn/ggsn_vty: create state-dir
|
||||
* doc: set state-dir to /var/lib/osmocom/osmo-ggsn
|
||||
* contrib/systemd: run as osmocom user
|
||||
* Use uniform log format for default config files
|
||||
* {contrib,debian}/osmo-ggsn.init: remove
|
||||
|
||||
[ Harald Welte ]
|
||||
* Add funding link to github mirror
|
||||
* README.md: Improve markdown formatting
|
||||
* README.md: Add Forum + Issue Tracker sections
|
||||
* README.md: Major overhaul
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
* README.md: cosmetic: fix a typo
|
||||
|
||||
-- Oliver Smith <osmith@sysmocom.de> Wed, 24 Jul 2024 15:13:31 +0200
|
||||
|
||||
osmo-ggsn (1.11.0) unstable; urgency=medium
|
||||
|
||||
[ Daniel Willmann ]
|
||||
* gtp: Add net GTP cause values and a function to check for success
|
||||
|
||||
-- Oliver Smith <osmith@sysmocom.de> Tue, 28 Nov 2023 13:38:29 +0100
|
||||
|
||||
osmo-ggsn (1.10.2) unstable; urgency=medium
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
* Do not hard-code -g and -O2 in CFLAGS
|
||||
* tests: use -no-install libtool flag to avoid ./lt-* scripts
|
||||
|
||||
[ Oliver Smith ]
|
||||
* doc/manuals/chapters/configuration: fix typo
|
||||
* debian: set compat level to 10
|
||||
* systemd: depend on networking-online.target
|
||||
* README: update documentation section
|
||||
* doc: running: update kernel-gtp limitations
|
||||
* lib/in46_addr: add in46a_from_gsna
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 12 Sep 2023 14:36:10 +0200
|
||||
|
||||
osmo-ggsn (1.10.1) unstable; urgency=medium
|
||||
|
||||
[ Oliver Smith ]
|
||||
|
||||
2
debian/compat
vendored
2
debian/compat
vendored
@@ -1 +1 @@
|
||||
9
|
||||
10
|
||||
|
||||
16
debian/control
vendored
16
debian/control
vendored
@@ -2,14 +2,14 @@ Source: osmo-ggsn
|
||||
Maintainer: Osmocom team <openbsc@lists.osmocom.org>
|
||||
Section: net
|
||||
Priority: optional
|
||||
Build-Depends: debhelper (>= 9),
|
||||
Build-Depends: debhelper (>= 10),
|
||||
autotools-dev,
|
||||
pkg-config,
|
||||
libdpkg-perl, git,
|
||||
dh-autoreconf,
|
||||
libosmocore-dev (>= 1.8.0),
|
||||
osmo-gsm-manuals-dev,
|
||||
libgtpnl-dev (>= 1.2.0)
|
||||
libosmocore-dev (>= 1.10.0),
|
||||
osmo-gsm-manuals-dev (>= 1.6.0),
|
||||
libgtpnl-dev (>= 1.3.0)
|
||||
Standards-Version: 3.9.6
|
||||
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-ggsn
|
||||
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-ggsn
|
||||
@@ -24,7 +24,7 @@ Description: Osmocom Gateway GPRS Support Node (GGSN)
|
||||
operators as the interface between the Internet and the rest of the
|
||||
mobile network infrastructure.
|
||||
|
||||
Package: libgtp6
|
||||
Package: libgtp10
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Section: libs
|
||||
@@ -49,7 +49,7 @@ Architecture: any
|
||||
Multi-Arch: same
|
||||
Section: libdevel
|
||||
Depends: ${misc:Depends},
|
||||
libgtp6 (= ${binary:Version})
|
||||
libgtp10 (= ${binary:Version})
|
||||
Description: Development files for libgtp
|
||||
OsmoGGSN is a Gateway GPRS Support Node (GGSN). It is used by mobile
|
||||
operators as the interface between the Internet and the rest of the
|
||||
@@ -62,7 +62,7 @@ Package: osmo-ggsn-dbg
|
||||
Section: debug
|
||||
Architecture: any
|
||||
Priority: extra
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libgtp6 (= ${binary:Version}), osmo-ggsn (= ${binary:Version})
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libgtp10 (= ${binary:Version}), osmo-ggsn (= ${binary:Version})
|
||||
Multi-Arch: same
|
||||
Description: Debug symbols for OsmoGGSN
|
||||
OsmoGGSN is a Gateway GPRS Support Node (GGSN). It is used by mobile
|
||||
@@ -82,7 +82,7 @@ Package: libgtp-dbg
|
||||
Section: debug
|
||||
Architecture: any
|
||||
Priority: extra
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libgtp6 (= ${binary:Version})
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libgtp10 (= ${binary:Version})
|
||||
Multi-Arch: same
|
||||
Description: Debug symbols for OsmoGGSN
|
||||
OsmoGGSN is a Gateway GPRS Support Node (GGSN). It is used by mobile
|
||||
|
||||
163
debian/osmo-ggsn.init
vendored
163
debian/osmo-ggsn.init
vendored
@@ -1,163 +0,0 @@
|
||||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: osmo-ggsn
|
||||
# Required-Start: $network $local_fs $remote_fs
|
||||
# Required-Stop: $network $remote_fs
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Gateway GPRS Support Node
|
||||
# Description: Gateway GPRS Support Node
|
||||
### END INIT INFO
|
||||
|
||||
# Author: Harald Welte <laforge@gnumonks.org>
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="OsmoGGSN Gateway GPRS Support Node"
|
||||
NAME=ggsn
|
||||
DAEMON=/usr/bin/osmo-ggsn
|
||||
DAEMON_ARGS="" # Arguments to run the daemon with
|
||||
PIDFILE=/var/run/$NAME.pid
|
||||
SCRIPTNAME=/etc/init.d/osmo-ggsn
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x $DAEMON ] || exit 0
|
||||
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/default/osmo-ggsn ] && . /etc/default/osmo-ggsn
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
. /lib/init/vars.sh
|
||||
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
DAEMON_ARGS="$DAEMON_ARGS"
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|
||||
|| return 1
|
||||
|
||||
# Check for runtime directory of nonvolatile data
|
||||
if [ ! -d /var/lib/osmo-ggsn ]; then
|
||||
mkdir /var/lib/osmo-ggsn
|
||||
fi
|
||||
|
||||
# Check for GTP restart counter
|
||||
if [ ! -f /var/lib/osmo-ggsn/gsn_restart ]; then
|
||||
echo 0 > /var/lib/osmo-ggsn/gsn_restart
|
||||
fi
|
||||
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
|
||||
$DAEMON_ARGS \
|
||||
|| return 2
|
||||
# Add code here, if necessary, that waits for the process to be ready
|
||||
# to handle requests from services started subsequently which depend
|
||||
# on this one. As a last resort, sleep for some time.
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
# Wait for children to finish too if this is a daemon that forks
|
||||
# and if the daemon is only ever run from this initscript.
|
||||
# If the above conditions are not satisfied then add some other code
|
||||
# that waits for the process to drop all resources that could be
|
||||
# needed by services started subsequently. A last resort is to
|
||||
# sleep for some time.
|
||||
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
[ "$?" = 2 ] && return 2
|
||||
# Many daemons don't delete their pidfiles when they exit.
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
#
|
||||
# Function that sends a SIGHUP to the daemon/service
|
||||
#
|
||||
do_reload() {
|
||||
#
|
||||
# If the daemon can reload its configuration without
|
||||
# restarting (for example, when it is sent a SIGHUP),
|
||||
# then implement that here.
|
||||
#
|
||||
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
#reload|force-reload)
|
||||
#
|
||||
# If do_reload() is not implemented then leave this commented out
|
||||
# and leave 'force-reload' as an alias for 'restart'.
|
||||
#
|
||||
#log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
#do_reload
|
||||
#log_end_msg $?
|
||||
#;;
|
||||
restart|force-reload)
|
||||
#
|
||||
# If the "reload" option is implemented then remove the
|
||||
# 'force-reload' alias
|
||||
#
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
:
|
||||
39
debian/postinst
vendored
Executable file
39
debian/postinst
vendored
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh -e
|
||||
case "$1" in
|
||||
configure)
|
||||
# Create the osmocom group and user (if it doesn't exist yet)
|
||||
if ! getent group osmocom >/dev/null; then
|
||||
groupadd --system osmocom
|
||||
fi
|
||||
if ! getent passwd osmocom >/dev/null; then
|
||||
useradd \
|
||||
--system \
|
||||
--gid osmocom \
|
||||
--home-dir /var/lib/osmocom \
|
||||
--shell /sbin/nologin \
|
||||
--comment "Open Source Mobile Communications" \
|
||||
osmocom
|
||||
fi
|
||||
|
||||
# Fix permissions of previous (root-owned) install (OS#4107)
|
||||
if dpkg --compare-versions "$2" le "1.13.0"; then
|
||||
if [ -e /etc/osmocom/osmo-ggsn.cfg ]; then
|
||||
chown -v osmocom:osmocom /etc/osmocom/osmo-ggsn.cfg
|
||||
chmod -v 0660 /etc/osmocom/osmo-ggsn.cfg
|
||||
fi
|
||||
|
||||
if [ -d /etc/osmocom ]; then
|
||||
chown -v root:osmocom /etc/osmocom
|
||||
chmod -v 2775 /etc/osmocom
|
||||
fi
|
||||
|
||||
mkdir -p /var/lib/osmocom
|
||||
chown -R -v osmocom:osmocom /var/lib/osmocom
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb(1) will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
#DEBHELPER#
|
||||
|
||||
2
debian/rules
vendored
2
debian/rules
vendored
@@ -16,7 +16,7 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||
|
||||
override_dh_strip:
|
||||
dh_strip -posmo-ggsn --dbg-package=osmo-ggsn-dbg
|
||||
dh_strip -plibgtp6 --dbg-package=libgtp-dbg
|
||||
dh_strip -plibgtp10 --dbg-package=libgtp-dbg
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure -- \
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
!!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging print category 0
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level ip info
|
||||
logging level tun info
|
||||
logging level ggsn info
|
||||
@@ -36,7 +38,7 @@ line vty
|
||||
no login
|
||||
!
|
||||
ggsn ggsn0
|
||||
gtp state-dir /tmp
|
||||
gtp state-dir /var/lib/osmocom/osmo-ggsn
|
||||
gtp bind-ip 127.0.0.2
|
||||
apn internet
|
||||
gtpu-mode kernel-gtp
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
!!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging print category 0
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level ip info
|
||||
logging level tun info
|
||||
logging level ggsn info
|
||||
@@ -36,7 +38,7 @@ line vty
|
||||
no login
|
||||
!
|
||||
ggsn ggsn0
|
||||
gtp state-dir /tmp
|
||||
gtp state-dir /var/lib/osmocom/osmo-ggsn
|
||||
gtp bind-ip 127.0.0.2
|
||||
apn internet
|
||||
gtpu-mode tun
|
||||
|
||||
@@ -16,7 +16,7 @@ your configuration file, like in below example:
|
||||
.Example: Single GGSN configuration section
|
||||
----
|
||||
ggsn ggsn0
|
||||
gtp state-dir /tmp
|
||||
gtp state-dir /var/lib/osmocom/osmo-ggsn
|
||||
gtp bind-ip 127.0.0.6
|
||||
apn internet
|
||||
gtpu-mode tun
|
||||
@@ -58,7 +58,7 @@ The following two mandatory configuration statements have to be given
|
||||
for every GGSN instance:
|
||||
|
||||
----
|
||||
OsmoGGSN(config-ggsn)# gtp state-dir /var/lib/ggsn/ggsn0 <1>
|
||||
OsmoGGSN(config-ggsn)# gtp state-dir /var/lib/osmocom/osmo-ggsn <1>
|
||||
OsmoGGSN(config-ggsn)# gtp bind-ip 127.0.0.6 <2>
|
||||
----
|
||||
<1> Store the GSN restart state in the specified directory
|
||||
@@ -101,7 +101,7 @@ OsmoGGSN(config-ggsn)# no shutdown ggsn <4>
|
||||
----
|
||||
<1> Change into privileged mode
|
||||
<2> Enter the interactive configuration mode
|
||||
<3> Enter the config ndoe of the GGSN instance `ggsn0`
|
||||
<3> Enter the config node of the GGSN instance `ggsn0`
|
||||
<4> Take the GGSN instance out of shutdown
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ OsmoGGSN(config-ggsn)# shutdown ggsn <4>
|
||||
----
|
||||
<1> Change into privileged mode
|
||||
<2> Enter the interactive configuration mode
|
||||
<3> Enter the config ndoe of the GGSN instance `ggsn0`
|
||||
<3> Enter the config node of the GGSN instance `ggsn0`
|
||||
<4> Shut down the GGSN instance
|
||||
|
||||
|
||||
@@ -215,8 +215,8 @@ OsmoGGSN(config-ggsn-apn)# no shutdown <5>
|
||||
----
|
||||
<1> Change into privileged mode
|
||||
<2> Enter the interactive configuration mode
|
||||
<3> Enter the config ndoe of the GGSN instance `ggsn0`
|
||||
<4> Enter the config ndoe of the APN `internet`
|
||||
<3> Enter the config node of the GGSN instance `ggsn0`
|
||||
<4> Enter the config node of the APN `internet`
|
||||
<5> Take the APN out of shutdown
|
||||
|
||||
|
||||
@@ -237,8 +237,8 @@ OsmoGGSN(config-ggsn-apn)# shutdown <5>
|
||||
----
|
||||
<1> Change into privileged mode
|
||||
<2> Enter the interactive configuration mode
|
||||
<3> Enter the config ndoe of the GGSN instance `ggsn0`
|
||||
<4> Enter the config ndoe of the APN `internet`
|
||||
<3> Enter the config node of the GGSN instance `ggsn0`
|
||||
<4> Enter the config node of the APN `internet`
|
||||
<5> Shut down the APN
|
||||
|
||||
[[ggsn_no_root]]
|
||||
@@ -302,7 +302,7 @@ Name=apn0 <1>
|
||||
Address=192.168.7.1/24 <2>
|
||||
IPMasquerade=yes <3>
|
||||
----
|
||||
<1> The netowrk device name, which must match the one in the apn0.netdev unit file above
|
||||
<1> The network device name, which must match the one in the apn0.netdev unit file above
|
||||
<2> The local IP address configured on the device
|
||||
<3> Requesting systemd to configure IP masquerading for this interface. Depending on your needs,
|
||||
You may not want this if you have proper end-to-end routing set up, and want to have transparent
|
||||
|
||||
@@ -83,7 +83,12 @@ ggsn ggsn0
|
||||
|
||||
=== GTP-U kernel module
|
||||
|
||||
WARNING: As of writing, the kernel module does not support IPv6.
|
||||
WARNING: As of writing, IPv6 support for the kernel module has not been
|
||||
upstreamed yet (OS#1952).
|
||||
|
||||
WARNING: As of writing, it is not possible to configure multiple APNs with
|
||||
gtpu-mode kernel-gpt. This is a limitation in OsmoGGSN, not in the
|
||||
kernel module (OS#6106).
|
||||
|
||||
OsmoGGSN has support to use the Linux kernel GTP-U tunnel driver to accelerate
|
||||
the data/user plane while still implementing the control plane (GTP-C) in
|
||||
|
||||
@@ -2,7 +2,16 @@ bin_PROGRAMS = osmo-ggsn
|
||||
|
||||
AM_LDFLAGS = @EXEC_LDFLAGS@
|
||||
|
||||
AM_CFLAGS = -O2 -D_GNU_SOURCE -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS)
|
||||
AM_CFLAGS = \
|
||||
-D_GNU_SOURCE \
|
||||
-fno-builtin \
|
||||
-Wall \
|
||||
-DSBINDIR='"$(sbindir)"' \
|
||||
-I$(top_srcdir)/include \
|
||||
$(LIBOSMOCORE_CFLAGS) \
|
||||
$(LIBOSMOCTRL_CFLAGS) \
|
||||
$(LIBOSMOVTY_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
osmo_ggsn_LDADD = @EXEC_LDADD@ -lgtp -L../gtp ../lib/libmisc.a $(LIBOSMOCORE_LIBS) $(LIBOSMOCTRL_LIBS) $(LIBOSMOVTY_LIBS)
|
||||
|
||||
|
||||
18
ggsn/ggsn.c
18
ggsn/ggsn.c
@@ -46,17 +46,19 @@
|
||||
#include <osmocom/ctrl/control_if.h>
|
||||
#include <osmocom/gsm/apn.h>
|
||||
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
#include <osmocom/gtp/gtp.h>
|
||||
|
||||
#include "../lib/tun.h"
|
||||
#include "../lib/ippool.h"
|
||||
#include "../lib/syserr.h"
|
||||
#include "../lib/in46_addr.h"
|
||||
#include "../lib/gtp-kernel.h"
|
||||
#include "../lib/util.h"
|
||||
#include "../gtp/pdp.h"
|
||||
#include "../gtp/gtp.h"
|
||||
#include "../lib/icmpv6.h"
|
||||
#include "pco.h"
|
||||
#include "ggsn.h"
|
||||
#include "../gtp/gtp_internal.h"
|
||||
|
||||
static int ggsn_tun_fd_cb(struct osmo_fd *fd, unsigned int what);
|
||||
static int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len);
|
||||
@@ -193,7 +195,7 @@ int apn_start(struct apn_ctx *apn)
|
||||
}
|
||||
LOGPAPN(LOGL_INFO, apn, "Opened TUN device %s\n", apn->tun.tun->devname);
|
||||
|
||||
/* Register with libosmcoore */
|
||||
/* Register with libosmocore */
|
||||
osmo_fd_setup(&apn->tun.fd, apn->tun.tun->fd, OSMO_FD_READ, ggsn_tun_fd_cb, apn, 0);
|
||||
osmo_fd_register(&apn->tun.fd);
|
||||
|
||||
@@ -202,11 +204,6 @@ int apn_start(struct apn_ctx *apn)
|
||||
break;
|
||||
case APN_GTPU_MODE_KERNEL_GTP:
|
||||
LOGPAPN(LOGL_INFO, apn, "Opening Kernel GTP device %s\n", apn->tun.cfg.dev_name);
|
||||
if (apn->cfg.apn_type_mask & (APN_TYPE_IPv6|APN_TYPE_IPv4v6)) {
|
||||
LOGPAPN(LOGL_ERROR, apn, "Kernel GTP currently supports only IPv4\n");
|
||||
apn_stop(apn);
|
||||
return -1;
|
||||
}
|
||||
if (gsn == NULL) {
|
||||
/* skip bringing up the APN now if the GSN is not initialized yet.
|
||||
* This happens during initial load of the config file, as the
|
||||
@@ -536,10 +533,11 @@ int create_context_ind(struct pdp_t *pdp)
|
||||
|
||||
in46a_to_eua(addr, num_addr, &pdp->eua);
|
||||
|
||||
if (apn->cfg.gtpu_mode == APN_GTPU_MODE_KERNEL_GTP && apn_supports_ipv4(apn)) {
|
||||
/* TODO: In IPv6, EUA doesn't contain the actual IP addr/prefix! */
|
||||
if (apn->cfg.gtpu_mode == APN_GTPU_MODE_KERNEL_GTP) {
|
||||
if (gtp_kernel_tunnel_add(pdp, apn->tun.cfg.dev_name) < 0) {
|
||||
LOGPPDP(LOGL_ERROR, pdp, "Cannot add tunnel to kernel: %s\n", strerror(errno));
|
||||
if (addrv6 && errno == EINVAL)
|
||||
LOGPPDP(LOGL_ERROR, pdp, "Maybe your kernel does not support GTP-U with IPv6 yet?\n");
|
||||
gtp_create_context_resp(gsn, pdp, GTPCAUSE_SYS_FAIL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/tdef.h>
|
||||
#include <osmocom/ctrl/control_if.h>
|
||||
#include <osmocom/gtp/gtp.h>
|
||||
|
||||
#include "../lib/tun.h"
|
||||
#include "../lib/ippool.h"
|
||||
#include "../lib/syserr.h"
|
||||
#include "../lib/in46_addr.h"
|
||||
#include "../gtp/gtp.h"
|
||||
|
||||
#include "sgsn.h"
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <inttypes.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
@@ -35,13 +37,14 @@
|
||||
#include <osmocom/vty/misc.h>
|
||||
#include <osmocom/vty/tdef_vty.h>
|
||||
|
||||
#include "../gtp/gtp.h"
|
||||
#include "../gtp/pdp.h"
|
||||
#include <osmocom/gtp/gtp.h>
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
|
||||
#include "../lib/util.h"
|
||||
|
||||
#include "ggsn.h"
|
||||
#include "sgsn.h"
|
||||
#include "../gtp/gtp_internal.h"
|
||||
|
||||
#define PREFIX_STR "Prefix (Network/Netmask)\n"
|
||||
#define IFCONFIG_STR "GGSN-based interface configuration\n"
|
||||
@@ -223,6 +226,11 @@ DEFUN(cfg_ggsn_state_dir, cfg_ggsn_state_dir_cmd,
|
||||
{
|
||||
struct ggsn_ctx *ggsn = (struct ggsn_ctx *) vty->index;
|
||||
|
||||
if (mkdir(argv[0], 0755) == -1 && errno != EEXIST) {
|
||||
vty_out(vty, "%% Failed to create state-dir: %s%s", argv[0], VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
osmo_talloc_replace_string(ggsn, &ggsn->cfg.state_dir, argv[0]);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
@@ -814,10 +822,7 @@ static const char *print_gsnaddr(const struct ul16_t *in)
|
||||
{
|
||||
struct in46_addr in46;
|
||||
|
||||
in46.len = in->l;
|
||||
OSMO_ASSERT(in->l <= sizeof(in46.v6));
|
||||
memcpy(&in46.v6, in->v, in->l);
|
||||
|
||||
in46a_from_gsna(in, &in46);
|
||||
return in46a_ntoa(&in46);
|
||||
}
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ ret_broken:
|
||||
osmo_hexdump_nospc((const uint8_t *)pco_in, pco_in->length));
|
||||
}
|
||||
|
||||
/* Handle IP Control Protocol, RFC 1332, extensions in RFC 1877 */
|
||||
static void process_pco_element_ipcp(const struct pco_element *pco_elem, struct msgb *resp,
|
||||
const struct apn_ctx *apn, struct pdp_t *pdp)
|
||||
{
|
||||
|
||||
11
ggsn/pco.h
11
ggsn/pco.h
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../gtp/pdp.h"
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
|
||||
/* 3GPP TS 24.008 10.5.6.3 */
|
||||
enum pco_protocols {
|
||||
@@ -42,12 +42,11 @@ struct pco_element {
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/* RFC 1332 */
|
||||
/* RFC 1332 IP Control Protocol options, extensions in RFC 1877 */
|
||||
enum ipcp_options {
|
||||
IPCP_OPT_IPADDR = 3,
|
||||
IPCP_OPT_PRIMARY_DNS = 129,
|
||||
IPCP_OPT_SECONDARY_DNS = 131,
|
||||
IPCP_OPT_IPADDR = 3, /* RFC 1332 3.3 */
|
||||
IPCP_OPT_PRIMARY_DNS = 129, /* RFC 1877 1.1 */
|
||||
IPCP_OPT_SECONDARY_DNS = 131, /* RFC 1877 1.2 */
|
||||
};
|
||||
|
||||
struct ipcp_option_hdr {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "sgsn.h"
|
||||
#include "ggsn.h"
|
||||
|
||||
#include "../gtp/gtp_internal.h"
|
||||
|
||||
static bool sgsn_peer_attempt_free(struct sgsn_peer *sgsn)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
|
||||
#include "../gtp/pdp.h"
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
|
||||
struct ggsn_ctx;
|
||||
struct pdp_priv_t;
|
||||
|
||||
@@ -2,14 +2,30 @@
|
||||
# Please read chapter "Library interface versions" of the libtool documentation
|
||||
# before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html
|
||||
# If major=current-age is increased, remember to update the dh_strip line in debian/rules!
|
||||
LIBVERSION=9:0:3
|
||||
LIBVERSION=10:0:0
|
||||
|
||||
lib_LTLIBRARIES = libgtp.la
|
||||
|
||||
include_HEADERS = gtp.h gsn.h pdp.h gtpie.h
|
||||
AM_CFLAGS = \
|
||||
-fno-builtin \
|
||||
-Wall \
|
||||
-DSBINDIR='"$(sbindir)"' \
|
||||
-I$(top_srcdir)/include \
|
||||
$(LIBOSMOCORE_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
AM_CFLAGS = -O2 -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb $(LIBOSMOCORE_CFLAGS)
|
||||
libgtp_la_SOURCES = \
|
||||
gsn.c \
|
||||
gsn_internal.h \
|
||||
gtp.c \
|
||||
gtp_internal.h \
|
||||
gtpie.c \
|
||||
lookupa.c \
|
||||
lookupa.h \
|
||||
pdp.c \
|
||||
queue.c \
|
||||
queue.h \
|
||||
$(NULL)
|
||||
|
||||
libgtp_la_SOURCES = gtp.c gtp.h gsn.c gsn.h gtpie.c gtpie.h pdp.c pdp.h lookupa.c lookupa.h queue.c queue.h
|
||||
libgtp_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined
|
||||
libgtp_la_LIBADD = $(LIBOSMOCORE_LIBS)
|
||||
|
||||
132
gtp/gsn.c
132
gtp/gsn.c
@@ -57,17 +57,19 @@
|
||||
|
||||
/* #include <stdint.h> ISO C99 types */
|
||||
|
||||
#include "pdp.h"
|
||||
#include "gtp.h"
|
||||
#include "gtpie.h"
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
#include <osmocom/gtp/gtp.h>
|
||||
#include <osmocom/gtp/gtpie.h>
|
||||
|
||||
#include "queue.h"
|
||||
#include "gsn_internal.h"
|
||||
|
||||
/* Error reporting functions */
|
||||
|
||||
#define LOGP_WITH_ADDR(ss, level, addr, fmt, args...) \
|
||||
LOGP(ss, level, "addr(%s:%d) " fmt, \
|
||||
inet_ntoa((addr).sin_addr), htons((addr).sin_port), \
|
||||
##args);
|
||||
##args)
|
||||
|
||||
static const struct rate_ctr_desc gsn_ctr_description[] = {
|
||||
[GSN_CTR_ERR_SOCKET] = { "err:socket", "Socket error" },
|
||||
@@ -423,11 +425,45 @@ free_filename:
|
||||
talloc_free(filename);
|
||||
}
|
||||
|
||||
static int create_and_bind_socket(const char *name, struct gsn_t *gsn, int *fd, int domain,
|
||||
const struct in_addr *listen, int port)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int type = SOCK_DGRAM;
|
||||
int protocol = 0;
|
||||
|
||||
*fd = socket(domain, type, protocol);
|
||||
|
||||
if (*fd < 0) {
|
||||
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SOCKET);
|
||||
LOGP(DLGTP, LOGL_ERROR,
|
||||
"%s socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n",
|
||||
name, domain, type, protocol, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = domain;
|
||||
addr.sin_addr = *listen;
|
||||
addr.sin_port = htons(port);
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
addr.sin_len = sizeof(addr);
|
||||
#endif
|
||||
|
||||
if (bind(*fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SOCKET);
|
||||
LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr,
|
||||
"%s bind(fd=%d) failed: Error = %s\n",
|
||||
name, *fd, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
|
||||
int mode)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
|
||||
LOGP(DLGTP, LOGL_NOTICE, "GTP: gtp_newgsn() started at %s\n", inet_ntoa(*listen));
|
||||
|
||||
*gsn = calloc(sizeof(struct gsn_t), 1); /* TODO */
|
||||
@@ -467,89 +503,35 @@ int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
|
||||
(*gsn)->cb_data_ind = 0;
|
||||
|
||||
/* Store function parameters */
|
||||
/* Same IP for user traffic and signalling */
|
||||
(*gsn)->gsnc = *listen;
|
||||
(*gsn)->gsnu = *listen;
|
||||
(*gsn)->mode = mode;
|
||||
|
||||
(*gsn)->fd0 = -1;
|
||||
(*gsn)->fd1c = -1;
|
||||
(*gsn)->fd1u = -1;
|
||||
|
||||
/* Create GTP version 0 socket */
|
||||
if (((*gsn)->fd0 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET);
|
||||
LOGP(DLGTP, LOGL_ERROR,
|
||||
"GTPv0 socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n",
|
||||
AF_INET, SOCK_DGRAM, 0, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr = *listen; /* Same IP for user traffic and signalling */
|
||||
addr.sin_port = htons(GTP0_PORT);
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
addr.sin_len = sizeof(addr);
|
||||
#endif
|
||||
|
||||
if (bind((*gsn)->fd0, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET);
|
||||
LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr,
|
||||
"bind(fd0=%d) failed: Error = %s\n",
|
||||
(*gsn)->fd0, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
if (create_and_bind_socket("GTPv0", *gsn, &(*gsn)->fd0, AF_INET, listen, GTP0_PORT) < 0)
|
||||
goto error;
|
||||
|
||||
/* Create GTP version 1 control plane socket */
|
||||
if (((*gsn)->fd1c = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET);
|
||||
LOGP(DLGTP, LOGL_ERROR,
|
||||
"GTPv1 control plane socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n",
|
||||
AF_INET, SOCK_DGRAM, 0, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr = *listen; /* Same IP for user traffic and signalling */
|
||||
addr.sin_port = htons(GTP1C_PORT);
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
addr.sin_len = sizeof(addr);
|
||||
#endif
|
||||
|
||||
if (bind((*gsn)->fd1c, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET);
|
||||
LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr,
|
||||
"bind(fd1c=%d) failed: Error = %s\n",
|
||||
(*gsn)->fd1c, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
if (create_and_bind_socket("GTPv1 control plane", *gsn, &(*gsn)->fd1c, AF_INET, listen, GTP1C_PORT) < 0)
|
||||
goto error;
|
||||
|
||||
/* Create GTP version 1 user plane socket */
|
||||
if (((*gsn)->fd1u = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET);
|
||||
LOGP(DLGTP, LOGL_ERROR,
|
||||
"GTPv1 user plane socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n",
|
||||
AF_INET, SOCK_DGRAM, 0, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr = *listen; /* Same IP for user traffic and signalling */
|
||||
addr.sin_port = htons(GTP1U_PORT);
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
addr.sin_len = sizeof(addr);
|
||||
#endif
|
||||
|
||||
if (bind((*gsn)->fd1u, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET);
|
||||
LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr,
|
||||
"bind(fd1u=%d) failed: Error = %s\n",
|
||||
(*gsn)->fd1u, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
if (create_and_bind_socket("GTPv1 user plane", *gsn, &(*gsn)->fd1u, AF_INET, listen, GTP1U_PORT) < 0)
|
||||
goto error;
|
||||
|
||||
/* Start internal queue timer */
|
||||
gtp_queue_timer_start(*gsn);
|
||||
|
||||
return 0;
|
||||
error:
|
||||
gtp_free(*gsn);
|
||||
*gsn = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int gtp_free(struct gsn_t *gsn)
|
||||
|
||||
3
gtp/gsn_internal.h
Normal file
3
gtp/gsn_internal.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void gtp_queue_timer_start(struct gsn_t *gsn);
|
||||
191
gtp/gtp.c
191
gtp/gtp.c
@@ -55,10 +55,13 @@
|
||||
|
||||
/* #include <stdint.h> ISO C99 types */
|
||||
|
||||
#include "pdp.h"
|
||||
#include "gtp.h"
|
||||
#include "gtpie.h"
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
#include <osmocom/gtp/gtp.h>
|
||||
#include <osmocom/gtp/gtpie.h>
|
||||
|
||||
#include "queue.h"
|
||||
#include "gsn_internal.h"
|
||||
#include "gtp_internal.h"
|
||||
|
||||
/* Error reporting functions */
|
||||
|
||||
@@ -638,8 +641,8 @@ int gtp_echo_req(struct gsn_t *gsn, int version, void *cbp,
|
||||
}
|
||||
|
||||
/* Send off an echo reply */
|
||||
int gtp_echo_resp(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, int fd, void *pack, unsigned len)
|
||||
static int gtp_echo_resp(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, int fd, void *pack, unsigned len)
|
||||
{
|
||||
union gtp_packet packet;
|
||||
unsigned int length = get_default_gtp(version, GTP_ECHO_RSP, &packet);
|
||||
@@ -650,8 +653,8 @@ int gtp_echo_resp(struct gsn_t *gsn, int version,
|
||||
}
|
||||
|
||||
/* Handle a received echo request */
|
||||
int gtp_echo_ind(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
|
||||
int fd, void *pack, unsigned len)
|
||||
static int gtp_echo_ind(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
|
||||
int fd, void *pack, unsigned len)
|
||||
{
|
||||
|
||||
/* Check if it was a duplicate request */
|
||||
@@ -663,8 +666,8 @@ int gtp_echo_ind(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
|
||||
}
|
||||
|
||||
/* Handle a received echo reply */
|
||||
int gtp_echo_conf(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
|
||||
void *pack, unsigned len)
|
||||
static int gtp_echo_conf(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
|
||||
void *pack, unsigned len)
|
||||
{
|
||||
union gtpie_member *ie[GTPIE_SIZE];
|
||||
unsigned char recovery;
|
||||
@@ -716,8 +719,8 @@ int gtp_echo_conf(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
|
||||
* only listen to the GTP0 port, and therefore will never receive
|
||||
* anything else than GTP0 */
|
||||
|
||||
int gtp_unsup_req(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
|
||||
int fd, void *pack, unsigned len)
|
||||
static int gtp_unsup_req(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
|
||||
int fd, void *pack, unsigned len)
|
||||
{
|
||||
union gtp_packet packet;
|
||||
|
||||
@@ -727,8 +730,8 @@ int gtp_unsup_req(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
|
||||
}
|
||||
|
||||
/* Handle a Version Not Supported message */
|
||||
int gtp_unsup_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
|
||||
void *pack, unsigned len)
|
||||
static int gtp_unsup_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
|
||||
void *pack, unsigned len)
|
||||
{
|
||||
|
||||
if (gsn->cb_unsup_ind)
|
||||
@@ -820,6 +823,40 @@ int gtp_ran_info_relay_req(struct gsn_t *gsn, const struct sockaddr_in *peer,
|
||||
return gtp_notification(gsn, 1, &packet, length, peer, gsn->fd1c, 0);
|
||||
}
|
||||
|
||||
/* ***********************************************************
|
||||
* Conversion functions
|
||||
*************************************************************/
|
||||
|
||||
/* ***********************************************************
|
||||
* IP address conversion functions
|
||||
* There exist several types of address representations:
|
||||
* - eua: End User Address. (29.060, 7.7.27, message type 128)
|
||||
* Used for signalling address to mobile station. Supports IPv4
|
||||
* IPv6 x.25 etc. etc.
|
||||
* - gsna: GSN Address. (29.060, 7.7.32, message type 133): IP address
|
||||
* of GSN. If length is 4 it is IPv4. If length is 16 it is IPv6.
|
||||
* - in_addr: IPv4 address struct.
|
||||
* - sockaddr_in: Socket API representation of IP address and
|
||||
* port number.
|
||||
*************************************************************/
|
||||
|
||||
int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna)
|
||||
{
|
||||
memset(dst, 0, sizeof(struct in_addr));
|
||||
if (gsna->l != 4)
|
||||
return EOF; /* Return if not IPv4 */
|
||||
memcpy(dst, gsna->v, gsna->l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src)
|
||||
{
|
||||
memset(gsna, 0, sizeof(struct ul16_t));
|
||||
gsna->l = 4;
|
||||
memcpy(gsna->v, src, gsna->l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ***********************************************************
|
||||
* Session management messages
|
||||
* Messages: create, update and delete PDP context
|
||||
@@ -988,22 +1025,9 @@ int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* API: Application response to context indication */
|
||||
int gtp_create_context_resp(struct gsn_t *gsn, struct pdp_t *pdp, int cause)
|
||||
{
|
||||
|
||||
/* Now send off a reply to the peer */
|
||||
gtp_create_pdp_resp(gsn, pdp->version, pdp, cause);
|
||||
|
||||
if (cause != GTPCAUSE_ACC_REQ)
|
||||
gtp_freepdp(gsn, pdp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Send Create PDP Context Response */
|
||||
int gtp_create_pdp_resp(struct gsn_t *gsn, int version, struct pdp_t *pdp,
|
||||
uint8_t cause)
|
||||
static int gtp_create_pdp_resp(struct gsn_t *gsn, int version, struct pdp_t *pdp,
|
||||
uint8_t cause)
|
||||
{
|
||||
union gtp_packet packet;
|
||||
unsigned int length =
|
||||
@@ -1011,7 +1035,7 @@ int gtp_create_pdp_resp(struct gsn_t *gsn, int version, struct pdp_t *pdp,
|
||||
|
||||
gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_CAUSE, cause);
|
||||
|
||||
if (cause == GTPCAUSE_ACC_REQ) {
|
||||
if (gtp_cause_successful(cause)) {
|
||||
|
||||
if (version == 0)
|
||||
gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
|
||||
@@ -1064,10 +1088,23 @@ int gtp_create_pdp_resp(struct gsn_t *gsn, int version, struct pdp_t *pdp,
|
||||
pdp->fd, pdp->seq, pdp->tid);
|
||||
}
|
||||
|
||||
/* API: Application response to context indication */
|
||||
int gtp_create_context_resp(struct gsn_t *gsn, struct pdp_t *pdp, int cause)
|
||||
{
|
||||
|
||||
/* Now send off a reply to the peer */
|
||||
gtp_create_pdp_resp(gsn, pdp->version, pdp, cause);
|
||||
|
||||
if (!gtp_cause_successful(cause))
|
||||
gtp_freepdp(gsn, pdp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Handle Create PDP Context Request */
|
||||
int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, int fd,
|
||||
void *pack, unsigned len)
|
||||
static int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, int fd,
|
||||
void *pack, unsigned len)
|
||||
{
|
||||
struct pdp_t *pdp, *pdp_old;
|
||||
struct pdp_t pdp_buf;
|
||||
@@ -1390,8 +1427,8 @@ recover_ret:
|
||||
}
|
||||
|
||||
/* Handle Create PDP Context Response */
|
||||
int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, void *pack, unsigned len)
|
||||
static int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, void *pack, unsigned len)
|
||||
{
|
||||
struct pdp_t *pdp;
|
||||
union gtpie_member *ie[GTPIE_SIZE];
|
||||
@@ -1445,7 +1482,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
|
||||
}
|
||||
|
||||
/* Check all conditional information elements */
|
||||
if (GTPCAUSE_ACC_REQ == cause) {
|
||||
if (gtp_cause_successful(cause)) {
|
||||
|
||||
if (version == 0) {
|
||||
if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
|
||||
@@ -1667,7 +1704,7 @@ static int gtp_update_pdp_resp(struct gsn_t *gsn, uint8_t version,
|
||||
|
||||
gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_CAUSE, cause);
|
||||
|
||||
if (cause == GTPCAUSE_ACC_REQ) {
|
||||
if (gtp_cause_successful(cause)) {
|
||||
|
||||
if (version == 0)
|
||||
gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
|
||||
@@ -1997,7 +2034,7 @@ static int gtp_update_pdp_conf(struct gsn_t *gsn, uint8_t version,
|
||||
|
||||
/* Check all conditional information elements */
|
||||
/* TODO: This does not handle GGSN-initiated update responses */
|
||||
if (cause == GTPCAUSE_ACC_REQ) {
|
||||
if (gtp_cause_successful(cause)) {
|
||||
if (version == 0) {
|
||||
if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
|
||||
&pdp->qos_neg0,
|
||||
@@ -2157,11 +2194,11 @@ int gtp_delete_context_req2(struct gsn_t *gsn, struct pdp_t *pdp, void *cbp,
|
||||
}
|
||||
|
||||
/* Send Delete PDP Context Response */
|
||||
int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, int fd,
|
||||
void *pack, unsigned len,
|
||||
struct pdp_t *pdp, struct pdp_t *linked_pdp,
|
||||
uint8_t cause, int teardown)
|
||||
static int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, int fd,
|
||||
void *pack, unsigned len,
|
||||
struct pdp_t *pdp, struct pdp_t *linked_pdp,
|
||||
uint8_t cause, int teardown)
|
||||
{
|
||||
union gtp_packet packet;
|
||||
unsigned int length =
|
||||
@@ -2172,7 +2209,7 @@ int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
|
||||
gtp_resp(version, gsn, pdp, &packet, length, peer, fd,
|
||||
get_seq(pack), get_tid(pack));
|
||||
|
||||
if (cause == GTPCAUSE_ACC_REQ) {
|
||||
if (gtp_cause_successful(cause)) {
|
||||
if ((teardown) || (version == 0)) { /* Remove all contexts */
|
||||
gtp_freepdp_teardown(gsn, linked_pdp);
|
||||
} else {
|
||||
@@ -2198,14 +2235,13 @@ int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
|
||||
}
|
||||
}
|
||||
}
|
||||
/* if (cause == GTPCAUSE_ACC_REQ) */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Handle Delete PDP Context Request */
|
||||
int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, int fd,
|
||||
void *pack, unsigned len)
|
||||
static int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, int fd,
|
||||
void *pack, unsigned len)
|
||||
{
|
||||
struct pdp_t *pdp = NULL;
|
||||
struct pdp_t *linked_pdp = NULL;
|
||||
@@ -2302,8 +2338,8 @@ int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
|
||||
}
|
||||
|
||||
/* Handle Delete PDP Context Response */
|
||||
int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, void *pack, unsigned len)
|
||||
static int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, void *pack, unsigned len)
|
||||
{
|
||||
union gtpie_member *ie[GTPIE_SIZE];
|
||||
uint8_t cause;
|
||||
@@ -2350,7 +2386,7 @@ int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
|
||||
}
|
||||
|
||||
/* Check the cause value (again) */
|
||||
if ((GTPCAUSE_ACC_REQ != cause) && (GTPCAUSE_NON_EXIST != cause)) {
|
||||
if (!gtp_cause_successful(cause) && (GTPCAUSE_NON_EXIST != cause)) {
|
||||
rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_UNEXPECTED_CAUSE);
|
||||
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
|
||||
"Unexpected cause value received: %d\n", cause);
|
||||
@@ -3051,61 +3087,6 @@ int gtp_data_req(struct gsn_t *gsn, struct pdp_t *pdp, void *pack, unsigned len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ***********************************************************
|
||||
* Conversion functions
|
||||
*************************************************************/
|
||||
|
||||
/* ***********************************************************
|
||||
* IP address conversion functions
|
||||
* There exist several types of address representations:
|
||||
* - eua: End User Address. (29.060, 7.7.27, message type 128)
|
||||
* Used for signalling address to mobile station. Supports IPv4
|
||||
* IPv6 x.25 etc. etc.
|
||||
* - gsna: GSN Address. (29.060, 7.7.32, message type 133): IP address
|
||||
* of GSN. If length is 4 it is IPv4. If length is 16 it is IPv6.
|
||||
* - in_addr: IPv4 address struct.
|
||||
* - sockaddr_in: Socket API representation of IP address and
|
||||
* port number.
|
||||
*************************************************************/
|
||||
|
||||
int ipv42eua(struct ul66_t *eua, struct in_addr *src)
|
||||
{
|
||||
eua->v[0] = PDP_EUA_ORG_IETF;
|
||||
eua->v[1] = PDP_EUA_TYPE_v4;
|
||||
if (src) {
|
||||
eua->l = 6;
|
||||
memcpy(&eua->v[2], src, 4);
|
||||
} else {
|
||||
eua->l = 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eua2ipv4(struct in_addr *dst, struct ul66_t *eua)
|
||||
{
|
||||
if ((eua->l != 6) || (eua->v[0] != PDP_EUA_ORG_IETF) || (eua->v[1] != PDP_EUA_TYPE_v4))
|
||||
return -1; /* Not IPv4 address */
|
||||
memcpy(dst, &eua->v[2], 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna)
|
||||
{
|
||||
memset(dst, 0, sizeof(struct in_addr));
|
||||
if (gsna->l != 4)
|
||||
return EOF; /* Return if not IPv4 */
|
||||
memcpy(dst, gsna->v, gsna->l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src)
|
||||
{
|
||||
memset(gsna, 0, sizeof(struct ul16_t));
|
||||
gsna->l = 4;
|
||||
memcpy(gsna->v, src, gsna->l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TS 29.060 has yet again a different encoding for IMSIs than
|
||||
* what we have in other places, so we cannot use the gsm48
|
||||
* decoding functions. Also, libgtp uses an uint64_t in
|
||||
|
||||
3
gtp/gtp_internal.h
Normal file
3
gtp/gtp_internal.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
uint64_t gtp_imsi_str2gtp(const char *str);
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gtpie.h"
|
||||
#include <osmocom/gtp/gtpie.h>
|
||||
|
||||
/*! Encode a TLV type Information Element.
|
||||
* \param[inout] p Pointer to output packet to which IE is appended
|
||||
|
||||
@@ -28,8 +28,10 @@
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "pdp.h"
|
||||
#include "gtp.h"
|
||||
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
#include <osmocom/gtp/gtp.h>
|
||||
|
||||
#include "lookupa.h"
|
||||
#include "queue.h"
|
||||
|
||||
|
||||
@@ -27,8 +27,10 @@
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include "pdp.h"
|
||||
#include "gtp.h"
|
||||
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
#include <osmocom/gtp/gtp.h>
|
||||
|
||||
#include "queue.h"
|
||||
|
||||
/*! \brief dump a queue_t to stdout */
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
#include "gtp.h"
|
||||
#include <osmocom/gtp/gtp.h>
|
||||
|
||||
#define QUEUE_DEBUG 0 /* Print debug information */
|
||||
|
||||
|
||||
3
include/Makefile.am
Normal file
3
include/Makefile.am
Normal file
@@ -0,0 +1,3 @@
|
||||
SUBDIRS = \
|
||||
osmocom \
|
||||
$(NULL)
|
||||
3
include/osmocom/Makefile.am
Normal file
3
include/osmocom/Makefile.am
Normal file
@@ -0,0 +1,3 @@
|
||||
SUBDIRS = \
|
||||
gtp \
|
||||
$(NULL)
|
||||
8
include/osmocom/gtp/Makefile.am
Normal file
8
include/osmocom/gtp/Makefile.am
Normal file
@@ -0,0 +1,8 @@
|
||||
libgtp_HEADERS = \
|
||||
gsn.h \
|
||||
gtp.h \
|
||||
gtpie.h \
|
||||
pdp.h \
|
||||
$(NULL)
|
||||
|
||||
libgtpdir = $(includedir)/osmocom/gtp
|
||||
@@ -175,7 +175,4 @@ extern int gtp_fd(struct gsn_t *gsn);
|
||||
extern int gtp_retrans(struct gsn_t *gsn) OSMO_DEPRECATED("This API is a no-op, libgtp already does the job internally");
|
||||
extern int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout) OSMO_DEPRECATED("This API is a no-op and will return a 1 day timeout");
|
||||
|
||||
/* Internal APIs: */
|
||||
void gtp_queue_timer_start(struct gsn_t *gsn);
|
||||
|
||||
#endif /* !_GSN_H */
|
||||
@@ -53,7 +53,7 @@
|
||||
#define GTP_UPDATE_PDP_RSP 19 /* Update PDP Context Response */
|
||||
#define GTP_DELETE_PDP_REQ 20 /* Delete PDP Context Request */
|
||||
#define GTP_DELETE_PDP_RSP 21 /* Delete PDP Context Response */
|
||||
/* 22-25 For future use. *//* In version GTP 1 anonomous PDP context */
|
||||
/* 22-25 For future use. *//* In version GTP 1 anonomous PDP context */
|
||||
#define GTP_ERROR 26 /* Error Indication */
|
||||
#define GTP_PDU_NOT_REQ 27 /* PDU Notification Request */
|
||||
#define GTP_PDU_NOT_RSP 28 /* PDU Notification Response */
|
||||
@@ -99,19 +99,21 @@ static inline const char *gtp_type_name(uint8_t val)
|
||||
#define GTPCAUSE_NO_ID_NEEDED 3 /* No identity needed */
|
||||
#define GTPCAUSE_MS_REFUSES_X 4 /* MS refuses */
|
||||
#define GTPCAUSE_MS_NOT_RESP_X 5 /* MS is not GPRS responding */
|
||||
#define GTPCAUSE_006 6 /* For future use 6-48 */
|
||||
#define GTPCAUSE_049 49 /* Cause values reserved for GPRS charging protocol use (See GTP' in GSM 12.15) 49-63 */
|
||||
#define GTPCAUSE_064 64 /* For future use 64-127 */
|
||||
/* 6-48 For future use */
|
||||
/* 49-63 Cause values reserved for GPRS charging protocol use (See GTP' in GSM 12.15) */
|
||||
/* 64-127 For future use */
|
||||
#define GTPCAUSE_ACC_REQ 128 /* Request accepted */
|
||||
#define GTPCAUSE_129 129 /* For future use 129-176 */
|
||||
#define GTPCAUSE_177 177 /* Cause values reserved for GPRS charging protocol use (See GTP' In GSM 12.15) 177-191 */
|
||||
#define GTPCAUSE_NEW_PDP_NET_PREF 129 /* New PDP type due to network preference */
|
||||
#define GTPCAUSE_NEW_PDP_ADDR_BEAR 130 /* New PDP type due to single address bearer only */
|
||||
/* 131-176 For future use */
|
||||
/* 177-191 Cause values reserved for GPRS charging protocol use (See GTP' In GSM 12.15) */
|
||||
#define GTPCAUSE_NON_EXIST 192 /* Non-existent */
|
||||
#define GTPCAUSE_INVALID_MESSAGE 193 /* Invalid message format */
|
||||
#define GTPCAUSE_IMSI_NOT_KNOWN 194 /* IMSI not known */
|
||||
#define GTPCAUSE_MS_DETACHED 195 /* MS is GPRS detached */
|
||||
#define GTPCAUSE_MS_NOT_RESP 196 /* MS is not GPRS responding */
|
||||
#define GTPCAUSE_MS_REFUSES 197 /* MS refuses */
|
||||
#define GTPCAUSE_198 198 /* For future use */
|
||||
/* 198 For future use */
|
||||
#define GTPCAUSE_NO_RESOURCES 199 /* No resources available */
|
||||
#define GTPCAUSE_NOT_SUPPORTED 200 /* Service not supported */
|
||||
#define GTPCAUSE_MAN_IE_INCORRECT 201 /* Mandatory IE incorrect */
|
||||
@@ -134,8 +136,15 @@ static inline const char *gtp_type_name(uint8_t val)
|
||||
#define GTPCAUSE_SYN_ERR_FILTER 218 /* Syntactic errors in packet filter(s) */
|
||||
#define GTPCAUSE_MISSING_APN 219 /* Missing or unknown APN */
|
||||
#define GTPCAUSE_UNKNOWN_PDP 220 /* Unknown PDP address or PDP type */
|
||||
#define GTPCAUSE_221 221 /* For Future Use 221-240 */
|
||||
#define GTPCAUSE_241 241 /* Cause Values Reserved For Gprs Charging Protocol Use (See Gtp' In Gsm 12.15) 241-255 */
|
||||
/* 221-240 For future use */
|
||||
/* 241-255 Cause Values Reserved For Gprs Charging Protocol Use (See Gtp' In Gsm 12.15) */
|
||||
|
||||
static inline bool gtp_cause_successful(uint8_t cause)
|
||||
{
|
||||
return cause == GTPCAUSE_ACC_REQ ||
|
||||
cause == GTPCAUSE_NEW_PDP_NET_PREF ||
|
||||
cause == GTPCAUSE_NEW_PDP_ADDR_BEAR;
|
||||
}
|
||||
|
||||
struct ul66_t;
|
||||
struct ul16_t;
|
||||
@@ -256,61 +265,12 @@ extern int gtp_ran_info_relay_req(struct gsn_t *gsn, const struct sockaddr_in *p
|
||||
extern int gtp_decaps0(struct gsn_t *gsn);
|
||||
extern int gtp_decaps1c(struct gsn_t *gsn);
|
||||
extern int gtp_decaps1u(struct gsn_t *gsn);
|
||||
/* Internal functions (not part of the API) */
|
||||
|
||||
extern int gtp_echo_req(struct gsn_t *gsn, int version, void *cbp,
|
||||
struct in_addr *inetaddrs);
|
||||
extern int gtp_echo_resp(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, int fd,
|
||||
void *pack, unsigned len);
|
||||
extern int gtp_echo_ind(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, int fd,
|
||||
void *pack, unsigned len);
|
||||
extern int gtp_echo_conf(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, void *pack, unsigned len);
|
||||
|
||||
extern int gtp_unsup_req(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer,
|
||||
int fd, void *pack, unsigned len);
|
||||
extern int gtp_unsup_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
|
||||
void *pack, unsigned len);
|
||||
|
||||
extern int gtp_create_pdp_resp(struct gsn_t *gsn, int version,
|
||||
struct pdp_t *pdp, uint8_t cause);
|
||||
|
||||
extern int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, int fd,
|
||||
void *pack, unsigned len);
|
||||
|
||||
extern int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer,
|
||||
void *pack, unsigned len);
|
||||
|
||||
extern int gtp_update_pdp_req(struct gsn_t *gsn, int version, void *cbp,
|
||||
struct in_addr *inetaddr, struct pdp_t *pdp);
|
||||
|
||||
extern int gtp_delete_pdp_req(struct gsn_t *gsn, int version, void *cbp,
|
||||
struct pdp_t *pdp);
|
||||
|
||||
extern int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, int fd,
|
||||
void *pack, unsigned len,
|
||||
struct pdp_t *pdp, struct pdp_t *linked_pdp,
|
||||
uint8_t cause, int teardown);
|
||||
|
||||
extern int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer, int fd,
|
||||
void *pack, unsigned len);
|
||||
|
||||
extern int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
|
||||
struct sockaddr_in *peer,
|
||||
void *pack, unsigned len);
|
||||
|
||||
extern int ipv42eua(struct ul66_t *eua, struct in_addr *src);
|
||||
extern int eua2ipv4(struct in_addr *dst, struct ul66_t *eua);
|
||||
extern int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna);
|
||||
extern int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src);
|
||||
|
||||
extern const char *imsi_gtp2str(const uint64_t *imsi);
|
||||
extern uint64_t gtp_imsi_str2gtp(const char *str);
|
||||
|
||||
#endif /* !_GTP_H */
|
||||
@@ -1,10 +1,42 @@
|
||||
noinst_LIBRARIES = libmisc.a
|
||||
|
||||
noinst_HEADERS = gnugetopt.h ippool.h lookup.h syserr.h tun.h in46_addr.h netdev.h gtp-kernel.h netns.h util.h icmpv6.h checksum.h
|
||||
noinst_HEADERS = \
|
||||
checksum.h \
|
||||
gnugetopt.h \
|
||||
gtp-kernel.h \
|
||||
icmpv6.h \
|
||||
in46_addr.h \
|
||||
ippool.h \
|
||||
lookup.h \
|
||||
netdev.h \
|
||||
netns.h \
|
||||
syserr.h \
|
||||
tun.h \
|
||||
util.h \
|
||||
$(NULL)
|
||||
|
||||
AM_CFLAGS = -O2 -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb $(LIBOSMOCORE_CFLAGS)
|
||||
AM_CFLAGS = \
|
||||
-fno-builtin \
|
||||
-Wall \
|
||||
-DSBINDIR='"$(sbindir)"' \
|
||||
-I$(top_srcdir)/include \
|
||||
$(LIBOSMOCORE_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
libmisc_a_SOURCES = getopt1.c getopt.c ippool.c lookup.c tun.c debug.c in46_addr.c netdev.c netns.c util.c icmpv6.c checksum.c
|
||||
libmisc_a_SOURCES = \
|
||||
checksum.c \
|
||||
debug.c \
|
||||
getopt.c \
|
||||
getopt1.c \
|
||||
icmpv6.c \
|
||||
in46_addr.c \
|
||||
ippool.c \
|
||||
lookup.c \
|
||||
netdev.c \
|
||||
netns.c \
|
||||
tun.c \
|
||||
util.c \
|
||||
$(NULL)
|
||||
|
||||
if ENABLE_GTP_KERNEL
|
||||
AM_CFLAGS += -DGTP_KERNEL $(LIBGTPNL_CFLAGS)
|
||||
|
||||
109
lib/gtp-kernel.c
109
lib/gtp-kernel.c
@@ -23,12 +23,13 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
#include <osmocom/gtp/gtp.h>
|
||||
|
||||
#include "../lib/tun.h"
|
||||
#include "../lib/syserr.h"
|
||||
#include "../lib/util.h"
|
||||
#include "../lib/ippool.h"
|
||||
#include "../gtp/pdp.h"
|
||||
#include "../gtp/gtp.h"
|
||||
|
||||
#include "gtp-kernel.h"
|
||||
|
||||
@@ -104,61 +105,97 @@ void gtp_kernel_stop(const char *devname)
|
||||
|
||||
int gtp_kernel_tunnel_add(struct pdp_t *pdp, const char *devname)
|
||||
{
|
||||
struct in_addr ms, sgsn;
|
||||
int ms_addr_count;
|
||||
struct in46_addr ms[2];
|
||||
struct in46_addr sgsn;
|
||||
struct gtp_tunnel *t;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
pdp_debug(__func__, devname, pdp);
|
||||
|
||||
t = gtp_tunnel_alloc();
|
||||
if (t == NULL)
|
||||
in46a_from_gsna(&pdp->gsnrc, &sgsn);
|
||||
|
||||
ms_addr_count = in46a_from_eua(&pdp->eua, ms);
|
||||
if (ms_addr_count < 0)
|
||||
return -1;
|
||||
|
||||
memcpy(&ms, &pdp->eua.v[2], sizeof(struct in_addr));
|
||||
memcpy(&sgsn, &pdp->gsnrc.v[0], sizeof(struct in_addr));
|
||||
for (int i = 0; i < ms_addr_count; i++) {
|
||||
t = gtp_tunnel_alloc();
|
||||
if (t == NULL)
|
||||
return -1;
|
||||
|
||||
gtp_tunnel_set_ifidx(t, if_nametoindex(devname));
|
||||
gtp_tunnel_set_version(t, pdp->version);
|
||||
gtp_tunnel_set_ms_ip4(t, &ms);
|
||||
gtp_tunnel_set_sgsn_ip4(t, &sgsn);
|
||||
if (pdp->version == 0) {
|
||||
gtp_tunnel_set_tid(t, pdp_gettid(pdp->imsi, pdp->nsapi));
|
||||
gtp_tunnel_set_flowid(t, pdp->flru);
|
||||
} else {
|
||||
gtp_tunnel_set_i_tei(t, pdp->teid_own);
|
||||
/* use the TEI advertised by SGSN when sending packets
|
||||
* towards the SGSN */
|
||||
gtp_tunnel_set_o_tei(t, pdp->teid_gn);
|
||||
gtp_tunnel_set_ifidx(t, if_nametoindex(devname));
|
||||
gtp_tunnel_set_version(t, pdp->version);
|
||||
|
||||
if (in46a_to_af(&ms[i]) == AF_INET)
|
||||
gtp_tunnel_set_ms_ip4(t, &ms[i].v4);
|
||||
else {
|
||||
/* In IPv6, EUA doesn't contain the actual IP
|
||||
* addr/prefix. Set higher bits to 0 to get the 64 bit
|
||||
* netmask. */
|
||||
memset(((void *)&ms[i].v6) + 8, 0, 8);
|
||||
gtp_tunnel_set_ms_ip6(t, &ms[i].v6);
|
||||
}
|
||||
|
||||
if (in46a_to_af(&sgsn) == AF_INET)
|
||||
gtp_tunnel_set_sgsn_ip4(t, &sgsn.v4);
|
||||
else
|
||||
gtp_tunnel_set_sgsn_ip6(t, &sgsn.v6);
|
||||
|
||||
if (pdp->version == 0) {
|
||||
gtp_tunnel_set_tid(t, pdp_gettid(pdp->imsi, pdp->nsapi));
|
||||
gtp_tunnel_set_flowid(t, pdp->flru);
|
||||
} else {
|
||||
gtp_tunnel_set_i_tei(t, pdp->teid_own);
|
||||
/* use the TEI advertised by SGSN when sending packets
|
||||
* towards the SGSN */
|
||||
gtp_tunnel_set_o_tei(t, pdp->teid_gn);
|
||||
}
|
||||
|
||||
ret = gtp_add_tunnel(gtp_nl.genl_id, gtp_nl.nl, t);
|
||||
gtp_tunnel_free(t);
|
||||
|
||||
if (ret != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
ret = gtp_add_tunnel(gtp_nl.genl_id, gtp_nl.nl, t);
|
||||
gtp_tunnel_free(t);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int gtp_kernel_tunnel_del(struct pdp_t *pdp, const char *devname)
|
||||
{
|
||||
int ms_addr_count;
|
||||
struct in46_addr ms[2];
|
||||
struct gtp_tunnel *t;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
pdp_debug(__func__, devname, pdp);
|
||||
|
||||
t = gtp_tunnel_alloc();
|
||||
if (t == NULL)
|
||||
ms_addr_count = in46a_from_eua(&pdp->eua, ms);
|
||||
if (ms_addr_count < 0)
|
||||
return -1;
|
||||
|
||||
gtp_tunnel_set_ifidx(t, if_nametoindex(devname));
|
||||
gtp_tunnel_set_version(t, pdp->version);
|
||||
if (pdp->version == 0) {
|
||||
gtp_tunnel_set_tid(t, pdp_gettid(pdp->imsi, pdp->nsapi));
|
||||
gtp_tunnel_set_flowid(t, pdp->flru);
|
||||
} else {
|
||||
gtp_tunnel_set_i_tei(t, pdp->teid_own);
|
||||
}
|
||||
for (int i = 0; i < ms_addr_count; i++) {
|
||||
t = gtp_tunnel_alloc();
|
||||
if (t == NULL)
|
||||
return -1;
|
||||
|
||||
ret = gtp_del_tunnel(gtp_nl.genl_id, gtp_nl.nl, t);
|
||||
gtp_tunnel_free(t);
|
||||
gtp_tunnel_set_ifidx(t, if_nametoindex(devname));
|
||||
gtp_tunnel_set_family(t, in46a_to_af(&ms[i]));
|
||||
gtp_tunnel_set_version(t, pdp->version);
|
||||
if (pdp->version == 0) {
|
||||
gtp_tunnel_set_tid(t, pdp_gettid(pdp->imsi, pdp->nsapi));
|
||||
gtp_tunnel_set_flowid(t, pdp->flru);
|
||||
} else {
|
||||
gtp_tunnel_set_i_tei(t, pdp->teid_own);
|
||||
}
|
||||
|
||||
ret = gtp_del_tunnel(gtp_nl.genl_id, gtp_nl.nl, t);
|
||||
gtp_tunnel_free(t);
|
||||
|
||||
if (ret != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -21,10 +21,11 @@
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include "checksum.h"
|
||||
|
||||
#include "../gtp/gtp.h"
|
||||
#include "../gtp/pdp.h"
|
||||
#include <osmocom/gtp/gtp.h>
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
|
||||
#include "checksum.h"
|
||||
#include "ippool.h"
|
||||
#include "syserr.h"
|
||||
#include "icmpv6.h"
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/endian.h>
|
||||
|
||||
#include "../gtp/gtp.h"
|
||||
#include "../gtp/pdp.h"
|
||||
#include <osmocom/gtp/gtp.h>
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
|
||||
#define ICMPv6_OPT_TYPE_PREFIX_INFO 0x03
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "../lib/in46_addr.h"
|
||||
#include "../gtp/pdp.h"
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
|
||||
@@ -375,3 +375,10 @@ default_to_dyn_v4:
|
||||
dst->v4.s_addr = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void in46a_from_gsna(const struct ul16_t *in, struct in46_addr *dst)
|
||||
{
|
||||
dst->len = in->l;
|
||||
OSMO_ASSERT(in->l <= sizeof(dst->v6));
|
||||
memcpy(&dst->v6, in->v, in->l);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <stdint.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "../gtp/pdp.h"
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
|
||||
/* a simple wrapper around an in6_addr to also contain the length of the address,
|
||||
* thereby implicitly indicating the address family of the address */
|
||||
@@ -39,3 +39,5 @@ static inline bool in46a_is_v6(const struct in46_addr *addr) {
|
||||
static inline bool in46a_is_v4(const struct in46_addr *addr) {
|
||||
return addr->len == sizeof(struct in_addr);
|
||||
}
|
||||
|
||||
void in46a_from_gsna(const struct ul16_t *in, struct in46_addr *dst);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#define _IPPOOL_H
|
||||
|
||||
#include "../lib/in46_addr.h"
|
||||
#include "../gtp/gtp.h"
|
||||
#include <osmocom/gtp/gtp.h>
|
||||
|
||||
/* Assuming that the address space is fragmented we need a hash table
|
||||
in order to return the addresses.
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../gtp/pdp.h"
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
|
||||
#include "ippool.h"
|
||||
#include "in46_addr.h"
|
||||
|
||||
@@ -7,5 +7,8 @@ Name: OsmoGGSN GTP Library
|
||||
Description: C Utility Library
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lgtp
|
||||
Cflags: -I${includedir}/
|
||||
|
||||
# Add two include paths to support:
|
||||
# * #include <osmocom/gtp/gtp.h> (like other Osmocom headers)
|
||||
# * #include <gtp.h> (legacy compat)
|
||||
Cflags: -I${includedir}/osmocom/gtp/ -I${includedir}/
|
||||
|
||||
@@ -2,12 +2,22 @@ bin_PROGRAMS = sgsnemu
|
||||
|
||||
AM_LDFLAGS = @EXEC_LDFLAGS@
|
||||
|
||||
AM_CFLAGS = -O2 -D_GNU_SOURCE -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb $(LIBOSMOCORE_CFLAGS)
|
||||
AM_CFLAGS = \
|
||||
-D_GNU_SOURCE \
|
||||
-fno-builtin \
|
||||
-Wall \
|
||||
-DSBINDIR='"$(sbindir)"' \
|
||||
-I$(top_srcdir)/include \
|
||||
$(LIBOSMOCORE_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
sgsnemu_LDADD = @EXEC_LDADD@ -lgtp -L../gtp ../lib/libmisc.a $(LIBOSMOCORE_LIBS)
|
||||
|
||||
if ENABLE_GTP_KERNEL
|
||||
AM_CFLAGS += -DGTP_KERNEL $(LIBGTPNL_CFLAGS)
|
||||
AM_CFLAGS += \
|
||||
-DGTP_KERNEL \
|
||||
$(LIBGTPNL_CFLAGS) \
|
||||
$(NULL)
|
||||
sgsnemu_LDADD += $(LIBGTPNL_LIBS)
|
||||
endif
|
||||
|
||||
|
||||
@@ -54,13 +54,15 @@
|
||||
#endif // HAVE_IN6_ADDR_GEN_MODE_NONE
|
||||
#endif
|
||||
|
||||
#include <osmocom/gtp/pdp.h>
|
||||
#include <osmocom/gtp/gtp.h>
|
||||
|
||||
#include "../lib/tun.h"
|
||||
#include "../lib/ippool.h"
|
||||
#include "../lib/syserr.h"
|
||||
#include "../lib/netns.h"
|
||||
#include "../lib/icmpv6.h"
|
||||
#include "../gtp/pdp.h"
|
||||
#include "../gtp/gtp.h"
|
||||
#include "../gtp/gtp_internal.h"
|
||||
#include "cmdline.h"
|
||||
|
||||
#define IPADDRLEN 256 /* Character length of addresses */
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
AM_CFLAGS = -Wall -I$(top_srcdir)/include $(LIBOSMOCORE_CFLAGS) -g
|
||||
AM_CFLAGS = \
|
||||
-Wall \
|
||||
-I$(top_srcdir)/include \
|
||||
$(LIBOSMOCORE_CFLAGS) \
|
||||
$(NULL)
|
||||
AM_LDFLAGS = -no-install
|
||||
|
||||
EXTRA_DIST = \
|
||||
gtpie_test.ok \
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/bits.h>
|
||||
|
||||
#include <osmocom/gtp/gtpie.h>
|
||||
|
||||
#include "../../lib/syserr.h"
|
||||
#include "../../gtp/gtpie.h"
|
||||
|
||||
static const uint8_t in[] = { 1,2,3,4,5,6 };
|
||||
static uint8_t buf[256];
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
AM_CFLAGS = -Wall -I$(top_srcdir)/include $(LIBOSMOCORE_CFLAGS) -g
|
||||
AM_CFLAGS = \
|
||||
-Wall \
|
||||
-I$(top_srcdir)/include \
|
||||
$(LIBOSMOCORE_CFLAGS) \
|
||||
$(NULL)
|
||||
AM_LDFLAGS = -no-install
|
||||
|
||||
EXTRA_DIST = ippool_test.ok \
|
||||
ippool_test.err \
|
||||
|
||||
Reference in New Issue
Block a user