First commit
This commit is contained in:
commit
e9699cfe78
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,325 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
##################################################
|
||||
# GNU Radio Python Flow Graph
|
||||
# Title: Jammer Gen
|
||||
# Generated: Fri Jul 27 16:32:38 2018
|
||||
##################################################
|
||||
|
||||
if __name__ == '__main__':
|
||||
import ctypes
|
||||
import sys
|
||||
if sys.platform.startswith('linux'):
|
||||
try:
|
||||
x11 = ctypes.cdll.LoadLibrary('libX11.so')
|
||||
x11.XInitThreads()
|
||||
except:
|
||||
print "Warning: failed to XInitThreads()"
|
||||
|
||||
from gnuradio import analog
|
||||
from gnuradio import eng_notation
|
||||
from gnuradio import gr
|
||||
from gnuradio.eng_option import eng_option
|
||||
from gnuradio.filter import firdes
|
||||
from gnuradio.wxgui import forms
|
||||
from grc_gnuradio import wxgui as grc_wxgui
|
||||
from optparse import OptionParser
|
||||
import SimpleXMLRPCServer
|
||||
import osmosdr
|
||||
import threading
|
||||
import time
|
||||
import wx
|
||||
|
||||
|
||||
class jammer_gen(grc_wxgui.top_block_gui):
|
||||
|
||||
def __init__(self):
|
||||
grc_wxgui.top_block_gui.__init__(self, title="Jammer Gen")
|
||||
_icon_path = "/usr/local/share/icons/hicolor/32x32/apps/gnuradio-grc.png"
|
||||
self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY))
|
||||
|
||||
##################################################
|
||||
# Variables
|
||||
##################################################
|
||||
self.var_rf_gain = var_rf_gain = 10
|
||||
self.var_if_gain = var_if_gain = 10
|
||||
self.var_cent_freq = var_cent_freq = 1874200000
|
||||
self.var_bb_gain = var_bb_gain = 10
|
||||
self.var_bandwidth = var_bandwidth = 10e6
|
||||
self.samp_rate = samp_rate = 5e6
|
||||
self.sample_rate = sample_rate = samp_rate
|
||||
self.rf_gain = rf_gain = var_rf_gain
|
||||
self.if_gain = if_gain = var_if_gain
|
||||
self.cent_freq = cent_freq = var_cent_freq
|
||||
self.bb_gain = bb_gain = var_bb_gain
|
||||
self.bandwidth = bandwidth = var_bandwidth
|
||||
|
||||
##################################################
|
||||
# Blocks
|
||||
##################################################
|
||||
_sample_rate_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self._sample_rate_text_box = forms.text_box(
|
||||
parent=self.GetWin(),
|
||||
sizer=_sample_rate_sizer,
|
||||
value=self.sample_rate,
|
||||
callback=self.set_sample_rate,
|
||||
label='Sample rate',
|
||||
converter=forms.float_converter(),
|
||||
proportion=0,
|
||||
)
|
||||
self._sample_rate_slider = forms.slider(
|
||||
parent=self.GetWin(),
|
||||
sizer=_sample_rate_sizer,
|
||||
value=self.sample_rate,
|
||||
callback=self.set_sample_rate,
|
||||
minimum=2e6,
|
||||
maximum=20e6,
|
||||
num_steps=10,
|
||||
style=wx.SL_HORIZONTAL,
|
||||
cast=float,
|
||||
proportion=1,
|
||||
)
|
||||
self.Add(_sample_rate_sizer)
|
||||
_rf_gain_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self._rf_gain_text_box = forms.text_box(
|
||||
parent=self.GetWin(),
|
||||
sizer=_rf_gain_sizer,
|
||||
value=self.rf_gain,
|
||||
callback=self.set_rf_gain,
|
||||
label='RF gain',
|
||||
converter=forms.float_converter(),
|
||||
proportion=0,
|
||||
)
|
||||
self._rf_gain_slider = forms.slider(
|
||||
parent=self.GetWin(),
|
||||
sizer=_rf_gain_sizer,
|
||||
value=self.rf_gain,
|
||||
callback=self.set_rf_gain,
|
||||
minimum=10,
|
||||
maximum=60,
|
||||
num_steps=10,
|
||||
style=wx.SL_HORIZONTAL,
|
||||
cast=float,
|
||||
proportion=1,
|
||||
)
|
||||
self.Add(_rf_gain_sizer)
|
||||
_if_gain_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self._if_gain_text_box = forms.text_box(
|
||||
parent=self.GetWin(),
|
||||
sizer=_if_gain_sizer,
|
||||
value=self.if_gain,
|
||||
callback=self.set_if_gain,
|
||||
label='IF gain',
|
||||
converter=forms.float_converter(),
|
||||
proportion=0,
|
||||
)
|
||||
self._if_gain_slider = forms.slider(
|
||||
parent=self.GetWin(),
|
||||
sizer=_if_gain_sizer,
|
||||
value=self.if_gain,
|
||||
callback=self.set_if_gain,
|
||||
minimum=10,
|
||||
maximum=60,
|
||||
num_steps=10,
|
||||
style=wx.SL_HORIZONTAL,
|
||||
cast=float,
|
||||
proportion=1,
|
||||
)
|
||||
self.Add(_if_gain_sizer)
|
||||
_cent_freq_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self._cent_freq_text_box = forms.text_box(
|
||||
parent=self.GetWin(),
|
||||
sizer=_cent_freq_sizer,
|
||||
value=self.cent_freq,
|
||||
callback=self.set_cent_freq,
|
||||
label='Freq',
|
||||
converter=forms.float_converter(),
|
||||
proportion=0,
|
||||
)
|
||||
self._cent_freq_slider = forms.slider(
|
||||
parent=self.GetWin(),
|
||||
sizer=_cent_freq_sizer,
|
||||
value=self.cent_freq,
|
||||
callback=self.set_cent_freq,
|
||||
minimum=900e6,
|
||||
maximum=2200e6,
|
||||
num_steps=500,
|
||||
style=wx.SL_HORIZONTAL,
|
||||
cast=float,
|
||||
proportion=1,
|
||||
)
|
||||
self.Add(_cent_freq_sizer)
|
||||
_bb_gain_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self._bb_gain_text_box = forms.text_box(
|
||||
parent=self.GetWin(),
|
||||
sizer=_bb_gain_sizer,
|
||||
value=self.bb_gain,
|
||||
callback=self.set_bb_gain,
|
||||
label='BB gain',
|
||||
converter=forms.float_converter(),
|
||||
proportion=0,
|
||||
)
|
||||
self._bb_gain_slider = forms.slider(
|
||||
parent=self.GetWin(),
|
||||
sizer=_bb_gain_sizer,
|
||||
value=self.bb_gain,
|
||||
callback=self.set_bb_gain,
|
||||
minimum=10,
|
||||
maximum=60,
|
||||
num_steps=10,
|
||||
style=wx.SL_HORIZONTAL,
|
||||
cast=float,
|
||||
proportion=1,
|
||||
)
|
||||
self.Add(_bb_gain_sizer)
|
||||
_bandwidth_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self._bandwidth_text_box = forms.text_box(
|
||||
parent=self.GetWin(),
|
||||
sizer=_bandwidth_sizer,
|
||||
value=self.bandwidth,
|
||||
callback=self.set_bandwidth,
|
||||
label='Bandwidth',
|
||||
converter=forms.float_converter(),
|
||||
proportion=0,
|
||||
)
|
||||
self._bandwidth_slider = forms.slider(
|
||||
parent=self.GetWin(),
|
||||
sizer=_bandwidth_sizer,
|
||||
value=self.bandwidth,
|
||||
callback=self.set_bandwidth,
|
||||
minimum=2e6,
|
||||
maximum=50e6,
|
||||
num_steps=10,
|
||||
style=wx.SL_HORIZONTAL,
|
||||
cast=float,
|
||||
proportion=1,
|
||||
)
|
||||
self.Add(_bandwidth_sizer)
|
||||
self.xmlrpc_server_0 = SimpleXMLRPCServer.SimpleXMLRPCServer(('localhost', 8888), allow_none=True)
|
||||
self.xmlrpc_server_0.register_instance(self)
|
||||
self.xmlrpc_server_0_thread = threading.Thread(target=self.xmlrpc_server_0.serve_forever)
|
||||
self.xmlrpc_server_0_thread.daemon = True
|
||||
self.xmlrpc_server_0_thread.start()
|
||||
self.osmosdr_sink_0 = osmosdr.sink( args="numchan=" + str(1) + " " + '' )
|
||||
self.osmosdr_sink_0.set_sample_rate(sample_rate)
|
||||
self.osmosdr_sink_0.set_center_freq(cent_freq, 0)
|
||||
self.osmosdr_sink_0.set_freq_corr(0, 0)
|
||||
self.osmosdr_sink_0.set_gain(rf_gain, 0)
|
||||
self.osmosdr_sink_0.set_if_gain(if_gain, 0)
|
||||
self.osmosdr_sink_0.set_bb_gain(bb_gain, 0)
|
||||
self.osmosdr_sink_0.set_antenna('1', 0)
|
||||
self.osmosdr_sink_0.set_bandwidth(bandwidth, 0)
|
||||
|
||||
self.analog_noise_source_x_0 = analog.noise_source_c(analog.GR_GAUSSIAN, 50, 0)
|
||||
|
||||
##################################################
|
||||
# Connections
|
||||
##################################################
|
||||
self.connect((self.analog_noise_source_x_0, 0), (self.osmosdr_sink_0, 0))
|
||||
|
||||
def get_var_rf_gain(self):
|
||||
return self.var_rf_gain
|
||||
|
||||
def set_var_rf_gain(self, var_rf_gain):
|
||||
self.var_rf_gain = var_rf_gain
|
||||
self.set_rf_gain(self.var_rf_gain)
|
||||
|
||||
def get_var_if_gain(self):
|
||||
return self.var_if_gain
|
||||
|
||||
def set_var_if_gain(self, var_if_gain):
|
||||
self.var_if_gain = var_if_gain
|
||||
self.set_if_gain(self.var_if_gain)
|
||||
|
||||
def get_var_cent_freq(self):
|
||||
return self.var_cent_freq
|
||||
|
||||
def set_var_cent_freq(self, var_cent_freq):
|
||||
self.var_cent_freq = var_cent_freq
|
||||
self.set_cent_freq(self.var_cent_freq)
|
||||
|
||||
def get_var_bb_gain(self):
|
||||
return self.var_bb_gain
|
||||
|
||||
def set_var_bb_gain(self, var_bb_gain):
|
||||
self.var_bb_gain = var_bb_gain
|
||||
self.set_bb_gain(self.var_bb_gain)
|
||||
|
||||
def get_var_bandwidth(self):
|
||||
return self.var_bandwidth
|
||||
|
||||
def set_var_bandwidth(self, var_bandwidth):
|
||||
self.var_bandwidth = var_bandwidth
|
||||
self.set_bandwidth(self.var_bandwidth)
|
||||
|
||||
def get_samp_rate(self):
|
||||
return self.samp_rate
|
||||
|
||||
def set_samp_rate(self, samp_rate):
|
||||
self.samp_rate = samp_rate
|
||||
self.set_sample_rate(self.samp_rate)
|
||||
|
||||
def get_sample_rate(self):
|
||||
return self.sample_rate
|
||||
|
||||
def set_sample_rate(self, sample_rate):
|
||||
self.sample_rate = sample_rate
|
||||
self._sample_rate_slider.set_value(self.sample_rate)
|
||||
self._sample_rate_text_box.set_value(self.sample_rate)
|
||||
self.osmosdr_sink_0.set_sample_rate(self.sample_rate)
|
||||
|
||||
def get_rf_gain(self):
|
||||
return self.rf_gain
|
||||
|
||||
def set_rf_gain(self, rf_gain):
|
||||
self.rf_gain = rf_gain
|
||||
self._rf_gain_slider.set_value(self.rf_gain)
|
||||
self._rf_gain_text_box.set_value(self.rf_gain)
|
||||
self.osmosdr_sink_0.set_gain(self.rf_gain, 0)
|
||||
|
||||
def get_if_gain(self):
|
||||
return self.if_gain
|
||||
|
||||
def set_if_gain(self, if_gain):
|
||||
self.if_gain = if_gain
|
||||
self._if_gain_slider.set_value(self.if_gain)
|
||||
self._if_gain_text_box.set_value(self.if_gain)
|
||||
self.osmosdr_sink_0.set_if_gain(self.if_gain, 0)
|
||||
|
||||
def get_cent_freq(self):
|
||||
return self.cent_freq
|
||||
|
||||
def set_cent_freq(self, cent_freq):
|
||||
self.cent_freq = cent_freq
|
||||
self._cent_freq_slider.set_value(self.cent_freq)
|
||||
self._cent_freq_text_box.set_value(self.cent_freq)
|
||||
self.osmosdr_sink_0.set_center_freq(self.cent_freq, 0)
|
||||
|
||||
def get_bb_gain(self):
|
||||
return self.bb_gain
|
||||
|
||||
def set_bb_gain(self, bb_gain):
|
||||
self.bb_gain = bb_gain
|
||||
self._bb_gain_slider.set_value(self.bb_gain)
|
||||
self._bb_gain_text_box.set_value(self.bb_gain)
|
||||
self.osmosdr_sink_0.set_bb_gain(self.bb_gain, 0)
|
||||
|
||||
def get_bandwidth(self):
|
||||
return self.bandwidth
|
||||
|
||||
def set_bandwidth(self, bandwidth):
|
||||
self.bandwidth = bandwidth
|
||||
self._bandwidth_slider.set_value(self.bandwidth)
|
||||
self._bandwidth_text_box.set_value(self.bandwidth)
|
||||
self.osmosdr_sink_0.set_bandwidth(self.bandwidth, 0)
|
||||
|
||||
|
||||
def main(top_block_cls=jammer_gen, options=None):
|
||||
|
||||
tb = top_block_cls()
|
||||
tb.Start(True)
|
||||
tb.Wait()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,109 @@
|
|||
# Modmobjam
|
||||
|
||||
A smart jamming proof of concept for mobile equipments that could be powered with [Modmobmap](https://github.com/Synacktiv/Modmobmap)
|
||||
|
||||
For more information, this little tool has been presented during SSTIC rump 2018:
|
||||
|
||||
- english slides: https://www.synacktiv.com/ressources/sstic_rump_2018_modmobjam.pdf
|
||||
- french presentation: https://static.sstic.org/rumps2018/SSTIC_2018-06-14_P10_RUMPS_22.mp4
|
||||
|
||||
## Warning
|
||||
|
||||
You should be warned that Jamming is illegal and you're responsible for any damages when using it on your own.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- a radio devices that is enabled to transmit signal (HackRF, USRP, bladeRF, and so on.)
|
||||
- GNU Radio installed
|
||||
- Modmobmap to perform automatic smartjamming: https://github.com/Synacktiv/Modmobmap
|
||||
|
||||
## Usage
|
||||
|
||||
### Manual jamming
|
||||
|
||||
If you have a HackRF or any device compatible with osmocom drivers, you can directly run the code provided in ``GRC/jammer_gen.py`` as follows:
|
||||
|
||||
``bash
|
||||
$ python GRC/jammer_gen.py
|
||||
``
|
||||
|
||||
For those who want to use another device like USRP, edit the GNU Radio block schema ``GRC/jammer_gen.grc``:
|
||||
|
||||
``bash
|
||||
$ gnuradio-companion GRC/jammer_gen.grc
|
||||
``
|
||||
|
||||
Then you can configure the central frequency with the WX GUI to target a frequency. But this tool has also a feature to do it automatically.
|
||||
|
||||
### Automatic smartjamming
|
||||
|
||||
To automate jamming, you can first get a list of we the [Modmobmap](https://github.com/Synacktiv/Modmobmap) that saves a JSON file after monitoring surrounding cells in a precise location. This JSON file looks as follows:
|
||||
|
||||
``bash
|
||||
$ cat cells_<generated timestamp>.json
|
||||
{
|
||||
"****-***50": {
|
||||
"PCI": "****",
|
||||
"PLMN": "208-01",
|
||||
"TAC": "50****",
|
||||
"band": 3,
|
||||
"bandwidth": "20MHz",
|
||||
"eARFCN": 1850,
|
||||
"type": "4G"
|
||||
},
|
||||
"7-***": {
|
||||
"PLMN": "208-20",
|
||||
"arfcn": 1018,
|
||||
"cid": "***",
|
||||
"type": "2G"
|
||||
},
|
||||
"****:-****12": {
|
||||
"PLMN": "208-1",
|
||||
"RX": 10712,
|
||||
"TX": 9762,
|
||||
"band": 1,
|
||||
"type": "3G"
|
||||
},
|
||||
[...]
|
||||
}
|
||||
``
|
||||
|
||||
After generating this file containing cells to jam, you can launch the RPC client that communicate with ``GRC/jammer_gen.py`` as follows:
|
||||
|
||||
``bash
|
||||
python smartjam_rpcclient.py -f cells_<generated timestamp>.json
|
||||
``
|
||||
|
||||
Then leverage the gain for transmission and you should observe that a lot of noise is overflowing the targeted cells.
|
||||
|
||||
Please note that the delay between each targeted cell can be set with the provided arguments.
|
||||
|
||||
## Arguments
|
||||
|
||||
``bash
|
||||
$ python smartjam_rpcclient.py -h 2 ↵
|
||||
usage: smartjam_rpcclient.py [-h] [-s HOST] [-p PORT] -f FILEPATH [-d DELAY]
|
||||
[-b BANDWIDTH] [-l LINKJAM] [-w FILTERPLMN]
|
||||
|
||||
Modmodjam - Software-Defined Radio Jammer
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-s HOST, --host HOST hostname to send RPC commands (default: "localhost")
|
||||
-p PORT, --port PORT RPC server port (e.g: 8888 by default)
|
||||
-f FILEPATH, --file FILEPATH
|
||||
Modmobmap json file
|
||||
-d DELAY, --delay DELAY
|
||||
Delay between each frequency to jam in sec (default:
|
||||
2)
|
||||
-b BANDWIDTH, --bandwidth BANDWIDTH
|
||||
Define a static bandwidth. Will also influence the
|
||||
sample rate. By default it will use the bandwidth of
|
||||
the JSON file
|
||||
-l LINKJAM, --linkjam LINKJAM
|
||||
Link to jam: "0" for downlink and "1" for uplink
|
||||
(default: "0")
|
||||
-w FILTERPLMN, --filterplm FILTERPLMN
|
||||
PLMN to filter. Example: 2082-1 (separated with
|
||||
commas)
|
||||
``
|
Binary file not shown.
After Width: | Height: | Size: 338 KiB |
|
@ -0,0 +1,99 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import time
|
||||
import json
|
||||
import random
|
||||
import xmlrpclib
|
||||
import argparse
|
||||
from utils.eu_arfcn_calc import *
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='Modmodjam - Software-Defined Radio Jammer')
|
||||
parser.add_argument('-s', '--host', dest='host', default='localhost',
|
||||
help='hostname to send RPC commands (default: "localhost")')
|
||||
parser.add_argument('-p', '--port', dest='port', default=8888,
|
||||
help='RPC server port (e.g: 8888 by default)')
|
||||
parser.add_argument('-f', '--file', dest='filepath', required=True,
|
||||
help='Modmobmap json file')
|
||||
parser.add_argument('-d', '--delay', dest='delay', default=2,
|
||||
help='Delay between each frequency to jam in sec (default: 2)')
|
||||
parser.add_argument('-b', '--bandwidth', dest='bandwidth', default=None,
|
||||
help='Define a static bandwidth. Will also influence the sample rate. By default it will use the bandwidth of the JSON file')
|
||||
parser.add_argument('-l', '--linkjam', dest='linkjam', default=0,
|
||||
help='Link to jam: "0" for downlink and "1" for uplink (default: "0")')
|
||||
parser.add_argument('-w', '--filterplm', dest='filterplmn', default=None,
|
||||
help='PLMN to filter. Example: 2082-1 (separated with commas)')
|
||||
|
||||
t_freqs = {}
|
||||
args = parser.parse_args()
|
||||
host = args.host
|
||||
port = int(args.port)
|
||||
linkjam = int(args.linkjam)
|
||||
filepath = args.filepath
|
||||
delay = int(args.delay)
|
||||
filterplmn = args.filterplmn
|
||||
bandwidth = args.bandwidth
|
||||
|
||||
s = xmlrpclib.Server("http://%s:%s" % (host, port))
|
||||
|
||||
with open(filepath) as f:
|
||||
modmobdata = json.load(f)
|
||||
|
||||
plmns = []
|
||||
if filterplmn is not None:
|
||||
plmns = args.filterplmn.split(',')
|
||||
|
||||
for key, val in modmobdata.items():
|
||||
plmn = val['PLMN']
|
||||
if plmn in plmns or filterplmn is None:
|
||||
band = None
|
||||
ctype = None
|
||||
findex = None
|
||||
downlink = None
|
||||
uplink = None
|
||||
cbandwidth = 10 # MHz
|
||||
if 'RX' in val:
|
||||
findex = val['RX']
|
||||
elif 'eARFCN' in val:
|
||||
findex = val['eARFCN']
|
||||
if 'band' in val:
|
||||
band = val['band']
|
||||
if 'type' in val:
|
||||
ctype = val['type']
|
||||
if bandwidth is not None:
|
||||
cbandwidth = bandwidth
|
||||
else:
|
||||
if 'bandwidth' in val:
|
||||
cbandwidth = int(val['bandwidth'].replace('MHz',''))
|
||||
try:
|
||||
if ctype == '3G':
|
||||
downlink, uplink = uarfcn2freq(band, findex, None)
|
||||
elif ctype == '4G':
|
||||
downlink, uplink = earfcn2freq(band, findex, None)
|
||||
elif ctype == '2G':
|
||||
pass
|
||||
# not implemented for our purposes
|
||||
if downlink is not None and uplink is not None:
|
||||
cent_freq = downlink
|
||||
if linkjam == 1:
|
||||
cent_freq = uplink
|
||||
t_freqs[key] = { 'freq' : cent_freq,
|
||||
'bandwidth' : cbandwidth }
|
||||
except Exception as e:
|
||||
print (e)
|
||||
while True:
|
||||
for key, val in t_freqs.items():
|
||||
print ("[+] Jamming cell {cell} central frequency at {freq} MHz with {bandwidth} MHz bandwidth".format(cell=key, freq=val['freq'], bandwidth=val['bandwidth']))
|
||||
s.set_var_cent_freq(val['freq']*1000000)
|
||||
s.set_var_bandwidth(val['bandwidth']*1000000)
|
||||
time.sleep(delay)
|
|
@ -0,0 +1,486 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
#####################################
|
||||
# UARFCN and EARFCN Calculator
|
||||
#####################################
|
||||
|
||||
##
|
||||
# Tables
|
||||
#
|
||||
table_earfcn = {
|
||||
1 : { 'FDL_Low' : 2110,
|
||||
'NDL_Offset' : 0,
|
||||
'DL_range' : (0,599),
|
||||
'FUL_Low' : 1920,
|
||||
'NUL_Offset' : 18000,
|
||||
'UP_range' : (1800,18599),
|
||||
},
|
||||
2 : { 'FDL_Low' : 1930,
|
||||
'NDL_Offset' : 600,
|
||||
'DL_range' : (600,1199),
|
||||
'FUL_Low' : 1850,
|
||||
'NUL_Offset' : 18600,
|
||||
'UP_range' : (18600,19199),
|
||||
},
|
||||
3 : { 'FDL_Low' : 1805,
|
||||
'NDL_Offset' : 1200,
|
||||
'DL_range' : (1200,1949),
|
||||
'FUL_Low' : 1710,
|
||||
'NUL_Offset' : 19200,
|
||||
'UP_range' : (19200,19949),
|
||||
},
|
||||
4 : { 'FDL_Low' : 2110,
|
||||
'NDL_Offset' : 1950,
|
||||
'DL_range' : (1950,2399),
|
||||
'FUL_Low' : 1710,
|
||||
'NUL_Offset' : 19950,
|
||||
'UP_range' : (19950,20399),
|
||||
},
|
||||
5 : { 'FDL_Low' : 869,
|
||||
'NDL_Offset' : 2400,
|
||||
'DL_range' : (2400,2649),
|
||||
'FUL_Low' : 824,
|
||||
'NUL_Offset' : 20400,
|
||||
'UP_range' : (20400,20649),
|
||||
},
|
||||
6 : { 'FDL_Low' : 875,
|
||||
'NDL_Offset' : 2650,
|
||||
'DL_range' : (2650,2749),
|
||||
'FUL_Low' : 830,
|
||||
'NUL_Offset' : 20650,
|
||||
'UP_range' : (20650,20749),
|
||||
},
|
||||
7 : { 'FDL_Low' : 2620,
|
||||
'NDL_Offset' : 2750,
|
||||
'DL_range' : (2750,3449),
|
||||
'FUL_Low' : 2500,
|
||||
'NUL_Offset' : 20750,
|
||||
'UP_range' : (20750,21449),
|
||||
},
|
||||
8 : { 'FDL_Low' : 925,
|
||||
'NDL_Offset' : 3450,
|
||||
'DL_range' : (3450,3799),
|
||||
'FUL_Low' : 880,
|
||||
'NUL_Offset' : 21450,
|
||||
'UP_range' : (21450,21799),
|
||||
},
|
||||
9 : { 'FDL_Low' : 1844.9,
|
||||
'NDL_Offset' : 3800,
|
||||
'DL_range' : (3800,4149),
|
||||
'FUL_Low' : 1749.9,
|
||||
'NUL_Offset' : 21800,
|
||||
'UP_range' : (21800,22149),
|
||||
},
|
||||
10 : { 'FDL_Low' : 2110,
|
||||
'NDL_Offset' : 4150,
|
||||
'DL_range' : (4150,4749),
|
||||
'FUL_Low' : 1710,
|
||||
'NUL_Offset' : 22150,
|
||||
'UP_range' : (22150,22749),
|
||||
},
|
||||
11 : { 'FDL_Low' : 1475.9,
|
||||
'NDL_Offset' : 4750,
|
||||
'DL_range' : (4750,4949),
|
||||
'FUL_Low' : 1427.9,
|
||||
'NUL_Offset' : 22750,
|
||||
'UP_range' : (22750,22949),
|
||||
},
|
||||
12 : { 'FDL_Low' : 729,
|
||||
'NDL_Offset' : 5010,
|
||||
'DL_range' : (5010,5179),
|
||||
'FUL_Low' : 699,
|
||||
'NUL_Offset' : 23010,
|
||||
'UP_range' : (23010,23179),
|
||||
},
|
||||
13 : { 'FDL_Low' : 746,
|
||||
'NDL_Offset' : 5180,
|
||||
'DL_range' : (5180,5279),
|
||||
'FUL_Low' : 777,
|
||||
'NUL_Offset' : 23180,
|
||||
'UP_range' : (23180,23279),
|
||||
},
|
||||
14 : { 'FDL_Low' : 758,
|
||||
'NDL_Offset' : 5280,
|
||||
'DL_range' : (5280,5379),
|
||||
'FUL_Low' : 788,
|
||||
'NUL_Offset' : 23280,
|
||||
'UP_range' : (23280,23379),
|
||||
},
|
||||
17 : { 'FDL_Low' : 734,
|
||||
'NDL_Offset' : 5730,
|
||||
'DL_range' : (5730,5849),
|
||||
'FUL_Low' : 704,
|
||||
'NUL_Offset' : 23730,
|
||||
'UP_range' : (23730,23849),
|
||||
},
|
||||
18 : { 'FDL_Low' : 860,
|
||||
'NDL_Offset' : 5850,
|
||||
'DL_range' : (5850,5999),
|
||||
'FUL_Low' : 815,
|
||||
'NUL_Offset' : 23850,
|
||||
'UP_range' : (23850,23999),
|
||||
},
|
||||
19 : { 'FDL_Low' : 875,
|
||||
'NDL_Offset' : 6000,
|
||||
'DL_range' : (6000,6149),
|
||||
'FUL_Low' : 830,
|
||||
'NUL_Offset' : 24000,
|
||||
'UP_range' : (24000,24149),
|
||||
},
|
||||
20 : { 'FDL_Low' : 791,
|
||||
'NDL_Offset' : 6150,
|
||||
'DL_range' : (6150,6449),
|
||||
'FUL_Low' : 832,
|
||||
'NUL_Offset' : 24150,
|
||||
'UP_range' : (24150,24449),
|
||||
},
|
||||
21 : { 'FDL_Low' : 1495.9,
|
||||
'NDL_Offset' : 6450,
|
||||
'DL_range' : (6450,6599),
|
||||
'FUL_Low' : 1447.9,
|
||||
'NUL_Offset' : 24450,
|
||||
'UP_range' : (24450,24599),
|
||||
},
|
||||
22 : { 'FDL_Low' : 3510,
|
||||
'NDL_Offset' : 6600,
|
||||
'DL_range' : (6600,7399),
|
||||
'FUL_Low' : 3410,
|
||||
'NUL_Offset' : 24600,
|
||||
'UP_range' : (24600,25399),
|
||||
},
|
||||
23 : { 'FDL_Low' : 2180,
|
||||
'NDL_Offset' : 7500,
|
||||
'DL_range' : (7500,7699),
|
||||
'FUL_Low' : 2000,
|
||||
'NUL_Offset' : 25500,
|
||||
'UP_range' : (25500,25699),
|
||||
},
|
||||
24 : { 'FDL_Low' : 1525,
|
||||
'NDL_Offset' : 7700,
|
||||
'DL_range' : (7700,8039),
|
||||
'FUL_Low' : 1626.5,
|
||||
'NUL_Offset' : 25700,
|
||||
'UP_range' : (25700,26039),
|
||||
},
|
||||
25 : { 'FDL_Low' : 1930,
|
||||
'NDL_Offset' : 8040,
|
||||
'DL_range' : (8040,8689),
|
||||
'FUL_Low' : 1850,
|
||||
'NUL_Offset' : 26040,
|
||||
'UP_range' : (26040,26689),
|
||||
},
|
||||
26 : { 'FDL_Low' : 859,
|
||||
'NDL_Offset' : 8690,
|
||||
'DL_range' : (8690,9039),
|
||||
'FUL_Low' : 814,
|
||||
'NUL_Offset' : 26690,
|
||||
'UP_range' : (26690,27039),
|
||||
},
|
||||
27 : { 'FDL_Low' : 852,
|
||||
'NDL_Offset' : 9040,
|
||||
'DL_range' : (9040,9209),
|
||||
'FUL_Low' : 807,
|
||||
'NUL_Offset' : 27040,
|
||||
'UP_range' : (27040,27209),
|
||||
},
|
||||
28 : { 'FDL_Low' : 758,
|
||||
'NDL_Offset' : 9210,
|
||||
'DL_range' : (9210,9659),
|
||||
'FUL_Low' : 703,
|
||||
'NUL_Offset' : 27210,
|
||||
'UP_range' : (27210,27659),
|
||||
},
|
||||
30 : { 'FDL_Low' : 2350,
|
||||
'NDL_Offset' : 9770,
|
||||
'DL_range' : (9770,9869),
|
||||
'FUL_Low' : 2305,
|
||||
'NUL_Offset' : 27660,
|
||||
'UP_range' : (27660,27759),
|
||||
},
|
||||
31 : { 'FDL_Low' : 462.5,
|
||||
'NDL_Offset' : 9870,
|
||||
'DL_range' : (9870,9919),
|
||||
'FUL_Low' : 452.5,
|
||||
'NUL_Offset' : 27760,
|
||||
'UP_range' : (27760,27809),
|
||||
},
|
||||
65 : { 'FDL_Low' : 2110,
|
||||
'NDL_Offset' : 65536,
|
||||
'DL_range' : (65536,66435),
|
||||
'FUL_Low' : 1920,
|
||||
'NUL_Offset' : 131072,
|
||||
'UP_range' : (131072,131971),
|
||||
},
|
||||
66 : { 'FDL_Low' : 2110,
|
||||
'NDL_Offset' : 66436,
|
||||
'DL_range' : (66436,67335),
|
||||
'FUL_Low' : 1710,
|
||||
'NUL_Offset' : 131972,
|
||||
'UP_range' : (131972,132671),
|
||||
},
|
||||
68 : { 'FDL_Low' : 753,
|
||||
'NDL_Offset' : 67536,
|
||||
'DL_range' : (67536,67835),
|
||||
'FUL_Low' : 698,
|
||||
'NUL_Offset' : 132672,
|
||||
'UP_range' : (132672,132971),
|
||||
},
|
||||
70 : { 'FDL_Low' : 1995,
|
||||
'NDL_Offset' : 68336,
|
||||
'DL_range' : (68336,68585),
|
||||
'FUL_Low' : 1695,
|
||||
'NUL_Offset' : 132972,
|
||||
'UP_range' : (132972,133121),
|
||||
},
|
||||
71 : { 'FDL_Low' : 617,
|
||||
'NDL_Offset' : 68586,
|
||||
'DL_range' : (68586,68935),
|
||||
'FUL_Low' : 663,
|
||||
'NUL_Offset' : 133122,
|
||||
'UP_range' : (133122,133471),
|
||||
},
|
||||
72 : { 'FDL_Low' : 461,
|
||||
'NDL_Offset' : 68936,
|
||||
'DL_range' : (68936,68985),
|
||||
'FUL_Low' : 451,
|
||||
'NUL_Offset' : 133472,
|
||||
'UP_range' : (133472,133521),
|
||||
},
|
||||
73 : { 'FDL_Low' : 460,
|
||||
'NDL_Offset' : 68986,
|
||||
'DL_range' : (68986,69465),
|
||||
'FUL_Low' : 450,
|
||||
'NUL_Offset' : 133522,
|
||||
'UP_range' : (133522,133571),
|
||||
},
|
||||
74 : { 'FDL_Low' : 1475,
|
||||
'NDL_Offset' : 69036,
|
||||
'DL_range' : (69036,69035),
|
||||
'FUL_Low' : 1427,
|
||||
'NUL_Offset' : 133572,
|
||||
'UP_range' : (133572,134001),
|
||||
},
|
||||
85 : { 'FDL_Low' : 728,
|
||||
'NDL_Offset' : 70366,
|
||||
'DL_range' : (70366,70545),
|
||||
'FUL_Low' : 698,
|
||||
'NUL_Offset' : 134002,
|
||||
'UP_range' : (134002,134181),
|
||||
},
|
||||
}
|
||||
|
||||
table_uarfcn = {
|
||||
1 : { 'FDL_Offset' : 0,
|
||||
'FDL_Low' : 2112.4,
|
||||
'DL_range' : (10562,10838),
|
||||
'FUL_Low' : 1922.4,
|
||||
'NUL_Offset' : 0,
|
||||
'UP_range' : (9612,9888),
|
||||
},
|
||||
2 : { 'FDL_Offset' : 0,
|
||||
'FDL_Low' : 1932.4,
|
||||
'DL_range' : (9662,9938),
|
||||
'FUL_Low' : 1852.4,
|
||||
'NUL_Offset' : 0,
|
||||
'UP_range' : (9262,9538),
|
||||
},
|
||||
3 : { 'FDL_Offset' : 1525,
|
||||
'FDL_Low' : 1712.4,
|
||||
'DL_range' : (937,1288),
|
||||
'FUL_Low' : 1807.4,
|
||||
'NUL_Offset' : 1575,
|
||||
'UP_range' : (1162,1513),
|
||||
},
|
||||
4 : { 'FDL_Offset' : 1805,
|
||||
'FDL_Low' : 2112.4,
|
||||
'DL_range' : (1537,1738),
|
||||
'FUL_Low' : 1712.4,
|
||||
'NUL_Offset' : 1450,
|
||||
'UP_range' : (1312,1513),
|
||||
},
|
||||
5 : { 'FDL_Offset' : 0,
|
||||
'FDL_Low' : 871.4,
|
||||
'DL_range' : (4357,4458),
|
||||
'FUL_Low' : 826.4,
|
||||
'NUL_Offset' : 0,
|
||||
'UP_range' : (4132,4233),
|
||||
},
|
||||
6 : { 'FDL_Offset' : 0,
|
||||
'FDL_Low' : 877.4,
|
||||
'DL_range' : (4387,4413),
|
||||
'FUL_Low' : 832.4,
|
||||
'NUL_Offset' : 0,
|
||||
'UP_range' : (4162,4188),
|
||||
},
|
||||
7 : { 'FDL_Offset' : 2175,
|
||||
'FDL_Low' : 2622.4,
|
||||
'DL_range' : (2237,2563),
|
||||
'FUL_Low' : 2502.4,
|
||||
'NUL_Offset' : 2100,
|
||||
'UP_range' : (2012,2338),
|
||||
},
|
||||
8 : { 'FDL_Offset' : 340,
|
||||
'FDL_Low' : 927.4,
|
||||
'DL_range' : (2937,3088),
|
||||
'FUL_Low' : 882.4,
|
||||
'NUL_Offset' : 340,
|
||||
'UP_range' : (2712,2863),
|
||||
},
|
||||
9 : { 'FDL_Offset' : 0,
|
||||
'FDL_Low' : 1847.4,
|
||||
'DL_range' : (9237,93878),
|
||||
'FUL_Low' : 1752.4,
|
||||
'NUL_Offset' : 0,
|
||||
'UP_range' : (8762,8912),
|
||||
},
|
||||
10 : { 'FDL_Offset' : 1490,
|
||||
'FDL_Low' : 2112.4,
|
||||
'DL_range' : (3112,3388),
|
||||
'FUL_Low' : 1712.4,
|
||||
'NUL_Offset' : 1135,
|
||||
'UP_range' : (2887,3163),
|
||||
},
|
||||
11 : { 'FDL_Offset' : 736,
|
||||
'FDL_Low' : 1478.4,
|
||||
'DL_range' : (3712,3812),
|
||||
'FUL_Low' : 1430.4,
|
||||
'NUL_Offset' : 733,
|
||||
'UP_range' : (3487,3587),
|
||||
},
|
||||
12 : { 'FDL_Offset' : -37,
|
||||
'FDL_Low' : 730.4,
|
||||
'DL_range' : (3837,3903),
|
||||
'FUL_Low' : 700.4,
|
||||
'NUL_Offset' : -22,
|
||||
'UP_range' : (3612,3678),
|
||||
},
|
||||
13 : { 'FDL_Offset' : -55,
|
||||
'FDL_Low' : 748.4,
|
||||
'DL_range' : (4017,4043),
|
||||
'FUL_Low' : 779.4,
|
||||
'NUL_Offset' : 21,
|
||||
'UP_range' : (3792,3818),
|
||||
},
|
||||
14 : { 'FDL_Offset' : -63,
|
||||
'FDL_Low' : 760.4,
|
||||
'DL_range' : (4117,4143),
|
||||
'FUL_Low' : 790.4,
|
||||
'NUL_Offset' : 12,
|
||||
'UP_range' : (3892,3918),
|
||||
},
|
||||
19 : { 'FDL_Offset' : 735,
|
||||
'FDL_Low' : 877.4,
|
||||
'DL_range' : (712,763),
|
||||
'FUL_Low' : 832.4,
|
||||
'NUL_Offset' : 770,
|
||||
'UP_range' : (312,363),
|
||||
},
|
||||
20 : { 'FDL_Offset' : -109,
|
||||
'FDL_Low' : 793.4,
|
||||
'DL_range' : (4512,4638),
|
||||
'FUL_Low' : 834.4,
|
||||
'NUL_Offset' : -23,
|
||||
'UP_range' : (4287,4413),
|
||||
},
|
||||
21 : { 'FDL_Offset' : 1326,
|
||||
'FDL_Low' : 1498.4,
|
||||
'DL_range' : (862,912),
|
||||
'FUL_Low' : 1450.4,
|
||||
'NUL_Offset' : 1358,
|
||||
'UP_range' : (462,512),
|
||||
},
|
||||
22 : { 'FDL_Offset' : 2580,
|
||||
'FDL_Low' : 3512.4,
|
||||
'DL_range' : (4662,5038),
|
||||
'FUL_Low' : 3412.4,
|
||||
'NUL_Offset' : 2525,
|
||||
'UP_range' : (4437,4813),
|
||||
},
|
||||
25 : { 'FDL_Offset' : 910,
|
||||
'FDL_Low' : 1932.4,
|
||||
'DL_range' : (5112,5413),
|
||||
'FUL_Low' : 1852.4,
|
||||
'NUL_Offset' : 875,
|
||||
'UP_range' : (4887,5188),
|
||||
},
|
||||
26 : { 'FDL_Offset' : -291,
|
||||
'FDL_Low' : 1932.4,
|
||||
'DL_range' : (5762,5913),
|
||||
'FUL_Low' : 1852.4,
|
||||
'NUL_Offset' : -291,
|
||||
'UP_range' : (5537,5688),
|
||||
},
|
||||
}
|
||||
|
||||
##
|
||||
# Functions
|
||||
#
|
||||
|
||||
def uarfcn2freq(band, dl_uarfcn=None, ul_uarfcn=None):
|
||||
'''
|
||||
in(1): int band index,
|
||||
in(2): int Downling UARFCN index,
|
||||
in(3): int Uplink UARFCN index,
|
||||
out: tuple (float downlink_freq, float uplink_freq)
|
||||
'''
|
||||
duplex_spacing = abs(table_uarfcn[band]['FDL_Low']-table_uarfcn[band]['FUL_Low'])
|
||||
FDL_Offset = table_uarfcn[band]['FDL_Offset']
|
||||
FUL_Offset = table_uarfcn[band]['NUL_Offset']
|
||||
downlink_freq = uplink_freq = None
|
||||
if dl_uarfcn is not None:
|
||||
downlink_freq = FDL_Offset + 0.2 * dl_uarfcn
|
||||
if ul_uarfcn is not None:
|
||||
uplink_freq = FUL_Offset + 0.2 * ul_uarfcn
|
||||
if downlink_freq is not None and uplink_freq is None:
|
||||
uplink_freq = downlink_freq - duplex_spacing
|
||||
elif downlink_freq is None and uplink_freq is not None:
|
||||
downlink_freq = downlink_freq + duplex_spacing
|
||||
return (downlink_freq, uplink_freq)
|
||||
|
||||
def earfcn2freq(band, dl_earfcn=None, ul_earfcn=None):
|
||||
'''
|
||||
in(1): int band index,
|
||||
in(2): int Downling EARFCN index,
|
||||
in(3): int Uplink EARFCN index,
|
||||
out: tuple (float downlink_freq, float uplink_freq)
|
||||
'''
|
||||
NDL_Offset = table_earfcn[band]['NDL_Offset']
|
||||
NUL_Offset = table_earfcn[band]['NUL_Offset']
|
||||
duplex_spacing = abs(table_earfcn[band]['FDL_Low']-table_earfcn[band]['FUL_Low'])
|
||||
FDL_Low = table_earfcn[band]['FDL_Low']
|
||||
FUL_Low = table_earfcn[band]['FUL_Low']
|
||||
downlink_freq = uplink_freq = None
|
||||
if dl_earfcn is not None:
|
||||
downlink_freq = FDL_Low + 0.1 * (dl_earfcn-NDL_Offset)
|
||||
if ul_earfcn is not None:
|
||||
uplink_freq = FUL_Low + 0.1 * (ul_earfcn-NUL_Offset)
|
||||
if downlink_freq is not None and uplink_freq is None:
|
||||
uplink_freq = downlink_freq - duplex_spacing
|
||||
elif downlink_freq is None and uplink_freq is not None:
|
||||
downlink_freq = downlink_freq + duplex_spacing
|
||||
return (downlink_freq, uplink_freq)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("nettype", type=int, help="select network type: 1 for 3G, and 2 for 4G")
|
||||
parser.add_argument("band", type=int, help="Band index")
|
||||
parser.add_argument("downlink", type=int, help="Downlink U/E-ARFCN")
|
||||
parser.add_argument("--uplink", type=int, help="Uplink U/E-ARFCN")
|
||||
args = parser.parse_args()
|
||||
if args.nettype == 1:
|
||||
ret = uarfcn2freq(args.band, args.downlink, args.uplink)
|
||||
elif args.nettype == 2:
|
||||
ret = earfcn2freq(args.band, args.downlink, args.uplink)
|
||||
print ("[+] Selected Downlink ARFCN %i (band %i)" % (args.downlink, args.band))
|
||||
print ("Downlink: %f MHz and Uplink: %f MHz" % (ret[0],ret[1]))
|
Loading…
Reference in New Issue