I'm programming an offline packets decoding program in C under Windows 7 x86.
I wonder how it is possible to know packet protocol, either if it is UDP or TCP?
You can know by checking the IP packet header, there is a Protocol field in the packet header that is used to indicate the type of the packet according to its value :
1 is ICMP
6 is TCP
17 is UDP
and so on. More information on this is available on Wikipedia
Edit: Here's the list of all the possible values for that field.
P.S:
I'm assuming IPv4 here, I don't know if things are the same with IPv6
The protocol is available in the IP header. Read more here
Related
I'm reading and trying to get an idea of C, and I tried to program a Java chat with UDP and TCP a couple of years back, and as much as I pulled it off... I could not do it.
I want to program sockets and I'm reading tons of documentation, but there is always a part that is unclear, every kicking documentation has a flaw.
For example, there is one about
int socket(int domain, int type, int protocol);
The domain I will use is clearly AF_INET, and if I want a TCP Socket I think type should be SOCK_STREAM, but what is protocol? Documentation says it should be 0... why??? what is it?
From the man page for socket:
The protocol specifies a particular protocol to be used with the socket. Normally only a single protocol exists to support a particular socket type within a given protocol family, in which case protocol can be specified as 0. However, it is possible that many protocols may exist, in which case a particular protocol must be specified in this manner. The protocol number to use is specific to the “communication domain” in which communication is to take place; see protocols(5). See getprotoent(3) on how to map protocol name strings to protocol numbers.
According to the man page for protocols:
This file is a plain ASCII file, describing the various DARPA internet protocols that are available from the TCP/IP subsystem. It should be consulted instead of using the numbers in the ARPA include files, or, even worse, just guessing them. These numbers will occur in the protocol field of any IP header.
Each line is of the following format:
protocol number aliases ...
...
/etc/protocols The protocols definition file.
And in the /etc/protocols file on my linux box:
ip 0 IP # internet protocol, pseudo protocol number
hopopt 0 HOPOPT # hop-by-hop options for ipv6
icmp 1 ICMP # internet control message protocol
igmp 2 IGMP # internet group management protocol
ggp 3 GGP # gateway-gateway protocol
ipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'')
st 5 ST # ST datagram mode
tcp 6 TCP # transmission control protocol
cbt 7 CBT # CBT, Tony Ballardie <A.Ballardie#cs.ucl.ac.uk>
egp 8 EGP # exterior gateway protocol
igp 9 IGP # any private interior gateway (Cisco: for IGRP)
bbn-rcc 10 BBN-RCC-MON # BBN RCC Monitoring
...
And according to the man page for getprotocol:
The getprotobyname() function returns a protoent structure for the entry from the database that matches the protocol name name. A connection is opened to the database if necessary.
...
The protoent structure is defined in as follows:
struct protoent {
char *p_name; /* official protocol name */
char **p_aliases; /* alias list */
int p_proto; /* protocol number */
}
So if you pass "ip" to getprotobyname() it would return 0 which is the number you are using anyway. But using 0 directly is always safe even if you don't know the name of the protocol.
The last protocol parameter of socket() can be used with raw packets. I will try to explain it practically.
If you are using raw sockets to get packets from TCP stack, you can control the amount of packet data you want to send/receive with this parameter.
socket (AF_INET, SOCK_RAW, IPPROTO_TCP);
Above call will give you a raw packet in which kernel will take care of the packet up to IP header. You will have to manually fill in the rest of the packet when sending it or when you will read the packet, kernel will provide the contents of TCP header as well with the data.
On the other hand:
socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
Using IPPROTO_RAW, you can control the packet from IP layer upwards. i.e. kernel will provide you services up to ethernet header, rest of the packet is in your control.
There may be different protocols to support a particular socket type, so that's why you also can specify the protocol in socket(2).
From the manpage (emphasis mine):
The protocol specifies a particular protocol to be used with the
socket. Normally only a single protocol exists to support a
particular socket type within a given protocol family, in which case
protocol can be specified as 0.
However, it is possible that many protocols may exist, in which case a particular protocol must be specified in this manner.
So it is not mandatory to specify the protocol as 0. Actually 0 means that the standard library will figure out the correct protocol for you. But you could specify it as explicitly and it is perfectly valid to do so.
On Linux, you can see the available protocols by doing:
$ cat /etc/protocols
# Internet (IP) protocols
#
# Updated from http://www.iana.org/assignments/protocol-numbers and other
# sources.
# New protocols will be added on request if they have been officially
# assigned by IANA and are not historical.
# If you need a huge list of used numbers please install the nmap package.
ip 0 IP # internet protocol, pseudo protocol number
hopopt 0 HOPOPT # IPv6 Hop-by-Hop Option [RFC1883]
icmp 1 ICMP # internet control message protocol
igmp 2 IGMP # Internet Group Management
ggp 3 GGP # gateway-gateway protocol
ipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'')
st 5 ST # ST datagram mode
I am sorry if the question is too naive, but I am confused. I want to send IPv6 jumbograms (to be able to multicast packets of size > 64 KB). I have been able to multicast normal IPv6 UDP packets successfully.
For sending jumbograms, from RFC 2675, I get that I have to make the following changes :
set payload length to 0
set next header to hop-by-hop
But, I don't get how to implement these in c socket programming (which function calls to make etc.). Do I have to create a custom header or are there functions like sendto available to send jumbograms?
You could use raw sockets if you are making your own headers. For more information, type man -s7 raw or look here. Note you will effectively need to implement your own IP stack that way.
However, my understanding is that linux itself supports IPv6 jumbograms natively so you don't need to bother. Try ifconfig lo mtu 100000 and do some tests over the loopback device to check.
I suspect the issue might be that your network adaptor and everything on the path (end to end) needs to support the jumbograms too.
I'm implementing TCP in Objective C and C.
When I send a Syn Packet to a server I do not get an answer.
A pcap file of the packet can be found here: Tcp-Syn.pcap
Is the packet malformed or am I missing some convention which leads to my packet being dropped?
Open your file in wireshark.
Go to Edit->Preferences->Protocols->TCP , enable "Validate the TCP checksum if possible"
You will find that the TCP checksum you've generated is wrong.
The MAC addresses in the ethernet headers are all 0 as well, which looks odd - where's this packet going to ?
When receiving a UDP packet, where I do not know neither content nor structure, how can I find out what the content is? Is that possible somehow? Wireshark tells me the data is:
12:03:01:00:00:00:00:00:1f:44:fe:a2:07:e2:4c:28:00:15:e1:e0:00:80:12:61
The question is just about the data itself, not header of lower layers.
Thanks in advance for your help.
Wireshark shows UDP header. There is 2 port numbers. Usually another port number is reserved for the used protocol (not always).
You may look from the port reservation table which is the used protocol.
And if you are lucky, you find the protocol specification from Web and you can open the content of the packet.
I am having this doubt in socket programming which I could not get cleared by reading the man pages.
In c the declaration of socket function is int socket(int domain, int type, int protocol);
The linux man page says that while type decides the stream that will be followed the protocol number is the one that decides the protocol being followed.
So my question is that suppose I give the type parameter as SOCK_STREAM which is reliable and add the protocol number for UDP would it give me a reliable UDP which is same as TCP but without flow control and congestion control.
Unfortunately I can't test this out as I have a single machine so there is no packet loss happening.
Could anyone clear this doubt? Thanks a lot...
UDP cannot be made reliable. Transmission of the packets is done on a "best effort" capacity, but any router/host along the chain is free to drop the packet in the garbage and NOT inform the sender that it has done so.
That's not to say you can't impose extra semantics on the sending and receiving ends to expect packets within a certain time frame and say "hey, we didn't get anything in the last X seconds". But that can't be done at the protocol level. UDP is a "dump it into the outbox and hope it gets there" protocol.
No. For an IPV4 or IPV6 protocol stack, SOCK_STREAM is going to get you TCP and the type SOCK_DGRAM is going to give you UDP. The protocol parameter is not used for either of the choices and the socket library is typically expecting a value of 0 to be specified there.
If you do this:
socket(AF_INET,SOCK_STREAM,IPPROTO_UDP):
socket() will return -1 and sett errno to
EPROTONOSUPPORT
The protocol type or the specified protocol
is not supported within this domain.