#ifdef __KERNEL__ #include #include #include #include #include #include #include #include #include #include "../proc_api/proc_api.h" #include "obj_api.h" #define OBJ_DEV_MAJOR (220) #define OBJ_DEV_NAME ("isg_objs") #define VERSION ("obj0.0.0.2") #define SHM_MEM_SIZE (1024 * 1024) #define OBJ_DBG_DIR ("obj") typedef struct { struct class *dev_class; atomic_t ref_count; unsigned int mem_size; unsigned char *mem_buf; } OBJECT_DRV, *POBJECT_DRV; static OBJECT_DRV g_obj_device; static PCMHI_OBJECT g_obj_data[OBJ_TYPE_MAX] = {NULL, NULL, NULL}; static int server_obj_show(struct seq_file *seq, void *token) { PCMHI_OBJECT obj, tmp; PSERVER_OBJ_CONTENT req = NULL; seq_printf(seq, "Total server items: %u\n", HASH_COUNT(g_obj_data[OBJ_TYPE_SERVER])); seq_printf(seq, "API root direcotry: /proc/%s/\n", PROC_API_DIR_NAME); HASH_ITER(hh, g_obj_data[OBJ_TYPE_SERVER], obj, tmp) { seq_printf(seq, " Name: %s\n", obj->name); seq_printf(seq, " Type: %d\n", obj->type); seq_printf(seq, " RefCount: %d\n", atomic_read(&obj->ref_count)); list_for_each_entry(req, &obj->data->content, list) { seq_printf(seq, " Min Port: %d\n", req->min_port); seq_printf(seq, " Max Port: %d\n", req->max_port); seq_printf(seq, " Pro Port: %d\n", req->pro_type); } } #if 0 PPROC_INFO pInfo = NULL, tmp = NULL; int i = 0; seq_printf(seq, "Total API items: %u\n", HASH_COUNT(g_proc_items)); seq_printf(seq, "API root direcotry: /proc/%s/\n", PROC_API_DIR_NAME); seq_puts(seq, "-------------------------------------" "-------------------------------------\n"); seq_puts(seq, "| ID | Direcotry | Name | Show | IOCtrl | Help |\n"); seq_puts(seq, "|------------------------------------" "------------------------------------|\n"); read_lock(&g_proc_lock); HASH_ITER(hh, g_proc_items, pInfo, tmp) { seq_printf(seq, "| %03d | %14s | %14s | %1s | %1s | %1s |\n", i++, pInfo->dir_name ? pInfo->dir_name : "", pInfo->data->name, pInfo->data->show ? "*" : "-", pInfo->data->ioctl ? "*" : "-", pInfo->data->help ? "*" : "-"); } read_unlock(&g_proc_lock); #endif seq_puts(seq, "-------------------------------------" "-------------------------------------\n"); return 0; } static int server_obj_ioctl(struct seq_file *seq, void *token) { PDBGFS_PRIV priv = (PDBGFS_PRIV)(seq->private); seq_printf(seq, "Run Command [%s] with (%s)\n", priv->cmd, priv->cmd_data); return 0; } static int server_obj_help(struct seq_file *seq, void *token) { PDBGFS_PRIV priv = (PDBGFS_PRIV)(seq->private); seq_puts(seq, "==============Options Helps=============\n"); seq_printf(seq, "usage: echo \"\" > /proc/%s/%s/%s\n", PROC_API_DIR_NAME, OBJ_DBG_DIR, priv->name); return 0; } static DBGFS_PRIV g_DbgConfig[] = { { "server", 0, 0L, NULL, NULL, server_obj_show, server_obj_ioctl, server_obj_help }, }; static PROC_API g_object_dbg = { OBJ_DBG_DIR, g_DbgConfig, sizeof(g_DbgConfig) / sizeof(g_DbgConfig[0]), }; static int obj_proc_init(void) { if(proc_api_register(&g_object_dbg) != ERR_DBGFS_NO_ERROR) { printk(KERN_ERR "Regisetr %s Error\n", g_object_dbg.dir_name); return -EINVAL; } return 0; } static int obj_proc_uninit(void) { return proc_api_unregister(&g_object_dbg); } const char *obj_version(void) { return VERSION; } PCMHI_OBJECT new_object(void) { PCMHI_OBJECT obj = (PCMHI_OBJECT)kmalloc(sizeof(CMHI_OBJECT), GFP_KERNEL); if(obj == NULL) { printk(KERN_ERR "Malloc CMHI_OBJECT Error\n"); } else { memset(obj, 0, sizeof(CMHI_OBJECT)); rwlock_init(&obj->lock); atomic_set(&obj->ref_count, 0); } return obj; } void free_object(PCMHI_OBJECT pObj) { if(pObj) { kfree(pObj); } } void object_init(void) { PCMHI_OBJECT pObj = create_server_object("list1", OBJ_TYPE_SERVER); if(!pObj) { printk(KERN_ERR "%s(%d): Create Object Error\n", __FUNCTION__, __LINE__); return; } HASH_ADD_STR(g_obj_data[OBJ_TYPE_SERVER], name, pObj); if(add_server_obj_data(pObj, 10000, 20000, IPPROTO_IP) != 0) { printk(KERN_ERR "%s(%d): Add Server Object error\n", __FUNCTION__, __LINE__); return; } if(add_server_obj_data(pObj, 80, 80, IPPROTO_TCP) != 0) { printk(KERN_ERR "%s(%d): Add Server Object error\n", __FUNCTION__, __LINE__); return; } if(add_server_obj_data(pObj, 443, 443, IPPROTO_UDP) != 0) { printk(KERN_ERR "%s(%d): Add Server Object error\n", __FUNCTION__, __LINE__); return; } } void object_uninit(void) { PCMHI_OBJECT obj, tmp; HASH_ITER(hh, g_obj_data[OBJ_TYPE_SERVER], obj, tmp) { HASH_DEL(g_obj_data[OBJ_TYPE_SERVER], obj); cleanup_server_object(obj); } } static int obj_open(struct inode *inode, struct file *filp) { atomic_inc(&g_obj_device.ref_count); return 0; } static int obj_release(struct inode *inode, struct file *filp) { atomic_dec(&g_obj_device.ref_count); return 0; } int obj_mmap(struct file *fd, struct vm_area_struct *vma) { int ret = remap_pfn_range(vma, vma->vm_start, virt_to_phys(g_obj_device.mem_buf) >> PAGE_SHIFT, g_obj_device.mem_size, PAGE_SHARED); return ret; } static struct file_operations obj_fops = { .open = obj_open, .release = obj_release, .mmap = obj_mmap, }; static int object_module_init(void) { struct page *p = NULL; printk(KERN_INFO "Hello ISG objects manager version: %s\n", VERSION); memset(&g_obj_device, 0, sizeof(OBJECT_DRV)); atomic_set(&g_obj_device.ref_count, 0); g_obj_device.mem_size = PAGE_ALIGN(SHM_MEM_SIZE); g_obj_device.mem_buf = (unsigned char *)__get_free_pages(GFP_KERNEL, get_order(g_obj_device.mem_size)); if(g_obj_device.mem_buf == NULL) { printk(KERN_ERR "Malloc %d pages error\n", get_order(g_obj_device.mem_size)); return -ENOMEM; } for(p = virt_to_page(g_obj_device.mem_buf); p < virt_to_page(g_obj_device.mem_buf + g_obj_device.mem_size); p++) { SetPageReserved(virt_to_page(p)); } memset(g_obj_device.mem_buf, 0, g_obj_device.mem_size); register_chrdev(OBJ_DEV_MAJOR, OBJ_DEV_NAME, &obj_fops); g_obj_device.dev_class = class_create(THIS_MODULE, "obj"); device_create(g_obj_device.dev_class, NULL, MKDEV(OBJ_DEV_MAJOR, 0), NULL, "obj/dev%d", 0); /* if(proc_api_register(&g_ProcApi) != ERR_DBGFS_NO_ERROR) { printk(KERN_ERR "Regisetr %s Error\n", g_ProcApi.dir_name); } */ obj_proc_init(); object_init(); return 0; } module_init(object_module_init); static void __exit object_module_exit(void) { struct page *p = NULL; printk(KERN_INFO "Bye ISG objects manager version: %s\n", VERSION); object_uninit(); if(atomic_read(&g_obj_device.ref_count) != 0) { printk(KERN_ERR "Device used, please close it first.\n"); while(atomic_read(&g_obj_device.ref_count) != 0) { schedule(); } } obj_proc_uninit(); if(g_obj_device.mem_buf) { for(p = virt_to_page(g_obj_device.mem_buf); p < virt_to_page(g_obj_device.mem_buf + g_obj_device.mem_size); p++) { ClearPageReserved(virt_to_page(g_obj_device.mem_buf)); } free_pages((unsigned long)g_obj_device.mem_buf, get_order(g_obj_device.mem_size)); } device_destroy(g_obj_device.dev_class, MKDEV(OBJ_DEV_MAJOR, 0)); class_destroy(g_obj_device.dev_class); unregister_chrdev(OBJ_DEV_MAJOR, OBJ_DEV_NAME); // proc_api_unregister(&g_ProcApi); } module_exit(object_module_exit); MODULE_LICENSE("Dual BSD/GPL"); #endif // __KERNEL__