3 * Near Field Communication nfctool
5 * Copyright (C) 2012 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 #include <sys/types.h>
28 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include <linux/tcp.h>
38 #include <near/nfc_copy.h>
41 #include "llcp-decode.h"
44 #define PCAP_MAGIC_NUMBER 0xa1b2c3d4
45 #define PCAP_MAJOR_VER 2
46 #define PCAP_MINOR_VER 4
47 #define PCAP_SNAP_LEN 0xFFFF
48 #define PCAP_NETWORK 0xF5
52 static GIOChannel *gio_channel = NULL;
55 static FILE *pcap_file = NULL;
56 static guint8 *buffer;
58 static int pcap_file_write_packet(guint8 *data, guint32 len,
59 struct timeval *timestamp)
64 if (pcap_file == NULL || data == NULL || len == 0)
67 val32 = timestamp->tv_sec;
68 if (fwrite(&val32, 4, 1, pcap_file) < 1)
71 val32 = timestamp->tv_usec;
72 if (fwrite(&val32, 4, 1, pcap_file) < 1)
75 if (len > PCAP_SNAP_LEN)
76 incl_len = PCAP_SNAP_LEN;
80 if (fwrite(&incl_len, 4, 1, pcap_file) < 1)
83 if (fwrite(&len, 4, 1, pcap_file) < 1)
86 if (fwrite(data, 1, incl_len, pcap_file) < incl_len)
95 static int pcap_file_init(char *pcap_filename)
101 pcap_file = fopen(pcap_filename, "w");
105 print_error("Can't open file %s: %s",
106 pcap_filename, strerror(err));
110 value32 = PCAP_MAGIC_NUMBER;
111 if (fwrite(&value32, 4, 1, pcap_file) < 1)
114 value16 = PCAP_MAJOR_VER;
115 if (fwrite(&value16, 2, 1, pcap_file) < 1)
118 value16 = PCAP_MINOR_VER;
119 if (fwrite(&value16, 2, 1, pcap_file) < 1)
123 if (fwrite(&value32, 4, 1, pcap_file) < 1)
125 if (fwrite(&value32, 4, 1, pcap_file) < 1)
128 value32 = PCAP_SNAP_LEN;
129 if (fwrite(&value32, 4, 1, pcap_file) < 1)
132 value32 = PCAP_NETWORK;
133 if (fwrite(&value32, 4, 1, pcap_file) < 1)
142 static void pcap_file_cleanup(void)
144 if (pcap_file != NULL) {
151 #define LINE_SIZE (10 + 3 * 16 + 2 + 18 + 1)
152 #define HUMAN_READABLE_OFFSET 59
155 * Dumps data in Hex+ASCII format as:
157 * 00000000: 01 01 43 20 30 70 72 6F 70 65 72 74 69 65 73 20 |..C 0properties |
160 void sniffer_print_hexdump(FILE *file, guint8 *data, guint32 len,
161 gchar *line_prefix, gboolean print_len)
166 gchar line[LINE_SIZE];
167 gchar *hexa = NULL, *human = NULL;
178 fprintf(file, "%s", line_prefix);
180 fprintf(file, "Total length: %u bytes\n", len);
183 while (total < len) {
185 memset(line, ' ', HUMAN_READABLE_OFFSET);
187 sprintf(line, "%08X: ", offset);
192 human = line + HUMAN_READABLE_OFFSET;
196 sprintf(hexa, "%02hhX ", data[total]);
197 *human++ = isprint((int)data[total]) ? (char)data[total] : '.';
200 if (++digits >= 16) {
204 fprintf(file, "%s", line_prefix);
205 fprintf(file, "%s\n", line);
213 if ((len & 0xF) != 0) {
217 fprintf(file, "%s", line_prefix);
218 fprintf(file, "%s\n", line);
222 static gboolean gio_handler(GIOChannel *channel,
223 GIOCondition cond, gpointer data)
229 guint8 ctrl[CMSG_SPACE(sizeof(struct timeval))];
230 struct cmsghdr *cmsg;
231 struct timeval msg_timestamp;
233 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
234 print_error("Sniffer IO error 0x%x\n", cond);
237 g_source_remove(watch);
244 sock = g_io_channel_unix_get_fd(channel);
246 memset(&msg, 0, sizeof(struct msghdr));
248 msg.msg_control = &ctrl;
249 msg.msg_controllen = sizeof(ctrl);
253 iov.iov_base = buffer;
254 iov.iov_len = opts.snap_len;
256 len = recvmsg(sock, &msg, 0);
258 print_error("recv: %s", strerror(errno));
262 cmsg = CMSG_FIRSTHDR(&msg);
263 if (cmsg && cmsg->cmsg_type == SCM_TIMESTAMP)
264 memcpy(&msg_timestamp, CMSG_DATA(cmsg), sizeof(struct timeval));
266 gettimeofday(&msg_timestamp, NULL);
268 llcp_print_pdu(buffer, len, &msg_timestamp);
270 pcap_file_write_packet(buffer, len, &msg_timestamp);
275 void sniffer_cleanup(void)
277 DBG("gio_channel: %p", gio_channel);
280 g_io_channel_shutdown(gio_channel, TRUE, NULL);
281 g_io_channel_unref(gio_channel);
288 llcp_decode_cleanup();
291 int sniffer_init(void)
293 struct sockaddr_nfc_llcp sockaddr;
298 if (opts.snap_len < SNAP_LEN)
299 opts.snap_len = SNAP_LEN;
301 buffer = g_malloc(opts.snap_len);
303 sock = socket(AF_NFC, SOCK_RAW, NFC_SOCKPROTO_LLCP);
306 print_error("socket: %s", strerror(errno));
310 err = setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
312 print_error("setsockopt: %s", strerror(errno));
314 memset(&sockaddr, 0, sizeof(struct sockaddr_nfc_llcp));
315 sockaddr.sa_family = AF_NFC;
316 sockaddr.dev_idx = opts.adapter_idx;
317 sockaddr.nfc_protocol = NFC_PROTO_NFC_DEP;
319 err = bind(sock, (struct sockaddr *)&sockaddr,
320 sizeof(struct sockaddr_nfc_llcp));
323 print_error("bind: %s", strerror(errno));
327 gio_channel = g_io_channel_unix_new(sock);
328 g_io_channel_set_close_on_unref(gio_channel, TRUE);
330 g_io_channel_set_encoding(gio_channel, NULL, NULL);
331 g_io_channel_set_buffered(gio_channel, FALSE);
333 watch = g_io_add_watch(gio_channel,
334 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
337 g_io_channel_unref(gio_channel);
339 if (opts.pcap_filename != NULL) {
340 err = pcap_file_init(opts.pcap_filename);
345 err = llcp_decode_init();
349 printf("Start sniffer on nfc%d\n\n", opts.adapter_idx);