source: lib/linktypes.c @ 77285d9

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 77285d9 was 77285d9, checked in by Shane Alcock <salcock@…>, 16 years ago

OpenBSD compatibility fixes - adding in various #defines and #includes that are needed to compile under OpenBSD
Added a replacement pcap_next_ex function for systems that aren't running pcap-0.8 or better

  • Property mode set to 100644
File size: 4.1 KB
Line 
1#include "libtrace.h"
2#include "config.h"
3#ifdef HAVE_PCAP
4#include <pcap.h>
5#endif
6
7#include "rt_protocol.h"
8#include <assert.h>
9#include "libtrace_int.h"
10#include <stdlib.h>
11#include <string.h>
12
13#ifndef WIN32
14#include <net/if_arp.h>
15#endif
16
17#ifndef ARPHRD_ETHER
18#define ARPHRD_ETHER    1               /* Ethernet 10/100Mbps.  */
19#endif
20
21#ifndef ARPHRD_PPP
22#define ARPHRD_PPP      512
23#endif
24
25/* This file maps libtrace types to/from pcap DLT and erf types
26 *
27 * When adding a new linktype to libtrace, add the mapping(s) here,
28 * and add the understanding of the type to get_ip(), and perhaps
29 * get_{source,destination}_mac (if your linklayer has mac's)
30 */
31
32libtrace_linktype_t pcap_dlt_to_libtrace(libtrace_dlt_t dlt)
33{
34        switch(dlt) {
35                case TRACE_DLT_NULL: return TRACE_TYPE_NONE;
36                case TRACE_DLT_EN10MB: return TRACE_TYPE_ETH;
37                case TRACE_DLT_ATM_RFC1483: return TRACE_TYPE_ATM;
38                case TRACE_DLT_IEEE802_11: return TRACE_TYPE_80211;
39                case TRACE_DLT_LINUX_SLL: return TRACE_TYPE_LINUX_SLL;
40                case TRACE_DLT_PFLOG: return TRACE_TYPE_PFLOG;
41        }
42        return ~0;
43}
44
45libtrace_dlt_t libtrace_to_pcap_dlt(libtrace_linktype_t type)
46{
47        switch(type) {
48                case TRACE_TYPE_NONE: return TRACE_DLT_NULL;
49                case TRACE_TYPE_ETH: return TRACE_DLT_EN10MB;
50                case TRACE_TYPE_ATM: return TRACE_DLT_ATM_RFC1483;
51                case TRACE_TYPE_80211: return TRACE_DLT_IEEE802_11;
52                case TRACE_TYPE_LINUX_SLL: return TRACE_DLT_LINUX_SLL;
53                case TRACE_TYPE_PFLOG: return TRACE_DLT_PFLOG;
54        }
55        return ~0;
56}
57
58enum rt_field_t pcap_dlt_to_rt(libtrace_dlt_t dlt) 
59{
60        /* For pcap the rt type is just the dlt + a fixed value */
61        return dlt + RT_DATA_PCAP;
62}
63
64libtrace_dlt_t rt_to_pcap_dlt(enum rt_field_t rt_type)
65{
66        assert(rt_type >= RT_DATA_PCAP);
67        return rt_type - RT_DATA_PCAP;
68}
69
70libtrace_linktype_t erf_type_to_libtrace(char erf)
71{
72        switch (erf) {
73                case TYPE_HDLC_POS:     return TRACE_TYPE_HDLC_POS;
74                case TYPE_ETH:          return TRACE_TYPE_ETH;
75                case TYPE_ATM:          return TRACE_TYPE_ATM;
76                case TYPE_AAL5:         return TRACE_TYPE_AAL5;
77        }
78        return ~0;
79}
80
81char libtrace_to_erf_type(libtrace_linktype_t linktype)
82{
83        switch(linktype) {
84                case TRACE_TYPE_HDLC_POS: return TYPE_HDLC_POS;
85                case TRACE_TYPE_ETH:    return TYPE_ETH;
86                case TRACE_TYPE_ATM:    return TYPE_ATM;
87                case TRACE_TYPE_AAL5:   return TYPE_AAL5;
88        }
89        return -1;
90}
91
92/** Tinker with a packet
93 * packets that don't support direction tagging are annoying, especially
94 * when we have direction tagging information!  So this converts the packet
95 * to TRACE_TYPE_LINUX_SLL which does support direction tagging.  This is a
96 * pcap style packet for the reason that it means it works with bpf filters.
97 *
98 * @note this will copy the packet, so use sparingly if possible.
99 */
100void promote_packet(libtrace_packet_t *packet)
101{
102        if (packet->trace->format->type == TRACE_FORMAT_PCAP) {
103                char *tmpbuffer;
104                libtrace_sll_header_t *hdr;
105
106                switch(pcap_dlt_to_libtrace(rt_to_pcap_dlt(packet->type))) {
107                        case TRACE_TYPE_LINUX_SLL:
108                                return; /* Unnecessary */
109
110                        case TRACE_TYPE_NONE:
111                        case TRACE_TYPE_ETH:
112                                /* This should be easy, just prepend the header */
113                                tmpbuffer= malloc(sizeof(libtrace_sll_header_t)
114                                                +trace_get_capture_length(packet)
115                                                +trace_get_framing_length(packet)
116                                                );
117
118                                hdr=(void*)((char*)tmpbuffer
119                                        +trace_get_framing_length(packet));
120
121                                hdr->pkttype=0; /* "outgoing" */
122                                if (pcap_dlt_to_libtrace(rt_to_pcap_dlt(packet->type))==TRACE_TYPE_ETH)
123                                        hdr->hatype = ARPHRD_ETHER;
124                                else
125                                        hdr->hatype = ARPHRD_PPP;
126                                trace_get_payload_from_link(
127                                        trace_get_link(packet),
128                                        trace_get_link_type(packet),
129                                        &hdr->protocol,
130                                        NULL);
131                                break;
132                        default:
133                                /* failed */
134                                return;
135                }
136                memcpy(tmpbuffer,packet->header,
137                                trace_get_framing_length(packet));
138                memcpy(tmpbuffer
139                                +sizeof(libtrace_sll_header_t)
140                                +trace_get_framing_length(packet),
141                                packet->payload,
142                                trace_get_capture_length(packet));
143                if (packet->buf_control == TRACE_CTRL_EXTERNAL) {
144                        packet->buf_control=TRACE_CTRL_PACKET;
145                }
146                else {
147                        free(packet->buffer);
148                }
149                packet->buffer=tmpbuffer;
150                packet->header=tmpbuffer;
151                packet->payload=tmpbuffer+trace_get_framing_length(packet);
152                packet->type=pcap_dlt_to_rt(TRACE_DLT_LINUX_SLL);
153                return;
154        }
155}
Note: See TracBrowser for help on using the repository browser.