Advertisement
mateorod

reboot.c

Apr 28th, 2014
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.56 KB | None | 0 0
  1. /*The goal here is to write a kernel module that reboots the machine whenever a TCP connection is opened on port 1600 -- it is a network "kill switch" if you will. I have included all the libraries that should be necessary to execute the program. For references, you should use the guide to network programming to give you a sense for how to write the network code (create socket, bind, listen, accept, what these functions do and how generally they are used), but all the functions we normally use are user mode functions. Here you will need to use kernel mode functions. I've provided a link to a (very much more complex) TCP server kernel module. (https://gist.github.com/llj098/752417). Look at it, see how the kernel version of these functions are being used, and figure out how to implement the reboot module. The program on the website given is much more complicated than we need, includes kernel threads, a waiting queue, recieving/sending messages, etc. You should try to understand it well enough to see how it does what it does and take the commands and functions you need to implement your task and use them -- you don't need to understand the whole thing by any means. A remark: in the TCP server, when they call accept(), they pass it the 'O_NONBLOCK' parameter, which is a value defined that tells accept not to block (wait until it accepts a connection). But this is the opposite of what we want -- you will want to execute the reboot code only after you've accepted a connection (you don't have to do anything with the connection). So replace 'O_NONBLOCK' with the value '0' instead -- this will tell accept to block and wait until an incoming connection is recieved. Attached also is a makefile which will allow you to build the module. Put the make file in the same directory as this .c file, and call 'make' -- it will use the makefile to link in the libraries you need to build a kernel module. If you change the name of this file, you will need to change the name referenced in the makefile.
  2. It should go like this when you are finished:
  3. run 'make'
  4. run 'sudo insmod systems-extracredit-1-reboot.ko'
  5. the terminal window should block as accept() is waiting for a connection.
  6. If you open another terminal window and type 'telnet 127.0.0.1 1600' (open a tcp connection to localhost (127.0.0.1) on port 1600), the machine should reboot.
  7. */
  8. #include <linux/init.h>
  9. #include <linux/module.h>
  10. #include <linux/kernel.h>
  11. #include <net/sock.h>
  12. /*I've included all the libraries you will need to solve the problem -- the example given includes many, many more, but I've pared it down to exactly what's necessary. You are free to include more if you like*/
  13.  
  14. int main()
  15. {
  16.     struct socket *socket;
  17.     struct socket *cscok;
  18.  
  19.     struct sockaddr_in sin;
  20.    
  21.     cscok=(struct socket*)kmalloc(sizeof(struct socket),GFP_KERNEL);
  22.  
  23.     sin.sin_addr.s_addr=htonl("127.0.0.1");
  24.     sin.sin_family=AF_INET;
  25.     sin.sin_port=htons(1600);
  26.  
  27.  
  28.     int error, ret;
  29.  
  30.         error = sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&socket);
  31.  
  32.         if(error<0) {
  33.             printk(KERN_ERR "CREATE SOCKET ERROR");
  34.             return -1;
  35.         }
  36.        
  37.         error = socket->ops->bind(socket,(struct sockaddr*)&sin,sizeof(sin));
  38.         if(error<0) {
  39.             printk(KERN_ERR "BIND ADDRESS");
  40.             return -1;
  41.         }
  42.        
  43.         error = socket->ops->listen(socket,0);
  44.         if(error<0) {
  45.             printk(KERN_ERR "LISTEN ERROR");
  46.             return -1;
  47.         }
  48.        
  49.         ret = socket->ops->accept(socket,cscok,0);
  50.         if(ret<0){
  51.             printk("accept error,release the socket\n");
  52.             sock_release(cscok);
  53.             return ret;
  54.         } else {
  55.             //simple_init()
  56.         }
  57.        
  58.     return 0;
  59. }
  60.  
  61. int simple_init(void)
  62. /*This function executes when the module is loaded*/
  63. {
  64.     /*This code reboots the machine. It executes the 'reboot' command with a user mode helper function, and it of course executes as root -- this process will be a child of the kernel and inherit all its permissions*/
  65.        static char * shutdown_argv = {"/sbin/reboot"};
  66.     char *argv[] = {shutdown_argv,NULL};
  67.     call_usermodehelper(shutdown_argv,argv,NULL,1);
  68. /*Those 3 lines will reboot the machine -- so so far, the kernel module will reboot the machine instantly when it is loaded. You need to write networking code so that the module loads, and the machine only reboots when it recieves a message on port 1600.*/
  69.  
  70.     return 0;
  71. }
  72. /* This function is called when the module is removed. */
  73. void simple_exit(void) {
  74.     printk(KERN_INFO "Removing Module\n");
  75. }
  76.  
  77. /* Macros for registering module entry and exit points. */
  78. module_init( main );
  79. module_exit( simple_exit );
  80.  
  81. MODULE_LICENSE("GPL");
  82. MODULE_DESCRIPTION("Simple Module");
  83. MODULE_AUTHOR("SGG");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement