source: lib/protocols_transport.c @ aa22b5b

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

If we have a complete header, but truncated at the end of it, we shouldn't return NULL from
get_payload_from_* functions so we can distinguish it from a truncated header.

  • Property mode set to 100644
File size: 4.0 KB
Line 
1#include "libtrace.h"
2#include "protocols.h"
3#include <assert.h>
4
5DLLEXPORT void *trace_get_transport(const libtrace_packet_t *packet, 
6                uint8_t *proto,
7                uint32_t *remaining
8                ) 
9{
10        uint8_t dummy_proto;
11        uint16_t ethertype;
12        uint32_t dummy_remaining;
13        void *transport;
14
15        if (!proto) proto=&dummy_proto;
16
17        if (!remaining) remaining=&dummy_remaining;
18
19        transport = trace_get_layer3(packet,&ethertype,remaining);
20
21        if (!transport || *remaining == 0)
22                return NULL;
23
24        switch (ethertype) {
25                case 0x0800: /* IPv4 */
26                        transport=trace_get_payload_from_ip(
27                                (libtrace_ip_t*)transport, proto, remaining);
28                        /* IPv6 */
29                        if (transport && *proto == 41) {
30                                transport=trace_get_payload_from_ip6(
31                                 (libtrace_ip6_t*)transport, proto,remaining);
32                        }
33                        return transport;
34                case 0x86DD: /* IPv6 */
35                        return trace_get_payload_from_ip6(
36                                (libtrace_ip6_t*)transport, proto, remaining);
37                       
38                default:
39                        printf("unknown ethertype=%04x\n",ethertype);
40                        *proto=0;
41                        return NULL;
42        }
43
44}
45
46DLLEXPORT libtrace_tcp_t *trace_get_tcp(libtrace_packet_t *packet) {
47        uint8_t proto;
48        libtrace_tcp_t *tcp;
49
50        tcp=(libtrace_tcp_t*)trace_get_transport(packet,&proto,NULL);
51
52        if (!tcp || proto != 6)
53                return NULL;
54
55        return (libtrace_tcp_t*)tcp;
56}
57
58DLLEXPORT libtrace_tcp_t *trace_get_tcp_from_ip(libtrace_ip_t *ip, uint32_t *remaining)
59{
60        libtrace_tcp_t *tcpptr = 0;
61
62        if (ip->ip_p == 6)  {
63                tcpptr = (libtrace_tcp_t *)
64                        trace_get_payload_from_ip(ip, NULL, remaining);
65        }
66
67        return tcpptr;
68}
69
70DLLEXPORT libtrace_udp_t *trace_get_udp(libtrace_packet_t *packet) {
71        uint8_t proto;
72        libtrace_udp_t *udp;
73
74        udp=(libtrace_udp_t*)trace_get_transport(packet,&proto,NULL);
75
76        if (!udp || proto != 17)
77                return NULL;
78
79        return udp;
80}
81
82DLLEXPORT libtrace_udp_t *trace_get_udp_from_ip(libtrace_ip_t *ip, uint32_t *remaining)
83{
84        libtrace_udp_t *udpptr = 0;
85
86        if (ip->ip_p == 17) {
87                udpptr = (libtrace_udp_t *)
88                        trace_get_payload_from_ip(ip, NULL, remaining);
89        }
90
91        return udpptr;
92}
93
94DLLEXPORT libtrace_icmp_t *trace_get_icmp(libtrace_packet_t *packet) {
95        uint8_t proto;
96        libtrace_icmp_t *icmp;
97
98        icmp=(libtrace_icmp_t*)trace_get_transport(packet,&proto,NULL);
99
100        if (!icmp || proto != 1)
101                return NULL;
102
103        return icmp;
104}
105
106DLLEXPORT libtrace_icmp_t *trace_get_icmp_from_ip(libtrace_ip_t *ip, uint32_t *remaining)
107{
108        libtrace_icmp_t *icmpptr = 0;
109
110        if (ip->ip_p == 1)  {
111                icmpptr = (libtrace_icmp_t *)trace_get_payload_from_ip(ip, 
112                                NULL, remaining);
113        }
114
115        return icmpptr;
116}
117
118DLLEXPORT void *trace_get_payload_from_udp(libtrace_udp_t *udp, uint32_t *remaining)
119{
120        if (remaining) {
121                if (*remaining < sizeof(libtrace_udp_t)) {
122                        *remaining = 0;
123                        return NULL;
124                }
125                *remaining-=sizeof(libtrace_udp_t);
126        }
127        return (void*)((char*)udp+sizeof(libtrace_udp_t));
128}
129
130DLLEXPORT void *trace_get_payload_from_tcp(libtrace_tcp_t *tcp, uint32_t *remaining)
131{
132        unsigned int dlen = tcp->doff*4;
133        if (remaining) {
134                if (*remaining < dlen) {
135                        *remaining = 0;
136                        return NULL;
137                }
138                *remaining-=dlen;
139        }
140        return (void *)((char *)tcp+dlen);
141}
142
143DLLEXPORT void *trace_get_payload_from_icmp(libtrace_icmp_t *icmp, uint32_t *remaining)
144{
145        if (remaining) {
146                if (*remaining < sizeof(libtrace_icmp_t)) {
147                        *remaining = 0;
148                        return NULL;
149                }
150                *remaining-=sizeof(libtrace_icmp_t);
151        }
152        return (char*)icmp+sizeof(libtrace_icmp_t);
153}
154
155/* Return the client port
156 */
157DLLEXPORT uint16_t trace_get_source_port(const libtrace_packet_t *packet)
158{
159        uint32_t remaining;
160        const struct ports_t *port = 
161                (const struct ports_t*)trace_get_transport((libtrace_packet_t*)packet,
162                        NULL, &remaining);
163
164        /* snapped too early */
165        if (remaining<2)
166                return 0;
167
168        if (port)
169                return ntohs(port->src);
170        else
171                return 0;
172}
173
174/* Same as get_source_port except use the destination port */
175DLLEXPORT uint16_t trace_get_destination_port(const libtrace_packet_t *packet)
176{
177        uint32_t remaining;
178        struct ports_t *port = 
179                (struct ports_t*)trace_get_transport((libtrace_packet_t*)packet,
180                        NULL, &remaining);
181        /* snapped to early */
182        if (remaining<4)
183                return 0;
184
185        if (port)
186                return ntohs(port->dst);
187        else
188                return 0;
189}
190
191
Note: See TracBrowser for help on using the repository browser.