I build a http packet by using libnet build functions, and send it by libnet_write. I see the packet is sent successfully via wireshark, the tcp and ip header are all right. But client cannot parse my packet. For example, the client doesn't load the html when I send "HTTP/1.1 200 OK" packet; the client doesn't jump to the redirect site when I send "HTTP/1.1 302 Moved Temporarily" packet. etc..
You provide no code in your question, and no example of the packet you construct, but HTTP runs over TCP, and you mention writing only a single packet. This cannot work. Establishing a TCP connection requires writing a SYN packet, reading the SYN/ACK response, and writing a final ACK.
Only after this 3-packet exchange can a TCP packet with data be sent.
Also, its not at all clear why you are trying to do this. If you want data to be received by an HTTP server, you should construct and send it with the normal socket APIs.
Related
I am working on a school project, in which I have to analyze .pcap files in C language using the libcap library. I am new to networking, however I do know that TCP is on the layer 4 and HTTP is on the 7th layer in the OSI model. I want to sort HTTP packets, and print out the source/destination ports but I'm a little confused how to distinguish HTTP protocols from TCP protocols.
Here is an example, which I don't understand:
EDIT: Here is another example, where the source port is 80, the length is 100. The 54th byte is 48, which is the same as for a HTTP 1.1 response packet. It is a TCP.
https://i.stack.imgur.com/RQs6v.png
The destination port here is 80, which is HTTP. However wireshark does not list this packet as a HTTP protocol, it is just TCP.
https://i.stack.imgur.com/TsVuO.png
Me question is how to determine based on bytes if the packet is a HTTP protocol or just a TCP protocol?
You cannot determine if a packet is HTTP or not just by looking at its headers. HTTP is application level, if you want to identify an HTTP stream you will have to check the innermost payload of the packet. In other words, HTTP packets are distinguishable just by looking at what comes after the TCP header. Wireshark already does this for you and marks packets that look like HTTP as such. You can filter packets identified as HTTP by Wireshark by simply typing http in the filter bar at the top.
In your case, the packet you show has Length = 0, so there really isn't anything to analyze other than the various headers of the different layers. The packet is not HTTP.
Determining HTTP traffic "based on bytes" can be done by looking at the payload: HTTP requests and responses have known formats. For example HTTP 1.1 requests start with <METHOD> <URI> HTTP/1.1\r\n, and responses with HTTP/1.1 <CODE> <MSG>\r\n.
I have a problem with making HTTPS requests from the client to the server.
My server is using Winsock with OpenSSL on top of the sockets, while my client is using WinHttp library. All these are done in C.
Below is a description of what happened (or how I understood it to be) at the server and client during a network communication:
At the server side, the application is blocked at accept() while waiting for connection to be made from the client. On the first HTTP request made by client using WinHttpSendRequest(), the accept() unblocks and creates a new thread. Then, accept() went into blocking state again until a new client connects to it.
In the thread at the server side, recv() receives the packet sent over by the client, then it sends over a response packet via send().
Upon receiving the response packet from server, WinHttpSendRequest() at the client side unblocks, before moving on to execute WinHttpReceiveResponse() and the rest of the code to read in the content of the response packet.
Meanwhile, recv() at the server side blocks until client sends over another request via WinHttpSendRequest(), and this goes on to and fro until the server sends a command to terminate the client.
This mechanism of using Winsock at the server side and WinHttp at the client side works for sending multiple HTTP requests from client to server over the same connection.
However, when I decided to add in a layer of encryption for this network communication, ie. client sends HTTPS instead of HTTP requests over, and server uses openSSL functions to receive and send packets (SSL_read() in replacement of recv() and SSL_write in replacement of send()), each time the client makes a WinHttpSendRequest(), accept() at the server side will unblock and return a new socket. In the previous scenario where encryption was not done and requests were HTTP, accept() at the server side will only unblock when it is the first request made by a new client; subsequent requests by the same client will be received through the blocking and unblocking of recv().
Just some things to note: For my client side, I have kept the handles for WinHttpOpen and WinHttpConnect open, while those of WinHttpOpenRequest and WinHttpSendRequest will be closed after each request and recreated for each new request. Also, packets received for both sides can be read properly after encryption (I know encryption was done as packets sniffed by Wireshark is unreadable).
I have been searching all over the internet to see if anyone has experienced the same thing, but to no avail :( Is there anyone who can explain to me why this is happening?
For servers written in tcp raw socket like nginx, how do servers correctly detect and handle non HTTP messages among HTTP messages(skip those bytes and move to the next valid http messages)?
It doesn't. If the first request on the connection doesn't start with a valid HTTP request line, it closes the connection. No other detection, no skipping, no moving to the next message.
A search for 'raw' at nginx.org returned no results.
Is it possible to receive any empty payload with recvfrom() with SOCK_DGRAM based socket? The server is only interested in the client header to send it back a message (i.e. single message, send only protocol).
0-sized datagrams are perfectly valid from socket API perspective and at least protocols IP, UDP, UNIX: one can send and receive them.
I have a project in C , in which I receive HTTP GET Requests (port 10000), process it and send appropriate response. I use winsock Libraries for network connections. Also I have a module which receives HTTPS request on a different port (port 10001). The client specifies which port it has to send to , if it is sending a http message it will send on port 10000 and if it is a https request it will send to port 10001.
Due to this I realize, that the coming request is a HTTP or HTTPS request.
There is a requirement, that the client will specify only one port number whether it is HTTP or HTTPS, i.e. it will send only on port 10000.
So now, when an HTTPS message comes on port 10000, it will be all encrypted but I want that message to go to port 10001. Is there any way to differentiate a HTTP or HTTPS request at the server level ?
If the first byte coming from client is 0x16, it's the beginning of SSL handshake. As it's not a possible start of HTTP request, you can differentiate requests by this property.