00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00036 #include "packet_parser.h"
00037
00038 #include <netinet/tcp.h>
00039 #include <netinet/ip.h>
00040 #include <netinet/ip6.h>
00041 #include <netinet/udp.h>
00042 #include <netinet/ip_icmp.h>
00043 #include <netinet/icmp6.h>
00044
00045 #include <config.h>
00046
00056 unsigned int get_ip_headers(tracking_t * tracking,
00057 const unsigned char *dgram,
00058 unsigned int dgram_size)
00059 {
00060 #ifdef LINUX
00061 struct iphdr *ip = (struct iphdr *) dgram;
00062 #endif
00063 #ifdef FREEBSD
00064 struct ip *ip = (struct ip*) dgram;
00065 #endif
00066 struct ip6_hdr *ip6 = (struct ip6_hdr *) dgram;
00067 unsigned int offset;
00068
00069
00070 #ifdef LINUX
00071 if (dgram_size < sizeof(struct iphdr))
00072 #elif defined(FREEBSD)
00073 if (dgram_size < sizeof(struct ip))
00074 #endif
00075 return 0;
00076
00077
00078 #ifdef LINUX
00079 if (ip->version == 4) {
00080
00081 uint32_to_ipv6(ip->saddr, &tracking->saddr);
00082 uint32_to_ipv6(ip->daddr, &tracking->daddr);
00083
00084
00085 offset = 4 * ip->ihl;
00086 tracking->protocol = ip->protocol;
00087
00088 #ifdef TRACKING_WITH_PAYLOAD
00089
00090 if ((offset + sizeof(tracking->payload)) <= dgram_size)
00091 memcpy(tracking->payload, dgram + offset,
00092 sizeof(tracking->payload));
00093 else
00094 memset(tracking->payload, 0,
00095 sizeof(tracking->payload));
00096 #endif
00097 } else if (ip->version == 6) {
00098 #else
00099 if (ip->ip_v == 4) {
00100
00101 uint32_to_ipv6(ip->ip_src.s_addr, &tracking->saddr);
00102 uint32_to_ipv6(ip->ip_dst.s_addr, &tracking->daddr);
00103
00104
00105 offset = 4 * ip->ip_hl;
00106 tracking->protocol = ip->ip_p;
00107
00108 #ifdef TRACKING_WITH_PAYLOAD
00109
00110 if ((offset + sizeof(tracking->payload)) <= dgram_size)
00111 memcpy(tracking->payload, dgram + offset,
00112 sizeof(tracking->payload));
00113 else
00114 memset(tracking->payload, 0,
00115 sizeof(tracking->payload));
00116 #endif //#ifdef TRACKING_WITH_PAYLOAD
00117 } else if (ip->ip_v == 6) {
00118 #endif
00119
00120
00121 unsigned char found_transport_layer = 0;
00122 #ifdef TRACKING_WITH_PAYLOAD
00123 unsigned char copy_payload = 1;
00124 #endif
00125 struct ip6_ext *generic_hdr;
00126 struct ip6_frag *frag_hdr;
00127
00128
00129 if (dgram_size < sizeof(struct ip6_hdr))
00130 return 0;
00131
00132
00133 tracking->saddr = ip6->ip6_src;
00134 tracking->daddr = ip6->ip6_dst;
00135
00136
00137 tracking->protocol = ip6->ip6_nxt;
00138
00139
00140
00141 offset = sizeof(struct ip6_hdr);
00142 found_transport_layer = 0;
00143 do {
00144 switch (tracking->protocol) {
00145 case IPPROTO_HOPOPTS:
00146 case IPPROTO_ROUTING:
00147 case IPPROTO_DSTOPTS:
00148 case IPPROTO_AH:
00149
00150
00151 generic_hdr =
00152 (struct ip6_ext *) (dgram + offset);
00153 tracking->protocol = generic_hdr->ip6e_nxt;
00154 offset +=
00155 (unsigned int) (generic_hdr->
00156 ip6e_len) * 8;
00157 break;
00158
00159 case IPPROTO_FRAGMENT:
00160 frag_hdr =
00161 (struct ip6_frag *) (dgram + offset);
00162 tracking->protocol = frag_hdr->ip6f_nxt;
00163 offset += 8;
00164 break;
00165
00166 case IPPROTO_ESP:
00167 case IPPROTO_NONE:
00168
00169
00170
00171
00172
00173
00174 #ifdef TRACKING_WITH_PAYLOAD
00175 copy_payload = 0;
00176 #endif
00177 found_transport_layer = 1;
00178 break;
00179
00180 default:
00181
00182 found_transport_layer = 1;
00183 break;
00184 }
00185 } while (!found_transport_layer);
00186
00187 #ifdef TRACKING_WITH_PAYLOAD
00188 if ((offset + sizeof(tracking->payload)) <= dgram_size
00189 && copy_payload) {
00190 memcpy(tracking->payload, dgram + offset,
00191 sizeof(tracking->payload));
00192 } else {
00193 memset(tracking->payload, 0,
00194 sizeof(tracking->payload));
00195 }
00196 #endif
00197 } else {
00198 offset = 0;
00199 }
00200 return offset;
00201 }
00202
00212 int get_udp_headers(tracking_t * tracking, const unsigned char *dgram,
00213 unsigned int dgram_size)
00214 {
00215 #ifdef LINUX
00216 struct udphdr *udp = (struct udphdr *) dgram;
00217
00218
00219 if (dgram_size < sizeof(struct udphdr))
00220 return -1;
00221
00222 tracking->source = ntohs(udp->source);
00223 tracking->dest = ntohs(udp->dest);
00224 tracking->type = 0;
00225 tracking->code = 0;
00226 #else
00227
00228 #endif
00229 return 0;
00230 }
00231
00232
00244 tcp_state_t get_tcp_headers(tracking_t * tracking,
00245 const unsigned char *dgram,
00246 unsigned int dgram_size)
00247 {
00248 #ifdef LINUX
00249 struct tcphdr *tcp = (struct tcphdr *) dgram;
00250
00251
00252 if (dgram_size < sizeof(struct tcphdr))
00253 return TCP_STATE_UNKNOW;
00254
00255 tracking->source = ntohs(tcp->source);
00256 tracking->dest = ntohs(tcp->dest);
00257 tracking->type = 0;
00258 tracking->code = 0;
00259
00260
00261
00262 if (tcp->fin || tcp->rst)
00263 return TCP_STATE_CLOSE;
00264
00265
00266 if (tcp->syn) {
00267 if (tcp->ack) {
00268 return TCP_STATE_ESTABLISHED;
00269 } else {
00270 return TCP_STATE_OPEN;
00271 }
00272 }
00273 #else
00274
00275 #endif
00276 return TCP_STATE_UNKNOW;
00277 }
00278
00288 int get_icmp_headers(tracking_t * tracking, const unsigned char *dgram,
00289 unsigned int dgram_size)
00290 {
00291 #ifdef LINUX
00292 struct icmphdr *icmp = (struct icmphdr *) dgram;
00293
00294
00295 if (dgram_size < sizeof(struct icmphdr))
00296 return -1;
00297
00298 tracking->source = 0;
00299 tracking->dest = 0;
00300 tracking->type = icmp->type;
00301 tracking->code = icmp->code;
00302 #else
00303
00304 #endif
00305 return 0;
00306 }
00307
00317 int get_icmpv6_headers(tracking_t * tracking, const unsigned char *dgram,
00318 unsigned int dgram_size)
00319 {
00320 struct icmp6_hdr *hdr = (struct icmp6_hdr *) dgram;
00321
00322
00323 if (dgram_size < sizeof(struct icmp6_hdr))
00324 return -1;
00325
00326 tracking->source = 0;
00327 tracking->dest = 0;
00328 tracking->type = hdr->icmp6_type;
00329 tracking->code = hdr->icmp6_code;
00330 return 0;
00331 }
00332