c TCP rawsocket options - c

how to include TCP options
MSS(maximum segment size),
WS(window scale),
sack-permitted.
options in c raw socket
we can include other options in TCP like source,destination,syn,ack
tcp->src,
tcp->dst,
tcp->syn,
tcp->ack.
.........
but when i include tcp reserverd special options mss,ws
tcp->mss,tcp->ws.
it shows an error that MSS,WS are not in the tcp header
can anyone show me how to include those options in tcp raw socket
thank you

TCP WS in Linux
Assuming Linux, I believe you cannot directly change the TCP window size in C. This is because this is handled directly by the kernel.
One way to modify the TCP WS is to employ a mix of the following sysctl variables (read more about them in man tcp):
tcp_wmem
tcp_rmem
tcp_window_scaling
According to RFC 1323 (https://www.ietf.org/rfc/rfc1323.txt), TCP window scaling allows a maximum WS of 65K. The default maximum TCP WS in the Linux kernel is 32K. According to man tcp, you would increase the size of your socket buffer, at which point TCP Window Scaling will be used.
TCP MSS in Linux
Once again, I believe this is only possible at the kernel level. You can override the default calculations for MSS (which are dynamically calculated based on hop distance) using the iptables kernel module. Specifically, using the --set-mss option.
See: http://lartc.org/howto/lartc.cookbook.mtu-mss.html
If I am wrong, please correct me.

Related

Accessing TCP header fields (without raw socket API)

I am writing an application that needs to get access to TCP header fields, for example, a sequence number or a TCP timestamp field.
Is it possible to get sequence numbers (or other header fields) by operating at the socket API without listening on a raw socket? (I want to avoid filtering out all the packets).
I am looking at the TCP_INFO but it has a limited information.
For example, after calling a recvmsg() and getting a data buffer, is it possible to know the sequence number of the segment that delivered the last byte in that received data buffer?
Thanks
You can try to use libpcap to capture packets. This lib allows to specify packet filter using the same syntax as in Wireshark, so you could limit captured packets to one connection only. One downside is that you would have to receive packets in normal way too, what complicated things a bit and is an additional performance overhead.
Update: you can also open raw socket and set Berkeley Packet Filter on it using socket option SO_ATTACH_FILTER. More details are here: https://www.kernel.org/doc/Documentation/networking/filter.txt . However you would have to implement TCP part of IP stack in your code too.

Set TCP Options on an unprivileged socket (not raw) in a Linux C program

Which TCP Options can I set for outgoing TCP packets on unprivileged socket (not raw) in a Linux C program? I refer to TCP Options in TCP Header.
I've checked http://linux.die.net/man/7/tcp so for now I can add/edit:
MSS, Timestamp, Window Scale, Sack, Fast Open (see answer below)
Is there a way to add other options? I'm especially interested in Multipath but any option will be helpful.
Thank you!
TCP Fast Open can be used with the MSG_FASTOPEN flag e.g.:
sendto(fd, data, len, MSG_FASTOPEN, ...
Note that it must be supported by the server side - on Linux this can be done with:
echo 2 > /proc/sys/net/ipv4/tcp_fastopen
There's a handy reference here

send ipv6 jumbograms in c (linux) : How to change packet headers

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.

Few queries regarding raw sockets in C

I want to make a chat room using raw socket in C. I have following problems:
Q 1 : Can I use select function to handle multiple connections in case of raw sockets ?
Q 2 : Port nos in sockets are real ports or logically implemented for various applications on transport layer??
Q 3 : I am having one computer only so using lo ( local loop) as my interface. So the process which is initiating the chat has send first and then receive call, so it's receiving it's own data. How to restrict it?
Any help would be appreciated since that would help me in increasing my confidence on raw sockets.
Thanks :)
If you want this to be a real, usable chat system, stop. Don't use raw sockets. Huge mistake.
If you are just playing around because you want to put “raw sockets” under the “Experience” section of your résumé, you may read on.
You can use the select function to detect when a raw socket has a packet available to receive, and when it can accept a packet to transmit. You can pass multiple file descriptors to a single call to select if you want to check multiple raw sockets (or whatever) simultaneously.
Port numbers are part of the TCP and UDP protocols (and some other transport layer protocols). The kernel doesn't look for port numbers when receiving packets for raw sockets.
The raw(7) man page‚ states:
All packets or errors matching the protocol number specified for the raw socket are passed to this socket.
And it also states:
A raw socket can be bound to a specific local address using the bind(2) call. If it isn't bound, all packets with the specified IP protocol are received.
Therefore you probably want to at least use different IP addresses for each end of the “connection”, and bind each end to its address.
“But!” you say, “I'm using loopback! I can only use the 127.0.0.1 address!” Not so, my friend. The entire 127.0.0.0/8 address block is reserved for loopback addresses; 127.0.0.1 is merely the most commonly-used loopback address. Linux (but perhaps not other systems) responds to every address in the loopback block. Try this in one window:
nc -v -l 10150
And then in another window:
nc -s 127.0.0.1 127.0.0.2 10150
You will see that you have created a TCP connection from 127.0.0.1 to 127.0.0.2. I think you can also bind your raw sockets to separate addresses. Then, when you receive a packet, you can check whether it's from the other end's IP address to decide whether to process or discard it.
Just curious, why do you want to use raw sockets? Raw sockets (AF_INET, SOCK_RAW) allow you to send out "raw" packets, where you are responsible for crafting everything but the MAC and IP layers.
A1: There are no "connections" with raw sockets. Just packets.
A2: There are no "ports" with raw sockets. Just packets. "Port numbers" as we know them are part of the TCP or UDP protocols, both of which are above the level at which we work with raw sockets.
A3: This is not specific to raw sockets - you would have this issue regardless of your protocol selection. To really answer this, we would need to know much more about your proposed protocol, since right now, you're simply blasting out raw IP packets.

TCP segment without options and data

I want to implement a simplified TCP/IP stack. Now I am writting my tcp_connect function.
In the handshake step, can I send the TCP segment without TCP options and data(Only send the TCP header in the client side)?
I don't think any options are required. However, it you don't send the Maximum Segment Size option, the default MSS that's assumed is only 576.
TCP handshaking segments don't usually include any data. However, it's legal to include it, so your stack should accept it if it receives it.
There is only three (simple for implementation) options described in RFC793:
Kind Length Meaning
---- ------ -------
0 - End of option list.
1 - No-Operation.
2 4 Maximum Segment Size.
You can try to append only "End of option list" to TCP header, or use predefined template.
As a client, you may not add data in outgoing handshake-segments, but you should be able to process incoming ones when you accept connection.
I tried as you saied, but cannot get response.
Did you try to use something like TCPdump on other side? Any incoming segments?

Resources