Skip to content

Commit 4ce61a8

Browse files
committed
added GTPping program to answer GTPU Ping frames
1 parent b9015ba commit 4ce61a8

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

GTPping.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
2+
# Author: Bjoern Riemer
3+
# simple program to answer GTP Ping messages used in GTPU
4+
5+
import os
6+
import signal
7+
from struct import pack, unpack
8+
from threading import Thread
9+
from socket import socket, timeout, error, \
10+
ntohs, htons, inet_aton, inet_ntoa, \
11+
AF_PACKET, SOCK_RAW, AF_INET, SOCK_DGRAM, SOL_SOCKET, SO_REUSEADDR
12+
#from libmich.mobnet.utils import log
13+
14+
def threadit(f, *args, **kwargs):
15+
th = Thread(target=f, args=args, kwargs=kwargs)
16+
th.start()
17+
return th
18+
19+
class GTPping(object):
20+
'''
21+
GTPU ping handler
22+
'''
23+
#
24+
# verbosity level: list of log types to display when calling
25+
# self._log(logtype, msg)
26+
DEBUG = ('ERR', 'WNG', 'INF', 'DBG')
27+
#
28+
# packet buffer space (over MTU...)
29+
BUFLEN = 2048
30+
31+
INT_IP = '0.0.0.0'
32+
INT_PORT = 2152
33+
34+
def __init__(self):
35+
#
36+
# create an UDP socket on the RNC / eNobeB side, on port 2152
37+
self.int_sk = socket(AF_INET, SOCK_DGRAM)
38+
# configure timeout, binding and rebinding on same address
39+
#self.int_sk.settimeout(0.003)
40+
#self.int_sk.setblocking(0)
41+
self.int_sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
42+
self.int_sk.bind((self.INT_IP, self.INT_PORT))
43+
#
44+
# interrupt handler
45+
def sigint_handler(signum, frame):
46+
self._log('INF', 'CTRL+C caught')
47+
self.stop()
48+
#signal.signal(signal.SIGINT, sigint_handler)
49+
#
50+
# and start listening and transferring packets in background
51+
self._listening = True
52+
self._listener_t = threadit(self.listen)
53+
self._log('INF', 'GTPU handler started')
54+
55+
56+
def _log(self, logtype='DBG', msg=''):
57+
# logtype: 'ERR', 'WNG', 'INF', 'DBG'
58+
if logtype in self.DEBUG:
59+
#log('[{0}] [GTPUd] {1}'.format(logtype, msg))
60+
print('[{0}] [GTPUd] {1}'.format(logtype, msg))
61+
62+
def listen(self):
63+
while self._listening:
64+
try:
65+
(bufint, from_address) = self.int_sk.recvfrom(self.BUFLEN)
66+
except timeout:
67+
# nothing to read anymore
68+
self._log('INF', 'read timeout')
69+
pass
70+
except error as err:
71+
self._log('ERR', 'internal network IF error '\
72+
'(recv): {0}'\
73+
.format(err))
74+
self.stop()
75+
else:
76+
self.handle_gtp_ping(bufint,from_address)
77+
78+
def stop(self):
79+
# stop local GTPU handler
80+
if self._listening:
81+
self._listening = False
82+
sleep(self.SELECT_TO * 2)
83+
try:
84+
# closing sockets
85+
self.int_sk.close()
86+
except Exception as err:
87+
self._log('ERR', 'socket error: {0}'.format(err))
88+
89+
def handle_gtp_ping(self, buf='\0', from_address=None):
90+
# extract the GTP header
91+
try:
92+
flags, msgtype, msglen, teid, seq = unpack('>BBHIH', buf[:10])
93+
except:
94+
self._log('WNG', 'invalid GTP packet')
95+
return
96+
if msgtype == 0x01:
97+
self._log('INF', "got GTP ping seq=%d teid=%d" % (seq,teid))
98+
if flags & 0x02:
99+
pass
100+
try:
101+
gtphdr = pack('>BBHIH', flags, 0x02, msglen, teid, seq)
102+
ret = self.int_sk.sendto(gtphdr+buf[10:], from_address)
103+
except Exception as err:
104+
self._log('ERR', 'internal network IF error (sendto): {0}'.format(err))
105+
else:
106+
#self._log('DBG', "packet is not GTP ping")
107+
pass
108+
109+
if __name__ == '__main__':
110+
gtpping = GTPping()

0 commit comments

Comments
 (0)