source: lib/format_linux.c @ 566e404

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

Fix bugs with forward porting of format_linux:

  • Fix the buffer management
  • Fill out uninitialised packet->type
  • Property mode set to 100644
File size: 6.6 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 -1;
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 -1;
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 -1;
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 0;
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;
115        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
116                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
117                packet->buf_control = TRACE_CTRL_PACKET;
118        }
119
120        packet->header = packet->buffer;
121        packet->type = RT_DATA_LINUX_NATIVE;
122        packet->payload = packet->buffer+sizeof(*hdr);
123
124        hdr=(void*)packet->buffer;
125        socklen_t socklen=sizeof(hdr->hdr);
126        hdr->wirelen = recvfrom(FORMAT(libtrace->format_data)->fd,
127                        (void*)packet->payload,
128                        LIBTRACE_PACKET_BUFSIZE-sizeof(*hdr),
129                        MSG_TRUNC,
130                        (void *)&hdr->hdr,
131                        &socklen);
132
133        if (hdr->wirelen==-1)
134                return -1;
135
136        if (ioctl(FORMAT(libtrace->format_data)->fd,SIOCGSTAMP,&hdr->ts)==-1)
137                perror("ioctl(SIOCGSTAMP)");
138
139        return hdr->wirelen+sizeof(*hdr);
140}
141
142static libtrace_linktype_t linuxnative_get_link_type(const struct libtrace_packet_t *packet) {
143        switch htons((((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_protocol)) {
144                case ETH_P_IP:
145                case ETH_P_IPV6:
146                case ETH_P_ARP:
147                        return TRACE_TYPE_ETH;
148                default: /* shrug, beyond me! */
149                        printf("unknown type %x\n",(((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_protocol));
150                        return -1;
151        }
152}
153
154static int8_t linuxnative_get_direction(const struct libtrace_packet_t *packet) {
155        switch (((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_pkttype) {
156                case PACKET_OUTGOING:
157                        return 0;
158                default:
159                        return 1;
160        }
161}
162
163static struct timeval linuxnative_get_timeval(const struct libtrace_packet_t *packet) { 
164        return ((struct libtrace_linuxnative_header*)(packet->buffer))->ts;
165}
166
167static int linuxnative_get_wire_length(const struct libtrace_packet_t *packet) {
168        return ((struct libtrace_linuxnative_header*)(packet->buffer))->wirelen;
169}
170
171static int linuxnative_get_framing_length(const struct libtrace_packet_t *packet) {
172        return sizeof(struct libtrace_linuxnative_header);
173}
174
175static size_t linuxnative_set_capture_length(struct libtrace_packet_t *packet,size_t size) {
176        return -1;
177}
178
179static int linuxnative_get_fd(const libtrace_t *trace) {
180        return FORMAT(trace->format_data)->fd;
181}
182
183static void linuxnative_help() {
184        printf("linuxnative format module: $Revision$\n");
185        printf("Supported input URIs:\n");
186        printf("\tint:\n");
187        printf("\n");
188        printf("Supported output URIs:\n");
189        printf("\tnone\n");
190        printf("\n");
191        return;
192}
193static struct libtrace_format_t linuxnative = {
194        "int",
195        "$Id: format_linuxnative.c,v 1.13 2005/11/22 23:38:56 dlawson Exp $",
196        TRACE_FORMAT_LINUX_NATIVE,
197        linuxnative_init_input,         /* init_input */
198        NULL,                           /* config_input */
199        NULL,                           /* start_input */
200        NULL,                           /* pause_input */
201        NULL,                           /* init_output */
202        NULL,                           /* config_output */
203        NULL,                           /* start_ouput */
204        linuxnative_fin_input,          /* fin_input */
205        NULL,                           /* fin_output */
206        linuxnative_read_packet,        /* read_packet */
207        NULL,                           /* fin_packet */
208        NULL,                           /* write_packet */
209        linuxnative_get_link_type,      /* get_link_type */
210        linuxnative_get_direction,      /* get_direction */
211        NULL,                           /* set_direction */
212        NULL,                           /* get_erf_timestamp */
213        linuxnative_get_timeval,        /* get_timeval */
214        NULL,                           /* get_seconds */
215        NULL,                           /* seek_erf */
216        NULL,                           /* seek_timeval */
217        NULL,                           /* seek_seconds */
218        NULL,                           /* get_capture_length */
219        linuxnative_get_wire_length,    /* get_wire_length */
220        linuxnative_get_framing_length, /* get_framing_length */
221        NULL,                           /* set_capture_length */
222        linuxnative_get_fd,             /* get_fd */
223        trace_event_trace,              /* trace_event */
224        linuxnative_help,               /* help */
225        NULL
226};
227
228void __attribute__((constructor)) linuxnative_constructor() {
229        register_format(&linuxnative);
230}
Note: See TracBrowser for help on using the repository browser.