Changeset 9231fe5 for lib/protocols.c
- Timestamp:
- 04/07/06 00:17:36 (16 years ago)
- Branches:
- 4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, getfragoff, help, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
- Children:
- d320b63
- Parents:
- a842286
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/protocols.c
ra842286 r9231fe5 6 6 #include "libtrace_int.h" 7 7 #include "wag.h" 8 9 10 static void *trace_get_ip_from_ethernet(void *ethernet, int *skipped) 8 #include <assert.h> 9 10 11 /* Returns the payload from 802.3 ethernet. Type optionally returned in 12 * "type" in host byte order. This will return a vlan header. 13 */ 14 static void *trace_get_payload_from_ethernet(void *ethernet, 15 uint16_t *type, 16 uint32_t *remaining) 11 17 { 12 18 libtrace_ether_t *eth = ethernet; 13 14 if (ntohs(eth->ether_type)==0x0800) { 15 if (skipped) 16 *skipped=sizeof(libtrace_ether_t); 17 return (void*)((char *)eth + sizeof(*eth)); 18 } else if (ntohs(eth->ether_type) == 0x8100) { 19 libtrace_8021q_t *vlanhdr = (libtrace_8021q_t *)eth; 20 if (skipped) 21 *skipped=sizeof(libtrace_ether_t); 22 if (ntohs(vlanhdr->vlan_ether_type) == 0x0800) { 23 return (void*)((char *)eth + sizeof(*vlanhdr)); 24 } 25 } 26 19 20 if (remaining) { 21 if (*remaining < sizeof(*eth)) 22 return NULL; 23 *remaining-=sizeof(*eth); 24 } 25 26 if (type) 27 *type = ntohs(eth->ether_type); 28 29 return (void*)((char *)eth + sizeof(*eth)); 30 } 31 32 /* skip any 802.1q headers if necessary 33 * type is input/output 34 */ 35 static void *trace_get_vlan_payload_from_ethernet_payload(void *ethernet, uint16_t *type, 36 uint32_t *remaining) 37 { 38 assert(type && "You must pass a type in!"); 39 40 if (*type == 0x8100) { 41 libtrace_8021q_t *vlanhdr = (libtrace_8021q_t *)ethernet; 42 43 if (remaining) { 44 if (*remaining < sizeof(libtrace_8021q_t)) 45 return NULL; 46 47 *remaining=*remaining-sizeof(libtrace_8021q_t); 48 } 49 50 *type = ntohs(vlanhdr->vlan_ether_type); 51 52 return (void*)((char *)ethernet + sizeof(*vlanhdr)); 53 } 54 27 55 return NULL; 28 56 } 29 57 30 static void *trace_get_ip6_from_ethernet(void *ethernet, int *skipped) 31 { 32 libtrace_ether_t *eth = ethernet; 33 34 if (ntohs(eth->ether_type)==0x86DD) { 35 if (skipped) 36 *skipped=sizeof(libtrace_ether_t); 37 return (void*)((char *)eth + sizeof(*eth)); 38 } else if (ntohs(eth->ether_type) == 0x8100) { 39 libtrace_8021q_t *vlanhdr = (libtrace_8021q_t *)eth; 40 if (skipped) 41 *skipped=sizeof(libtrace_ether_t); 42 if (ntohs(vlanhdr->vlan_ether_type) == 0x86DD) { 43 return (void*)((char *)eth + sizeof(*vlanhdr)); 44 } 45 } 46 47 return NULL; 48 } 49 50 static void *trace_get_ip_from_80211(void *link, int *skipped) 58 static void *trace_get_payload_from_80211(void *link, uint16_t *type, uint32_t *remaining) 51 59 { 52 60 libtrace_80211_t *wifi = link; 53 61 struct ieee_802_11_payload *eth; 54 62 55 if (*skipped) skipped+=sizeof(libtrace_80211_t); 56 57 if (!wifi) { 58 return NULL; 59 } 63 if (remaining && *remaining < sizeof(libtrace_80211_t)) 64 return NULL; 60 65 61 66 /* Data packet? */ … … 64 69 } 65 70 66 if (skipped) *skipped+=sizeof(*eth); 67 eth=(void*)((char*)wifi+sizeof(libtrace_80211_t)); 68 69 if (ntohs(eth->type) == 0x0800) { 70 return (void*)((char*)eth + sizeof(*eth)); 71 } else if (ntohs(eth->type) == 0x8100) { 72 struct libtrace_8021q *vlanhdr = (struct libtrace_8021q *)eth; 73 if (ntohs(vlanhdr->vlan_ether_type) == 0x0800) { 74 if (skipped) *skipped+=sizeof(*vlanhdr); 75 return (void*)((char*)eth + sizeof(*vlanhdr)); 76 } 77 } 78 79 return NULL; 80 } 81 82 static void *trace_get_ip6_from_80211(void *link, int *skipped) 83 { 84 libtrace_80211_t *wifi = link; 85 struct ieee_802_11_payload *eth; 86 87 if (*skipped) skipped+=sizeof(libtrace_80211_t); 88 89 if (!wifi) { 90 return NULL; 91 } 92 93 /* Data packet? */ 94 if (wifi->type != 2) { 95 return NULL; 96 } 97 98 if (skipped) *skipped+=sizeof(*eth); 99 eth=(void*)((char*)wifi+sizeof(libtrace_80211_t)); 100 101 if (ntohs(eth->type) == 0x86DD) { 102 return (void*)((char*)eth + sizeof(*eth)); 103 } else if (ntohs(eth->type) == 0x8100) { 104 struct libtrace_8021q *vlanhdr = (struct libtrace_8021q *)eth; 105 if (ntohs(vlanhdr->vlan_ether_type) == 0x86DD) { 106 if (skipped) *skipped+=sizeof(*vlanhdr); 107 return (void*)((char*)eth + sizeof(*vlanhdr)); 108 } 109 } 110 111 return NULL; 112 } 113 114 /* TODO: split these cases into get_*_from_* functions */ 115 struct libtrace_ip *trace_get_ip(const struct libtrace_packet_t *packet) { 116 struct libtrace_ip *ipptr = 0; 117 118 switch(trace_get_link_type(packet)) { 71 if (remaining && *remaining < sizeof(*eth)) 72 return NULL; 73 74 eth=(void*)((char*)wifi+sizeof(*eth)); 75 76 if (*type) *type=eth->type; 77 78 return eth; 79 } 80 81 static void *trace_get_payload_from_linux_sll(void *link, 82 uint16_t *type, uint32_t *remaining) 83 { 84 struct trace_sll_header_t *sll; 85 86 sll = link; 87 88 if (remaining) { 89 if (*remaining < sizeof(*sll)) 90 return NULL; 91 *remaining-=sizeof(*sll); 92 } 93 94 if (*type) *type = sll->protocol; 95 96 return (void*)((char*)sll+sizeof(*sll)); 97 } 98 99 static void *trace_get_payload_from_atm(void *link, 100 uint16_t *type, uint32_t *remaining) 101 { 102 /* 64 byte capture. */ 103 struct libtrace_llcsnap *llc = link; 104 105 if (remaining) { 106 if (*remaining < sizeof(struct libtrace_llcsnap)+4) 107 return NULL; 108 *remaining-=(sizeof(struct libtrace_llcsnap)+4); 109 } 110 111 /* advance the llc ptr +4 into the link layer. 112 * TODO: need to check what is in these 4 bytes. 113 * don't have time! 114 */ 115 llc = (void*)((char *)llc + 4); 116 117 if (*type) *type = ntohs(llc->type); 118 119 return (void*)((char*)llc+sizeof(*llc)); 120 } 121 122 static void *trace_get_payload_from_legacy_pos(void *link, 123 uint16_t *type, uint32_t *remaining) 124 { 125 /* 64 byte capture. */ 126 struct libtrace_pos *pos = link; 127 128 if (remaining) { 129 if (*remaining < sizeof(struct libtrace_pos)) 130 return NULL; 131 *remaining-=sizeof(struct libtrace_pos); 132 } 133 134 if (type) *type = ntohs(pos->ether_type); 135 136 return (void*)((char *)pos+sizeof(*pos)); 137 } 138 139 static void *trace_get_payload_from_pflog(void *link, 140 uint16_t *type, uint32_t *remaining) 141 { 142 struct trace_pflog_header_t *pflog = link; 143 if (remaining) { 144 if (*remaining<sizeof(*pflog)) 145 return NULL; 146 *remaining-=sizeof(*pflog); 147 } 148 if (type) { 149 switch(pflog->af) { 150 case AF_INET6: *type=0x86DD; break; 151 case AF_INET: *type=0x0800; break; 152 default: 153 /* Unknown */ 154 return NULL; 155 } 156 } 157 return (void*)((char*)pflog+ sizeof(*pflog)); 158 } 159 160 void *trace_get_payload_from_link(void *link, libtrace_linktype_t linktype, 161 uint16_t *type, uint32_t *remaining) 162 { 163 switch(linktype) { 119 164 case TRACE_TYPE_80211_PRISM: 120 ipptr = trace_get_ip_from_80211( 121 (char*)trace_get_link(packet)+144, 122 NULL); 123 break; 165 return trace_get_payload_from_80211((char*)link+144, 166 type,remaining); 124 167 case TRACE_TYPE_80211: 125 ipptr = trace_get_ip_from_80211( 126 trace_get_link(packet), 127 NULL); 128 break; 168 return trace_get_payload_from_80211(link,type,remaining); 129 169 case TRACE_TYPE_ETH: 130 170 case TRACE_TYPE_LEGACY_ETH: 131 ipptr = trace_get_ip_from_ethernet( 132 trace_get_link(packet), 133 NULL); 134 break; 171 return trace_get_payload_from_ethernet(link,type,remaining); 135 172 case TRACE_TYPE_NONE: 136 ipptr = trace_get_link(packet); 137 break; 173 return link; /* I love the simplicity */ 138 174 case TRACE_TYPE_LINUX_SLL: 139 { 140 struct trace_sll_header_t *sll; 141 142 sll = trace_get_link(packet); 143 if (!sll) { 144 ipptr = NULL; 145 } else if (ntohs(sll->protocol)!=0x0800) { 146 ipptr = NULL; 147 } 148 else { 149 ipptr=(void*)((char*)sll+sizeof(*sll)); 150 } 151 } 152 break; 175 return trace_get_payload_from_linux_sll(link,type,remaining); 153 176 case TRACE_TYPE_PFLOG: 154 { 155 struct trace_pflog_header_t *pflog; 156 pflog = trace_get_link(packet); 157 if (!pflog) { 158 ipptr = NULL; 159 break; 160 } 161 if (pflog->af != AF_INET6) { 162 ipptr = NULL; 163 } else { 164 ipptr = (void*)((char*)pflog+ 165 sizeof(*pflog)); 166 } 167 } 168 break; 177 return trace_get_payload_from_pflog(link,type,remaining); 169 178 case TRACE_TYPE_LEGACY_POS: 170 { 171 /* 64 byte capture. */ 172 struct libtrace_pos *pos = 173 trace_get_link(packet); 174 if (ntohs(pos->ether_type) == 0x0800) { 175 ipptr=(void*)((char *)pos+sizeof(*pos)); 176 } else { 177 ipptr=NULL; 178 } 179 break; 180 181 } 179 return trace_get_payload_from_legacy_pos(link,type,remaining); 182 180 case TRACE_TYPE_LEGACY_ATM: 183 181 case TRACE_TYPE_ATM: 184 { 185 /* 64 byte capture. */ 186 struct libtrace_llcsnap *llc = 187 trace_get_link(packet); 188 189 /* advance the llc ptr +4 into the link layer. 190 * need to check what is in these 4 bytes. 191 * don't have time! 192 */ 193 llc = (void*)((char *)llc + 4); 194 if (ntohs(llc->type) == 0x0800) { 195 ipptr=(void*)((char*)llc+sizeof(*llc)); 196 } else { 197 ipptr = NULL; 198 } 199 break; 200 } 182 return trace_get_payload_from_atm(link,type,remaining); 201 183 default: 202 184 fprintf(stderr,"Don't understand link layer type %i in trace_get_ip6()\n", 203 trace_get_link_type(packet)); 204 ipptr=NULL; 205 break; 206 } 207 208 return ipptr; 209 } 210 211 /* TODO: split these cases into get_*_from_* functions */ 212 struct libtrace_ip6 *trace_get_ip6(const struct libtrace_packet_t *packet) { 213 libtrace_ip6_t *ipptr = 0; 214 215 switch(trace_get_link_type(packet)) { 216 case TRACE_TYPE_80211_PRISM: 217 { 218 ipptr = trace_get_ip6_from_80211( 219 (char*)trace_get_link(packet)+144, NULL); 220 } 221 break; 222 case TRACE_TYPE_80211: 223 ipptr = trace_get_ip6_from_80211( 224 trace_get_link(packet), 225 NULL); 226 break; 227 case TRACE_TYPE_ETH: 228 case TRACE_TYPE_LEGACY_ETH: 229 { 230 ipptr = trace_get_ip6_from_ethernet( 231 trace_get_link(packet), 232 NULL); 233 break; 234 } 235 case TRACE_TYPE_NONE: 236 ipptr = trace_get_link(packet); 237 break; 238 case TRACE_TYPE_LINUX_SLL: 239 { 240 trace_sll_header_t *sll; 241 242 sll = trace_get_link(packet); 243 if (!sll) { 244 ipptr = NULL; 245 } else if (ntohs(sll->protocol)!=0x86DD) { 246 ipptr = NULL; 247 } 248 else { 249 ipptr = (void*)((char*)sll+ 250 sizeof(*sll)); 251 } 252 } 253 break; 254 case TRACE_TYPE_PFLOG: 255 { 256 struct trace_pflog_header_t *pflog; 257 pflog = trace_get_link(packet); 258 if (!pflog) { 259 ipptr = NULL; 260 break; 261 } 262 if (pflog->af != AF_INET) { 263 ipptr = NULL; 264 } else { 265 ipptr = (void*)((char*)pflog+ 266 sizeof(*pflog)); 267 } 268 } 269 break; 270 case TRACE_TYPE_LEGACY_POS: 271 { 272 /* 64 byte capture. */ 273 struct libtrace_pos *pos = 274 trace_get_link(packet); 275 if (ntohs(pos->ether_type) == 0x86DD) { 276 ipptr=(void*)((char *)pos+sizeof(*pos)); 277 } else { 278 ipptr=NULL; 279 } 280 break; 281 282 } 283 case TRACE_TYPE_LEGACY_ATM: 284 case TRACE_TYPE_ATM: 285 { 286 /* 64 byte capture. */ 287 struct libtrace_llcsnap *llc = 288 trace_get_link(packet); 289 290 /* advance the llc ptr +4 into the link layer. 291 * need to check what is in these 4 bytes. 292 * don't have time! 293 */ 294 llc = (void*)((char *)llc + 4); 295 if (ntohs(llc->type) == 0x86DD) { 296 ipptr=(void*)((char*)llc+sizeof(*llc)); 297 } else { 298 ipptr = NULL; 299 } 300 break; 301 } 302 default: 303 fprintf(stderr,"Don't understand link layer type %i in trace_get_ip()\n", 304 trace_get_link_type(packet)); 305 ipptr=NULL; 306 break; 307 } 308 309 return ipptr; 185 linktype); 186 return NULL; 187 } 188 } 189 190 libtrace_ip_t *trace_get_ip(libtrace_packet_t *packet) 191 { 192 uint16_t type; 193 void *ret=trace_get_payload_from_link( 194 trace_get_link(packet), 195 trace_get_link_type(packet), 196 &type, NULL); 197 198 if (!ret) 199 return NULL; 200 201 ret=trace_get_vlan_payload_from_ethernet_payload(ret,&type,NULL); 202 203 if (!ret || type!=0x0800) 204 return NULL; 205 206 return ret; 207 } 208 209 libtrace_ip6_t *trace_get_ip6(libtrace_packet_t *packet) 210 { 211 uint16_t type; 212 void *ret=trace_get_payload_from_link( 213 trace_get_link(packet), 214 trace_get_link_type(packet), 215 &type,NULL); 216 217 if (!ret) 218 return NULL; 219 220 ret=trace_get_vlan_payload_from_ethernet_payload(ret,&type,NULL); 221 222 if (!ret || type!=0x86DD) 223 return NULL; 224 225 return ret; 310 226 } 311 227 … … 313 229 314 230 void *trace_get_payload_from_ip(libtrace_ip_t *ipptr, uint8_t *prot, 315 int *skipped)231 uint32_t *remaining) 316 232 { 317 233 void *trans_ptr = 0; 318 234 319 if ((ipptr->ip_off & SW_IP_OFFMASK) == 0) { 320 if (skipped) *skipped=(ipptr->ip_hl * 4); 321 trans_ptr = (void *)((char *)ipptr + (ipptr->ip_hl * 4)); 322 if (prot) *prot = ipptr->ip_p; 323 } 235 if ((ipptr->ip_off & SW_IP_OFFMASK) != 0) 236 return NULL; 237 238 if (remaining) { 239 if (*remaining<(ipptr->ip_hl*4U)) { 240 return NULL; 241 } 242 *remaining-=(ipptr->ip_hl * 4); 243 } 244 245 trans_ptr = (void *)((char *)ipptr + (ipptr->ip_hl * 4)); 246 247 if (prot) *prot = ipptr->ip_p; 248 324 249 return trans_ptr; 325 250 } 326 251 327 252 void *trace_get_payload_from_ip6(libtrace_ip6_t *ipptr, uint8_t *prot, 328 int *skipped)253 uint32_t *remaining) 329 254 { 330 255 void *payload = (char*)ipptr+sizeof(libtrace_ip6_t); 331 256 uint8_t nxt = ipptr->nxt; 332 257 333 if (skipped) skipped+=sizeof(libtrace_ip6_t); 258 if (remaining) { 259 if (*remaining<sizeof(libtrace_ip6_t)) 260 return NULL; 261 *remaining-=sizeof(libtrace_ip6_t); 262 } 334 263 335 264 while(1) { … … 345 274 +sizeof(libtrace_ip6_ext_t); 346 275 347 if (skipped) 348 *skipped+=len; 276 if (remaining) { 277 if (*remaining < len) { 278 /* Snap too short */ 279 return NULL; 280 } 281 *remaining-=len; 282 } 349 283 350 284 payload=(char*)payload+len; … … 359 293 } 360 294 361 static void *trace_get_ip4_transport(const libtrace_packet_t *packet, 362 uint8_t *proto) 363 { 364 libtrace_ip_t *ipptr = 0; 365 366 if (!(ipptr = trace_get_ip(packet))) { 367 return 0; 368 } 369 370 return trace_get_payload_from_ip(ipptr,proto,NULL); 371 } 372 373 static void *trace_get_ip6_transport(const libtrace_packet_t *packet, 374 uint8_t *proto) 375 { 376 libtrace_ip6_t *ipptr = 0; 377 378 if (!(ipptr = trace_get_ip6(packet))) { 379 return 0; 380 } 381 382 return trace_get_payload_from_ip6(ipptr,proto,NULL); 383 } 384 385 void *trace_get_transport(const struct libtrace_packet_t *packet, 386 uint8_t *proto) 295 void *trace_get_transport(libtrace_packet_t *packet, 296 uint8_t *proto, 297 uint32_t *remaining 298 ) 387 299 { 388 300 void *transport; 389 301 uint8_t dummy; 302 uint16_t ethertype; 390 303 391 304 if (!proto) proto=&dummy; 392 305 393 transport=trace_get_ip4_transport(packet,proto); 394 if (transport) { 395 if (*proto == 41) { 396 trace_get_payload_from_ip6(transport,proto,NULL); 397 } 398 return transport; 399 } 400 401 return trace_get_ip6_transport(packet,proto); 402 } 403 404 libtrace_tcp_t *trace_get_tcp(const libtrace_packet_t *packet) { 306 if (remaining) 307 *remaining = trace_get_capture_length(packet); 308 309 transport = trace_get_payload_from_link( 310 trace_get_link(packet), 311 trace_get_link_type(packet), 312 ðertype, 313 remaining); 314 315 if (!transport) 316 return NULL; 317 318 transport = trace_get_vlan_payload_from_ethernet_payload(transport, 319 ðertype, 320 remaining); 321 322 if (!transport) 323 return NULL; 324 325 switch (*proto) { 326 case 0x0800: /* IPv4 */ 327 transport=trace_get_payload_from_ip(transport, proto, remaining); 328 /* IPv6 */ 329 if (transport && *proto == 41) { 330 transport=trace_get_payload_from_ip6(transport, 331 proto,remaining); 332 } 333 return transport; 334 case 0x86DD: /* IPv6 */ 335 return trace_get_payload_from_ip6(transport, proto, remaining); 336 337 default: 338 return NULL; 339 } 340 341 } 342 343 libtrace_tcp_t *trace_get_tcp(libtrace_packet_t *packet) { 405 344 uint8_t proto; 406 345 libtrace_tcp_t *tcp; 407 346 408 tcp=trace_get_transport(packet,&proto );347 tcp=trace_get_transport(packet,&proto,NULL); 409 348 410 349 if (proto != 6) … … 414 353 } 415 354 416 libtrace_tcp_t *trace_get_tcp_from_ip(libtrace_ip_t *ip, int *skipped)355 libtrace_tcp_t *trace_get_tcp_from_ip(libtrace_ip_t *ip, uint32_t *remaining) 417 356 { 418 357 struct libtrace_tcp *tcpptr = 0; … … 420 359 if (ip->ip_p == 6) { 421 360 tcpptr = (struct libtrace_tcp *) 422 trace_get_payload_from_ip(ip, NULL, skipped);361 trace_get_payload_from_ip(ip, NULL, remaining); 423 362 } 424 363 … … 430 369 libtrace_udp_t *udp; 431 370 432 udp=trace_get_transport(packet,&proto );371 udp=trace_get_transport(packet,&proto,NULL); 433 372 434 373 if (proto != 17) … … 438 377 } 439 378 440 libtrace_udp_t *trace_get_udp_from_ip(libtrace_ip_t *ip, int *skipped)379 libtrace_udp_t *trace_get_udp_from_ip(libtrace_ip_t *ip, uint32_t *remaining) 441 380 { 442 381 struct libtrace_udp *udpptr = 0; … … 444 383 if (ip->ip_p == 17) { 445 384 udpptr = (libtrace_udp_t *) 446 trace_get_payload_from_ip(ip, NULL, skipped);385 trace_get_payload_from_ip(ip, NULL, remaining); 447 386 } 448 387 … … 450 389 } 451 390 452 libtrace_icmp_t *trace_get_icmp( constlibtrace_packet_t *packet) {391 libtrace_icmp_t *trace_get_icmp(libtrace_packet_t *packet) { 453 392 uint8_t proto; 454 393 libtrace_icmp_t *icmp; 455 394 456 icmp=trace_get_transport(packet,&proto );395 icmp=trace_get_transport(packet,&proto,NULL); 457 396 458 397 if (proto != 1) … … 462 401 } 463 402 464 libtrace_icmp_t *trace_get_icmp_from_ip(libtrace_ip_t *ip, int *skipped)403 libtrace_icmp_t *trace_get_icmp_from_ip(libtrace_ip_t *ip, uint32_t *remaining) 465 404 { 466 405 libtrace_icmp_t *icmpptr = 0; 467 406 468 407 if (ip->ip_p == 1) { 469 icmpptr = (libtrace_icmp_t *)trace_get_payload_from_ip(ip, NULL, skipped); 408 icmpptr = (libtrace_icmp_t *)trace_get_payload_from_ip(ip, 409 NULL, remaining); 470 410 } 471 411 … … 473 413 } 474 414 475 void *trace_get_payload_from_udp(libtrace_udp_t *udp, int *skipped) 476 { 477 if (skipped) *skipped+=sizeof(libtrace_udp_t); 415 void *trace_get_payload_from_udp(libtrace_udp_t *udp, uint32_t *remaining) 416 { 417 if (remaining) { 418 if (*remaining < sizeof(libtrace_udp_t)) 419 return NULL; 420 *remaining-=sizeof(libtrace_udp_t); 421 } 478 422 return (void*)((char*)udp+sizeof(libtrace_udp_t)); 479 423 } 480 424 481 void *trace_get_payload_from_tcp(libtrace_tcp_t *tcp, int *skipped) 482 { 483 int dlen = tcp->doff*4; 484 if (skipped) *skipped=dlen; 425 void *trace_get_payload_from_tcp(libtrace_tcp_t *tcp, uint32_t *remaining) 426 { 427 unsigned int dlen = tcp->doff*4; 428 if (remaining) { 429 if (*remaining < dlen) 430 return NULL; 431 *remaining-=dlen; 432 } 485 433 return tcp+dlen; 486 434 } 487 435 488 void *trace_get_payload_from_icmp(libtrace_icmp_t *icmp, int *skipped) 489 { 490 if (skipped) *skipped = sizeof(libtrace_icmp_t); 436 void *trace_get_payload_from_icmp(libtrace_icmp_t *icmp, uint32_t *remaining) 437 { 438 if (remaining) { 439 if (*remaining < sizeof(libtrace_icmp_t)) 440 return NULL; 441 *remaining-=sizeof(libtrace_icmp_t); 442 } 491 443 return (char*)icmp+sizeof(libtrace_icmp_t); 492 444 } 493 445 446 struct ports_t { 447 uint16_t src; 448 uint16_t dst; 449 }; 450 451 /* Return the client port 452 */ 453 uint16_t trace_get_source_port(const libtrace_packet_t *packet) 454 { 455 struct ports_t *port = trace_get_transport((libtrace_packet_t*)packet, 456 NULL, NULL); 457 458 return ntohs(port->src); 459 } 460 461 /* Same as get_source_port except use the destination port */ 462 uint16_t trace_get_destination_port(const libtrace_packet_t *packet) 463 { 464 struct ports_t *port = trace_get_transport((libtrace_packet_t*)packet, 465 NULL, NULL); 466 467 return ntohs(port->dst); 468 } 469 470 471 uint8_t *trace_get_source_mac(libtrace_packet_t *packet) { 472 void *link = trace_get_link(packet); 473 libtrace_80211_t *wifi = link; 474 libtrace_ether_t *ethptr = link; 475 if (!link) 476 return NULL; 477 switch (trace_get_link_type(packet)) { 478 case TRACE_TYPE_80211: 479 return (uint8_t*)&wifi->mac2; 480 case TRACE_TYPE_ETH: 481 return (uint8_t*)ðptr->ether_shost; 482 default: 483 fprintf(stderr,"Not implemented\n"); 484 assert(0); 485 } 486 } 487 488 uint8_t *trace_get_destination_mac(libtrace_packet_t *packet) { 489 void *link = trace_get_link(packet); 490 libtrace_80211_t *wifi = link; 491 libtrace_ether_t *ethptr = link; 492 if (!link) 493 return NULL; 494 switch (trace_get_link_type(packet)) { 495 case TRACE_TYPE_80211: 496 return (uint8_t*)&wifi->mac1; 497 case TRACE_TYPE_ETH: 498 return (uint8_t*)ðptr->ether_dhost; 499 default: 500 fprintf(stderr,"Not implemented\n"); 501 assert(0); 502 } 503 } 504 505 struct sockaddr *trace_get_source_address(const libtrace_packet_t *packet, 506 struct sockaddr *addr) 507 { 508 uint16_t proto; 509 uint32_t remaining; 510 void *transport; 511 static struct sockaddr_storage dummy; 512 513 if (!addr) 514 addr=(struct sockaddr*)&dummy; 515 516 remaining = trace_get_capture_length(packet); 517 518 transport = trace_get_payload_from_link( 519 trace_get_link(packet), 520 trace_get_link_type(packet), 521 &proto, 522 &remaining); 523 524 if (!transport) 525 return false; 526 527 transport = trace_get_vlan_payload_from_ethernet_payload(transport, 528 &proto, 529 &remaining); 530 531 if (!transport) 532 return false; 533 534 switch (proto) { 535 case 0x0800: /* IPv4 */ 536 { 537 struct sockaddr_in *addr4=(struct sockaddr_in*)addr; 538 libtrace_ip_t *ip = transport; 539 addr4->sin_family=AF_INET; 540 addr4->sin_port=0; 541 addr4->sin_addr=ip->ip_src; 542 return addr; 543 } 544 case 0x86DD: /* IPv6 */ 545 { 546 struct sockaddr_in6 *addr6=(struct sockaddr_in6*)addr; 547 libtrace_ip6_t *ip6 = transport; 548 addr6->sin6_family=AF_INET6; 549 addr6->sin6_port=0; 550 addr6->sin6_flowinfo=0; 551 addr6->sin6_addr=ip6->ip_src; 552 return addr; 553 } 554 default: 555 return NULL; 556 } 557 } 558 559 struct sockaddr *trace_get_destination_address(const libtrace_packet_t *packet, 560 struct sockaddr *addr) 561 { 562 uint16_t proto; 563 uint32_t remaining; 564 void *transport; 565 static struct sockaddr_storage dummy; 566 567 if (!addr) 568 addr=(struct sockaddr*)&dummy; 569 570 remaining = trace_get_capture_length(packet); 571 572 transport = trace_get_payload_from_link( 573 trace_get_link(packet), 574 trace_get_link_type(packet), 575 &proto, 576 &remaining); 577 578 if (!transport) 579 return false; 580 581 transport = trace_get_vlan_payload_from_ethernet_payload(transport, 582 &proto, 583 &remaining); 584 585 if (!transport) 586 return false; 587 588 switch (proto) { 589 case 0x0800: /* IPv4 */ 590 { 591 struct sockaddr_in *addr4=(struct sockaddr_in*)addr; 592 libtrace_ip_t *ip = transport; 593 addr4->sin_family=AF_INET; 594 addr4->sin_port=0; 595 addr4->sin_addr=ip->ip_dst; 596 return addr; 597 } 598 case 0x86DD: /* IPv6 */ 599 { 600 struct sockaddr_in6 *addr6=(struct sockaddr_in6*)addr; 601 libtrace_ip6_t *ip6 = transport; 602 addr6->sin6_family=AF_INET6; 603 addr6->sin6_port=0; 604 addr6->sin6_flowinfo=0; 605 addr6->sin6_addr=ip6->ip_dst; 606 return addr; 607 } 608 default: 609 return NULL; 610 } 611 } 612
Note: See TracChangeset
for help on using the changeset viewer.