Project

General

Profile

Download (5.29 KB) Statistics
| Branch: | Tag: | Revision:
1
/* simtrace - main program for the host PC
2
 *
3
 * (C) 2010-2011 by Harald Welte <hwelte@hmw-consulting.de>
4
 *
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
#include <stdlib.h>
23
#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
#include <libusb.h>
36

    
37
#include "simtrace.h"
38
#include "simtrace_usb.h"
39
#include "apdu_split.h"
40

    
41
#include <osmocom/core/gsmtap.h>
42
#include <osmocom/core/gsmtap_util.h>
43
#include <osmocom/core/utils.h>
44

    
45
static struct apdu_split *as;
46
static struct gsmtap_inst *g_gti;
47

    
48
static int gsmtap_send_sim(const uint8_t *apdu, unsigned int len)
49
{
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
	rc = write(gsmtap_inst_fd(g_gti), buf, gross_len);
67
	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
	printf("APDU: %s\n", osmo_hexdump(buf, len));
80
	gsmtap_send_sim(buf, len);
81
}
82

    
83
static int process_usb_msg(uint8_t *buf, int len)
84
{
85
	struct simtrace_hdr *sh = (struct simtrace_hdr *)buf;
86
	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
		if (sh->flags & SIMTRACE_FLAG_PPS_FIDI) {
101
			printf("PPS(Fi=%u/Di=%u) ",
102
				sh->res[0], sh->res[1]);
103
		}
104
		/* 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
		"\t-k\t--keep-running\n"
131
		"\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
	{ "keep-running", 0, 0, 'k' },
140
	{ NULL, 0, 0, 0 }
141
};
142

    
143
static void run_mainloop(struct libusb_device_handle *devh)
144
{
145
	unsigned int msg_count, byte_count = 0;
146
	char buf[16*265];
147
	int xfer_len;
148
	int rc;
149

    
150
	printf("Entering main loop\n");
151
	apdu_split_reset(as);
152

    
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
	char *gsmtap_host = "127.0.0.1";
171
	int rc;
172
	int c, ret = 1;
173
	int skip_atr = 0;
174
	int keep_running = 0;
175
	struct libusb_device_handle *devh;
176

    
177
	print_welcome();
178

    
179
	while (1) {
180
		int option_index = 0;
181

    
182
		c = getopt_long(argc, argv, "i:ahk", opts, &option_index);
183
		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
		case 'k':
197
			keep_running = 1;
198
			break;
199
		}
200
	}
201

    
202
	rc = libusb_init(NULL);
203
	if (rc < 0) {
204
		fprintf(stderr, "libusb initialization failed\n");
205
		goto close_exit;
206
	}
207

    
208
	g_gti = gsmtap_source_init(gsmtap_host, GSMTAP_UDP_PORT, 0);
209
	if (!g_gti) {
210
		perror("unable to open GSMTAP");
211
		goto close_exit;
212
	}
213
	gsmtap_source_add_sink(g_gti);
214

    
215
	as = apdu_split_init(&apdu_out_cb, NULL);
216
	if (!as)
217
		goto release_exit;
218

    
219
	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

    
226
		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

    
232
		run_mainloop(devh);
233
		ret = 0;
234

    
235
		libusb_release_interface(devh, 0);
236
close_exit:
237
		if (devh)
238
			libusb_close(devh);
239
		if (keep_running)
240
			sleep(1);
241
	} while (keep_running);
242

    
243
release_exit:
244
	libusb_exit(NULL);
245
	return ret;
246
}
(4-4/7)
Add picture from clipboard (Maximum size: 48.8 MB)