source: lib/format_linux.c @ dd2eaee

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

Add new pcapfile: uri for natively reading pcap files (without libpcap)
Add initialiser so we don't need to rely on gccisms for initialisation

  • Property mode set to 100644
File size: 6.5 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
48#include <string.h>
49#include <net/if.h>
50#include <sys/ioctl.h>
51
52static struct libtrace_format_t linuxnative;
53
54struct libtrace_format_data_t {
55        int fd;
56};
57
58struct libtrace_linuxnative_header {
59        struct timeval ts;
60        int wirelen;
61        struct sockaddr_ll hdr;
62};
63
64#define FORMAT(x) ((struct libtrace_format_data_t*)(x))
65
66static int linuxnative_init_input(struct libtrace_t *libtrace) {
67        struct sockaddr_ll addr;
68        libtrace->format_data = (struct libtrace_format_data_t *)
69                malloc(sizeof(struct libtrace_format_data_t));
70        FORMAT(libtrace->format_data)->fd = 
71                                socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
72        if (FORMAT(libtrace->format_data)->fd==-1) {
73                free(libtrace->format_data);
74                return -1;
75        }
76        addr.sll_family = AF_PACKET;
77        addr.sll_protocol = htons(ETH_P_ALL);
78        if (strlen(libtrace->uridata)) {
79                addr.sll_ifindex = if_nametoindex(libtrace->uridata);
80                if (addr.sll_ifindex == 0) {
81                        close(FORMAT(libtrace->format_data)->fd);
82                        free(libtrace->format_data);
83                        return -1;
84                }
85        }
86        else {
87                addr.sll_ifindex = 0;
88        }
89        if (bind(FORMAT(libtrace->format_data)->fd,
90                                (struct sockaddr*)&addr,
91                                sizeof(addr))==-1) {
92                free(libtrace->format_data);
93                return -1;
94        }
95        /* enable promisc mode when listening on an interface */
96        if (addr.sll_ifindex!=0) {
97                struct packet_mreq mreq;
98                socklen_t socklen = sizeof(mreq);
99                mreq.mr_ifindex = addr.sll_ifindex;
100                mreq.mr_type = PACKET_MR_PROMISC;
101                setsockopt(FORMAT(libtrace->format_data)->fd,
102                                SOL_PACKET,
103                                PACKET_ADD_MEMBERSHIP,
104                                &mreq,
105                                socklen);
106        }
107
108        return 0;
109}
110
111static int linuxnative_fin_input(struct libtrace_t *libtrace) {
112        close(FORMAT(libtrace->format_data)->fd);
113        free(libtrace->format_data);
114        return 0;
115}
116
117static int linuxnative_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
118        struct libtrace_linuxnative_header *hdr;
119        socklen_t socklen;
120        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
121                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
122                packet->buf_control = TRACE_CTRL_PACKET;
123        }
124
125        packet->header = packet->buffer;
126        packet->type = RT_DATA_LINUX_NATIVE;
127        packet->payload = (char*)packet->buffer+sizeof(*hdr);
128
129        hdr=(void*)packet->buffer;
130        socklen=sizeof(hdr->hdr);
131        hdr->wirelen = recvfrom(FORMAT(libtrace->format_data)->fd,
132                        (void*)packet->payload,
133                        LIBTRACE_PACKET_BUFSIZE-sizeof(*hdr),
134                        MSG_TRUNC,
135                        (void *)&hdr->hdr,
136                        &socklen);
137
138        if (hdr->wirelen==-1)
139                return -1;
140
141        if (ioctl(FORMAT(libtrace->format_data)->fd,SIOCGSTAMP,&hdr->ts)==-1)
142                perror("ioctl(SIOCGSTAMP)");
143
144        return hdr->wirelen+sizeof(*hdr);
145}
146
147static libtrace_linktype_t linuxnative_get_link_type(const struct libtrace_packet_t *packet) {
148        switch (htons((((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_protocol))) {
149                case ETH_P_IP:
150                case ETH_P_IPV6:
151                case ETH_P_ARP:
152                        return TRACE_TYPE_ETH;
153                default: /* shrug, beyond me! */
154                        printf("unknown type %x\n",(((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_protocol));
155                        return -1;
156        }
157}
158
159static int8_t linuxnative_get_direction(const struct libtrace_packet_t *packet) {
160        switch (((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_pkttype) {
161                case PACKET_OUTGOING:
162                        return 0;
163                default:
164                        return 1;
165        }
166}
167
168static struct timeval linuxnative_get_timeval(const struct libtrace_packet_t *packet) { 
169        return ((struct libtrace_linuxnative_header*)(packet->buffer))->ts;
170}
171
172static int linuxnative_get_wire_length(const struct libtrace_packet_t *packet) {
173        return ((struct libtrace_linuxnative_header*)(packet->buffer))->wirelen;
174}
175
176static int linuxnative_get_framing_length(const struct libtrace_packet_t *packet) {
177        return sizeof(struct libtrace_linuxnative_header);
178}
179
180static int linuxnative_get_fd(const libtrace_t *trace) {
181        return FORMAT(trace->format_data)->fd;
182}
183
184static void linuxnative_help() {
185        printf("linuxnative format module: $Revision$\n");
186        printf("Supported input URIs:\n");
187        printf("\tint:\n");
188        printf("\n");
189        printf("Supported output URIs:\n");
190        printf("\tnone\n");
191        printf("\n");
192        return;
193}
194static struct libtrace_format_t linuxnative = {
195        "int",
196        "$Id: format_linuxnative.c,v 1.13 2005/11/22 23:38:56 dlawson Exp $",
197        TRACE_FORMAT_LINUX_NATIVE,
198        linuxnative_init_input,         /* init_input */
199        NULL,                           /* config_input */
200        NULL,                           /* start_input */
201        NULL,                           /* pause_input */
202        NULL,                           /* init_output */
203        NULL,                           /* config_output */
204        NULL,                           /* start_ouput */
205        linuxnative_fin_input,          /* fin_input */
206        NULL,                           /* fin_output */
207        linuxnative_read_packet,        /* read_packet */
208        NULL,                           /* fin_packet */
209        NULL,                           /* write_packet */
210        linuxnative_get_link_type,      /* get_link_type */
211        linuxnative_get_direction,      /* get_direction */
212        NULL,                           /* set_direction */
213        NULL,                           /* get_erf_timestamp */
214        linuxnative_get_timeval,        /* get_timeval */
215        NULL,                           /* get_seconds */
216        NULL,                           /* seek_erf */
217        NULL,                           /* seek_timeval */
218        NULL,                           /* seek_seconds */
219        NULL,                           /* get_capture_length */
220        linuxnative_get_wire_length,    /* get_wire_length */
221        linuxnative_get_framing_length, /* get_framing_length */
222        NULL,                           /* set_capture_length */
223        linuxnative_get_fd,             /* get_fd */
224        trace_event_trace,              /* trace_event */
225        linuxnative_help,               /* help */
226        NULL
227};
228
229void CONSTRUCTOR linuxnative_constructor() {
230        register_format(&linuxnative);
231}
Note: See TracBrowser for help on using the repository browser.