summaryrefslogtreecommitdiff
path: root/gsmstack/source_pcap_burst.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2008-12-01 01:19:19 +0530
committerHarald Welte <laforge@gnumonks.org>2008-12-01 01:19:19 +0530
commitfd405f799425b6832a0c9cc7a56b07f43288b8b1 (patch)
treec02cdfa014a63339950a98ef7e3bdbebb44adbf5 /gsmstack/source_pcap_burst.c
parent753c2fc0f6861f6a3dcf6e5520343d93b5ed2317 (diff)
gsmstack: add new unfinished GSM burst/channel demultiplex
This is some unfinished work on a new codebase for 'proper' demultiplex of all the various physical and logical channel types. Basically this includes everything needed to get from the differential-decoded bursts up to the MAC blocks that can be passed up to layer 2.
Diffstat (limited to 'gsmstack/source_pcap_burst.c')
-rw-r--r--gsmstack/source_pcap_burst.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/gsmstack/source_pcap_burst.c b/gsmstack/source_pcap_burst.c
new file mode 100644
index 0000000..bb340e7
--- /dev/null
+++ b/gsmstack/source_pcap_burst.c
@@ -0,0 +1,148 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pcap.h>
+
+#include "gsmstack.h"
+#include "gsmtap.h"
+
+/* source_pcap_burst.c: read a PCAP file with GSMTAP_UM_BURST packets
+ * and feed them into the stack.
+ *
+ * (C) 2008 by Harald Welte <laforge@gnumonks.org>
+ *
+ * TODO:
+ * fix PCAP endianness
+ */
+
+
+static struct gsm_rf_chan rfchans[NR_ARFCN];
+
+static int read_pcap_hdr(int fd)
+{
+ int rc;
+ struct pcap_file_header pfh;
+
+ rc = read(fd, &pfh, sizeof(pfh));
+ if (rc < sizeof(pfh))
+ return -EIO;
+
+ if (pfh.magic != TCPDUMP_MAGIC)
+ return -EINVAL;
+
+ if (pfh.linktype != LINKTYPE_GSMTAP)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int send_burst(struct gsmtap_hdr *gh, int burst_len,
+ struct timeval *tv)
+{
+ unsigned char *data = (unsigned char *)gh + sizeof(*gh);
+ struct gsm_burst burst;
+ struct gsm_rf_chan *rfchan;
+ struct gsm_phys_chan *pchan;
+ unsigned int arfcn;
+
+ arfcn = ntohs(gh->arfcn);
+
+ /* Create new RF channel structure if we've not seen this ARFCN
+ * before */
+ if (!rfchans[arfcn]) {
+ rfchans[arfcn] = gsm_init_rfchan(arfcn);
+ if (!rfchans[arfcn]) {
+ fprintf(stderr, "cannot init rfchan ARFCN=%u\n",
+ arfcn);
+ return -EINVAL;
+ }
+ }
+
+ rfchan = rfchans[arfcn];
+ pchan = rfchan->phys_chan[gh->timeslot];
+
+ memset(&burst, 0, sizeof(burst));
+ burst.phys_chan = pchan;
+ burst.burst_type = gh->burst_type;
+ burst.rx_frame_nr = ntohl(gh->frame_number);
+ memcpy(&burst.rx_time, tv, sizeof(burst.rx_time));
+ memcpy(burst.decoded, data, burst_len);
+
+ return gsm_rx_burst(&burst, 0);
+}
+
+/* fills 'buf' with gsmtap_hdr and payload, returns length of payload */
+static int read_one_pkt(int fd, unsigned char *buf, int bufsize,
+ struct timeval *tv)
+{
+ struct pcap_sf_pkthdr pkthdr;
+ struct gsmtap_hdr *gh = (struct gsmtap_hdr *) buf;
+ int len, burstlen;
+
+ len = read(fd, &pkthdr, sizeof(pkthdr));
+ if (len < sizeof(pkthdr))
+ return -1;
+
+ /* FIXME: ntohl on caplen and len? */
+
+ if (pkthdr.caplen < sizeof(*gh))
+ return -2;
+
+ if (pkthdr.len > pkthdr.caplen)
+ return -3;
+
+ if (bufsize < pkthdr.len)
+ return -4;
+
+ if (tv) {
+ tv.tv_sec = pkthdr.tv_sec;
+ tv.tv_usec = pkthdr.tv_usec;
+ }
+
+ len = read(fd, buf, pkthdr.caplen)
+ if (len < pkthdr.caplen)
+ return -5;
+
+ if (gh->version != GSMTAP_VERSION ||
+ gh->type != GSMTAP_TYPE_UM_BURST)
+ return -6;
+
+ return pkthdr.caplen - sizeof(*gh);
+}
+
+int main(int argc, char **argv)
+{
+ char *fname;
+ int fd, rc;
+
+ if (argc != 2) {
+ fprintf(stderr, "please specify pcap filename\n");
+ exit(2);
+ }
+
+ fname = argv[1];
+
+ fd = open(fname, O_RDONLY);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+
+ rc = read_pcap_hdr(fd);
+ if (rc < 0) {
+ perror("pcap_hdr");
+ exit(1);
+ }
+
+ while (1) {
+ unsigned char buf[1024];
+ struct timeval tv;
+ int burst_len;
+ burst_len = read_one_pkt(fd, &tv, sbuf, sizeof(buf));
+ if (burst_len < 0) {
+ fprintf(stderr, "read_one_pkt() = %d\n", burst_len);
+ exit(3);
+ }
+ rc = send_burst((struct gsmtap_hdr *)buf, burst_len, &tv);
+ }
+}
personal git repositories of Harald Welte. Your mileage may vary