Project

General

Profile

Download (5.29 KB) Statistics
| Branch: | Tag: | Revision:
1 1a37d409 Harald Welte
/* simtrace - main program for the host PC
2
 *
3 4e2a451d Harald Welte
 * (C) 2010-2011 by Harald Welte <hwelte@hmw-consulting.de>
4 1a37d409 Harald Welte
 *
5
 *  This program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License version 2 
7
 *  as published by the Free Software Foundation
8
 *
9
 *  This program is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this program; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 */
18
19
#include <errno.h>
20
#include <unistd.h>
21
#include <stdio.h>
22 00608064 Peter Stuge
#include <stdlib.h>
23 1a37d409 Harald Welte
#include <string.h>
24
#include <stdint.h>
25
#include <time.h>
26
#define _GNU_SOURCE
27
#include <getopt.h>
28
29
#include <sys/time.h>
30
#include <sys/types.h>
31
#include <sys/socket.h>
32
#include <netinet/in.h>
33
#include <arpa/inet.h>
34
35 18ad51fe Peter Stuge
#include <libusb.h>
36 1a37d409 Harald Welte
37
#include "simtrace.h"
38
#include "simtrace_usb.h"
39
#include "apdu_split.h"
40
41 96def428 Harald Welte
#include <osmocom/core/gsmtap.h>
42 4e2a451d Harald Welte
#include <osmocom/core/gsmtap_util.h>
43 f1c60623 Holger Hans Peter Freyther
#include <osmocom/core/utils.h>
44 1a37d409 Harald Welte
45
static struct apdu_split *as;
46 4e2a451d Harald Welte
static struct gsmtap_inst *g_gti;
47 1a37d409 Harald Welte
48 4e2a451d Harald Welte
static int gsmtap_send_sim(const uint8_t *apdu, unsigned int len)
49 1a37d409 Harald Welte
{
50
	struct gsmtap_hdr *gh;
51
	unsigned int gross_len = len + sizeof(*gh);
52
	uint8_t *buf = malloc(gross_len);
53
	int rc;
54
55
	if (!buf)
56
		return -ENOMEM;
57
58
	memset(buf, 0, sizeof(*gh));
59
	gh = (struct gsmtap_hdr *) buf;
60
	gh->version = GSMTAP_VERSION;
61
	gh->hdr_len = sizeof(*gh)/4;
62
	gh->type = GSMTAP_TYPE_SIM;
63
64
	memcpy(buf + sizeof(*gh), apdu, len);
65
66 4e2a451d Harald Welte
	rc = write(gsmtap_inst_fd(g_gti), buf, gross_len);
67 1a37d409 Harald Welte
	if (rc < 0) {
68
		perror("write gsmtap");
69
		free(buf);
70
		return rc;
71
	}
72
73
	free(buf);
74
	return 0;
75
}
76
77
static void apdu_out_cb(uint8_t *buf, unsigned int len, void *user_data)
78
{
79 f1c60623 Holger Hans Peter Freyther
	printf("APDU: %s\n", osmo_hexdump(buf, len));
80 4e2a451d Harald Welte
	gsmtap_send_sim(buf, len);
81 1a37d409 Harald Welte
}
82
83
static int process_usb_msg(uint8_t *buf, int len)
84
{
85 7b76e0ce Peter Stuge
	struct simtrace_hdr *sh = (struct simtrace_hdr *)buf;
86 1a37d409 Harald Welte
	uint8_t *payload = buf += sizeof(*sh);
87
	int payload_len = len - sizeof(*sh);
88
89
	if (payload_len < 0)
90
		return -EINVAL;
91
	
92
	switch (sh->cmd) {
93
	case SIMTRACE_MSGT_DATA:
94
		/* special treatment for ATR */
95
		if (sh->flags & SIMTRACE_FLAG_ATR) {
96
			printf("ATR ");
97
			apdu_out_cb(payload, payload_len, NULL);
98
			break;
99
		}
100 b14d0ad2 Harald Welte
		if (sh->flags & SIMTRACE_FLAG_PPS_FIDI) {
101
			printf("PPS(Fi=%u/Di=%u) ",
102
				sh->res[0], sh->res[1]);
103
		}
104 1a37d409 Harald Welte
		/* everything else goes into APDU splitter */
105
		apdu_split_in(as, payload, payload_len);
106
#if 0
107
		/* If waiting time has expired, signal explicit boundary */
108
		if (sh->flags & SIMTRACE_FLAG_WTIME_EXP)
109
			apdu_split_boundary(as);
110
#endif
111
		break;
112
	case SIMTRACE_MSGT_RESET:
113
	default:
114
		printf("unknown simtrace msg type 0x%02x\n", sh->cmd);
115
		break;
116
	}
117
}
118
119
static void print_welcome(void)
120
{
121
	printf("simtrace - GSM SIM and smartcard tracing\n"
122
	       "(C) 2010 by Harald Welte <laforge@gnumonks.org>\n\n");
123
}
124
125
static void print_help(void)
126
{
127
	printf( "\t-i\t--gsmtap-ip\tA.B.C.D\n"
128
		"\t-a\t--skip-atr\n"
129
		"\t-h\t--help\n"
130 5f9f3837 Holger Hans Peter Freyther
		"\t-k\t--keep-running\n"
131 1a37d409 Harald Welte
		"\n"
132
		);
133
}
134
135
static const struct option opts[] = {
136
	{ "gsmtap-ip", 1, 0, 'i' },
137
	{ "skip-atr", 0, 0, 'a' },
138
	{ "help", 0, 0, 'h' },
139 5f9f3837 Holger Hans Peter Freyther
	{ "keep-running", 0, 0, 'k' },
140 1a37d409 Harald Welte
	{ NULL, 0, 0, 0 }
141
};
142
143 943d7d28 Holger Hans Peter Freyther
static void run_mainloop(struct libusb_device_handle *devh)
144 1a37d409 Harald Welte
{
145 943d7d28 Holger Hans Peter Freyther
	unsigned int msg_count, byte_count = 0;
146 1a37d409 Harald Welte
	char buf[16*265];
147 943d7d28 Holger Hans Peter Freyther
	int xfer_len;
148
	int rc;
149
150
	printf("Entering main loop\n");
151 54683c7b Holger Hans Peter Freyther
	apdu_split_reset(as);
152 943d7d28 Holger Hans Peter Freyther
153
	while (1) {
154
		rc = libusb_bulk_transfer(devh, SIMTRACE_IN_EP, buf, sizeof(buf), &xfer_len, 100000);
155
		if (rc < 0 && rc != LIBUSB_ERROR_TIMEOUT) {
156
			fprintf(stderr, "BULK IN transfer error; rc=%d\n", rc);
157
			return;
158
		}
159
		if (xfer_len > 0) {
160
			//printf("URB: %s\n", osmo_hexdump(buf, rc));
161
			process_usb_msg(buf, xfer_len);
162
			msg_count++;
163
			byte_count += xfer_len;
164
		}
165
	}
166
}
167
168
int main(int argc, char **argv)
169
{
170 1a37d409 Harald Welte
	char *gsmtap_host = "127.0.0.1";
171 943d7d28 Holger Hans Peter Freyther
	int rc;
172
	int c, ret = 1;
173 1a37d409 Harald Welte
	int skip_atr = 0;
174 5f9f3837 Holger Hans Peter Freyther
	int keep_running = 0;
175 943d7d28 Holger Hans Peter Freyther
	struct libusb_device_handle *devh;
176 1a37d409 Harald Welte
177
	print_welcome();
178
179
	while (1) {
180
		int option_index = 0;
181
182 5f9f3837 Holger Hans Peter Freyther
		c = getopt_long(argc, argv, "i:ahk", opts, &option_index);
183 1a37d409 Harald Welte
		if (c == -1)
184
			break;
185
		switch (c) {
186
		case 'h':
187
			print_help();
188
			exit(0);
189
			break;
190
		case 'i':
191
			gsmtap_host = optarg;
192
			break;
193
		case 'a':
194
			skip_atr = 1;
195
			break;
196 5f9f3837 Holger Hans Peter Freyther
		case 'k':
197
			keep_running = 1;
198
			break;
199 1a37d409 Harald Welte
		}
200
	}
201
202 18ad51fe Peter Stuge
	rc = libusb_init(NULL);
203
	if (rc < 0) {
204
		fprintf(stderr, "libusb initialization failed\n");
205
		goto close_exit;
206
	}
207
208 4e2a451d Harald Welte
	g_gti = gsmtap_source_init(gsmtap_host, GSMTAP_UDP_PORT, 0);
209
	if (!g_gti) {
210
		perror("unable to open GSMTAP");
211 18ad51fe Peter Stuge
		goto close_exit;
212 1a37d409 Harald Welte
	}
213 4e2a451d Harald Welte
	gsmtap_source_add_sink(g_gti);
214 1a37d409 Harald Welte
215 943d7d28 Holger Hans Peter Freyther
	as = apdu_split_init(&apdu_out_cb, NULL);
216
	if (!as)
217
		goto release_exit;
218
219 5f9f3837 Holger Hans Peter Freyther
	do {
220
		devh = libusb_open_device_with_vid_pid(NULL, SIMTRACE_USB_VENDOR, SIMTRACE_USB_PRODUCT);
221
		if (!devh) {
222
			fprintf(stderr, "can't open USB device\n");
223
			goto close_exit;
224
		}
225 18ad51fe Peter Stuge
226 5f9f3837 Holger Hans Peter Freyther
		rc = libusb_claim_interface(devh, 0);
227
		if (rc < 0) {
228
			fprintf(stderr, "can't claim interface; rc=%d\n", rc);
229
			goto close_exit;
230
		}
231 1a37d409 Harald Welte
232 5f9f3837 Holger Hans Peter Freyther
		run_mainloop(devh);
233
		ret = 0;
234 18ad51fe Peter Stuge
235 5f9f3837 Holger Hans Peter Freyther
		libusb_release_interface(devh, 0);
236 18ad51fe Peter Stuge
close_exit:
237 5f9f3837 Holger Hans Peter Freyther
		if (devh)
238
			libusb_close(devh);
239
		if (keep_running)
240
			sleep(1);
241
	} while (keep_running);
242
243
release_exit:
244 18ad51fe Peter Stuge
	libusb_exit(NULL);
245
	return ret;
246 1a37d409 Harald Welte
}
Add picture from clipboard (Maximum size: 48.8 MB)