diff --git a/Linux Kernel Module/dma_net.c b/Linux Kernel Module/dma_net.c new file mode 100644 index 0000000..b39c016 --- /dev/null +++ b/Linux Kernel Module/dma_net.c @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPLv3"); +MODULE_AUTHOR("QuarkTree"); +MODULE_DESCRIPTION("Enhanced DMA/Network Module with Parameter Support"); + +#define DMA_BUF_SIZE 4096 + +static char *target_ip = "10.0.0.20"; +module_param(target_ip, charp, 0644); +MODULE_PARM_DESC(target_ip, "Target IP address (default: 10.0.0.20)"); + +static int target_port = 1234; +module_param(target_port, int, 0644); +MODULE_PARM_DESC(target_port, "Target port number (default: 1234)"); + +static bool use_dma = true; +module_param(use_dma, bool, 0644); +MODULE_PARM_DESC(use_dma, "Use DMA buffer (true/false, default: true)"); + +static void *data_buf; +static dma_addr_t dma_handle; +static struct socket *sock; + +static int __init dma_net_module_init(void) { + struct sockaddr_in sin; + int ret; + struct msghdr msg; + struct kvec iov; + __be32 ip_addr; + + if (target_port < 1 || target_port > 65535) { + printk(KERN_ERR "Invalid port number: %d\n", target_port); + return -EINVAL; + } + + ip_addr = in_aton(target_ip); + if (ip_addr == INADDR_NONE) { + printk(KERN_ERR "Invalid IP address: %s\n", target_ip); + return -EINVAL; + } + + if (use_dma) { + data_buf = dma_alloc_coherent(NULL, DMA_BUF_SIZE, &dma_handle, GFP_KERNEL); + printk(KERN_INFO "Allocated DMA buffer at %p (phys: %pad)\n", + data_buf, &dma_handle); + } else { + data_buf = kmalloc(DMA_BUF_SIZE, GFP_KERNEL); + printk(KERN_INFO "Allocated kernel buffer at %p\n", data_buf); + } + + if (!data_buf) { + printk(KERN_ERR "Failed to allocate buffer\n"); + return -ENOMEM; + } + + ret = sock_create_kern(&init_net, AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); + if (ret < 0) { + printk(KERN_ERR "Socket creation failed: %d\n", ret); + goto free_buffer; + } + + sock->flags |= O_NONBLOCK; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(target_port); + sin.sin_addr.s_addr = ip_addr; + + printk(KERN_INFO "Connecting to %s:%d...\n", target_ip, target_port); + + ret = sock->ops->connect(sock, (struct sockaddr *)&sin, sizeof(sin), 0); + if (ret != -EINPROGRESS && ret < 0) { + printk(KERN_ERR "Connect error: %d\n", ret); + goto close_sock; + } + + for (int i = 0; i < 10; i++) { + if (sock->sk->sk_state == TCP_ESTABLISHED) break; + msleep(100); + } + + if (sock->sk->sk_state != TCP_ESTABLISHED) { + printk(KERN_ERR "Connection timeout (state: %d)\n", + sock->sk->sk_state); + ret = -ETIMEDOUT; + goto close_sock; + } + + printk(KERN_INFO "Connected successfully to %s:%d\n", + target_ip, target_port); + + memset(data_buf, 0xAA, DMA_BUF_SIZE); + + memset(&msg, 0, sizeof(msg)); + iov.iov_base = data_buf; + iov.iov_len = DMA_BUF_SIZE; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + ret = sock_sendmsg(sock, &msg, DMA_BUF_SIZE); + if (ret < 0) { + printk(KERN_ERR "Send failed: %d (sent %d bytes)\n", ret, ret > 0 ? ret : 0); + goto close_sock; + } + + printk(KERN_INFO "Sent %d bytes to %s:%d\n", + ret, target_ip, target_port); + return 0; + +close_sock: + if (sock) { + sock_release(sock); + sock = NULL; + } +free_buffer: + if (data_buf) { + if (use_dma) { + dma_free_coherent(NULL, DMA_BUF_SIZE, data_buf, dma_handle); + printk(KERN_INFO "Freed DMA buffer\n"); + } else { + kfree(data_buf); + printk(KERN_INFO "Freed kernel buffer\n"); + } + data_buf = NULL; + } + return ret; +} + +static void __exit dma_net_module_exit(void) { + if (sock) { + sock_release(sock); + printk(KERN_INFO "Socket released\n"); + } + if (data_buf) { + if (use_dma) { + dma_free_coherent(NULL, DMA_BUF_SIZE, data_buf, dma_handle); + printk(KERN_INFO "Freed DMA buffer\n"); + } else { + kfree(data_buf); + printk(KERN_INFO "Freed kernel buffer\n"); + } + data_buf = NULL; + } + printk(KERN_INFO "Module unloaded\n"); +} + +module_init(dma_net_module_init); +module_exit(dma_net_module_exit);