diff --git a/p4/__pycache__/p4_template.cpython-310.pyc b/p4/__pycache__/p4_template.cpython-310.pyc index 0282441..643a957 100644 Binary files a/p4/__pycache__/p4_template.cpython-310.pyc and b/p4/__pycache__/p4_template.cpython-310.pyc differ diff --git a/p4/piglet-drop.p4 b/p4/piglet-drop.p4 index 913fcd3..caf7358 100644 --- a/p4/piglet-drop.p4 +++ b/p4/piglet-drop.p4 @@ -186,7 +186,11 @@ control MyProcessing(inout headers hdr, } action check_udp_rules() { - +is_safe = is_safe && !(((hdr.ipv4.src & 0x0) == 0x00000000) && ((hdr.ipv4.dst & 0xffffff00) == 0xc0a80100) && ((hdr.udp.dst_port == 22))); +is_safe = is_safe && !(((hdr.ipv4.src & 0x0) == 0x00000000) && ((hdr.ipv4.dst & 0xffffff00) == 0xc0a80100) && ((hdr.udp.dst_port == 1433))); +is_safe = is_safe && !(((hdr.ipv4.src & 0x0) == 0x00000000) && ((hdr.ipv4.dst & 0xffffff00) == 0xc0a80100) && ((hdr.udp.dst_port == 80))); +is_safe = is_safe && !(((hdr.ipv4.src & 0x0) == 0x00000000) && ((hdr.ipv4.dst & 0xffffff00) == 0xc0a80100) && ((hdr.udp.dst_port == 21))); +is_safe = is_safe && !(((hdr.ipv4.src & 0x0) == 0x00000000) && ((hdr.ipv4.dst & 0xffffff00) == 0xc0a80100) && ((hdr.udp.dst_port == 28881))); } action check_tcp_rules() { diff --git a/p4/ruleset/droprule.rules b/p4/ruleset/droprule.rules index 4366348..1237aa5 100644 --- a/p4/ruleset/droprule.rules +++ b/p4/ruleset/droprule.rules @@ -1,5 +1,10 @@ -drop icmp any any -> $HOME_NET any (msg:"--> Drop the ping cmd!"; dsize:>5000; gid:1000002; sid:1000002; rev:1;) +drop icmp any any -> $HOME_NET any (msg:"--> Drop the ping cmd!"; dsize:>5000; gid:1000002; sid:1000000; rev:1;) drop tcp any any -> $HOME_NET 22 (msg:"SSH Brute Force Attempt"; flow:to_server,established; content:"SSH-"; depth:4; detection_filter:track by_src, count 5, seconds 60; sid:100001;) drop tcp any any -> $HOME_NET 1433 (msg:"SQL Injection Attempt"; flow:to_server,established; content:"'"; pcre:"/(%27)|(')|(--)|(%23)|(#)/i"; sid:100002;) drop tcp any any -> $HOME_NET 80 (msg:"HTTP Shell Command Execution"; flow:to_server,established; content:"|0d 0a|"; content:"User-Agent|3a|"; http_header; pcre:"/(?:cmd|shell_exec|passthru|exec|system|popen|proc_open|pcntl_exec)\s*(/i"; sid:100003;) -drop tcp any any -> $HOME_NET 21 (msg:"FTP Brute Force Attempt"; flow:to_server,established; content:"530"; depth:3; detection_filter:track by_src, count 5, seconds 60; sid:100004;) \ No newline at end of file +drop tcp any any -> $HOME_NET 21 (msg:"FTP Brute Force Attempt"; flow:to_server,established; content:"530"; depth:3; detection_filter:track by_src, count 5, seconds 60; sid:100004;) +drop udp any any -> $HOME_NET 22 (msg:"SSH Brute Force Attempt"; flow:to_server,established; content:"SSH-"; depth:4; detection_filter:track by_src, count 5, seconds 60; sid:100005;) +drop udp any any -> $HOME_NET 1433 (msg:"SQL Injection Attempt"; flow:to_server,established; content:"'"; pcre:"/(%27)|(')|(--)|(%23)|(#)/i"; sid:100006;) +drop udp any any -> $HOME_NET 80 (msg:"HTTP Shell Command Execution"; flow:to_server,established; content:"|0d 0a|"; content:"User-Agent|3a|"; http_header; pcre:"/(?:cmd|shell_exec|passthru|exec|system|popen|proc_open|pcntl_exec)\s*(/i"; sid:100007;) +drop udp any any -> $HOME_NET 21 (msg:"FTP Brute Force Attempt"; flow:to_server,established; content:"530"; depth:3; detection_filter:track by_src, count 5, seconds 60; sid:100008;) +drop udp any any -> $HOME_NET 28881 (msg:"Dummy Rules"; flow:to_server,established; content:"530"; depth:3; detection_filter:track by_src, count 5, seconds 60; sid:100008;) diff --git a/softwares/dma-proxy/Common/dma-proxy.h b/softwares/dma-proxy/Common/dma-proxy.h index 8393164..bba0768 100644 --- a/softwares/dma-proxy/Common/dma-proxy.h +++ b/softwares/dma-proxy/Common/dma-proxy.h @@ -25,7 +25,7 @@ #define T_BUFFER unsigned char -#define BUFFER_SIZE (128 * 1024) /* must match driver exactly */ +#define BUFFER_SIZE (8 * 2048) /* must match driver exactly */ #define BUFFER_SLOT_COUNT (BUFFER_SIZE / sizeof(T_BUFFER)) #define BUFFER_COUNT 32 /* driver only */ diff --git a/softwares/dma-proxy/Kernel/Kernel_mcdma/Makefile b/softwares/dma-proxy/Kernel/Kernel_mcdma/Makefile deleted file mode 100644 index 960d37b..0000000 --- a/softwares/dma-proxy/Kernel/Kernel_mcdma/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -MOD = dma-proxy-mcdma -KPATH :=/lib/modules/$(shell uname -r)/build -PWD :=$(shell pwd) -obj-m = $(MOD).o - -all: - $(MAKE) -C $(KPATH) M=$(PWD) modules - -clean: - $(MAKE) -C $(KPATH) M=$(PWD) clean - -insmod: all - sudo rmmod $(MOD).ko; true - sudo insmod $(MOD).ko - -log: - tail -f /var/log/messages diff --git a/softwares/dma-proxy/Kernel/Kernel_mcdma/Module.symvers b/softwares/dma-proxy/Kernel/Kernel_mcdma/Module.symvers deleted file mode 100644 index e69de29..0000000 diff --git a/softwares/dma-proxy/Kernel/Kernel_mcdma/dma-proxy-mcdma.c b/softwares/dma-proxy/Kernel/Kernel_mcdma/dma-proxy-mcdma.c deleted file mode 100644 index 71ec58e..0000000 --- a/softwares/dma-proxy/Kernel/Kernel_mcdma/dma-proxy-mcdma.c +++ /dev/null @@ -1,666 +0,0 @@ -/** - * Copyright (C) 2021 Xilinx, Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may - * not use this file except in compliance with the License. A copy of the - * License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -/* DMA Proxy - * - * This module is designed to be a small example of a DMA device driver that is - * a client to the DMA Engine using the AXI DMA / MCDMA driver. It serves as a proxy - * for kernel space DMA control to a user space application. - * - * A zero copy scheme is provided by allowing user space to mmap a kernel allocated - * memory region into user space, referred to as a set of channel buffers. Ioctl functions - * are provided to start a DMA transfer (non-blocking), finish a DMA transfer (blocking) - * previously started, or start and finish a DMA transfer blocking until it is complete. - * An input argument which specifies a channel buffer number (0 - N) to be used for the - * transfer is required. - * - * By default the kernel memory allocated for user space mapping is going to be - * non-cached at this time. Non-cached memory is pretty slow for the application. - * A h/w coherent system for MPSOC has been tested and is recommended for higher - * performance applications. - * - * Hardware coherency requires the following items in the system as documented on the - * Xilinx wiki and summarized below:: - * The AXI DMA read and write channels AXI signals must be tied to the correct state to - * generate coherent transactions. - * An HPC slave port on MPSOC is required - * The CCI of MPSOC must be initialized prior to the APU booting Linux - * A dma-coherent property is added in the device tree for the proxy driver. - * - * There is an associated user space application, dma_proxy_test.c, and dma_proxy.h - * that works with this device driver. - * - * The hardware design was tested with an AXI DMA / MCDMA with scatter gather and - * with the transmit channel looped back to the receive channel. It should - * work with or without scatter gather as the scatter gather mentioned in the - * driver is only at the s/w framework level rather than in the hw. - * - * This driver is character driver which creates devices that user space can - * access for each DMA channel, such as /dev/dma_proxy_rx and /dev/dma_proxy_tx. - * The number and names of channels are taken from the device tree. - * Multiple instances of the driver (with multiple IPs) are also supported. - - * An internal test mode is provided to allow it to be self testing without the - * need for a user space application and this mode is good for making bigger - * changes to this driver. - * - * This driver is designed to be simple to help users get familiar with how to - * use the DMA driver provided by Xilinx which uses the Linux DMA Engine. - * - * To use this driver a node must be added into the device tree. Add a - * node similar to the examples below adjusting the dmas property to match the - * name of the AXI DMA / MCDMA node. - * - * The dmas property contains pairs with the first of each pair being a reference - * to the DMA IP in the device tree and the second of each pair being the - * channel of the DMA IP. For the AXI DMA IP the transmit channel is always 0 and - * the receive is always 1. For the AXI MCDMA IP the 1st transmit channel is - * always 0 and receive channels start at 16 since there can be a maximum of 16 - * transmit channels. Each name in the dma-names corresponds to a pair in the dmas - * property and is only a logical name that allows user space access to the channel - * such that the name can be any name as long as it is unique. - * - * For h/w coherent systems with MPSoC, the property dma-coherent can be added - * to the node in the device tree. - * - * Example device tree nodes: - * - * For AXI DMA with transmit and receive channels with a loopback in hardware - * - * dma_proxy { - * compatible ="xlnx,dma_proxy"; - * dmas = <&axi_dma_1_loopback 0 &axi_dma_1_loopback 1>; - * dma-names = "dma_proxy_tx", "dma_proxy_rx"; - * }; - * - * For AXI DMA with only the receive channel - * - * dma_proxy2 { - * compatible ="xlnx,dma_proxy"; - * dmas = <&axi_dma_0_noloopback 1>; - * dma-names = "dma_proxy_rx_only"; - * }; - * - * For AXI MCDMA with two channels - * - * dma_proxy3 { - * compatible ="xlnx,dma_proxy"; - * dmas = <&axi_mcdma_0 0 &axi_mcdma_0 16 &axi_mcdma_0 1 &axi_mcdma_0 17>; - * dma-names = "dma_proxy_tx_0", "dma_proxy_rx_0", "dma_proxy_tx_1", "dma_proxy_rx_1"; - * }; - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../../Common/dma-proxy.h" - -MODULE_LICENSE("GPL"); - -#define DRIVER_NAME "dma_proxy_mcdma" -#define TX_CHANNEL 0 -#define RX_CHANNEL 1 -#define ERROR -1 -#define TEST_SIZE 1024 - -/* The following module parameter controls if the internal test runs when the module is inserted. - * Note that this test requires a transmit and receive channel to function and uses the first - * transmit and receive channnels when multiple channels exist. - */ -static unsigned internal_test = 0; -module_param(internal_test, int, S_IRUGO); - -/* The following data structures represent a single channel of DMA, transmit or receive in the case - * when using AXI DMA. It contains all the data to be maintained for the channel. - */ -struct proxy_bd { - struct completion cmp; - dma_cookie_t cookie; - dma_addr_t dma_handle; - struct scatterlist sglist; -}; -struct dma_proxy_channel { - struct channel_buffer *buffer_table_p; /* user to kernel space interface */ - dma_addr_t buffer_phys_addr; - - struct device *proxy_device_p; /* character device support */ - struct device *dma_device_p; - dev_t dev_node; - struct cdev cdev; - struct class *class_p; - - struct proxy_bd bdtable[BUFFER_COUNT]; - - struct dma_chan *channel_p; /* dma support */ - u32 direction; /* DMA_MEM_TO_DEV or DMA_DEV_TO_MEM */ - int bdindex; -}; - -struct dma_proxy { - int channel_count; - struct dma_proxy_channel *channels; - char **names; - struct work_struct work; -}; - -static int total_count; - -/* Handle a callback and indicate the DMA transfer is complete to another - * thread of control - */ -static void sync_callback(void *completion) -{ - /* Indicate the DMA transaction completed to allow the other - * thread of control to finish processing - */ - complete(completion); -} - -/* Prepare a DMA buffer to be used in a DMA transaction, submit it to the DMA engine - * to ibe queued and return a cookie that can be used to track that status of the - * transaction - */ -static void start_transfer(struct dma_proxy_channel *pchannel_p) -{ - enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; - struct dma_async_tx_descriptor *chan_desc; - struct dma_device *dma_device = pchannel_p->channel_p->device; - int bdindex = pchannel_p->bdindex; - - /* A single entry scatter gather list is used as it's not clear how to do it with a simpler method. - * Get a descriptor for the transfer ready to submit - */ - sg_init_table(&pchannel_p->bdtable[bdindex].sglist, 1); - sg_dma_address(&pchannel_p->bdtable[bdindex].sglist) = pchannel_p->bdtable[bdindex].dma_handle; - sg_dma_len(&pchannel_p->bdtable[bdindex].sglist) = pchannel_p->buffer_table_p[bdindex].length; - - chan_desc = dma_device->device_prep_slave_sg(pchannel_p->channel_p, &pchannel_p->bdtable[bdindex].sglist, 1, - pchannel_p->direction, flags, NULL); - - if (!chan_desc) { - printk(KERN_ERR "dmaengine_prep*() error\n"); - } else { - chan_desc->callback = sync_callback; - chan_desc->callback_param = &pchannel_p->bdtable[bdindex].cmp; - - /* Initialize the completion for the transfer and before using it - * then submit the transaction to the DMA engine so that it's queued - * up to be processed later and get a cookie to track it's status - */ - init_completion(&pchannel_p->bdtable[bdindex].cmp); - - pchannel_p->bdtable[bdindex].cookie = dmaengine_submit(chan_desc); - if (dma_submit_error(pchannel_p->bdtable[bdindex].cookie)) { - printk("Submit error\n"); - return; - } - - /* Start the DMA transaction which was previously queued up in the DMA engine - */ - dma_async_issue_pending(pchannel_p->channel_p); - } -} - -/* Wait for a DMA transfer that was previously submitted to the DMA engine - */ -static void wait_for_transfer(struct dma_proxy_channel *pchannel_p) -{ - unsigned long timeout = msecs_to_jiffies(3000); - enum dma_status status; - int bdindex = pchannel_p->bdindex; - - pchannel_p->buffer_table_p[bdindex].status = PROXY_BUSY; - - /* Wait for the transaction to complete, or timeout, or get an error - */ - timeout = wait_for_completion_timeout(&pchannel_p->bdtable[bdindex].cmp, timeout); - status = dma_async_is_tx_complete(pchannel_p->channel_p, pchannel_p->bdtable[bdindex].cookie, NULL, NULL); - - if (timeout == 0) { - pchannel_p->buffer_table_p[bdindex].status = PROXY_TIMEOUT; - printk(KERN_ERR "DMA timed out\n"); - } else if (status != DMA_COMPLETE) { - pchannel_p->buffer_table_p[bdindex].status = PROXY_ERROR; - printk(KERN_ERR "DMA returned completion callback status of: %s\n", - status == DMA_ERROR ? "error" : "in progress"); - } else - pchannel_p->buffer_table_p[bdindex].status = PROXY_NO_ERROR; -} - -/* The following functions are designed to test the driver from within the device - * driver without any user space. It uses the first channel buffer for the transmit and receive. - * If this works but the user application does not then the user application is at fault. - */ -static void tx_test(struct work_struct *local_work) -{ - struct dma_proxy *lp; - lp = container_of(local_work, struct dma_proxy, work); - - /* Use the 1st buffer for the test - */ - lp->channels[TX_CHANNEL].buffer_table_p[0].length = TEST_SIZE; - lp->channels[TX_CHANNEL].bdindex = 0; - - start_transfer(&lp->channels[TX_CHANNEL]); - wait_for_transfer(&lp->channels[TX_CHANNEL]); -} - -static void test(struct dma_proxy *lp) -{ - int i; - - printk("Starting internal test\n"); - - /* Initialize the buffers for the test - */ - for (i = 0; i < TEST_SIZE / sizeof(unsigned int); i++) { - lp->channels[TX_CHANNEL].buffer_table_p[0].buffer[i] = i; - lp->channels[RX_CHANNEL].buffer_table_p[0].buffer[i] = 0; - } - - /* Since the transfer function is blocking the transmit channel is started from a worker - * thread - */ - INIT_WORK(&lp->work, tx_test); - schedule_work(&lp->work); - - /* Receive the data that was just sent and looped back - */ - lp->channels[RX_CHANNEL].buffer_table_p->length = TEST_SIZE; - lp->channels[TX_CHANNEL].bdindex = 0; - - start_transfer(&lp->channels[RX_CHANNEL]); - wait_for_transfer(&lp->channels[RX_CHANNEL]); - - /* Verify the receiver buffer matches the transmit buffer to - * verify the transfer was good - */ - for (i = 0; i < TEST_SIZE / sizeof(unsigned int); i++) - if (lp->channels[TX_CHANNEL].buffer_table_p[0].buffer[i] != - lp->channels[RX_CHANNEL].buffer_table_p[0].buffer[i]) { - printk("buffers not equal, first index = %d\n", i); - break; - } - - printk("Internal test complete\n"); -} - -/* Map the memory for the channel interface into user space such that user space can - * access it using coherent memory which will be non-cached for s/w coherent systems - * such as Zynq 7K or the current default for Zynq MPSOC. MPSOC can be h/w coherent - * when set up and then the memory will be cached. - */ -static int mmap(struct file *file_p, struct vm_area_struct *vma) -{ - struct dma_proxy_channel *pchannel_p = (struct dma_proxy_channel *)file_p->private_data; - - return dma_mmap_coherent(pchannel_p->dma_device_p, vma, - pchannel_p->buffer_table_p, pchannel_p->buffer_phys_addr, - vma->vm_end - vma->vm_start); -} - -/* Open the device file and set up the data pointer to the proxy channel data for the - * proxy channel such that the ioctl function can access the data structure later. - */ -static int local_open(struct inode *ino, struct file *file) -{ - file->private_data = container_of(ino->i_cdev, struct dma_proxy_channel, cdev); - - return 0; -} - -/* Close the file and there's nothing to do for it - */ -static int release(struct inode *ino, struct file *file) -{ -#if 0 - struct dma_proxy_channel *pchannel_p = (struct dma_proxy_channel *)file->private_data; - struct dma_device *dma_device = pchannel_p->channel_p->device; - - /* Stop all the activity when the channel is closed assuming this - * may help if the application is aborted without normal closure - * This is not working and causes an issue that may need investigation in the - * DMA driver at the lower level. - */ - dma_device->device_terminate_all(pchannel_p->channel_p); -#endif - return 0; -} - -/* Perform I/O control to perform a DMA transfer using the input as an index - * into the buffer descriptor table such that the application is in control of - * which buffer to use for the transfer.The BD in this case is only a s/w - * structure for the proxy driver, not related to the hw BD of the DMA. - */ -static long ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct dma_proxy_channel *pchannel_p = (struct dma_proxy_channel *)file->private_data; - - /* Get the bd index from the input argument as all commands require it - */ - if(copy_from_user(&pchannel_p->bdindex, (int *)arg, sizeof(pchannel_p->bdindex))) - return -EINVAL; - - /* Perform the DMA transfer on the specified channel blocking til it completes - */ - switch(cmd) { - case START_XFER: - start_transfer(pchannel_p); - break; - case FINISH_XFER: - wait_for_transfer(pchannel_p); - break; - case XFER: - start_transfer(pchannel_p); - wait_for_transfer(pchannel_p); - break; - } - - return 0; -} - -static struct file_operations dm_fops = { - .owner = THIS_MODULE, - .open = local_open, - .release = release, - .unlocked_ioctl = ioctl, - .mmap = mmap -}; - - -/* Initialize the driver to be a character device such that is responds to - * file operations. - */ -static int cdevice_init(struct dma_proxy_channel *pchannel_p, char *name) -{ - int rc; - char device_name[32] = "dma_proxy"; - static struct class *local_class_p = NULL; - - /* Allocate a character device from the kernel for this driver. - */ - rc = alloc_chrdev_region(&pchannel_p->dev_node, 0, 1, "dma_proxy"); - - if (rc) { - dev_err(pchannel_p->dma_device_p, "unable to get a char device number\n"); - return rc; - } - - /* Initialize the device data structure before registering the character - * device with the kernel. - */ - cdev_init(&pchannel_p->cdev, &dm_fops); - pchannel_p->cdev.owner = THIS_MODULE; - rc = cdev_add(&pchannel_p->cdev, pchannel_p->dev_node, 1); - - if (rc) { - dev_err(pchannel_p->dma_device_p, "unable to add char device\n"); - goto init_error1; - } - - /* Only one class in sysfs is to be created for multiple channels, - * create the device in sysfs which will allow the device node - * in /dev to be created - */ - if (!local_class_p) { - local_class_p = class_create(THIS_MODULE, DRIVER_NAME); - - if (IS_ERR(pchannel_p->dma_device_p->class)) { - dev_err(pchannel_p->dma_device_p, "unable to create class\n"); - rc = ERROR; - goto init_error2; - } - } - pchannel_p->class_p = local_class_p; - - /* Create the device node in /dev so the device is accessible - * as a character device - */ - strcat(device_name, name); - pchannel_p->proxy_device_p = device_create(pchannel_p->class_p, NULL, - pchannel_p->dev_node, NULL, name); - - if (IS_ERR(pchannel_p->proxy_device_p)) { - dev_err(pchannel_p->dma_device_p, "unable to create the device\n"); - goto init_error3; - } - - return 0; - -init_error3: - class_destroy(pchannel_p->class_p); - -init_error2: - cdev_del(&pchannel_p->cdev); - -init_error1: - unregister_chrdev_region(pchannel_p->dev_node, 1); - return rc; -} - -/* Exit the character device by freeing up the resources that it created and - * disconnecting itself from the kernel. - */ -static void cdevice_exit(struct dma_proxy_channel *pchannel_p) -{ - /* Take everything down in the reverse order - * from how it was created for the char device - */ - if (pchannel_p->proxy_device_p) { - device_destroy(pchannel_p->class_p, pchannel_p->dev_node); - - /* If this is the last channel then get rid of the /sys/class/dma_proxy - */ - if (total_count == 1) - class_destroy(pchannel_p->class_p); - - cdev_del(&pchannel_p->cdev); - unregister_chrdev_region(pchannel_p->dev_node, 1); - } -} - -/* Create a DMA channel by getting a DMA channel from the DMA Engine and then setting - * up the channel as a character device to allow user space control. - */ -static int create_channel(struct platform_device *pdev, struct dma_proxy_channel *pchannel_p, char *name, u32 direction) -{ - int rc, bd; - - /* Request the DMA channel from the DMA engine and then use the device from - * the channel for the proxy channel also. - */ - pchannel_p->dma_device_p = &pdev->dev; - pchannel_p->channel_p = dma_request_chan(&pdev->dev, name); - if (!pchannel_p->channel_p) { - dev_err(pchannel_p->dma_device_p, "DMA channel request error\n"); - return ERROR; - } - - /* Initialize the character device for the dma proxy channel - */ - rc = cdevice_init(pchannel_p, name); - if (rc) - return rc; - - pchannel_p->direction = direction; - - /* Allocate DMA memory that will be shared/mapped by user space, allocating - * a set of buffers for the channel with user space specifying which buffer - * to use for a tranfer.. - */ - pchannel_p->buffer_table_p = (struct channel_buffer *) - dmam_alloc_coherent(pchannel_p->dma_device_p, - sizeof(struct channel_buffer) * BUFFER_COUNT, - &pchannel_p->buffer_phys_addr, GFP_KERNEL); - printk(KERN_INFO "Allocating memory, virtual address: %px physical address: %px\n", - pchannel_p->buffer_table_p, (void *)pchannel_p->buffer_phys_addr); - - /* Initialize each entry in the buffer descriptor table such that the physical address - * address of each buffer is ready to use later. - */ - for (bd = 0; bd < BUFFER_COUNT; bd++) - pchannel_p->bdtable[bd].dma_handle = (dma_addr_t)(pchannel_p->buffer_phys_addr + - (sizeof(struct channel_buffer) * bd) + offsetof(struct channel_buffer, buffer)); - - /* The buffer descriptor index into the channel buffers should be specified in each - * ioctl but we will initialize it to be safe. - */ - pchannel_p->bdindex = 0; - if (!pchannel_p->buffer_table_p) { - dev_err(pchannel_p->dma_device_p, "DMA allocation error\n"); - return ERROR; - } - return 0; -} -/* Initialize the dma proxy device driver module. - */ -static int dma_proxy_probe(struct platform_device *pdev) -{ - int rc, i; - struct dma_proxy *lp; - struct device *dev = &pdev->dev; - - printk(KERN_INFO "dma_proxy module initialized\n"); - - lp = (struct dma_proxy *) devm_kmalloc(&pdev->dev, sizeof(struct dma_proxy), GFP_KERNEL); - if (!lp) { - dev_err(dev, "Cound not allocate proxy device\n"); - return -ENOMEM; - } - dev_set_drvdata(dev, lp); - - /* Figure out how many channels there are from the device tree based - * on the number of strings in the dma-names property - */ - lp->channel_count = device_property_read_string_array(&pdev->dev, - "dma-names", NULL, 0); - if (lp->channel_count <= 0) - return 0; - - printk("Device Tree Channel Count: %d\r\n", lp->channel_count); - - /* Allocate the memory for channel names and then get the names - * from the device tree - */ - lp->names = devm_kmalloc_array(&pdev->dev, lp->channel_count, - sizeof(char *), GFP_KERNEL); - if (!lp->names) - return -ENOMEM; - - rc = device_property_read_string_array(&pdev->dev, "dma-names", - (const char **)lp->names, lp->channel_count); - if (rc < 0) - return rc; - - /* Allocate the memory for the channels since the number is known. - */ - lp->channels = devm_kmalloc(&pdev->dev, - sizeof(struct dma_proxy_channel) * lp->channel_count, GFP_KERNEL); - if (!lp->channels) - return -ENOMEM; - - /* Create the channels in the proxy. The direction does not matter - * as the DMA channel has it inside it and uses it, other than this will not work - * for cyclic mode. - */ - for (i = 0; i < lp->channel_count; i++) { - printk("Creating channel %s\r\n", lp->names[i]); - rc = create_channel(pdev, &lp->channels[i], lp->names[i], DMA_MEM_TO_DEV); - - if (rc) - return rc; - total_count++; - } - - if (internal_test) - test(lp); - return 0; -} - -/* Exit the dma proxy device driver module. - */ -static int dma_proxy_remove(struct platform_device *pdev) -{ - int i; - struct device *dev = &pdev->dev; - struct dma_proxy *lp = dev_get_drvdata(dev); - - printk(KERN_INFO "dma_proxy module exited\n"); - - /* Take care of the char device infrastructure for each - * channel except for the last channel. Handle the last - * channel seperately. - */ - for (i = 0; i < lp->channel_count; i++) { - if (lp->channels[i].proxy_device_p) - cdevice_exit(&lp->channels[i]); - total_count--; - } - /* Take care of the DMA channels and any buffers allocated - * for the DMA transfers. The DMA buffers are using managed - * memory such that it's automatically done. - */ - for (i = 0; i < lp->channel_count; i++) - if (lp->channels[i].channel_p) { - lp->channels[i].channel_p->device->device_terminate_all(lp->channels[i].channel_p); - dma_release_channel(lp->channels[i].channel_p); - } - return 0; -} - -static const struct of_device_id dma_proxy_of_ids[] = { - { .compatible = "xlnx,dma_proxy_mcdma",}, - {} -}; - -static struct platform_driver dma_proxy_driver = { - .driver = { - .name = "dma_proxy_driver_mcdma", - .owner = THIS_MODULE, - .of_match_table = dma_proxy_of_ids, - }, - .probe = dma_proxy_probe, - .remove = dma_proxy_remove, -}; - -static int __init dma_proxy_init(void) -{ - return platform_driver_register(&dma_proxy_driver); -} - -static void __exit dma_proxy_exit(void) -{ - platform_driver_unregister(&dma_proxy_driver); -} - -module_init(dma_proxy_init) -module_exit(dma_proxy_exit) - -MODULE_AUTHOR("Xilinx, Inc."); -MODULE_DESCRIPTION("DMA Proxy Prototype"); -MODULE_LICENSE("GPL v2"); diff --git a/softwares/dma-proxy/Kernel/Kernel_mcdma/dma-proxy-mcdma.mod b/softwares/dma-proxy/Kernel/Kernel_mcdma/dma-proxy-mcdma.mod deleted file mode 100644 index bfbd5fd..0000000 --- a/softwares/dma-proxy/Kernel/Kernel_mcdma/dma-proxy-mcdma.mod +++ /dev/null @@ -1,2 +0,0 @@ -/home/ubuntu/Piglet/softwares/dma-proxy/Kernel/Kernel_mcdma/dma-proxy-mcdma.o - diff --git a/softwares/gateway/automated-perf.py b/softwares/gateway/automated-perf.py new file mode 100644 index 0000000..2c783d3 --- /dev/null +++ b/softwares/gateway/automated-perf.py @@ -0,0 +1,190 @@ +import re +import subprocess +from multiprocessing import Process, Manager +import os +from scapy.all import Ether, IP, TCP, UDP, sendpfast, Raw +import time +from tqdm import tqdm +from openpyxl import Workbook +import pickle +from datetime import datetime + +def get_cases(pkt_types, pkt_lengths, cap_ppses): + cases = [] + for pkt_type in pkt_types: + for pkt_length in pkt_lengths: + for cap_pps in cap_ppses: + cases.append((pkt_type, pkt_length, cap_pps)) + return cases + +def pad_message(m, l, protocol="TCP"): + TCP_LENGTH = 54 + UDP_LENGTH = 42 + active_length = TCP_LENGTH if protocol == "TCP" else UDP_LENGTH + padding_message = "-PADDING-" + lm = len(m) + padded_len = l - (active_length + lm) + padding_message *= int(1 + padded_len / len(padding_message)) + padded_message = m + padding_message + return padded_message[:(l - active_length)] + +def execute_command(command, return_dict): + try: + process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) + output, error = process.communicate() + return_dict["output"] = output + return_dict["error"] = error + return_dict["return_code"] = process.returncode + except subprocess.CalledProcessError as e: + return_dict["output"] = None + return_dict["error"] = str(e) + return_dict["return_code"] = e.returncode + +def get_packet(preset, length, protocol): + basepkt = Ether(src="08:00:27:00:00:02", dst="08:00:27:00:00:01") / IP(src="10.147.18.200", dst="192.168.1.55") + message = pad_message(f"{preset.capitalize()} Packet", length, protocol) + if protocol == "TCP": + if preset == "harmless": + return basepkt / TCP(sport=5000, dport=1234) / Raw(load=message) + elif preset == "suspicious": + return basepkt / TCP(sport=5000, dport=80) / Raw(load=message) + elif preset == "harmful": + return basepkt / TCP(sport=5000, dport=22) / Raw(load=message) + elif preset == "mixed": + message2 = pad_message("Suspicious Packet", length + 10, protocol) + return [ + basepkt / TCP(sport=5000, dport=1234) / Raw(load=message), + basepkt / TCP(sport=5000, dport=80) / Raw(load=message2) + ] + else: + if preset == "harmless": + return basepkt / UDP(dport=1234) / Raw(load=message) + elif preset == "suspicious": + return basepkt / UDP(dport=80) / Raw(load=message) + elif preset == "harmful": + return basepkt / UDP(dport=22) / Raw(load=message) + elif preset == "mixed": + message2 = pad_message("Suspicious Packet", length + 10, protocol) + return [ + basepkt / UDP(dport=1234) / Raw(load=message), + basepkt / UDP(dport=80) / Raw(load=message2) + ] + +def execute_test(pkt_type, pkt_length, cap_pps, injector, sniffer, pkt_repeat, timeout, active_protocol): + command = ["/home/jkulrativid/Desktop/Piglet/softwares/gateway/perf-sniffer", sniffer, "\"\"", str(pkt_length), str(pkt_repeat), "0", "0", str(timeout)] + if pkt_type == "mixed": + command = ["/home/jkulrativid/Desktop/Piglet/softwares/gateway/perf-sniffer", sniffer, "\"\"", str(pkt_length), str(pkt_repeat), str(pkt_length + 10), str(pkt_repeat), str(timeout)] + + manager = Manager() + return_dict = manager.dict() + p = Process(target=execute_command, args=(command, return_dict)) + p.start() + + time.sleep(1) + + pkt = get_packet(pkt_type, pkt_length, active_protocol) + sendpfast(pkt, iface=injector, loop=pkt_repeat, file_cache=True, mbps=1000, pps=cap_pps) + + p.join() + + output, error, return_code = return_dict["output"], return_dict["error"], return_dict["return_code"] + + if return_code != 0: + print("Error occurred while executing the command.") + print("Error message:") + print(error) + exit(1) + + duration = re.search(r"Duration: (.+?) s, (.+?) ns", output).group(1) + throughput_mbps = re.search(r"Throughput\(Mbps\): (.+?) Mbps", output).group(1) + pps = re.search(r"Packet per second: (.+?) pps", output).group(1) + pkt_count = re.search(r"overall pkt1 count = ([0-9]+)", output).group(1) + if pkt_type == "mixed": + pkt_count2 = re.search(r"overall pkt2 count = ([0-9]+)", output).group(1) + pkt_count = f"{int(pkt_count) + int(pkt_count2)} (pkt1: {pkt_count}, pkt2: {pkt_count2})" + print(f"Duration: {duration} s") + print(f"Throughput: {throughput_mbps} Mbps") + print(f"Packet per second: {pps} pps") + print(f"Packet count: {pkt_count}") + return duration, throughput_mbps, pps, pkt_count + +def write_single_run(ws, base_row, base_col, result): + pkt_type, pkt_length, cap_pps, duration, throughput_mbps, pps, pkt_count = result + ws.cell(row=base_row, column=base_col, value=throughput_mbps) + ws.cell(row=base_row + 1, column=base_col, value=pps) + ws.cell(row=base_row + 2, column=base_col, value=duration) + ws.cell(row=base_row + 3, column=base_col, value=pkt_count) + +def save_to_excel(results, dir, title): + row_increment = 4 + col_increment = 3 + wb = Workbook() + ws = wb.active + ws.title = title + row = 1 + col = 1 + for i, runs in enumerate(results): + for j, result in enumerate(runs): + write_single_run(ws, row, col + j, result) + row += row_increment + if row % (4 * row_increment) == 1: + col += col_increment + row = 1 + wb.save(f"{dir}/{title}.xlsx") + +def main(): + injector = "enp5s0" # RJ-45 + sniffer = "enxc84d442973a0" # gray + current_time = datetime.now() + + save_to_dir = "results-" + current_time.strftime("%m-%d-%Y--%H-%M-%S") + print("save directory", save_to_dir) + + repeat_count = 3 + pkt_types = ["harmless", "suspicious", "harmful", "mixed"] + pkt_lengths = [65, 100, 500, 1500] + cap_ppses = [17000, 20000, 25000, 30000] + # pkt_repeat = 200_000 if test_title != "mixed" else 100_000 + + protocols = ["TCP", "UDP"] + for active_protocol in protocols: + for pkt_type in pkt_types: + test_title = f"{pkt_type}_{active_protocol}" + pkt_repeat = 200_000 if pkt_type != "mixed" else 100_000 + pkt_repeat = 100 if pkt_type == "harmful" else pkt_repeat + timeout = 50 if pkt_type != "harmful" else 10 + # pkt_repeat = 2 + + print(f"testing {test_title} packets") + print(f"pkt_types: {pkt_types}") + print(f"pkt_lengths: {pkt_lengths}") + print(f"cap_ppses: {cap_ppses}") + print(f"pkt_repeat: {pkt_repeat}") + print(f"timeout: {timeout}") + print(f"active_protocol: {active_protocol}") + + print("injector:", injector) + print("sniffer:", sniffer) + + cases = get_cases([pkt_type], pkt_lengths, cap_ppses) + results = [] + for case in tqdm(cases): + pkt_type, pkt_length, cap_pps = case + print(f"Executing test case: {pkt_type}, {pkt_length}, {cap_pps}\r") + runs = [] + for i in range(repeat_count): + duration, throughput_mbps, pps, pkt_count = execute_test(pkt_type, pkt_length, cap_pps, injector, sniffer, pkt_repeat, timeout, active_protocol) + runs.append((pkt_type, pkt_length, cap_pps, duration, throughput_mbps, pps, pkt_count)) + results.append(runs) + + if not os.path.exists(save_to_dir): + os.makedirs(save_to_dir) + if not os.path.exists(f"{save_to_dir}/{active_protocol}"): + os.makedirs(f"{save_to_dir}/{active_protocol}") + + save_to_excel(results, f"{save_to_dir}/{active_protocol}", test_title) + with open(f"{save_to_dir}/{active_protocol}/{test_title}.pkl", "wb") as f: + pickle.dump(results, f) + +if __name__ == '__main__': + main() diff --git a/softwares/gateway/pcap-utils.c b/softwares/gateway/pcap-utils.c index 60ab57d..554f307 100644 --- a/softwares/gateway/pcap-utils.c +++ b/softwares/gateway/pcap-utils.c @@ -30,8 +30,6 @@ #define PCAP_TIMEOUT 1000 // doesn't seems useful for a non-blocking mode - - /* * print data in rows of 16 bytes: offset hex ascii * @@ -137,68 +135,82 @@ parsed_packet get_empty_packet() { parsed_packet.ip = NULL; parsed_packet.tcp = NULL; parsed_packet.payload = NULL; + parsed_packet.size_total = 0; parsed_packet.size_ip = 0; parsed_packet.size_tcp = 0; + parsed_packet.size_udp = 0; parsed_packet.size_payload = 0; return parsed_packet; } // still bug but nevermind -parsed_packet parse_packet(const u_char *packet) { - parsed_packet parsed_packet = get_empty_packet(); - +int parse_packet(const u_char *packet, parsed_packet *parsed_packet) { struct ether_header *ethernet; struct ip *ip; struct tcphdr *tcp; + struct udphdr *udp; char *payload; int size_ip; int size_tcp; + int size_udp; int size_payload; // parse ethernet ethernet = (struct ether_header*)(packet); - parsed_packet.ethernet = ethernet; + parsed_packet->ethernet = ethernet; // parse ip ip = (struct ip*)(packet + SIZE_ETHERNET); size_ip = ip->ip_hl*4; if (size_ip < 20) { - printf(" * Invalid IP header length: %u bytes\n", size_ip); - return parsed_packet; + //printf(" * Invalid IP header length: %u bytes\n", size_ip); + return -1; } - parsed_packet.ip = ip; - parsed_packet.size_ip = size_ip; + parsed_packet->ip = ip; + parsed_packet->size_ip = size_ip; // determine protocol switch(ip->ip_p) { case IPPROTO_TCP: - break; + // parse tcp + tcp = (struct tcphdr*)(packet + SIZE_ETHERNET + size_ip); + size_tcp = tcp->th_off * 4; + if (size_tcp < 20) { + //printf(" * Invalid TCP header length: %u bytes\n", size_tcp); + return -1; + } + parsed_packet->tcp = tcp; + parsed_packet->size_tcp = size_tcp; + + payload = (char *)(packet + SIZE_ETHERNET + size_ip + size_tcp); + size_payload = ntohs(ip->ip_len) - (size_ip + size_tcp); + parsed_packet->payload = payload; + parsed_packet->size_payload = size_payload; + + parsed_packet->size_total = SIZE_ETHERNET + size_ip + size_tcp + size_payload; + + return 0; case IPPROTO_UDP: - return parsed_packet; + udp = (struct udphdr*)(packet + SIZE_ETHERNET + size_ip); + size_udp = 8; + parsed_packet->udp = udp; + parsed_packet->size_udp = size_udp; + + payload = (char *)(packet + SIZE_ETHERNET + size_ip + parsed_packet->size_udp); + size_payload = ntohs(ip->ip_len) - (size_ip + size_udp); + parsed_packet->payload = payload; + parsed_packet->size_payload = size_payload; + + parsed_packet->size_total = SIZE_ETHERNET + size_ip + size_udp + size_payload; + + return 0; case IPPROTO_ICMP: - return parsed_packet; + return 1; case IPPROTO_IP: - return parsed_packet; + return 1; default: - return parsed_packet; - } - - // parse tcp - tcp = (struct tcphdr*)(packet + SIZE_ETHERNET + size_ip); - size_tcp = tcp->th_off * 4; - if (size_tcp < 20) { - printf(" * Invalid TCP header length: %u bytes\n", size_tcp); - return parsed_packet; + return -1; } - parsed_packet.tcp = tcp; - parsed_packet.size_tcp = size_tcp; - - payload = (char *)(packet + SIZE_ETHERNET + size_ip + size_tcp); - size_payload = ntohs(ip->ip_len) - (size_ip + size_tcp); - parsed_packet.payload = payload; - parsed_packet.size_payload = size_payload; - - return parsed_packet; } /* diff --git a/softwares/gateway/pcap-utils.h b/softwares/gateway/pcap-utils.h index 779d903..51e148c 100644 --- a/softwares/gateway/pcap-utils.h +++ b/softwares/gateway/pcap-utils.h @@ -18,9 +18,12 @@ typedef struct { struct ether_header *ethernet; struct ip *ip; struct tcphdr *tcp; + struct udphdr *udp; char *payload; + int size_total; int size_ip; int size_tcp; + int size_udp; int size_payload; } parsed_packet; @@ -35,7 +38,7 @@ pcap_t* initiate_inject_pcap(char *dev); void cleanup_pcap(pcap_t *handle, struct bpf_program *fp); -parsed_packet parse_packet(const u_char *packet); +int parse_packet(const u_char *packet, parsed_packet *parsed_packet); int parse_packet_for_length(const u_char *packet); diff --git a/softwares/gateway/results-05-18-2024--19-08-15/TCP/harmless_TCP.pkl b/softwares/gateway/results-05-18-2024--19-08-15/TCP/harmless_TCP.pkl new file mode 100644 index 0000000..a60f565 Binary files /dev/null and b/softwares/gateway/results-05-18-2024--19-08-15/TCP/harmless_TCP.pkl differ diff --git a/softwares/gateway/results-05-18-2024--19-08-15/TCP/harmless_TCP.xlsx b/softwares/gateway/results-05-18-2024--19-08-15/TCP/harmless_TCP.xlsx new file mode 100644 index 0000000..0dee454 Binary files /dev/null and b/softwares/gateway/results-05-18-2024--19-08-15/TCP/harmless_TCP.xlsx differ diff --git a/softwares/gateway/results-05-18-2024--19-08-15/TCP/suspicious_TCP.pkl b/softwares/gateway/results-05-18-2024--19-08-15/TCP/suspicious_TCP.pkl new file mode 100644 index 0000000..6a839bb Binary files /dev/null and b/softwares/gateway/results-05-18-2024--19-08-15/TCP/suspicious_TCP.pkl differ diff --git a/softwares/gateway/results-05-18-2024--19-08-15/TCP/suspicious_TCP.xlsx b/softwares/gateway/results-05-18-2024--19-08-15/TCP/suspicious_TCP.xlsx new file mode 100644 index 0000000..d4acca4 Binary files /dev/null and b/softwares/gateway/results-05-18-2024--19-08-15/TCP/suspicious_TCP.xlsx differ diff --git a/softwares/gateway/results-05-18-2024--20-12-38/TCP/harmless_TCP.pkl b/softwares/gateway/results-05-18-2024--20-12-38/TCP/harmless_TCP.pkl new file mode 100644 index 0000000..da991d3 Binary files /dev/null and b/softwares/gateway/results-05-18-2024--20-12-38/TCP/harmless_TCP.pkl differ diff --git a/softwares/gateway/results-05-18-2024--20-12-38/TCP/harmless_TCP.xlsx b/softwares/gateway/results-05-18-2024--20-12-38/TCP/harmless_TCP.xlsx new file mode 100644 index 0000000..c1241fe Binary files /dev/null and b/softwares/gateway/results-05-18-2024--20-12-38/TCP/harmless_TCP.xlsx differ diff --git a/softwares/gateway/results-05-18-2024--20-12-38/UDP/harmless_UDP.pkl b/softwares/gateway/results-05-18-2024--20-12-38/UDP/harmless_UDP.pkl new file mode 100644 index 0000000..b1ca651 Binary files /dev/null and b/softwares/gateway/results-05-18-2024--20-12-38/UDP/harmless_UDP.pkl differ diff --git a/softwares/gateway/results-05-18-2024--20-12-38/UDP/harmless_UDP.xlsx b/softwares/gateway/results-05-18-2024--20-12-38/UDP/harmless_UDP.xlsx new file mode 100644 index 0000000..6ecd1b4 Binary files /dev/null and b/softwares/gateway/results-05-18-2024--20-12-38/UDP/harmless_UDP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--14-14-18/UDP/harmful_UDP.pkl b/softwares/gateway/results-05-19-2024--14-14-18/UDP/harmful_UDP.pkl new file mode 100644 index 0000000..5d41481 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--14-14-18/UDP/harmful_UDP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--14-14-18/UDP/harmful_UDP.xlsx b/softwares/gateway/results-05-19-2024--14-14-18/UDP/harmful_UDP.xlsx new file mode 100644 index 0000000..3cc5b89 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--14-14-18/UDP/harmful_UDP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--14-14-18/UDP/harmless_UDP.pkl b/softwares/gateway/results-05-19-2024--14-14-18/UDP/harmless_UDP.pkl new file mode 100644 index 0000000..aa06422 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--14-14-18/UDP/harmless_UDP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--14-14-18/UDP/harmless_UDP.xlsx b/softwares/gateway/results-05-19-2024--14-14-18/UDP/harmless_UDP.xlsx new file mode 100644 index 0000000..7c8e2f5 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--14-14-18/UDP/harmless_UDP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--14-14-18/UDP/mixed_UDP.pkl b/softwares/gateway/results-05-19-2024--14-14-18/UDP/mixed_UDP.pkl new file mode 100644 index 0000000..4280d59 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--14-14-18/UDP/mixed_UDP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--14-14-18/UDP/mixed_UDP.xlsx b/softwares/gateway/results-05-19-2024--14-14-18/UDP/mixed_UDP.xlsx new file mode 100644 index 0000000..7cb2874 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--14-14-18/UDP/mixed_UDP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--14-14-18/UDP/suspicious_UDP.pkl b/softwares/gateway/results-05-19-2024--14-14-18/UDP/suspicious_UDP.pkl new file mode 100644 index 0000000..4b835fd Binary files /dev/null and b/softwares/gateway/results-05-19-2024--14-14-18/UDP/suspicious_UDP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--14-14-18/UDP/suspicious_UDP.xlsx b/softwares/gateway/results-05-19-2024--14-14-18/UDP/suspicious_UDP.xlsx new file mode 100644 index 0000000..7ea052e Binary files /dev/null and b/softwares/gateway/results-05-19-2024--14-14-18/UDP/suspicious_UDP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--15-30-04/TCP/harmful_TCP.pkl b/softwares/gateway/results-05-19-2024--15-30-04/TCP/harmful_TCP.pkl new file mode 100644 index 0000000..57c4c7d Binary files /dev/null and b/softwares/gateway/results-05-19-2024--15-30-04/TCP/harmful_TCP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--15-30-04/TCP/harmful_TCP.xlsx b/softwares/gateway/results-05-19-2024--15-30-04/TCP/harmful_TCP.xlsx new file mode 100644 index 0000000..c3065a5 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--15-30-04/TCP/harmful_TCP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--15-30-04/TCP/harmless_TCP.pkl b/softwares/gateway/results-05-19-2024--15-30-04/TCP/harmless_TCP.pkl new file mode 100644 index 0000000..0c456bf Binary files /dev/null and b/softwares/gateway/results-05-19-2024--15-30-04/TCP/harmless_TCP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--15-30-04/TCP/harmless_TCP.xlsx b/softwares/gateway/results-05-19-2024--15-30-04/TCP/harmless_TCP.xlsx new file mode 100644 index 0000000..988f65e Binary files /dev/null and b/softwares/gateway/results-05-19-2024--15-30-04/TCP/harmless_TCP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--15-30-04/TCP/mixed_TCP.pkl b/softwares/gateway/results-05-19-2024--15-30-04/TCP/mixed_TCP.pkl new file mode 100644 index 0000000..83eaddc Binary files /dev/null and b/softwares/gateway/results-05-19-2024--15-30-04/TCP/mixed_TCP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--15-30-04/TCP/mixed_TCP.xlsx b/softwares/gateway/results-05-19-2024--15-30-04/TCP/mixed_TCP.xlsx new file mode 100644 index 0000000..6031b20 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--15-30-04/TCP/mixed_TCP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--15-30-04/TCP/suspicious_TCP.pkl b/softwares/gateway/results-05-19-2024--15-30-04/TCP/suspicious_TCP.pkl new file mode 100644 index 0000000..1317e35 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--15-30-04/TCP/suspicious_TCP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--15-30-04/TCP/suspicious_TCP.xlsx b/softwares/gateway/results-05-19-2024--15-30-04/TCP/suspicious_TCP.xlsx new file mode 100644 index 0000000..7d84377 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--15-30-04/TCP/suspicious_TCP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--15-30-04/UDP/harmless_UDP.pkl b/softwares/gateway/results-05-19-2024--15-30-04/UDP/harmless_UDP.pkl new file mode 100644 index 0000000..da73970 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--15-30-04/UDP/harmless_UDP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--15-30-04/UDP/harmless_UDP.xlsx b/softwares/gateway/results-05-19-2024--15-30-04/UDP/harmless_UDP.xlsx new file mode 100644 index 0000000..4e5d061 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--15-30-04/UDP/harmless_UDP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--15-30-04/UDP/suspicious_UDP.pkl b/softwares/gateway/results-05-19-2024--15-30-04/UDP/suspicious_UDP.pkl new file mode 100644 index 0000000..071da5c Binary files /dev/null and b/softwares/gateway/results-05-19-2024--15-30-04/UDP/suspicious_UDP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--15-30-04/UDP/suspicious_UDP.xlsx b/softwares/gateway/results-05-19-2024--15-30-04/UDP/suspicious_UDP.xlsx new file mode 100644 index 0000000..4fb9c58 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--15-30-04/UDP/suspicious_UDP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/TCP/harmful_TCP.pkl b/softwares/gateway/results-05-19-2024--20-13-51/TCP/harmful_TCP.pkl new file mode 100644 index 0000000..5f64124 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/TCP/harmful_TCP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/TCP/harmful_TCP.xlsx b/softwares/gateway/results-05-19-2024--20-13-51/TCP/harmful_TCP.xlsx new file mode 100644 index 0000000..854809f Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/TCP/harmful_TCP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/TCP/harmless_TCP.pkl b/softwares/gateway/results-05-19-2024--20-13-51/TCP/harmless_TCP.pkl new file mode 100644 index 0000000..1e0c48a Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/TCP/harmless_TCP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/TCP/harmless_TCP.xlsx b/softwares/gateway/results-05-19-2024--20-13-51/TCP/harmless_TCP.xlsx new file mode 100644 index 0000000..de2965f Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/TCP/harmless_TCP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/TCP/mixed_TCP.pkl b/softwares/gateway/results-05-19-2024--20-13-51/TCP/mixed_TCP.pkl new file mode 100644 index 0000000..53d89db Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/TCP/mixed_TCP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/TCP/mixed_TCP.xlsx b/softwares/gateway/results-05-19-2024--20-13-51/TCP/mixed_TCP.xlsx new file mode 100644 index 0000000..6edd2e2 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/TCP/mixed_TCP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/TCP/suspicious_TCP.pkl b/softwares/gateway/results-05-19-2024--20-13-51/TCP/suspicious_TCP.pkl new file mode 100644 index 0000000..5bea782 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/TCP/suspicious_TCP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/TCP/suspicious_TCP.xlsx b/softwares/gateway/results-05-19-2024--20-13-51/TCP/suspicious_TCP.xlsx new file mode 100644 index 0000000..7ce4356 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/TCP/suspicious_TCP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/UDP/harmful_UDP.pkl b/softwares/gateway/results-05-19-2024--20-13-51/UDP/harmful_UDP.pkl new file mode 100644 index 0000000..c6589fe Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/UDP/harmful_UDP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/UDP/harmful_UDP.xlsx b/softwares/gateway/results-05-19-2024--20-13-51/UDP/harmful_UDP.xlsx new file mode 100644 index 0000000..9b17289 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/UDP/harmful_UDP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/UDP/harmless_UDP.pkl b/softwares/gateway/results-05-19-2024--20-13-51/UDP/harmless_UDP.pkl new file mode 100644 index 0000000..5d83fdd Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/UDP/harmless_UDP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/UDP/harmless_UDP.xlsx b/softwares/gateway/results-05-19-2024--20-13-51/UDP/harmless_UDP.xlsx new file mode 100644 index 0000000..1e2c6fd Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/UDP/harmless_UDP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/UDP/mixed_UDP.pkl b/softwares/gateway/results-05-19-2024--20-13-51/UDP/mixed_UDP.pkl new file mode 100644 index 0000000..655693a Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/UDP/mixed_UDP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/UDP/mixed_UDP.xlsx b/softwares/gateway/results-05-19-2024--20-13-51/UDP/mixed_UDP.xlsx new file mode 100644 index 0000000..b7127aa Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/UDP/mixed_UDP.xlsx differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/UDP/suspicious_UDP.pkl b/softwares/gateway/results-05-19-2024--20-13-51/UDP/suspicious_UDP.pkl new file mode 100644 index 0000000..349ffd1 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/UDP/suspicious_UDP.pkl differ diff --git a/softwares/gateway/results-05-19-2024--20-13-51/UDP/suspicious_UDP.xlsx b/softwares/gateway/results-05-19-2024--20-13-51/UDP/suspicious_UDP.xlsx new file mode 100644 index 0000000..3309284 Binary files /dev/null and b/softwares/gateway/results-05-19-2024--20-13-51/UDP/suspicious_UDP.xlsx differ diff --git a/softwares/unified-controller/.gitignore b/softwares/unified-controller/.gitignore index 4ce66a1..44801ba 100644 --- a/softwares/unified-controller/.gitignore +++ b/softwares/unified-controller/.gitignore @@ -1,2 +1,3 @@ # executable files. -unified-controller \ No newline at end of file +unified-controller +unified-controller-dummy \ No newline at end of file diff --git a/softwares/unified-controller/Makefile b/softwares/unified-controller/Makefile index 728aa52..8e01b88 100644 --- a/softwares/unified-controller/Makefile +++ b/softwares/unified-controller/Makefile @@ -9,6 +9,11 @@ LDFLAGS = -lpcap -pthread unified-controller: g++ -o unified-controller unified-controller.cpp $(IMPORTED) $(CFLAGS) $(LDFLAGS) +# unified-controller-dummy just receives packet and forwards it to to eth out +.PHONY: unified-controller-dummy +unified-controller-dummy: + g++ -o unified-controller-dummy unified-controller-dummy.cpp $(IMPORTED) $(CFLAGS) $(LDFLAGS) + .PHONY: clean clean: rm unified-controller diff --git a/softwares/unified-controller/unified-controller-dummy.cpp b/softwares/unified-controller/unified-controller-dummy.cpp new file mode 100644 index 0000000..88a73fb --- /dev/null +++ b/softwares/unified-controller/unified-controller-dummy.cpp @@ -0,0 +1,345 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../dma-proxy/Common/dma-proxy.h" +#include "../gateway/pcap-utils.h" + +/* The user must tune the application number of channels to match the proxy driver device tree + * and the names of each channel must match the dma-names in the device tree for the proxy + * driver node. The number of channels can be less than the number of names as the other + * channels will just not be used in testing. + */ +#define TX_CHANNEL_COUNT 1 +#define RX_CHANNEL_COUNT 2 + +#define MAX_PKT_SIZE 64 // KB + +const char *tx_channel_names[] = { "dma_proxy_tx_0", /* add unique channel names here */ }; +const char *rx_channel_names[] = { "dma_proxy_rx_0", "dma_proxy_rx_1",/* add unique channel names here */ }; + +/* Internal data which should work without tuning */ + +struct channel { + struct channel_buffer *buf_ptr; + int fd; + pthread_t tid; +}; + +static int verify; +static int test_size = MAX_PKT_SIZE * 1024; +static volatile int stop = 0; +int num_transfers; + +struct channel tx_channels[TX_CHANNEL_COUNT], rx_channels[RX_CHANNEL_COUNT]; + +pcap_t *sniffer_handle; +struct bpf_program s_fp; + +pcap_t *inject_snort_handle; + +pcap_t *inject_egress_handle; + +/*******************************************************************************************************************/ +/* Handle a control C or kill, maybe the actual signal number coming in has to be more filtered? + * The stop should cause a graceful shutdown of all the transfers so that the application can + * be started again afterwards. + */ +void sigint(int a) +{ + stop = 1; +} + +/*******************************************************************************************************************/ +/* Get the clock time in usecs to allow performance testing + */ +static uint64_t get_posix_clock_time_usec () +{ + struct timespec ts; + + if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0) + return (uint64_t) (ts.tv_sec * 1000000 + ts.tv_nsec / 1000); + else + return 0; +} + +/*******************************************************************************************************************/ +/* + * The following function is the transmit thread to allow the transmit and the receive channels to be + * operating simultaneously. Some of the ioctl calls are blocking so that multiple threads are required. + */ +void tx_thread(struct channel *channel_ptr) +{ + int i, counter = 0, buffer_id=0, in_progress_count = 0; + int stop_in_progress = 0; + + // Start all buffers being sent + + while(!stop){ + + if (stop & !stop_in_progress) { + stop_in_progress = 1; + num_transfers = counter + RX_BUFFER_COUNT; + } + + + // wait for packet to come in + + struct pcap_pkthdr *header; + const u_char *packet; + while(!stop){ + int status = pcap_next_ex(sniffer_handle, &header, &packet); + if (status == 1){ + //printf("pktlen:%d, pktcaplen:%d\n", header->len, header->caplen); + channel_ptr->buf_ptr[buffer_id].length = test_size; + break; + } + if (status == 0){ + // printf("timeout\n"); + continue; + } + if (status == -1){ + //fprintf(stderr, "Error reading the packets: %s\n", pcap_geterr(sniffer_handle)); + continue; + } + } + + parsed_packet parsed_packet = parse_packet(packet); + int l4_size; + if (parsed_packet.tcp != nullptr) { + l4_size = parsed_packet.size_tcp; + } else { + l4_size = parsed_packet.size_udp; + } + int packet_size = SIZE_ETHERNET + parsed_packet.size_ip + l4_size + parsed_packet.size_payload; + int status = pcap_inject(inject_egress_handle, packet, packet_size); + if (status == -1){ + fprintf(stderr, "Error sending packet to egress: %s\n", pcap_geterr(inject_egress_handle)); + } + + if (channel_ptr->buf_ptr[buffer_id].status != channel_buffer::proxy_status::PROXY_NO_ERROR){ + printf("Proxy tx transfer error: error_id=%d\n", channel_ptr->buf_ptr[buffer_id].status); + } + } +} + +// to snort +void rx_thread_0(struct channel *channel_ptr) +{ + int in_progress_count = 0, buffer_id = 0; + int rx_counter = 0; + int status; + parsed_packet parsed_packet; + int packet_size; + int sleep_time_ms = 50; + + while(!stop){ + memset(channel_ptr->buf_ptr[buffer_id].buffer, 0, test_size); + channel_ptr->buf_ptr[buffer_id].length = test_size; + ioctl(channel_ptr->fd, START_XFER, &buffer_id); + + while(!stop){ + ioctl(channel_ptr->fd, FINISH_XFER, &buffer_id); + if (channel_ptr->buf_ptr[buffer_id].status == channel_buffer::proxy_status::PROXY_NO_ERROR) { + break; + } + else { + if (channel_ptr->buf_ptr[buffer_id].status == channel_buffer::proxy_status::PROXY_TIMEOUT){ + // printf("timeout\n"); + std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time_ms)); + continue; + } + //printf("Proxy rx transfer error, # transfers %d, # completed %d, # in progress %d\n", + // num_transfers, rx_counter, in_progress_count); + // exit(1); + return; + } + } + + + // send to snort (handle error status) + // get size of packet by parsing + parsed_packet = parse_packet((const u_char *)channel_ptr->buf_ptr[buffer_id].buffer); + packet_size = SIZE_ETHERNET + parsed_packet.size_ip + parsed_packet.size_tcp + parsed_packet.size_payload; + //printf("size_ip = %d, size_tcp = %d, size_payload = %d, total = %d\n", parsed_packet.size_ip, parsed_packet.size_tcp, parsed_packet.size_payload, + // packet_size); + print_payload((const u_char *)channel_ptr->buf_ptr[buffer_id].buffer, 100); + status = pcap_inject(inject_snort_handle, channel_ptr->buf_ptr[buffer_id].buffer, packet_size); + if (status == -1){ + //fprintf(stderr, "Error sending packet to snort: %s\n", pcap_geterr(inject_snort_handle)); + } + + buffer_id += BUFFER_INCREMENT; + buffer_id %= RX_BUFFER_COUNT; + } +} + +// to egress +void rx_thread_1(struct channel *channel_ptr) +{ + int in_progress_count = 0, buffer_id = 0; + int rx_counter = 0; + int status; + parsed_packet parsed_packet; + int packet_size; + + while(!stop){ + memset(channel_ptr->buf_ptr[buffer_id].buffer, 0, test_size); + channel_ptr->buf_ptr[buffer_id].length = test_size; + ioctl(channel_ptr->fd, START_XFER, &buffer_id); + + while(!stop){ + ioctl(channel_ptr->fd, FINISH_XFER, &buffer_id); + if (channel_ptr->buf_ptr[buffer_id].status == channel_buffer::proxy_status::PROXY_NO_ERROR) { + break; + } + else { + if (channel_ptr->buf_ptr[buffer_id].status == channel_buffer::proxy_status::PROXY_TIMEOUT){ + // printf("timeout\n"); + continue; + } + //printf("Proxy rx transfer error, # transfers %d, # completed %d, # in progress %d\n", + // num_transfers, rx_counter, in_progress_count); + } + } + + // send to egress (handle error status) + // get size of packet by parsing + parsed_packet = parse_packet((const u_char *)channel_ptr->buf_ptr[buffer_id].buffer); + packet_size = SIZE_ETHERNET + parsed_packet.size_ip + parsed_packet.size_tcp + parsed_packet.size_payload; + status = pcap_inject(inject_egress_handle, channel_ptr->buf_ptr[buffer_id].buffer, packet_size); + if (status == -1){ + //fprintf(stderr, "Error sending packet to egress: %s\n", pcap_geterr(inject_egress_handle)); + } + + buffer_id += BUFFER_INCREMENT; + buffer_id %= RX_BUFFER_COUNT; + } +} + + +/*******************************************************************************************************************/ +/* + * Setup the transmit and receive threads so that the transmit thread is low priority to help prevent it from + * overrunning the receive since most testing is done without any backpressure to the transmit channel. + */ +void setup_threads() +{ + pthread_attr_t tattr_tx; + int newprio = 20, i; + struct sched_param param; + + /* The transmit thread should be lower priority than the receive + * Get the default attributes and scheduling param + */ + pthread_attr_init (&tattr_tx); + pthread_attr_getschedparam (&tattr_tx, ¶m); + + /* Set the transmit priority to the lowest + */ + param.sched_priority = newprio; + pthread_attr_setschedparam (&tattr_tx, ¶m); + + pthread_create(&tx_channels[0].tid, &tattr_tx, (void* (*)(void*))tx_thread, (void *)&tx_channels[0]); +} + +/*******************************************************************************************************************/ +/* + * The main program starts the transmit thread and then does the receive processing to do a number of DMA transfers. + */ +int main(int argc, char *argv[]) +{ + int i; + uint64_t start_time, end_time, time_diff; + int mb_sec; + int buffer_id = 0; + int max_channel_count = TX_CHANNEL_COUNT; + + printf("DMA proxy test\n"); + + signal(SIGINT, sigint); + + if (argc != 4) { + printf("Usage: dma-proxy-test \n"); + exit(EXIT_FAILURE); + } + + char *s_dev, *i_dev, *e_dev; + s_dev = argv[1]; + i_dev = argv[2]; + e_dev = argv[3]; + +// initiate pcaps + // sniffer + sniffer_handle = initiate_sniff_pcap(&s_fp, s_dev, ""); + if (sniffer_handle == NULL) { + printf("Can't initiate sniff pcap\n"); + exit(EXIT_FAILURE); + } + + // snort + inject_snort_handle = initiate_inject_pcap(i_dev); + if (inject_snort_handle == NULL) { + printf("Can't initiate inject-snort pcap\n"); + exit(EXIT_FAILURE); + } + + // egress + inject_egress_handle = initiate_inject_pcap(e_dev); + if (inject_egress_handle == NULL) { + printf("Can't initiate inject-egress pcap\n"); + exit(EXIT_FAILURE); + } + + /* Open the file descriptors for each tx channel and map the kernel driver memory into user space */ + + for (i = 0; i < TX_CHANNEL_COUNT; i++) { + char channel_name[64] = "/dev/"; + strcat(channel_name, tx_channel_names[i]); + tx_channels[i].fd = open(channel_name, O_RDWR); + if (tx_channels[i].fd < 1) { + printf("Unable to open DMA proxy device file: %s\r", channel_name); + exit(EXIT_FAILURE); + } + tx_channels[i].buf_ptr = (struct channel_buffer *)mmap(NULL, sizeof(struct channel_buffer) * TX_BUFFER_COUNT, + PROT_READ | PROT_WRITE, MAP_SHARED, tx_channels[i].fd, 0); + if (tx_channels[i].buf_ptr == MAP_FAILED) { + printf("Failed to mmap tx channel\n"); + exit(EXIT_FAILURE); + } + } + + /* Open the file descriptors for each rx channel and map the kernel driver memory into user space */ + + /* Grab the start time to calculate performance then start the threads & transfers on all channels */ + + setup_threads(); + + for (i = 0; i < TX_CHANNEL_COUNT; i++) { + pthread_join(tx_channels[i].tid, NULL); + munmap(tx_channels[i].buf_ptr, sizeof(struct channel_buffer)); + close(tx_channels[i].fd); + } + + printf("DMA proxy test complete\n"); + + return 0; +} \ No newline at end of file diff --git a/softwares/unified-controller/unified-controller.cpp b/softwares/unified-controller/unified-controller.cpp index 005821f..8ab0422 100644 --- a/softwares/unified-controller/unified-controller.cpp +++ b/softwares/unified-controller/unified-controller.cpp @@ -1,45 +1,3 @@ -/** - * Copyright (C) 2021 Xilinx, Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may - * not use this file except in compliance with the License. A copy of the - * License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -/* DMA Proxy Test Application - * - * This application is intended to be used with the DMA Proxy device driver. It provides - * an example application showing how to use the device driver to do user space DMA - * operations. - * - * The driver allocates coherent memory which is non-cached in a s/w coherent system - * or cached in a h/w coherent system. - * - * Transmit and receive buffers in that memory are mapped to user space such that the - * application can send and receive data using DMA channels (transmit and receive). - * - * It has been tested with AXI DMA and AXI MCDMA systems with transmit looped back to - * receive. Note that the receive channel of the AXI DMA throttles the transmit with - * a loopback while this is not the case with AXI MCDMA. - * - * Build information: The pthread library is required for linking. Compiler optimization - * makes a very big difference in performance with -O3 being good performance and - * -O0 being very low performance. - * - * The user should tune the number of channels and channel names to match the device - * tree. - * - * More complete documentation is contained in the device driver (dma-proxy.c). - */ - #include #include #include @@ -65,15 +23,13 @@ #include "../dma-proxy/Common/dma-proxy.h" #include "../gateway/pcap-utils.h" -/* The user must tune the application number of channels to match the proxy driver device tree - * and the names of each channel must match the dma-names in the device tree for the proxy - * driver node. The number of channels can be less than the number of names as the other - * channels will just not be used in testing. - */ +// DEBUG=1 WILL PRINT DEBUG LOG ELSE NOT +#define DEBUG 0 + #define TX_CHANNEL_COUNT 1 #define RX_CHANNEL_COUNT 2 -#define MAX_PKT_SIZE 64 // KB +#define MTU 2048 // 1500 but prefer much larger that frame size const char *tx_channel_names[] = { "dma_proxy_tx_0", /* add unique channel names here */ }; const char *rx_channel_names[] = { "dma_proxy_rx_0", "dma_proxy_rx_1",/* add unique channel names here */ }; @@ -87,7 +43,6 @@ struct channel { }; static int verify; -static int test_size = MAX_PKT_SIZE * 1024; static volatile int stop = 0; int num_transfers; @@ -101,7 +56,8 @@ pcap_t *inject_snort_handle; pcap_t *inject_egress_handle; /*******************************************************************************************************************/ -/* Handle a control C or kill, maybe the actual signal number coming in has to be more filtered? +#if DEBUG==1 +#endif/* Handle a control C or kill, maybe the actual signal number coming in has to be more filtered? * The stop should cause a graceful shutdown of all the transfers so that the application can * be started again afterwards. */ @@ -123,7 +79,6 @@ static uint64_t get_posix_clock_time_usec () return 0; } -/*******************************************************************************************************************/ /* * The following function is the transmit thread to allow the transmit and the receive channels to be * operating simultaneously. Some of the ioctl calls are blocking so that multiple threads are required. @@ -132,6 +87,8 @@ void tx_thread(struct channel *channel_ptr) { int i, counter = 0, buffer_id=0, in_progress_count = 0; int stop_in_progress = 0; + int sleep_time_ms = 1; + int check_packet = 0, status = 0; // Start all buffers being sent @@ -142,9 +99,6 @@ void tx_thread(struct channel *channel_ptr) num_transfers = counter + RX_BUFFER_COUNT; } - - // wait for packet to come in - struct pcap_pkthdr *header; const u_char *packet; while(!stop){ @@ -152,29 +106,51 @@ void tx_thread(struct channel *channel_ptr) if (status == 1){ // copy to buffer // printf("packet received\n"); - memset(channel_ptr->buf_ptr[buffer_id].buffer, 0, test_size); + check_packet = parse_packet_for_length(packet); + if (check_packet == -1){ + continue; + } + if (check_packet == -2) { + status = pcap_inject(inject_snort_handle, channel_ptr->buf_ptr[buffer_id].buffer, header->len); + if (status == -1){ + fprintf(stderr, "Error sending packet to snort: %s\n", pcap_geterr(inject_snort_handle)); + } + continue; + } memcpy(channel_ptr->buf_ptr[buffer_id].buffer, packet, header->len); +#if DEBUG==1 printf("pktlen:%d, pktcaplen:%d\n", header->len, header->caplen); - channel_ptr->buf_ptr[buffer_id].length = test_size; +#endif + channel_ptr->buf_ptr[buffer_id].length = header->len; break; } if (status == 0){ - // printf("timeout\n"); - continue; + // timeout just repeat } if (status == -1){ +#if DEBUG==1 fprintf(stderr, "Error reading the packets: %s\n", pcap_geterr(sniffer_handle)); +#endif continue; } } - ioctl(channel_ptr->fd, XFER, &buffer_id); + ioctl(channel_ptr->fd, START_XFER, &buffer_id); - if (channel_ptr->buf_ptr[buffer_id].status != channel_buffer::proxy_status::PROXY_NO_ERROR){ - printf("Proxy tx transfer error: error_id=%d\n", channel_ptr->buf_ptr[buffer_id].status); + while (!stop) { + ioctl(channel_ptr->fd, FINISH_XFER, &buffer_id); + if (channel_ptr->buf_ptr[buffer_id].status == channel_buffer::proxy_status::PROXY_NO_ERROR) { + break; + } + if (channel_ptr->buf_ptr[buffer_id].status == channel_buffer::proxy_status::PROXY_ERROR){ +#if DEBUG==1 + printf("Proxy tx transfer error: error_id=%d\n", channel_ptr->buf_ptr[buffer_id].status); +#endif + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time_ms)); } - buffer_id += BUFFER_INCREMENT; buffer_id %= TX_BUFFER_COUNT; } @@ -186,45 +162,50 @@ void rx_thread_0(struct channel *channel_ptr) int in_progress_count = 0, buffer_id = 0; int rx_counter = 0; int status; - parsed_packet parsed_packet; + parsed_packet parsed_packet = get_empty_packet(); int packet_size; - int sleep_time_ms = 50; + int sleep_time_ms = 3; while(!stop){ - memset(channel_ptr->buf_ptr[buffer_id].buffer, 0, test_size); - channel_ptr->buf_ptr[buffer_id].length = test_size; + channel_ptr->buf_ptr[buffer_id].length = MTU; ioctl(channel_ptr->fd, START_XFER, &buffer_id); + + int parse_success = 0; while(!stop){ ioctl(channel_ptr->fd, FINISH_XFER, &buffer_id); if (channel_ptr->buf_ptr[buffer_id].status == channel_buffer::proxy_status::PROXY_NO_ERROR) { + parse_success = 1; break; } - else { - if (channel_ptr->buf_ptr[buffer_id].status == channel_buffer::proxy_status::PROXY_TIMEOUT){ - // printf("timeout\n"); - std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time_ms)); - continue; - } - printf("Proxy rx transfer error, # transfers %d, # completed %d, # in progress %d\n", - num_transfers, rx_counter, in_progress_count); - // exit(1); - return; + if (channel_ptr->buf_ptr[buffer_id].status == channel_buffer::proxy_status::PROXY_ERROR){ +#if DEBUG==1 + printf("Rx thread 0 transfer error\n"); +#endif + break; } } + if (!parse_success) continue; - // send to snort (handle error status) - // get size of packet by parsing - parsed_packet = parse_packet((const u_char *)channel_ptr->buf_ptr[buffer_id].buffer); - packet_size = SIZE_ETHERNET + parsed_packet.size_ip + parsed_packet.size_tcp + parsed_packet.size_payload; - printf("size_ip = %d, size_tcp = %d, size_payload = %d, total = %d\n", parsed_packet.size_ip, parsed_packet.size_tcp, parsed_packet.size_payload, - packet_size); + packet_size = parse_packet_for_length((const u_char *)channel_ptr->buf_ptr[buffer_id].buffer); + if (packet_size < 0) { + // failed to parse packet + printf("rx0 error: packet size = %d\n", packet_size); + continue; + } + +#if DEBUG==1 + printf("size_ip = %d, size_tcp = %d, size_payload = %d, total = %d\n", parsed_packet.size_ip, parsed_packet.size_tcp, parsed_packet.size_payload, packet_size); print_payload((const u_char *)channel_ptr->buf_ptr[buffer_id].buffer, 100); +#endif status = pcap_inject(inject_snort_handle, channel_ptr->buf_ptr[buffer_id].buffer, packet_size); +#if DEBUG==1 if (status == -1){ fprintf(stderr, "Error sending packet to snort: %s\n", pcap_geterr(inject_snort_handle)); } + printf("successfully sent packet size %d\n", parsed_packet.size_total); +#endif buffer_id += BUFFER_INCREMENT; buffer_id %= RX_BUFFER_COUNT; @@ -237,37 +218,58 @@ void rx_thread_1(struct channel *channel_ptr) int in_progress_count = 0, buffer_id = 0; int rx_counter = 0; int status; - parsed_packet parsed_packet; + parsed_packet parsed_packet = get_empty_packet(); int packet_size; + int sleep_time_ms = 1; while(!stop){ - memset(channel_ptr->buf_ptr[buffer_id].buffer, 0, test_size); - channel_ptr->buf_ptr[buffer_id].length = test_size; + channel_ptr->buf_ptr[buffer_id].length = MTU; ioctl(channel_ptr->fd, START_XFER, &buffer_id); + + int parse_success = 0; while(!stop){ ioctl(channel_ptr->fd, FINISH_XFER, &buffer_id); if (channel_ptr->buf_ptr[buffer_id].status == channel_buffer::proxy_status::PROXY_NO_ERROR) { + parse_success = 1; + break; + } + if (channel_ptr->buf_ptr[buffer_id].status == channel_buffer::proxy_status::PROXY_ERROR){ +#if DEBUG==1 + printf("Rx thread 1 transfer error\n"); +#endif break; - } - else { - if (channel_ptr->buf_ptr[buffer_id].status == channel_buffer::proxy_status::PROXY_TIMEOUT){ - // printf("timeout\n"); - continue; - } - printf("Proxy rx transfer error, # transfers %d, # completed %d, # in progress %d\n", - num_transfers, rx_counter, in_progress_count); } +#if DEBUG==1 + printf("Rx thread 1 DMA busy\n"); +#endif + + std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time_ms)); } + if (!parse_success) continue; + // send to egress (handle error status) // get size of packet by parsing - parsed_packet = parse_packet((const u_char *)channel_ptr->buf_ptr[buffer_id].buffer); - packet_size = SIZE_ETHERNET + parsed_packet.size_ip + parsed_packet.size_tcp + parsed_packet.size_payload; + packet_size = parse_packet_for_length((const u_char *)channel_ptr->buf_ptr[buffer_id].buffer); + if (packet_size < 0) { +#if DEBUG==1 + printf("failed to parse packet: size=%d\n", packet_size); +#endif + continue; + } + +#if DEBUG==1 + printf("parsed packet total size %d\n", parsed_packet.size_total); +#endif + status = pcap_inject(inject_egress_handle, channel_ptr->buf_ptr[buffer_id].buffer, packet_size); +#if DEBUG==1 if (status == -1){ fprintf(stderr, "Error sending packet to egress: %s\n", pcap_geterr(inject_egress_handle)); } + printf("successfully sent packet size %d\n", parsed_packet.size_total); +#endif buffer_id += BUFFER_INCREMENT; buffer_id %= RX_BUFFER_COUNT; @@ -280,7 +282,7 @@ void rx_thread_1(struct channel *channel_ptr) * Setup the transmit and receive threads so that the transmit thread is low priority to help prevent it from * overrunning the receive since most testing is done without any backpressure to the transmit channel. */ -void setup_threads(int *num_transfers) +void setup_threads() { pthread_attr_t tattr_tx; int newprio = 20, i; @@ -319,8 +321,8 @@ int main(int argc, char *argv[]) signal(SIGINT, sigint); - if (argc != 5) { - printf("Usage: dma-proxy-test <# of DMA transfers to perform> \n"); + if (argc != 4) { + printf("Usage: dma-proxy-test \n"); exit(EXIT_FAILURE); } @@ -329,8 +331,6 @@ int main(int argc, char *argv[]) i_dev = argv[2]; e_dev = argv[3]; - num_transfers = atoi(argv[4]); - // initiate pcaps // sniffer sniffer_handle = initiate_sniff_pcap(&s_fp, s_dev, ""); @@ -392,25 +392,13 @@ int main(int argc, char *argv[]) /* Grab the start time to calculate performance then start the threads & transfers on all channels */ start_time = get_posix_clock_time_usec(); - setup_threads(&num_transfers); + setup_threads(); /* Do the minimum to know the transfers are done before getting the time for performance */ for (i = 0; i < RX_CHANNEL_COUNT; i++) pthread_join(rx_channels[i].tid, NULL); - /* Grab the end time and calculate the performance */ - - end_time = get_posix_clock_time_usec(); - time_diff = end_time - start_time; - mb_sec = ((1000000 / (double)time_diff) * (num_transfers * max_channel_count * (double)test_size)) / 1000000; - - printf("Time: %ld microseconds\n", time_diff); - printf("Transfer size: %lld KB\n", (long long)(num_transfers) * (test_size / 1024) * max_channel_count); - printf("Throughput: %d MB / sec \n", mb_sec); - - /* Clean up all the channels before leaving */ - for (i = 0; i < TX_CHANNEL_COUNT; i++) { pthread_join(tx_channels[i].tid, NULL); munmap(tx_channels[i].buf_ptr, sizeof(struct channel_buffer)); @@ -421,7 +409,7 @@ int main(int argc, char *argv[]) close(rx_channels[i].fd); } - printf("DMA proxy test complete\n"); + printf("unified controller shutted down.\nPlease reset DMA properly\n"); return 0; } \ No newline at end of file