📄 proc.c
字号:
struct wrap_ndis_device *wnd = (struct wrap_ndis_device *)data; char setting[MAX_PROC_STR_LEN], *p; unsigned int i; NTSTATUS res; if (count > MAX_PROC_STR_LEN) return -EINVAL; memset(setting, 0, sizeof(setting)); if (copy_from_user(setting, buf, count)) return -EFAULT; if ((p = strchr(setting, '\n'))) *p = 0; if ((p = strchr(setting, '='))) *p = 0; if (!strcmp(setting, "hangcheck_interval")) { if (!p) return -EINVAL; p++; i = simple_strtol(p, NULL, 10); hangcheck_del(wnd); if (i > 0) { wnd->hangcheck_interval = i * HZ; hangcheck_add(wnd); } } else if (!strcmp(setting, "suspend")) { if (!p) return -EINVAL; p++; i = simple_strtol(p, NULL, 10); if (i <= 0 || i > 3) return -EINVAL; if (wrap_is_pci_bus(wnd->wd->dev_bus)) i = wrap_pnp_suspend_pci_device(wnd->wd->pci.pdev, PMSG_SUSPEND); else#if defined(CONFIG_USB) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) i = wrap_pnp_suspend_usb_device(wnd->wd->usb.intf, PMSG_SUSPEND);#else i = -1;#endif if (i) return -EINVAL; } else if (!strcmp(setting, "resume")) { if (wrap_is_pci_bus(wnd->wd->dev_bus)) i = wrap_pnp_resume_pci_device(wnd->wd->pci.pdev); else#if defined(CONFIG_USB) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) i = wrap_pnp_resume_usb_device(wnd->wd->usb.intf);#else i = -1;#endif if (i) return -EINVAL; } else if (!strcmp(setting, "stats_enabled")) { if (!p) return -EINVAL; p++; i = simple_strtol(p, NULL, 10); if (i > 0) wnd->iw_stats_enabled = TRUE; else wnd->iw_stats_enabled = FALSE; } else if (!strcmp(setting, "packet_filter")) { if (!p) return -EINVAL; p++; i = simple_strtol(p, NULL, 10); res = mp_set_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, i); if (res) WARNING("setting packet_filter failed: %08X", res); } else if (!strcmp(setting, "reinit")) { if (ndis_reinit(wnd) != NDIS_STATUS_SUCCESS) return -EFAULT; } else { struct ndis_configuration_parameter param; struct unicode_string key; struct ansi_string ansi; if (!p) return -EINVAL; p++; RtlInitAnsiString(&ansi, p); if (RtlAnsiStringToUnicodeString(¶m.data.string, &ansi, TRUE) != STATUS_SUCCESS) EXIT1(return -EFAULT); param.type = NdisParameterString; RtlInitAnsiString(&ansi, setting); if (RtlAnsiStringToUnicodeString(&key, &ansi, TRUE) != STATUS_SUCCESS) { RtlFreeUnicodeString(¶m.data.string); EXIT1(return -EINVAL); } NdisWriteConfiguration(&res, wnd->nmb, &key, ¶m); RtlFreeUnicodeString(&key); RtlFreeUnicodeString(¶m.data.string); if (res != NDIS_STATUS_SUCCESS) return -EFAULT; } return count;}int wrap_procfs_add_ndis_device(struct wrap_ndis_device *wnd){ struct proc_dir_entry *procfs_entry; if (wrap_procfs_entry == NULL) return -ENOMEM; if (wnd->procfs_iface) { ERROR("%s already registered?", wnd->netdev_name); return -EINVAL; } wnd->procfs_iface = proc_mkdir(wnd->netdev_name, wrap_procfs_entry); if (wnd->procfs_iface == NULL) { ERROR("couldn't create proc directory"); return -ENOMEM; } wnd->procfs_iface->uid = proc_uid; wnd->procfs_iface->gid = proc_gid; procfs_entry = create_proc_entry("hw", S_IFREG | S_IRUSR | S_IRGRP, wnd->procfs_iface); if (procfs_entry == NULL) { ERROR("couldn't create proc entry for 'hw'"); goto err_hw; } else { procfs_entry->uid = proc_uid; procfs_entry->gid = proc_gid; procfs_entry->data = wnd; procfs_entry->read_proc = procfs_read_ndis_hw; } procfs_entry = create_proc_entry("stats", S_IFREG | S_IRUSR | S_IRGRP, wnd->procfs_iface); if (procfs_entry == NULL) { ERROR("couldn't create proc entry for 'stats'"); goto err_stats; } else { procfs_entry->uid = proc_uid; procfs_entry->gid = proc_gid; procfs_entry->data = wnd; procfs_entry->read_proc = procfs_read_ndis_stats; } procfs_entry = create_proc_entry("encr", S_IFREG | S_IRUSR | S_IRGRP, wnd->procfs_iface); if (procfs_entry == NULL) { ERROR("couldn't create proc entry for 'encr'"); goto err_encr; } else { procfs_entry->uid = proc_uid; procfs_entry->gid = proc_gid; procfs_entry->data = wnd; procfs_entry->read_proc = procfs_read_ndis_encr; } procfs_entry = create_proc_entry("settings", S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP, wnd->procfs_iface); if (procfs_entry == NULL) { ERROR("couldn't create proc entry for 'settings'"); goto err_settings; } else { procfs_entry->uid = proc_uid; procfs_entry->gid = proc_gid; procfs_entry->data = wnd; procfs_entry->read_proc = procfs_read_ndis_settings; procfs_entry->write_proc = procfs_write_ndis_settings; } return 0;err_settings: remove_proc_entry("encr", wnd->procfs_iface);err_encr: remove_proc_entry("stats", wnd->procfs_iface);err_stats: remove_proc_entry("hw", wnd->procfs_iface);err_hw: remove_proc_entry(wnd->netdev_name, wrap_procfs_entry); wnd->procfs_iface = NULL; return -ENOMEM;}void wrap_procfs_remove_ndis_device(struct wrap_ndis_device *wnd){ struct proc_dir_entry *procfs_iface = xchg(&wnd->procfs_iface, NULL); if (procfs_iface == NULL) return; remove_proc_entry("hw", procfs_iface); remove_proc_entry("stats", procfs_iface); remove_proc_entry("encr", procfs_iface); remove_proc_entry("settings", procfs_iface); if (wrap_procfs_entry) remove_proc_entry(wnd->netdev_name, wrap_procfs_entry);}static int procfs_read_debug(char *page, char **start, off_t off, int count, int *eof, void *data){ char *p = page; enum alloc_type type; if (off != 0) { *eof = 1; return 0; } p += sprintf(p, "%d\n", debug); type = 0;#ifdef ALLOC_DEBUG for (type = 0; type < ALLOC_TYPE_MAX; type++) p += sprintf(p, "total size of allocations in %d: %d\n", type, alloc_size(type));#endif return (p - page);}static int procfs_write_debug(struct file *file, const char *buf, unsigned long count, void *data){ int i; char setting[MAX_PROC_STR_LEN], *p; if (count > MAX_PROC_STR_LEN) return -EINVAL; memset(setting, 0, sizeof(setting)); if (copy_from_user(setting, buf, count)) return -EFAULT; if ((p = strchr(setting, '\n'))) *p = 0; if ((p = strchr(setting, '='))) *p = 0; i = simple_strtol(setting, NULL, 10); if (i >= 0 && i < 10) debug = i; else return -EINVAL; return count;}int wrap_procfs_init(void){ struct proc_dir_entry *procfs_entry; wrap_procfs_entry = proc_mkdir(DRIVER_NAME, proc_net_root); if (wrap_procfs_entry == NULL) { ERROR("couldn't create procfs directory"); return -ENOMEM; } wrap_procfs_entry->uid = proc_uid; wrap_procfs_entry->gid = proc_gid; procfs_entry = create_proc_entry("debug", S_IFREG | S_IRUSR | S_IRGRP, wrap_procfs_entry); if (procfs_entry == NULL) { ERROR("couldn't create proc entry for 'debug'"); return -ENOMEM; } else { procfs_entry->uid = proc_uid; procfs_entry->gid = proc_gid; procfs_entry->read_proc = procfs_read_debug; procfs_entry->write_proc = procfs_write_debug; } return 0;}void wrap_procfs_remove(void){ if (wrap_procfs_entry == NULL) return; remove_proc_entry("debug", wrap_procfs_entry); remove_proc_entry(DRIVER_NAME, proc_net_root);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -