Advertisement
saleks28

bos3_module

Jan 13th, 2020
390
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.78 KB | None | 0 0
  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/kernel.h>
  4. #include <linux/pci.h>
  5. #include <linux/ioctl.h>
  6. #include <linux/version.h>
  7. #include <asm/uaccess.h>
  8. #include <linux/string.h>
  9. #include <linux/fs.h>
  10. #include <asm/segment.h>
  11. #include <linux/buffer_head.h>
  12.  
  13. #include "caller.h"
  14.  
  15. MODULE_LICENSE("GPL");
  16. MODULE_AUTHOR("Sorokin AA");
  17. MODULE_DESCRIPTION("ioctl module");
  18. MODULE_VERSION("0.01");
  19.  
  20. static char logBuffer[1024] = "\0";
  21. // dev_open function
  22. static int dev_open(struct inode* n, struct file* f)
  23. {
  24.      return 0;
  25. }
  26.  
  27. // dev_release function
  28. static int dev_release(struct inode* n, struct file* f)
  29. {
  30.      return 0;
  31. }
  32.  
  33. static ssize_t dev_read( struct file * file, char * buf, size_t count, loff_t *ppos )
  34. {
  35.      int len = strlen(logBuffer);
  36.      if( count < len ) return -EINVAL;
  37.      if( *ppos != 0 ) {
  38.           printk( KERN_INFO "=== read return : 0\n" );  // EOF
  39.           return 0;
  40.      }
  41.  
  42.      if(copy_to_user(buf, logBuffer, len))
  43.      {
  44.         return -EINVAL;
  45.      }
  46.      *ppos = len;
  47.      return len;
  48. }
  49.  
  50. // find pci
  51. static void findPCI(int operType, argVenDev venDev, int devFN)
  52. {
  53.      if (operType == FIND_FUNCTION_NUMBER)
  54.      {
  55.           struct pci_dev *dev = NULL;
  56.           dev = pci_get_device(venDev.vendor, venDev.device, dev);
  57.           if(dev == NULL)
  58.           {
  59.                strcat(logBuffer, "Can't find a device with such vendor and device\n");
  60.                strcat(logBuffer, "\n");
  61.           }
  62.           else {
  63.                strcat(logBuffer, "Found a device with such vendor and device\n");
  64.                sprintf(logBuffer + strlen(logBuffer), "Device function number: %d", dev->devfn);
  65.                strcat(logBuffer, "\n");
  66.           }
  67.      }
  68.      else if (operType == FIND_VENDOR_DEVICE)
  69.      {
  70.           struct pci_dev *dev = NULL;
  71.           bool found = false;
  72.           do {
  73.                dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
  74.                if(dev == NULL)
  75.                     break;
  76.                if(dev->devfn == devFN)
  77.                {
  78.                     strcat(logBuffer, "Found a device with function number\n");
  79.                     sprintf(logBuffer + strlen(logBuffer), "Vendor: %d\n", dev->vendor);
  80.                     sprintf(logBuffer + strlen(logBuffer), "Device: %d", dev->device);
  81.                     strcat(logBuffer, "\n");
  82.                     found = true;
  83.                }
  84.           } while (dev != NULL);
  85.           if(!found)
  86.           {
  87.                strcat(logBuffer, "Can't find a device with such function number\n");
  88.           }
  89.      }
  90. }
  91.  
  92. static void writeLog(void)
  93. {
  94.      struct file *log = NULL;
  95.      static char filePath[] = "/home/sorokinaa/Documents/bos3/ioctl_log";
  96.  
  97.      log = filp_open(filePath, O_WRONLY | O_APPEND, 0);
  98.      if (log == NULL)
  99.      {
  100.           pr_info("filp open error\n");
  101.           return;
  102.      }
  103.      kernel_write(log, logBuffer, strlen(logBuffer), &log->f_pos);
  104.      filp_close(log, NULL);
  105.      memset(logBuffer, 0, 1024);
  106. }
  107.  
  108. // dev_ioctl
  109. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
  110. static int dev_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
  111. #else
  112. static long dev_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
  113. #endif
  114. {
  115.      if(_IOC_TYPE(cmd) != IOCTL_MAGIC) return -ENOTTY;
  116.      void __user *arg_user = (void __user*)arg;
  117.      argVenDev venDev;
  118.      int devFN;
  119.      strcat(logBuffer, "\n");
  120.      strcat(logBuffer, "IOCTL is called\n");
  121.      switch( cmd )
  122.      {
  123.      case IOCTL_GET_PSI_DEVFN:
  124.      {
  125.           strcat(logBuffer, "DEVFN is called\n");
  126.           copy_from_user(&venDev, arg_user, sizeof(venDev));
  127.           // pr_info("Vendor sent: %u", venDev.vendor);
  128.           // pr_info("Device sent: %u\n", venDev.device);
  129.           // pr_info("\n");
  130.           findPCI(FIND_FUNCTION_NUMBER, venDev, devFN);
  131.           strcat(logBuffer, "\n");
  132.           break;
  133.      }
  134.      case IOCTL_GET_PSI_VENDEV:
  135.      {
  136.           strcat(logBuffer, "VENDEV is called\n");
  137.           copy_from_user(&devFN, arg_user, sizeof(devFN));
  138.           // pr_info("Function sent: %d\n", devFN);
  139.           // pr_info("\n");
  140.           findPCI(FIND_VENDOR_DEVICE, venDev, devFN);
  141.           strcat(logBuffer, "\n");
  142.           break;
  143.      }
  144.      }
  145.      writeLog();
  146.      return 0;
  147. }
  148.  
  149. struct file_operations ioctlOps = {
  150.     .read = dev_read,
  151. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
  152.      .ioctl = dev_ioctl,
  153. #else
  154.      .unlocked_ioctl = dev_ioctl,
  155. #endif
  156.     .open = dev_open,
  157.     .release = dev_release,
  158. };
  159.  
  160. static void printDevices(void)
  161. {
  162.      struct pci_dev *dev = NULL;
  163.      do {
  164.           dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
  165.           if(dev == NULL)
  166.                break;
  167.           pr_info("Device function number: %lu", dev->devfn);
  168.           pr_info("Vendor id: %u", dev->vendor);
  169.           pr_info("Device id: %u", dev->device);
  170.           pr_info("\n");
  171.      }while (dev != NULL);
  172. }
  173.  
  174. // Init function  
  175. static int __init initModule(void)
  176. {
  177.      // pr_info = define printk with KERN_INFO priority
  178.      pr_info("Called init function\n");
  179.      
  180.      // List all PSI device numbers to see numbers with dmesg
  181.      printDevices();
  182.  
  183.      // Registering device to access it by /dev/ioctl_module
  184.      int ret;
  185.      if ( (ret = register_chrdev(200, "ioctl_module", &ioctlOps) < 0) )
  186.      {
  187.           pr_info("Can't register current device\n" );
  188.           return 1;  
  189.      }
  190.      else
  191.      {
  192.           pr_info("Successfully registered device\n");
  193.           pr_info("\n");
  194.      }
  195.      return 0;
  196. }
  197.  
  198. // Exit function
  199. static void __exit exitModule(void)
  200. {
  201.      unregister_chrdev(200, "ioctl_module");
  202.      pr_info( "Called exit function\n" );
  203. }
  204.  
  205. // Registering module functions
  206. module_init(initModule);
  207. module_exit(exitModule);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement