/*
     Sexy-SOCKET v0.1 
     ~~~~~~~~~~~~~~~~
     This LKM will provide AF_INET sockets only to root account. 
     It is created for w4rcr0 wargame (http://www.ii-labs.org/wargame/).
     Sexy-SOCKET will work on 2.2.x and 2.4.x kernels.
     			Coded by DownBload <downbload@hotmail.com> \ 
			         Illegal Instruction Labs <www.ii-labs.org>
*/

#define MODULE
#define __KERNEL__
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/errno.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <asm/unistd.h>
#include <asm/uaccess.h>

extern void *sys_call_table[];

int (*origsock)(int call, unsigned long *args);

// STOLEN KERNEL SOURCE
#define AL(x) ((x) * sizeof(unsigned long))
static unsigned char nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
                                AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
		                AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
// END OF KERNEL SOURCE

int *hacksock(int call, unsigned long *args)
{
  // STOLEN KERNEL SOURCE
  unsigned long a[6];
  unsigned long a0,a1;
  int err;

  if(call<1||call>SYS_RECVMSG)
    return -EINVAL;
   
  /* copy_from_user should be SMP safe. */
  if (copy_from_user(a, args, nargs[call]))
   return -EFAULT;
  a0=a[0];
  a1=a[1];
  // END OF KERNEL SOURCE											
  if ((current->uid != 0) && (call == SYS_SOCKET) && (a0 == AF_INET))
     return -1;
  else
     return origsock (call,args);
}

 
int init_module (void)
{
  origsock = sys_call_table[__NR_socketcall];
  sys_call_table[__NR_socketcall] = hacksock;
  return 0;
}


void cleanup_module(void)
{
  sys_call_table[__NR_socketcall] = origsock;
}

