views:

86

answers:

3

The definition can be seen here.

The candidate answer may be tcp and dst port 80,but can tcp and dst port 80 guarantee it's HTTP traffic and includes all HTTP traffic?

It seems not,because some site can be visited by specifying a different port other than 80 this way:

http://domain.name:8080

So my question is: what's the exact BPF for HTTP?

UPDATE

Is there an implementation to verify whether a packet is a HTTP one in c already?

A: 

BPF is not a stateful packet filter and so any traffic that is on non-standard HTTP ports won't be detectable with BPF. BPF filters at the transport layer and not the application layer, so it just cares about TCP/IP, not the application data encapsulated within TCP/IP packets. Your best bet is to filter on common HTTP ports, 80, 8000, and 8080. Also 443 if you want to account for HTTPS as well.

Daniel DiPaolo
+1  A: 

There's no exact BPF for HTTP, because HTTP is not a link-layer protocol. The best way to do this is to choose any traffic that appears likely to be HTTP, and then verify that in your application. You will have to stitch together TCP segments to do so, as data in a particular TCP segment from the middle of a stream does not indicate the application-layer protocol.

WhirlWind
How do I verify whether it's HTTP packet ?
Gtker
You reassemble the TCP stream, and make sure the beginning corresponds to the HTTP protocol. Packets are IP, not HTTP, as HTTP is an application-layer protocol.
WhirlWind
A: 
  • Simplest filter: tcp and dst port 80
  • Many ports (including SSL): tcp and (dst port 80 or dst port 8080 or dst port 443)
  • If you want only HTTP GET packets for example, and don't mind that you will only get the first packet of every GET and you assume there are no TCP options in the GET packets, you can filter TCP and the fact that the TCP payload (HTTP) starts with "GET " without the quotes: tcp and tcp[20:4] = 0x47455420
  • If you think there can be TCP options (I'm pretty sure it's not that common for non SYN packets), you can do a more complex filter, which actually uses the TCP header and checks for the TCP header length (instead of assuming it's 20): tcp and tcp[(tcp[12] >> 4) * 4 : 4] = 0x47455420
  • A combination of all these filters would look like that (though SSL won't really work here since the GET is encrypted): tcp and (dst port 80 or dst port 8080 or dst port 443) and tcp[(tcp[12] >> 4) * 4 : 4] = 0x47455420
  • In a similar manner, you can filter any HTTP request method by filtering the bytes that this method starts with. If you want also the SYN and SYN-ACK packets, you add them by filtering the TCP flags using bitwise operations.
  • Unfortunately, filtering all HTTP traffic is pretty hard since a packet that isn't in the first in the request or response is pretty hard to filter - any TCP payload can be part of an HTTP request or response. If you want all HTTP traffic, you should probably rely on ports alone.
brickner