We have read so many things about invoking System Calls on Linux. Theories are useless unless we implement them :) (at least I believe). Thus Let's play with sockets by calling System/Kernel services directly. i.e. we will not use methods provided by C runtime libs. We will implement methods of POSIX Socket API like socket, bind etc.
Linux provides single system call called "sys_socketcall" for socket related operations. Its System call number is 102 (defined as macro __NR_socketcall in /usr/include/asm/unistd.h). Its protype defined in kernel is as follows:
long sys_socketcall(int call, unsigned long *args)
The fist parameter 'call' is an integer that identifies the specific operation to be performed. The possible values for call are defined in /usr/include/linux/net.h. Some of them are listem below:
#define SYS_SOCKET 1 /* sys_socket(2) */
#define SYS_BIND 2 /* sys_bind(2) */
#define SYS_CONNECT 3 /* sys_connect(2) */
#define SYS_LISTEN 4 /* sys_listen(2) */
#define SYS_ACCEPT 5 /* sys_accept(2) */
The second parameter 'args' is a pointer to an array of 'long' containing arguments for the operation.
Let's implement POSIX socket creation method "int socket(int domain, int type, int protocol)":
int my_socket(int domain, int type, int protocol)
{
long arg[3], sock = 0;
/*
Copy 'domain', 'type' and 'protocol' in 'arg' array. This array will be passed to system call as parameter to kernel.
*/
arg[0] = domain;
arg[1] = type;
arg[2] = protocol;
/*
long sys_socketcall(int call, unsigned long *args) ;
To call above system call, we would need to copy "__NR_socketcall" System call no. into eax register, "SYS_SOCKET" socket operation 'call' code into ebx, and an array of 'long' containing 'domain', 'type', 'protocol' into ecx register.
The following code does the same thing. For more informaiton, find on google 'assembly using gcc' :).
*/
asm(
"int $0x80\n\t" /* int 0x80 invokes Linux system call */
:"=a"(sock) /* system call returns output in eax register, copy eax
registers value into sock */
:"a"(__NR_socketcall), "b"(SYS_SOCKET), "c"(arg)
/*
Above line passes "__NR_socketcall" System call no into eax register,
"SYS_SOCKET" socket operation 'call' code into ebx,
and an array of 'long' containing 'domain', 'type', 'protocol' into ecx register.
*/
); /* asm statement ends here*/
return sock; /* return socket FD*/
}
For the sake of simplicity, I haven't perfomed sanity check. While writing your own implementation, please do perform sanity check before invoking System call.
Similarly, you can define all the socket methods like bind, listen,accept, send etc and can make your own Socket library. Is not it simple? May be I have picked the simple one ;) to System Call simple.
Please leave your comments!!!
Please leave your comments!!!
lmao nice bot
ReplyDelete