source: lib/format_linux.c @ 85a79b0

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

Fixed lots of warnings

  • Property mode set to 100644
File size: 9.4 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
52struct libtrace_format_data_t {
53        int fd;
54        int snaplen;
55        int promisc;
56};
57
58struct libtrace_linuxnative_header {
59        struct timeval ts;
60        int wirelen;
61        int caplen;
62        struct sockaddr_ll hdr;
63};
64
65struct libtrace_linuxnative_format_data_t {
66        int fd;
67};
68
69#define FORMAT(x) ((struct libtrace_format_data_t*)(x))
70#define DATAOUT(x) ((struct libtrace_linuxnative_format_data_t*)((x)->format_data))
71
72static int linuxnative_init_input(libtrace_t *libtrace) 
73{
74        libtrace->format_data = (struct libtrace_format_data_t *)
75                malloc(sizeof(struct libtrace_format_data_t));
76        FORMAT(libtrace->format_data)->fd = -1;
77        FORMAT(libtrace->format_data)->promisc = 0;
78        FORMAT(libtrace->format_data)->snaplen = 65536;
79
80        return 0;
81}
82
83static int linuxnative_init_output(libtrace_out_t *libtrace)
84{
85        libtrace->format_data = (struct libtrace_linuxnative_format_data_t*)
86                malloc(sizeof(struct libtrace_linuxnative_format_data_t));
87        DATAOUT(libtrace)->fd = -1;
88
89        return 0;
90}
91
92static int linuxnative_start_input(libtrace_t *libtrace)
93{
94        struct sockaddr_ll addr;
95        memset(&addr,0,sizeof(addr));
96        FORMAT(libtrace->format_data)->fd = 
97                                socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
98        if (FORMAT(libtrace->format_data)->fd==-1) {
99                free(libtrace->format_data);
100                return -1;
101        }
102        addr.sll_family = AF_PACKET;
103        addr.sll_protocol = htons(ETH_P_ALL);
104        if (strlen(libtrace->uridata)) {
105                addr.sll_ifindex = if_nametoindex(libtrace->uridata);
106                if (addr.sll_ifindex == 0) {
107                        close(FORMAT(libtrace->format_data)->fd);
108                        free(libtrace->format_data);
109                        return -1;
110                }
111        }
112        else {
113                addr.sll_ifindex = 0;
114        }
115        if (bind(FORMAT(libtrace->format_data)->fd,
116                                (struct sockaddr*)&addr,
117                                sizeof(addr))==-1) {
118                free(libtrace->format_data);
119                return -1;
120        }
121        /* enable promisc mode when listening on an interface */
122        if (addr.sll_ifindex!=0) {
123                struct packet_mreq mreq;
124                socklen_t socklen = sizeof(mreq);
125                memset(&mreq,0,sizeof(mreq));
126                mreq.mr_ifindex = addr.sll_ifindex;
127                mreq.mr_type = PACKET_MR_PROMISC;
128                setsockopt(FORMAT(libtrace->format_data)->fd,
129                                SOL_PACKET,
130                                PACKET_ADD_MEMBERSHIP,
131                                &mreq,
132                                socklen);
133        }
134
135        return 0;
136}
137
138static int linuxnative_start_output(libtrace_out_t *libtrace)
139{
140        FORMAT(libtrace->format_data)->fd = 
141                                socket(PF_PACKET, SOCK_RAW, 0);
142        if (FORMAT(libtrace->format_data)->fd==-1) {
143                free(libtrace->format_data);
144                return -1;
145        }
146
147        return 0;
148}
149
150static int linuxnative_pause_input(libtrace_t *libtrace)
151{
152        close(FORMAT(libtrace->format_data)->fd);
153        FORMAT(libtrace->format_data)->fd=-1;
154
155        return 0;
156}
157
158static int linuxnative_fin_input(libtrace_t *libtrace) 
159{
160        free(libtrace->format_data);
161        return 0;
162}
163
164static int linuxnative_fin_output(libtrace_out_t *libtrace)
165{
166        close(DATAOUT(libtrace)->fd);
167        DATAOUT(libtrace)->fd=-1;
168        free(libtrace->format_data);
169        return 0;
170}
171
172static int linuxnative_config_input(libtrace_t *libtrace,
173                trace_option_t option,
174                void *data)
175{
176        switch(option) {
177                case TRACE_OPTION_SNAPLEN:
178                        FORMAT(libtrace->format_data)->snaplen=*(int*)data;
179                        return 0;
180                case TRACE_OPTION_PROMISC:
181                        FORMAT(libtrace->format_data)->promisc=*(int*)data;
182                        return 0;
183                case TRACE_OPTION_FILTER:
184                        /* We don't support bpf filters in any special way
185                         * so return an error and let libtrace deal with
186                         * emulating it
187                         */
188                        break;
189                case TRACE_META_FREQ:
190                        /* No meta-data for this format */
191                        break;
192                /* Avoid default: so that future options will cause a warning
193                 * here to remind us to implement it, or flag it as
194                 * unimplementable
195                 */
196        }
197        trace_set_err(libtrace,TRACE_ERR_UNKNOWN_OPTION,
198                        "Unknown option %i", option);
199        return -1;
200}
201
202#define LIBTRACE_MIN(a,b) ((a)<(b) ? (a) : (b))
203
204static int linuxnative_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) 
205{
206        struct libtrace_linuxnative_header *hdr;
207        socklen_t socklen;
208        int snaplen;
209        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
210                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
211                packet->buf_control = TRACE_CTRL_PACKET;
212        }
213
214        packet->header = packet->buffer;
215        packet->type = RT_DATA_LINUX_NATIVE;
216        packet->payload = (char*)packet->buffer+sizeof(*hdr);
217
218        hdr=(struct libtrace_linuxnative_header*)packet->buffer;
219        socklen=sizeof(hdr->hdr);
220        snaplen=LIBTRACE_MIN(
221                        (int)LIBTRACE_PACKET_BUFSIZE-(int)sizeof(*hdr),
222                        (int)FORMAT(libtrace->format_data)->snaplen);
223        hdr->wirelen = recvfrom(FORMAT(libtrace->format_data)->fd,
224                        (void*)packet->payload,
225                        snaplen,
226                        MSG_TRUNC,
227                        (struct sockaddr *)&hdr->hdr,
228                        &socklen);
229
230        if (hdr->wirelen==-1)
231                return -1;
232
233        hdr->caplen=LIBTRACE_MIN(snaplen,hdr->wirelen);
234
235        if (ioctl(FORMAT(libtrace->format_data)->fd,SIOCGSTAMP,&hdr->ts)==-1)
236                perror("ioctl(SIOCGSTAMP)");
237
238        return hdr->wirelen+sizeof(*hdr);
239}
240
241static int linuxnative_write_packet(libtrace_out_t *trace, 
242                libtrace_packet_t *packet) 
243{
244        struct sockaddr_ll hdr;
245
246        hdr.sll_family = AF_PACKET;
247        hdr.sll_protocol = 0;
248        hdr.sll_ifindex = if_nametoindex(trace->uridata);
249        hdr.sll_hatype = 0;
250        hdr.sll_pkttype = 0;
251        hdr.sll_halen = 6; /* FIXME */
252        memcpy(hdr.sll_addr,packet->payload,hdr.sll_halen);
253
254        return sendto(DATAOUT(trace)->fd,
255                        packet->payload,
256                        trace_get_capture_length(packet),
257                        0,
258                        (struct sockaddr*)&hdr, sizeof(hdr));
259
260}
261
262static libtrace_linktype_t linuxnative_get_link_type(const struct libtrace_packet_t *packet) {
263        int linktype=(((struct libtrace_linuxnative_header*)(packet->buffer))
264                                ->hdr.sll_hatype);
265        switch (linktype) {
266                case ARPHRD_ETHER:
267                        return TRACE_TYPE_ETH;
268                case ARPHRD_PPP:
269                        return TRACE_TYPE_NONE;
270                default: /* shrug, beyond me! */
271                        printf("unknown type %x\n",linktype);
272                        return (libtrace_linktype_t)~0U;
273        }
274}
275
276static libtrace_direction_t linuxnative_get_direction(const struct libtrace_packet_t *packet) {
277        switch (((struct libtrace_linuxnative_header*)(packet->buffer))->hdr.sll_pkttype) {
278                case PACKET_OUTGOING:
279                        return TRACE_DIR_OUTGOING;
280                default:
281                        return TRACE_DIR_INCOMING;
282        }
283}
284
285static struct timeval linuxnative_get_timeval(const libtrace_packet_t *packet) 
286{
287        return ((struct libtrace_linuxnative_header*)(packet->buffer))->ts;
288}
289
290static int linuxnative_get_capture_length(const libtrace_packet_t *packet)
291{
292        return ((struct libtrace_linuxnative_header*)(packet->buffer))->caplen;
293}
294
295static int linuxnative_get_wire_length(const libtrace_packet_t *packet) 
296{
297        return ((struct libtrace_linuxnative_header*)(packet->buffer))->wirelen;
298}
299
300static int linuxnative_get_framing_length(UNUSED
301                const libtrace_packet_t *packet) 
302{
303        return sizeof(struct libtrace_linuxnative_header);
304}
305
306static int linuxnative_get_fd(const libtrace_t *trace) {
307        return FORMAT(trace->format_data)->fd;
308}
309
310static void linuxnative_help() {
311        printf("linuxnative format module: $Revision$\n");
312        printf("Supported input URIs:\n");
313        printf("\tint:\n");
314        printf("\n");
315        printf("Supported output URIs:\n");
316        printf("\tnone\n");
317        printf("\n");
318        return;
319}
320static struct libtrace_format_t linuxnative = {
321        "int",
322        "$Id: format_linuxnative.c,v 1.13 2005/11/22 23:38:56 dlawson Exp $",
323        TRACE_FORMAT_LINUX_NATIVE,
324        linuxnative_init_input,         /* init_input */
325        linuxnative_config_input,       /* config_input */
326        linuxnative_start_input,        /* start_input */
327        linuxnative_pause_input,        /* pause_input */
328        linuxnative_init_output,        /* init_output */
329        NULL,                           /* config_output */
330        linuxnative_start_output,       /* start_ouput */
331        linuxnative_fin_input,          /* fin_input */
332        linuxnative_fin_output,         /* fin_output */
333        linuxnative_read_packet,        /* read_packet */
334        NULL,                           /* fin_packet */
335        linuxnative_write_packet,       /* write_packet */
336        linuxnative_get_link_type,      /* get_link_type */
337        linuxnative_get_direction,      /* get_direction */
338        NULL,                           /* set_direction */
339        NULL,                           /* get_erf_timestamp */
340        linuxnative_get_timeval,        /* get_timeval */
341        NULL,                           /* get_seconds */
342        NULL,                           /* seek_erf */
343        NULL,                           /* seek_timeval */
344        NULL,                           /* seek_seconds */
345        linuxnative_get_capture_length, /* get_capture_length */
346        linuxnative_get_wire_length,    /* get_wire_length */
347        linuxnative_get_framing_length, /* get_framing_length */
348        NULL,                           /* set_capture_length */
349        linuxnative_get_fd,             /* get_fd */
350        trace_event_device,             /* trace_event */
351        linuxnative_help,               /* help */
352        NULL
353};
354
355void linuxnative_constructor() {
356        register_format(&linuxnative);
357}
Note: See TracBrowser for help on using the repository browser.