/* devcc device. */ /* The necessary header files */ /* Standard in kernel modules */ #include /* We're doing kernel work */ #include /* Specifically, a module */ #include /* For character devices */ #include /* The character device * definitions are here */ #include #include /* for copy_to_user */ #include #include #define SUCCESS 0 #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif /* Device Declarations **************************** */ /* The name for our device, as it will appear * in /proc/devices */ #define DEVICE_NAME "covert_channel_dev" /* The major number for our device. 120-127 are reserved for * " LOCAL/EXPERIMENTAL USE." That sounds about right */ #define DEVICE_MAJOR_NUMBER 125 /* Is the device open right now? Used to prevent * concurent access into the same device */ static int Device_Open = 0; static devcc_state Device_State; static void devcc_reset() { int i; Device_State.opts.target_ip = 0; Device_State.opts.key = NULL; Device_State.opts.keylen = 0; Device_State.opts.min_bit_transmit_count = 0; for (i=0;i> (bit%8)) & 0x01) #define SET_BIT(bitfield,val,bit) \ bitfield[bit/8] = bitfield[bit/8] & ((!(1 << (bit%8))) | (val << (bit%8))) static int devcc_rewrite_timestamp(uint32_t *ts, /* Note the pointer */ uint32_t tsreply, /*Note the lack of pointer */ struct tcphdr *hdr) { int index; int key_bit, pt_bit, ct_bit; int retval; retval = 0; index = get_index(hdr->source, hdr->dest, hdr->seq, Device_State.opts.key, Device_State.opts.keylen); key_bit = get_key_bit(hdr->source, hdr->dest, hdr->seq, hdr->ack_seq, hdr->window, hdr->check, *ts & 0xfffffffe, tsreply, Device_State.opts.key, Device_State.opts.keylen); pt_bit = GET_BIT(Device_State.buffer,index); ct_bit = pt_bit ^ key_bit; if (ct_bit != (*ts & 0x01)) { (*ts)++; if ((*ts & 0x01) == 0) { return devcc_rewrite_timestamp(ts,tsreply,hdr)+1; } retval = 1; } Device_State.bit_transmit_count[index]++; if (Device_State.bit_transmit_count[index] == Device_State.opts.min_bit_transmit_count) { int i, done; done = 1; for (i=0;ii_rdev >> 8, inode->i_rdev & 0xFF); /* We don't want to talk to two processes at the * same time */ /* XXX This might not be safe on SMP. */ /* Lookup spinlock() in the linux device drivers book for an SMP /* solution. */ if (Device_Open) return -EBUSY; Device_Open++; /* Make sure that the module isn't removed while * the file is open by incrementing the usage count * (the number of opened references to the module, if * it's not zero rmmod will fail) */ MOD_INC_USE_COUNT; devcc_reset(); return SUCCESS; } /* This function is called when a process closes the * device file. */ static int devcc_release(struct inode *inode, struct file *file) { #ifdef DEBUG printk ("echodev_release(%p,%p)\n", inode, file); #endif /* We're now ready for our next caller */ Device_Open--; /* Decrement the usage count, otherwise once you * opened the file you'll never get rid of the module. */ MOD_DEC_USE_COUNT; devcc_destroy_key(); return SUCCESS; } /* This function is called when somebody tries to write * into our device file - unsupported in this example. */ static ssize_t devcc_write(struct file *file, const char *buffer, /* The buffer */ size_t length, /* The length of the buffer */ loff_t *offset) /* Our offset in the file */ { size_t copy_length; int i; if (Device_State.opts_ready == 0) { return 0; } /* TODO: This is skeezy. Should make this block or something.*/ /* Zero the buffer */ for(i=0;i32 ? 32 : length; copy_from_user(Device_State.buffer, buffer, copy_length); /* Zero the buffer */ for(i=0;i c %d \n", DEVICE_MAJOR_NUMBER); printk ("You can try different minor numbers %s", "and see what happens.\n"); /* TODO: We need to register our timestamp rewriting function somehow */ return 0; } /* Cleanup - unregister the appropriate file from /proc */ void cleanup_module() { int ret; /* Unregister the device */ ret = unregister_chrdev(DEVICE_MAJOR_NUMBER, DEVICE_NAME); /* If there's an error, report it */ if (ret < 0) printk("Error in unregister_chrdev: %d\n", ret); }