source: lib/linktypes.c @ 92b3f87

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 92b3f87 was fe4ab68, checked in by Matt Brown <mattb@…>, 15 years ago

Add the ARPHRD_PPP constant which Window's doesn't supply

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