Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <linux/slab.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/fs.h>
- #include <linux/errno.h>
- #include <asm/uaccess.h>
- #include <linux/ctype.h>
- #include <linux/config.h>
- #include <linux/types.h>
- #include <linux/proc_fs.h>
- #include <linux/fcntl.h>
- #include <asm/system.h>
- #include "enc.h"
- MODULE_LICENSE("GPL"); // CONSTANT for any code includes modules
- // Now we declare the functions of the fops
- static int open(struct inode* node, struct file* f) ; // OPEN OPERATION
- static int release(struct inode* node, struct file* f) ; // RELEASE OPERATION
- static ssize_t read(struct file* f, char* buf, size_t count, loff_t* fpos) ; // READING OPERATION
- static ssize_t write(struct file* f, const char* buf, size_t count, loff_t* fpos) ; // WRITING OPERATION
- int ioctl(struct inode* node, struct file* f, unsigned int cmd, unsigned long arg) ; // IOCTL OPERATION
- // We assign the parameters of the module, with intialziation..
- int enc_devices = 4; // Intial value
- int memory_size = 4096; // Intial value
- MODULE_PARM(memory_size, "i"); // i - meaning integer
- MODULE_PARM(enc_devices, "i"); // i - meaning integer
- static int major; // will hold the major # of my device driver
- // Giving a struct for the fops..
- static struct file_operations fops =
- {
- .open = open,
- .release = release,
- .read = read,
- .write = write,
- .ioctl = ioctl,
- .owner = THIS_MODULE
- };
- // Each device has unique data, so we give it a struct
- struct deviceData
- {
- char* readENC;
- char* writeENC;
- char* buffer;
- int key;
- };
- static struct deviceData* dD = NULL; // Intial 'value'
- // ------------ HELP FUNCTIONS --------------------------
- static void encrypt(char* buf, size_t size, int key)
- {
- int i;
- if(key%2 == 0) // we do the first encryption
- {
- for(i = 0; i < size; ++i)
- buf[i] = key | ((unsigned char)buf[i]);
- }
- else // It means key%2 == 1, we do the second encryption
- {
- for(i = 0; i < size; ++i)
- buf[i] = (((unsigned char)buf[i])+key*5)%255;
- }
- }
- static void reverseEncrypt(char* buf, size_t size, int key) // Reverse function to the second encryption
- {
- int i = 0;
- if(key%2 == 1)
- {
- for(i=0;i<size;i++)
- bufr[i] = (((unsigned char)buf[i]) - 5*key + 255*5)%255; // we add 5*255 because 5*key can be
- // maximum 255*5
- }
- else // key % 2 != 1...
- {
- return; // we do nothing... undefineable..
- }
- }
- // ------------------------------------------ SOME FUNCTIONS HAVE CONNECTION WITH MANAGING THE DEVICE -------------------------------
- void cleanup_module(void)
- {
- int i;
- // Free the buffers...
- for (i = 0; i < enc_devices; ++i)
- kfree(dD[i].buffer);
- // Delete data...
- kfree(dD);
- // Delete the connection...
- unregister_chrdev(major, "enc");
- return;
- }
- int init_module(void)
- {
- major = register_chrdev(0, "enc", &fops); // Try to make connection between the device to the major.
- if (major < 0) // Suppose it failed, then...
- {
- printk(KERN_WARNING "can't get dynamic major\n");
- return -1;
- }
- // If we get here, connection made successfuly.. so..
- printk(KERN_WARNING "enc: We got the major- %d\n", major);
- dD = kmalloc(sizeof(*dD) * enc_devices, GFP_KERNEL); // ALLOCATION, according to the number of the encyrpted devices..
- int i;
- for (i = 0; i<enc_devices; i++)
- {
- // Updating fields..
- dD[i].writeENC = kmalloc(memory_size, GFP_KERNEL);
- dD[i].readENC = dD[i].writeENC;
- dD[i].buffer = dD[i].readENC;
- dD[i].key = i;
- }
- printk(KERN_INFO "Intialization made successfuly with the following: devices %d,memory size %d, device data %p\n",
- enc_devices, memory_size, dD);
- return 0;
- }
- static int open(struct inode* node, struct file* f)
- {
- if (MINOR(node->i_rdev) > enc_devices)
- return -ENODEV; // Process uses wrong minor number..
- f->private_data = dD + MINOR(node->i_rdev); // Directing...
- MOD_INC_USE_COUNT;
- return 0;
- }
- static int release(struct inode* node, struct file* f)
- {
- MOD_DEC_USE_COUNT;
- return 0;
- }
- static int ioctl (struct inode* node, struct file* f, unsigned int cmd, unsigned long arg)
- {
- int minor = MINOR(node->i_rdev);
- switch (cmd)
- {
- case ENC_SEQ:
- dD[minor].key = (dD[minor].key + 1)%256; // According to the written in hw2...
- return dD[minor].key;
- case ENC_RESET:
- dD[minor].key = minor;
- dD[minor].writeENC = dD[minor].buffer;
- dD[minor].readENC = dD[minor].writeENC;
- return 0;
- default:
- return -EINVAL; // proper error.
- }
- }
- static ssize_t write(struct file* f, const char* buf, size_t size, loff_t* fpos)
- {
- size_t b_ytes;
- struct dD* dData = f->private_data;
- if (dData->readENC <= dData->writeENC )
- {
- b_ytes = memory_size - dData->writeENC + dData->readENC;
- if (size > b_ytes) return -EINVAL; // According to HW2..
- if(size <= memory_size + dData->buffer - dData->writeENC)
- {
- if (copy_from_user(dData-> writeENC, buf, size) != 0)
- return -EFAULT; // According to Hw2
- dData->writeENC = size + dData->writeENC; // Advancing
- if (dData->writeENC == memory_size + dData->buffer)
- dData-> writeENC = dData->buffer;
- }
- else
- {
- size_t defineSize = memory_size + dData->buffer - dData->writeENC;
- if (copy_from_user(dData->writeENC, buf, defineSize))
- return -EFAULT; // according to hw2...
- dData-> writeENC = dData->buffer;
- if (copy_from_user(dData->writeENC, buf, size - defineSize))
- return -EFAULT; // according to hw2...
- dData->writeENC = dData->writeENC + size; // Advancing
- }
- }
- else
- {
- b_ytes = dData->readENC - dData->writep;
- if (size > b_ytes)
- return -EINVAL;
- if (copy_from_user(dData->writeENC, buf, size))
- return -EFAULT;
- dData->writeENC += size;
- }
- *fpos = size + *fpos;
- }
- static ssize_t read (struct file* f, char* buf, size_t size, loff_t* fpos)
- {
- size_t b_ytes;
- struct dD* dData = file->private_data;
- if (dData->readENC <= dData->writeENC)
- b_ytes = dData->writeENC - dData->readENC;
- else
- b_ytes = memory_size + dData->writeENC - dData->readENC);
- if (b_ytes < size)
- size = b_ytes;
- if(dData->readENC <= dData->writeENC)
- {
- encrypt(dData->readENC, size, dData->key);
- if(copy_to_user(buf, dData->readENC, size))
- return -EFAULT; // according to hw2
- memset(dData->readENC, 0, size);
- dData->readENC = size + dData->readENC; // now we can advance it after finished..
- }
- else
- {
- if(size <= memory_size + dData->buffer - dData->readENC ))
- {
- encrypt(dData->readENC, size, dData->key);
- if(copy_to_user(buf, dData->readENC, size))
- return -EFAULT; // according to hw2
- memset(dData->readENC, 0, size);
- dData->readENC = dData->readENC + size; // now we can advance it.
- }
- else
- {
- size_t theProperSize = memory_size - dData->readENC + dData->buffer);
- encrypt(dData->readENC, theProperSize, dData->key);
- if(copy_to_user(buf, dData->readENC, size))
- return -EFAULT; // according to hw2..
- memset(dData->readENC, 0, size);
- dData->readENC = dData->buffer;
- encrypt(dData->readENC, size - theProperSize, dData->key);
- if(copy_to_user(buf, dData->readENC, size))
- return -EFAULT; // according to hw2..
- memset(dData->readENC, 0, size);
- dData->readENC = size - theProperSize + dData->readENC; // advancing as demanded...
- }
- }
- *fpos = *fpos + size;
- return size;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement