source: lib/format_linux.c @ 97e39a7

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 97e39a7 was 97e39a7, checked in by Perry Lorier <perry@…>, 16 years ago

Port new linux native capture type from libtrace 2.
Fail if we try and decode a pcap link type and we don't have pcap installed.

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2004 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *         
8 * All rights reserved.
9 *
10 * This code has been developed by the University of Waikato WAND
11 * research group. For further information please see http://www.wand.net.nz/
12 *
13 * libtrace is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * libtrace is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with libtrace; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 *
27 * $Id: format_template.c,v 1.13 2005/11/22 23:38:56 dlawson Exp $
28 *
29 */
30
31#include "libtrace.h"
32#include "libtrace_int.h"
33#include "format_helper.h"
34#include "config.h"
35#include "stdlib.h"
36
37#ifdef HAVE_INTTYPES_H
38#  include <inttypes.h>
39#else
40# error "Can't find inttypes.h"
41#endif
42
43#include <sys/socket.h>
44#include <netpacket/packet.h>
45#include <net/ethernet.h>
46#include <net/if_arp.h>
47
48static struct libtrace_format_t linuxnative;
49
50struct libtrace_format_data_t {
51        int fd;
52};
53
54struct libtrace_linuxnative_header {
55        struct timeval ts;
56        int wirelen;
57        struct sockaddr_ll hdr;
58};
59
60#define FORMAT(x) ((struct libtrace_format_data_t*)(x))
61
62static int linuxnative_init_input(struct libtrace_t *libtrace) {
63        struct sockaddr_ll addr;
64        libtrace->format_data = (struct libtrace_format_data_t *)
65                malloc(sizeof(struct libtrace_format_data_t));
66        FORMAT(libtrace->format_data)->fd = 
67                                socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
68        if (FORMAT(libtrace->format_data)->fd==-1) {
69                free(libtrace->format_data);
70                return 0;
71        }
72        addr.sll_family = AF_PACKET;
73        addr.sll_protocol = htons(ETH_P_ALL);
74        if (strlen(libtrace->uridata)) {
75                addr.sll_ifindex = if_nametoindex(libtrace->uridata);
76                if (addr.sll_ifindex == 0) {
77                        close(FORMAT(libtrace->format_data)->fd);
78                        free(libtrace->format_data);
79                        return 0;
80                }
81        }
82        else {
83                addr.sll_ifindex = 0;
84        }
85        if (bind(FORMAT(libtrace->format_data)->fd,
86                                (struct sockaddr*)&addr,
87                                sizeof(addr))==-1) {
88                free(libtrace->format_data);
89                return 0;
90        }
91        /* enable promisc mode when listening on an interface */
92        if (addr.sll_ifindex!=0) {
93                struct packet_mreq mreq;
94                socklen_t socklen = sizeof(mreq);
95                mreq.mr_ifindex = addr.sll_ifindex;
96                mreq.mr_type = PACKET_MR_PROMISC;
97                setsockopt(FORMAT(libtrace->format_data)->fd,
98                                SOL_PACKET,
99                                PACKET_ADD_MEMBERSHIP,
100                                &mreq,
101                                socklen);
102        }
103
104        return 1;
105}
106
107static int linuxnative_fin_input(struct libtrace_t *libtrace) {
108        close(FORMAT(libtrace->format_data)->fd);
109        free(libtrace->format_data);
110        return 0;
111}
112
113static int linuxnative_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
114        struct libtrace_linuxnative_header *hdr=(void*)packet->buffer;
115        socklen_t socklen=sizeof(hdr->hdr);
116        hdr->wirelen = recvfrom(FORMAT(libtrace->format_data)->fd,
117                        (void*)packet->buffer+sizeof(*hdr),
118                        sizeof(packet->buffer)-sizeof(*hdr),
119                        MSG_TRUNC,
120                        (void *)&hdr->hdr,
121                        &socklen);
122
123        if (hdr->wirelen==-1)
124                return -1;
125
126        if (ioctl(FORMAT(libtrace->format_data)->fd,SIOCGSTAMP,&hdr->ts)==-1)
127                perror("ioctl(SIOCGSTAMP)");
128
129        return hdr->wirelen+sizeof(*hdr);
130}
131
132static libtrace_linktype_t linuxnative_get_link_type(const struct libtrace_packet_t *packet) {
133        switch htons((((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_protocol)) {
134                case ETH_P_IP:
135                case ETH_P_IPV6:
136                case ETH_P_ARP:
137                        return TRACE_TYPE_ETH;
138                default: /* shrug, beyond me! */
139                        printf("unknown type %x\n",(((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_protocol));
140                        return -1;
141        }
142}
143
144static int8_t linuxnative_get_direction(const struct libtrace_packet_t *packet) {
145        switch (((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_pkttype) {
146                case PACKET_OUTGOING:
147                        return 0;
148                default:
149                        return 1;
150        }
151}
152
153static struct timeval linuxnative_get_timeval(const struct libtrace_packet_t *packet) { 
154        return ((struct libtrace_linuxnative_header*)(packet->buffer))->ts;
155}
156
157static int linuxnative_get_wire_length(const struct libtrace_packet_t *packet) {
158        return ((struct libtrace_linuxnative_header*)(packet->buffer))->wirelen;
159}
160
161static int linuxnative_get_framing_length(const struct libtrace_packet_t *packet) {
162        return sizeof(struct libtrace_linuxnative_header);
163}
164
165static size_t linuxnative_set_capture_length(struct libtrace_packet_t *packet,size_t size) {
166        return -1;
167}
168
169static int linuxnative_get_fd(const libtrace_t *trace) {
170        return FORMAT(trace->format_data)->fd;
171}
172
173static void linuxnative_help() {
174        printf("linuxnative format module: $Revision$\n");
175        printf("Supported input URIs:\n");
176        printf("\tint:\n");
177        printf("\n");
178        printf("Supported output URIs:\n");
179        printf("\tnone\n");
180        printf("\n");
181        return;
182}
183static struct libtrace_format_t linuxnative = {
184        "int",
185        "$Id: format_linuxnative.c,v 1.13 2005/11/22 23:38:56 dlawson Exp $",
186        TRACE_FORMAT_LINUX_NATIVE,
187        linuxnative_init_input,         /* init_input */
188        NULL,                           /* config_input */
189        NULL,                           /* start_input */
190        NULL,                           /* pause_input */
191        NULL,                           /* init_output */
192        NULL,                           /* config_output */
193        NULL,                           /* start_ouput */
194        linuxnative_fin_input,          /* fin_input */
195        NULL,                           /* fin_output */
196        linuxnative_read_packet,        /* read_packet */
197        NULL,                           /* fin_packet */
198        NULL,                           /* write_packet */
199        linuxnative_get_link_type,      /* get_link_type */
200        linuxnative_get_direction,      /* get_direction */
201        NULL,                           /* set_direction */
202        NULL,                           /* get_erf_timestamp */
203        linuxnative_get_timeval,        /* get_timeval */
204        NULL,                           /* get_seconds */
205        NULL,                           /* seek_erf */
206        NULL,                           /* seek_timeval */
207        NULL,                           /* seek_seconds */
208        NULL,                           /* get_capture_length */
209        linuxnative_get_wire_length,    /* get_wire_length */
210        linuxnative_get_framing_length, /* get_framing_length */
211        NULL,                           /* set_capture_length */
212        linuxnative_get_fd,             /* get_fd */
213        trace_event_trace,              /* trace_event */
214        linuxnative_help,               /* help */
215        NULL
216};
217
218void __attribute__((constructor)) linuxnative_constructor() {
219        register_format(&linuxnative);
220}
Note: See TracBrowser for help on using the repository browser.