How to create a TCP-IP named socket file in Unix? - file

I found out that, under 'everything is a file' philosophy in Unix, even sockets are considered as files, and can be stored in a path in file system. So, I was trying to create a TCP-IP socket file out of curiosity.
This answer shows how to create a named Unix domain socket file. But struct sockaddr_in doesn't have sin_path field. So I have no idea how to create a named TCP-IP socket file. Can anyone tell me how to do this?

... even sockets are considered as files, and can be stored in a path in file system.
Not really. There are some sockets where the endpoint is represented by a file. These are UNIX domain sockets (AF_UNIX) and their is a variant which has a message semantic (SOCK_DGRAM) similar to UDP and one which has a stream semantic (SOCK_STREAM) similar to TCP.
But, UDP and TCP sockets have a no file representation in UNIX. They have a file descriptor though similar to normal files (and read and write system calls work with these), but they are not represented by a path in the file system.
There is also something like /dev/tcp/.. to deal with sockets inside the bash shell. But this is not an actual path on the file system either, but only a fancy syntax specific to the bash shell.
For more on this see also Wikipedia: Everything is a file which specifically notes:
... Therefore, a more accurate description of this feature is Everything is a file descriptor.

Related

Implementing FTP Server/Client in C

I am asked for an assignment that requires implementation of FTP protocol. I have gone through the documentation given at RFC959.
I am confused with a couple of implementation details
1)If a file needs to be transferred, what function can be used. can a simple send() function be used for a non text file.
2) Is it possible to get a good tutorial that speaks about implementing Modes and file structures, and to specify, which are essential.
hope to get a reply soon.
FTP transfers file through a plain TCP connection, and you can transfer any kind of file with it. There is no difference between text files and binary files, they are all just sequence of bytes.
For the file transmission is sufficient to open a connection and call the write function many times until the entire file is transmitted (check the return value of write to know how many bytes it sent).
The rest of the FTP protocol is text based and is sent to a different port.
There is a good tutorial on using FTP directly through netcat, that can be useful to understand how things work. Understanding active and passive mode can also be useful, since you are going to implement at least one of them.
Also, use wireshark to follow a TCP stream and see the data you are sending/receiving, it can be very useful in debugging.
The protocol implementation won't give you a file structure. The protocol is here to define some rules and states.
The dev/prog part is up to you. You just need to respect the FTP protocol in order to gain the normalization and the compatibility with other client/server.
Best regards

get an ioctl file descriptor for ethernet port

I need to get the file descriptor to use in ioctl() calls for an ethernet port in Linux. Not sure how to do this.
Just use the file descriptor of an open socket, using the name of the device in the ifreq structure passed to ioctl(), assuming your program has adequate permissions to do so.
From the docs:
Linux supports some standard ioctls to
configure network devices. They can
be used on any socket's file
descriptor regardless of the family or
type. They pass an ifreq structure:
The socket need not be bound to the target device, or be of any specific family. Any open socket fd will do (again, with appropriate privileges), just open one for your specific task, wait for ioctl() to return and close it.
See man 7 netdevice for more, or here if you don't have the appropriate documentation packages installed (hint, the package is usually named manpages-dev or manpages-devel, depending on your distro)
You can also take a look at the source to the net-tools package, which may be named differently depending on your distro. That's the source to ifconfig (Debian / Ubuntu here).
Sorry for the original ambiguity, I thought you were trying to configure a special multi function device (not sure why now, perhaps lack of sleep).
You can do something like this fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)
Use strace to see what functions ifconfig calls.

IPC vs domain sock vs named pipes

Whats the different between IPC and Unix domain sockets and named pipes?
I got vague definitions from various books but couldn't get clarity on which one should be used where.
Just about any way two processes communicate with each other could be considered a form of IPC.
For example:
Unnamed Pipes ( cat file.txt | grep foo ) or Named Pipes
Unix Domain Sockets
TCP or UDP sockets
Netlink Sockets on Linux
Various Shared Memory Mechanisms such as Memory Mapped Files
High Speed Message Passing such as ZeroMQ
As qrdl stated, UNIX-domain sockets and named pipes are both IPC mechanisms.
Of these two, named pipes are simpler to work with, but much less flexible than UNIX-domain sockets. For example, if you potentially expect more than one reading process for each writing process, then UNIX-domain sockets are a must; if you expect the reading process to stop and start during the execution of the writing process, then you'll need UNIX-domain sockets.
IPC stands for Inter-Process Communications. UNIX domain sockets and named pipes are just two IPC mechanisms, described in Wikipedia:
Unix domain sockets
Named pipes
Thanks for focusing to the question, few updated features:
In Domain sockets, actual communication (the data exchange) does not use the file system, but buffers in kernel memory. By default, it is full-duplex mode.
Named pipes are identified by their access point, a file kept on the file system for handling the data. A named pipe by default supports blocked read and write operations. However, it is possible to make named pipes support non-blocking operations by specifying the O_NONBLOCK flag while opening them. A named pipe must be opened either read-only or write-only. It must not be opened for read-write because it is half-duplex,a one-way channel.

N:1 file descriptors?

Is it possible to have N file descriptors be seen to a program as 1 file descriptor such that data received on any of the N file descriptors (ie from N sockets) will be forwarded back to the calling API on the single file descriptor, hiding the fact that it may actually be coming from a different file descriptor? Is it also possible to have writes similarly be abstracted (but going back to the correct Nth file descriptor)?
Since you tag and use the word socket, I presume that your data is coming over a network path and you actually want to read multiple sources over the same socket.
If you are working with TCP/IP sockets, you already have that scheme with UDP sockets listening on a local port to which multiple sources can send data.
You cannot have such a TCP socket, however the select API is available on all standard implementations to let you open multiple TCP listening sockets, one per source, and then do a select on the whole lot. You will not be able to 'hide' the source here.
If abstraction is what you are after, a better idea would be to write a small application that will manage this multiple communication end-points and talk with your primary application over IPC. You can implement a short-header to address end-points to this small application. Your primary application will then see everything over one communication point.
It will also solve your problem of abstracting the writes nicely.

using unix domain socket and sharing fd's

Not been able to figure out why recvmsg() blocks when i try this test app on ubuntu.
http://web.mit.edu/kolya/misc/break-chroot.c
thanks
I strongly remember file descriptor passing only working over Unix Datagram sockets, not Unix stream sockets. This may also necessitate resends. Your example is too large (and I'm too lazy) to do a proper analysis, but look here for alternative example code. I've used that example myself on both FreeBSD and Linux, it works.

Resources