source: lib/linktypes.c @ 5e85c23

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

More warnings squashed

  • Property mode set to 100644
File size: 8.8 KB
Line 
1#include "libtrace.h"
2#include "config.h"
3
4#include "rt_protocol.h"
5#include <assert.h>
6#include "libtrace_int.h"
7#include <stdlib.h>
8#include <string.h>
9
10#ifndef WIN32
11#include <net/if_arp.h>
12#endif
13
14#ifndef ARPHRD_ETHER
15#define ARPHRD_ETHER    1               /* Ethernet 10/100Mbps.  */
16#endif
17
18#ifndef ARPHRD_PPP
19#define ARPHRD_PPP      512
20#endif
21
22#ifndef ARPHRD_IEEE80211
23#define ARPHRD_IEEE80211        801
24#endif
25
26
27/* This file maps libtrace types to/from pcap DLT and erf types
28 *
29 * When adding a new linktype to libtrace, add the mapping(s) here,
30 * and add the understanding of the type to get_ip(), and perhaps
31 * get_{source,destination}_mac (if your linklayer has mac's)
32 */
33
34libtrace_linktype_t pcap_dlt_to_libtrace(libtrace_dlt_t dlt)
35{
36        switch(dlt) {
37                case TRACE_DLT_RAW: return TRACE_TYPE_NONE;
38                case TRACE_DLT_EN10MB: return TRACE_TYPE_ETH;
39                case TRACE_DLT_IEEE802_11: return TRACE_TYPE_80211;
40                case TRACE_DLT_LINUX_SLL: return TRACE_TYPE_LINUX_SLL;
41                case TRACE_DLT_PFLOG: return TRACE_TYPE_PFLOG;
42                case TRACE_DLT_IEEE802_11_RADIO: return TRACE_TYPE_80211_RADIO;
43                case TRACE_DLT_ATM_RFC1483: return TRACE_TYPE_LLCSNAP;
44                                         
45        }
46        return ~0U;
47}
48
49
50libtrace_dlt_t libtrace_to_pcap_dlt(libtrace_linktype_t type)
51{
52        /* If pcap doesn't have a DLT, you can either ask pcap to register
53         * you a DLT, (and perhaps write a tcpdump decoder for it), or you
54         * can add it to demote_packet
55         */
56        switch(type) {
57                case TRACE_TYPE_NONE: return TRACE_DLT_RAW;
58                case TRACE_TYPE_ETH: return TRACE_DLT_EN10MB;
59                case TRACE_TYPE_80211: return TRACE_DLT_IEEE802_11;
60                case TRACE_TYPE_LINUX_SLL: return TRACE_DLT_LINUX_SLL;
61                case TRACE_TYPE_PFLOG: return TRACE_DLT_PFLOG;
62                case TRACE_TYPE_80211_RADIO: return TRACE_DLT_IEEE802_11_RADIO;
63                case TRACE_TYPE_ATM:
64                        /* Dispite hints to the contrary, there is no DLT
65                         * for 'raw atm packets that happen to be missing
66                         * the HEC' or even 'raw atm packets that have a hec'.
67                         *
68                         * The closest are DLT_ATM_RFC1483 but that doesn't
69                         * include the ATM header, only the LLCSNAP header.
70                         */
71                        return ~0U;
72                case TRACE_TYPE_LLCSNAP: return TRACE_DLT_ATM_RFC1483;
73        }
74        return ~0U;
75}
76
77libtrace_rt_types_t pcap_dlt_to_rt(libtrace_dlt_t dlt) 
78{
79        /* For pcap the rt type is just the dlt + a fixed value */
80        return dlt + TRACE_RT_DATA_DLT;
81}
82
83libtrace_dlt_t rt_to_pcap_dlt(libtrace_rt_types_t rt_type)
84{
85        assert(rt_type >= TRACE_RT_DATA_DLT);
86        return rt_type - TRACE_RT_DATA_DLT;
87}
88
89libtrace_linktype_t erf_type_to_libtrace(char erf)
90{
91        switch (erf) {
92                case TYPE_HDLC_POS:     return TRACE_TYPE_HDLC_POS;
93                case TYPE_ETH:          return TRACE_TYPE_ETH;
94                case TYPE_ATM:          return TRACE_TYPE_ATM;
95                case TYPE_AAL5:         return TRACE_TYPE_AAL5;
96        }
97        return ~0U;
98}
99
100char libtrace_to_erf_type(libtrace_linktype_t linktype)
101{
102        switch(linktype) {
103                case TRACE_TYPE_HDLC_POS: return TYPE_HDLC_POS;
104                case TRACE_TYPE_ETH:    return TYPE_ETH;
105                case TRACE_TYPE_ATM:    return TYPE_ATM;
106                case TRACE_TYPE_AAL5:   return TYPE_AAL5;
107                case TRACE_TYPE_LLCSNAP: return -1;
108        }
109        return -1;
110}
111
112libtrace_linktype_t arphrd_type_to_libtrace(unsigned int arphrd) {
113        switch(arphrd) {
114                case ARPHRD_ETHER: return TRACE_TYPE_ETH;       
115                case ARPHRD_IEEE80211: return TRACE_TYPE_80211;
116                case ARPHRD_80211_RADIOTAP: return TRACE_TYPE_80211_RADIO;
117        }
118        return ~0U;
119}
120
121unsigned int libtrace_to_arphrd_type(libtrace_linktype_t linktype) {
122        switch(linktype) {
123                case TRACE_TYPE_ETH: return ARPHRD_ETHER;
124                case TRACE_TYPE_80211: return ARPHRD_IEEE80211;
125                case TRACE_TYPE_80211_RADIO: return ARPHRD_80211_RADIOTAP;
126        }
127        return ~0U;
128}
129
130/** Tinker with a packet
131 * packets that don't support direction tagging are annoying, especially
132 * when we have direction tagging information!  So this converts the packet
133 * to TRACE_TYPE_LINUX_SLL which does support direction tagging.  This is a
134 * pcap style packet for the reason that it means it works with bpf filters.
135 *
136 * @note this will copy the packet, so use sparingly if possible.
137 */
138void promote_packet(libtrace_packet_t *packet)
139{
140        if (packet->trace->format->type == TRACE_FORMAT_PCAP) {
141                char *tmpbuffer;
142                libtrace_sll_header_t *hdr;
143
144                if (pcap_dlt_to_libtrace(rt_to_pcap_dlt(packet->type))
145                        == TRACE_TYPE_LINUX_SLL) {
146                        /* This is already been promoted, so ignore it */
147                        return;
148                }
149
150                /* This should be easy, just prepend the header */
151                tmpbuffer= (char*)malloc(
152                                sizeof(libtrace_sll_header_t)
153                                +trace_get_capture_length(packet)
154                                +trace_get_framing_length(packet)
155                                );
156
157                hdr=(libtrace_sll_header_t*)((char*)tmpbuffer
158                        +trace_get_framing_length(packet));
159
160                hdr->halen=htons(6);
161                hdr->pkttype=TRACE_SLL_OUTGOING;
162
163                switch(pcap_dlt_to_libtrace(rt_to_pcap_dlt(packet->type))) {
164                        case TRACE_TYPE_NONE:
165                                trace_get_payload_from_link(
166                                        trace_get_link(packet),
167                                        trace_get_link_type(packet),
168                                        &hdr->protocol,
169                                        NULL);
170                                hdr->hatype = htons(ARPHRD_PPP);
171                                hdr->protocol=htons(hdr->protocol);
172                                break;
173                        case TRACE_TYPE_ETH:
174                                hdr->hatype = htons(ARPHRD_ETHER);
175                                hdr->protocol=htons(0x0060); /* ETH_P_LOOP */
176                                break;
177                        default:
178                                /* failed */
179                                return;
180                }
181                memcpy(tmpbuffer,packet->header,
182                                trace_get_framing_length(packet));
183                memcpy(tmpbuffer
184                                +sizeof(libtrace_sll_header_t)
185                                +trace_get_framing_length(packet),
186                                packet->payload,
187                                trace_get_capture_length(packet));
188                if (packet->buf_control == TRACE_CTRL_EXTERNAL) {
189                        packet->buf_control=TRACE_CTRL_PACKET;
190                }
191                else {
192                        free(packet->buffer);
193                }
194                packet->buffer=tmpbuffer;
195                packet->header=tmpbuffer;
196                packet->payload=tmpbuffer+trace_get_framing_length(packet);
197                packet->type=pcap_dlt_to_rt(TRACE_DLT_LINUX_SLL);
198                ((struct libtrace_pcapfile_pkt_hdr_t*) packet->header)->caplen+=
199                        sizeof(libtrace_sll_header_t);
200                ((struct libtrace_pcapfile_pkt_hdr_t*) packet->header)->wirelen+=
201                        sizeof(libtrace_sll_header_t);
202                return;
203        }
204}
205
206/* Try and simplify the packet one step, kinda the opposite to promote_packet
207 *
208 * returns true if demotion was possible, false if not.
209 */
210bool demote_packet(libtrace_packet_t *packet)
211{
212        uint8_t type;
213        uint32_t remaining;
214        char *tmp;
215        struct timeval tv;
216        static libtrace_t *trace = NULL;
217        switch(trace_get_link_type(packet)) {
218                case TRACE_TYPE_POS:
219                        remaining=trace_get_capture_length(packet);
220                        packet->payload=trace_get_payload_from_pos(
221                                packet->payload,NULL,&remaining);
222
223                        tmp=malloc(
224                                trace_get_capture_length(packet)
225                                +sizeof(libtrace_pcapfile_pkt_hdr_t)
226                                );
227
228                        tv=trace_get_timeval(packet);
229                        ((libtrace_pcapfile_pkt_hdr_t*)tmp)->ts_sec=tv.tv_sec;
230                        ((libtrace_pcapfile_pkt_hdr_t*)tmp)->ts_usec=tv.tv_usec;
231                        ((libtrace_pcapfile_pkt_hdr_t*)tmp)->wirelen
232                                = trace_get_wire_length(packet)-(trace_get_capture_length(packet)-remaining);
233                        ((libtrace_pcapfile_pkt_hdr_t*)tmp)->caplen
234                                = remaining;
235
236                        memcpy(tmp+sizeof(libtrace_pcapfile_pkt_hdr_t),
237                                        packet->payload,
238                                        remaining);
239                        if (packet->buf_control == TRACE_CTRL_EXTERNAL) {
240                                packet->buf_control=TRACE_CTRL_PACKET;
241                        }
242                        else {
243                                free(packet->buffer);
244                        }
245                        packet->buffer=tmp;
246                        packet->header=tmp;
247                        packet->payload=tmp+sizeof(libtrace_pcapfile_pkt_hdr_t);
248                        packet->type=pcap_dlt_to_rt(TRACE_DLT_RAW);
249                       
250                        if (trace == NULL) {
251                                trace = trace_create_dead("pcap:-");
252                        }
253
254                        packet->trace=trace;
255
256                        return true;
257                case TRACE_TYPE_ATM:
258                        remaining=trace_get_capture_length(packet);
259                        packet->payload=trace_get_payload_from_atm(
260                                packet->payload,&type,&remaining);
261
262                        tmp=malloc(
263                                trace_get_capture_length(packet)
264                                +sizeof(libtrace_pcapfile_pkt_hdr_t)
265                                );
266
267                        tv=trace_get_timeval(packet);
268                        ((libtrace_pcapfile_pkt_hdr_t*)tmp)->ts_sec=tv.tv_sec;
269                        ((libtrace_pcapfile_pkt_hdr_t*)tmp)->ts_usec=tv.tv_usec;
270                        ((libtrace_pcapfile_pkt_hdr_t*)tmp)->wirelen
271                                = trace_get_wire_length(packet)-(trace_get_capture_length(packet)-remaining);
272                        ((libtrace_pcapfile_pkt_hdr_t*)tmp)->caplen
273                                = remaining;
274
275                        memcpy(tmp+sizeof(libtrace_pcapfile_pkt_hdr_t),
276                                        packet->payload,
277                                        remaining);
278                        if (packet->buf_control == TRACE_CTRL_EXTERNAL) {
279                                packet->buf_control=TRACE_CTRL_PACKET;
280                        }
281                        else {
282                                free(packet->buffer);
283                        }
284                        packet->buffer=tmp;
285                        packet->header=tmp;
286                        packet->payload=tmp+sizeof(libtrace_pcapfile_pkt_hdr_t);
287                        packet->type=pcap_dlt_to_rt(TRACE_DLT_ATM_RFC1483);
288                       
289                        if (trace == NULL) {
290                                trace = trace_create_dead("pcap:-");
291                        }
292
293                        packet->trace=trace;
294
295                        return true;
296
297                case TRACE_TYPE_LINUX_SLL:
298                        switch(ntohs(((libtrace_sll_header_t*)packet->payload)
299                                        ->hatype)) {
300                                case ARPHRD_PPP:
301                                        packet->type=pcap_dlt_to_rt(TRACE_DLT_RAW);
302                                        break;
303                                case ARPHRD_ETHER:
304                                        packet->type=pcap_dlt_to_rt(TRACE_DLT_EN10MB);
305                                        break;
306                                default:
307                                        /* Dunno how to demote this packet */
308                                        return false;
309                        }
310                        /* Skip the Linux SLL header */
311                        packet->payload=(void*)((char*)packet->payload
312                                        +sizeof(libtrace_sll_header_t));
313                        trace_set_capture_length(packet,
314                                trace_get_capture_length(packet)
315                                        -sizeof(libtrace_sll_header_t));
316                        break;
317                default:
318                        return false;
319        }
320        return true;
321}
Note: See TracBrowser for help on using the repository browser.