blob: b874ac403a06d528edce483dfc4d3609c937156a [file] [log] [blame]
Harald Weltedc9b4e92012-11-15 00:12:56 +01001/* read PCAP file with meas_feed data and write it to sqlite3 database */
2
3/* (C) 2012 by Harald Welte <laforge@gnumonks.org>
4 *
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#include <string.h>
23#include <errno.h>
24#include <unistd.h>
25#include <stdlib.h>
26#include <stdio.h>
27
28#include <netinet/in.h>
29#include <netinet/ip.h>
30#include <netinet/udp.h>
31
Harald Weltedc9b4e92012-11-15 00:12:56 +010032#include <osmocom/core/socket.h>
33#include <osmocom/core/utils.h>
Harald Weltedc9b4e92012-11-15 00:12:56 +010034#include <osmocom/core/select.h>
35#include <osmocom/core/talloc.h>
36
37#include <osmocom/gsm/gsm_utils.h>
38
39#include <openbsc/meas_feed.h>
40
41#include <pcap/pcap.h>
42
43#include "meas_db.h"
44
45static struct meas_db_state *db;
46
47static void handle_mfm(const struct pcap_pkthdr *h,
48 const struct meas_feed_meas *mfm)
49{
50 const char *scenario;
51
52 if (strlen(mfm->scenario))
53 scenario = mfm->scenario;
54 else
55 scenario = NULL;
56
57 meas_db_insert(db, mfm->imsi, mfm->name, h->ts.tv_sec,
58 scenario, &mfm->mr);
59}
60
61static void pcap_cb(u_char *user, const struct pcap_pkthdr *h,
62 const u_char *bytes)
63{
64 const char *cur = bytes;
65 const struct iphdr *ip;
66 const struct udphdr *udp;
67 const struct meas_feed_meas *mfm;
68 uint16_t udplen;
69
70 if (h->caplen < 14+20+8)
71 return;
72
73 /* Check if there is IPv4 in the Ethernet */
74 if (cur[12] != 0x08 || cur[13] != 0x00)
75 return;
76
77 cur += 14; /* ethernet header */
78 ip = (struct iphdr *) cur;
79
80 if (ip->version != 4)
81 return;
82 cur += ip->ihl * 4;
83
84 if (ip->protocol != IPPROTO_UDP)
85 return;
86
87 udp = (struct udphdr *) cur;
88
89 if (udp->dest != htons(8888))
90 return;
91
92 udplen = ntohs(udp->len);
93 if (udplen != sizeof(*udp) + sizeof(*mfm))
94 return;
95 cur += sizeof(*udp);
96
97 mfm = (const struct meas_feed_meas *) cur;
98
99 handle_mfm(h, mfm);
100}
101
102int main(int argc, char **argv)
103{
104 char errbuf[PCAP_ERRBUF_SIZE+1];
105 char *pcap_fname, *db_fname;
106 pcap_t *pc;
107 int rc;
108
109 if (argc < 3) {
110 fprintf(stderr, "You need to specify PCAP and database file\n");
111 exit(2);
112 }
113
114 pcap_fname = argv[1];
115 db_fname = argv[2];
116
117 pc = pcap_open_offline(pcap_fname, errbuf);
118 if (!pc) {
119 fprintf(stderr, "Cannot open %s: %s\n", pcap_fname, errbuf);
120 exit(1);
121 }
122
123 db = meas_db_open(NULL, db_fname);
124 if (!db)
125 exit(0);
126
127 rc = meas_db_begin(db);
128 if (rc < 0) {
129 fprintf(stderr, "Error during BEGIN\n");
130 exit(1);
131 }
132
133 pcap_loop(pc, 0 , pcap_cb, NULL);
134
135 meas_db_commit(db);
136
137 exit(0);
138}