blob: 261ee61aea36b09d0093c5ac5e31e612316d5998 [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>
34#include <osmocom/core/msgb.h>
35#include <osmocom/core/select.h>
36#include <osmocom/core/talloc.h>
37
38#include <osmocom/gsm/gsm_utils.h>
39
40#include <openbsc/meas_feed.h>
41
42#include <pcap/pcap.h>
43
44#include "meas_db.h"
45
46static struct meas_db_state *db;
47
48static void handle_mfm(const struct pcap_pkthdr *h,
49 const struct meas_feed_meas *mfm)
50{
51 const char *scenario;
52
53 if (strlen(mfm->scenario))
54 scenario = mfm->scenario;
55 else
56 scenario = NULL;
57
58 meas_db_insert(db, mfm->imsi, mfm->name, h->ts.tv_sec,
59 scenario, &mfm->mr);
60}
61
62static void pcap_cb(u_char *user, const struct pcap_pkthdr *h,
63 const u_char *bytes)
64{
65 const char *cur = bytes;
66 const struct iphdr *ip;
67 const struct udphdr *udp;
68 const struct meas_feed_meas *mfm;
69 uint16_t udplen;
70
71 if (h->caplen < 14+20+8)
72 return;
73
74 /* Check if there is IPv4 in the Ethernet */
75 if (cur[12] != 0x08 || cur[13] != 0x00)
76 return;
77
78 cur += 14; /* ethernet header */
79 ip = (struct iphdr *) cur;
80
81 if (ip->version != 4)
82 return;
83 cur += ip->ihl * 4;
84
85 if (ip->protocol != IPPROTO_UDP)
86 return;
87
88 udp = (struct udphdr *) cur;
89
90 if (udp->dest != htons(8888))
91 return;
92
93 udplen = ntohs(udp->len);
94 if (udplen != sizeof(*udp) + sizeof(*mfm))
95 return;
96 cur += sizeof(*udp);
97
98 mfm = (const struct meas_feed_meas *) cur;
99
100 handle_mfm(h, mfm);
101}
102
103int main(int argc, char **argv)
104{
105 char errbuf[PCAP_ERRBUF_SIZE+1];
106 char *pcap_fname, *db_fname;
107 pcap_t *pc;
108 int rc;
109
110 if (argc < 3) {
111 fprintf(stderr, "You need to specify PCAP and database file\n");
112 exit(2);
113 }
114
115 pcap_fname = argv[1];
116 db_fname = argv[2];
117
118 pc = pcap_open_offline(pcap_fname, errbuf);
119 if (!pc) {
120 fprintf(stderr, "Cannot open %s: %s\n", pcap_fname, errbuf);
121 exit(1);
122 }
123
124 db = meas_db_open(NULL, db_fname);
125 if (!db)
126 exit(0);
127
128 rc = meas_db_begin(db);
129 if (rc < 0) {
130 fprintf(stderr, "Error during BEGIN\n");
131 exit(1);
132 }
133
134 pcap_loop(pc, 0 , pcap_cb, NULL);
135
136 meas_db_commit(db);
137
138 exit(0);
139}