📄 pktgen.c
字号:
static int proc_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data){ int i = 0, max, len; char name[16], valstr[32]; unsigned long value = 0; int idx = (int)(long)(data); struct pktgen_info* info = NULL; char* result = NULL; int tmp; if ((idx < 0) || (idx >= MAX_PKTGEN)) { printk("ERROR: idx: %i is out of range in proc_write\n", idx); return -EINVAL; } info = &(pginfos[idx]); result = &(info->result[0]); if (count < 1) { sprintf(result, "Wrong command format"); return -EINVAL; } max = count - i; tmp = count_trail_chars(&user_buffer[i], max); if (tmp < 0) return tmp; i += tmp; /* Read variable name */ len = strn_len(&user_buffer[i], sizeof(name) - 1); if (len < 0) return len; memset(name, 0, sizeof(name)); if (copy_from_user(name, &user_buffer[i], len)) return -EFAULT; i += len; max = count -i; len = count_trail_chars(&user_buffer[i], max); if (len < 0) return len; i += len; if (debug) printk("pg: %s,%lu\n", name, count); if (!strcmp(name, "stop")) { if (info->do_run_run) { strcpy(result, "Stopping"); } else { strcpy(result, "Already stopped...\n"); } info->do_run_run = 0; return count; } if (!strcmp(name, "pkt_size")) { len = num_arg(&user_buffer[i], 10, &value); if (len < 0) return len; i += len; if (value < 14+20+8) value = 14+20+8; info->pkt_size = value; sprintf(result, "OK: pkt_size=%u", info->pkt_size); return count; } if (!strcmp(name, "frags")) { len = num_arg(&user_buffer[i], 10, &value); if (len < 0) return len; i += len; info->nfrags = value; sprintf(result, "OK: frags=%u", info->nfrags); return count; } if (!strcmp(name, "ipg")) { len = num_arg(&user_buffer[i], 10, &value); if (len < 0) return len; i += len; info->ipg = value; sprintf(result, "OK: ipg=%u", info->ipg); return count; } if (!strcmp(name, "udp_src_min")) { len = num_arg(&user_buffer[i], 10, &value); if (len < 0) return len; i += len; info->udp_src_min = value; sprintf(result, "OK: udp_src_min=%u", info->udp_src_min); return count; } if (!strcmp(name, "udp_dst_min")) { len = num_arg(&user_buffer[i], 10, &value); if (len < 0) return len; i += len; info->udp_dst_min = value; sprintf(result, "OK: udp_dst_min=%u", info->udp_dst_min); return count; } if (!strcmp(name, "udp_src_max")) { len = num_arg(&user_buffer[i], 10, &value); if (len < 0) return len; i += len; info->udp_src_max = value; sprintf(result, "OK: udp_src_max=%u", info->udp_src_max); return count; } if (!strcmp(name, "udp_dst_max")) { len = num_arg(&user_buffer[i], 10, &value); if (len < 0) return len; i += len; info->udp_dst_max = value; sprintf(result, "OK: udp_dst_max=%u", info->udp_dst_max); return count; } if (!strcmp(name, "clone_skb")) { len = num_arg(&user_buffer[i], 10, &value); if (len < 0) return len; i += len; info->clone_skb = value; sprintf(result, "OK: clone_skb=%d", info->clone_skb); return count; } if (!strcmp(name, "count")) { len = num_arg(&user_buffer[i], 10, &value); if (len < 0) return len; i += len; info->count = value; sprintf(result, "OK: count=%llu", (unsigned long long) info->count); return count; } if (!strcmp(name, "src_mac_count")) { len = num_arg(&user_buffer[i], 10, &value); if (len < 0) return len; i += len; info->src_mac_count = value; sprintf(result, "OK: src_mac_count=%d", info->src_mac_count); return count; } if (!strcmp(name, "dst_mac_count")) { len = num_arg(&user_buffer[i], 10, &value); if (len < 0) return len; i += len; info->dst_mac_count = value; sprintf(result, "OK: dst_mac_count=%d", info->dst_mac_count); return count; } if (!strcmp(name, "odev")) { len = strn_len(&user_buffer[i], sizeof(info->outdev) - 1); if (len < 0) return len; memset(info->outdev, 0, sizeof(info->outdev)); if (copy_from_user(info->outdev, &user_buffer[i], len)) return -EFAULT; i += len; sprintf(result, "OK: odev=%s", info->outdev); return count; } if (!strcmp(name, "flag")) { char f[32]; len = strn_len(&user_buffer[i], sizeof(f) - 1); if (len < 0) return len; memset(f, 0, 32); if (copy_from_user(f, &user_buffer[i], len)) return -EFAULT; i += len; if (strcmp(f, "IPSRC_RND") == 0) { info->flags |= F_IPSRC_RND; } else if (strcmp(f, "!IPSRC_RND") == 0) { info->flags &= ~F_IPSRC_RND; } else if (strcmp(f, "IPDST_RND") == 0) { info->flags |= F_IPDST_RND; } else if (strcmp(f, "!IPDST_RND") == 0) { info->flags &= ~F_IPDST_RND; } else if (strcmp(f, "UDPSRC_RND") == 0) { info->flags |= F_UDPSRC_RND; } else if (strcmp(f, "!UDPSRC_RND") == 0) { info->flags &= ~F_UDPSRC_RND; } else if (strcmp(f, "UDPDST_RND") == 0) { info->flags |= F_UDPDST_RND; } else if (strcmp(f, "!UDPDST_RND") == 0) { info->flags &= ~F_UDPDST_RND; } else if (strcmp(f, "MACSRC_RND") == 0) { info->flags |= F_MACSRC_RND; } else if (strcmp(f, "!MACSRC_RND") == 0) { info->flags &= ~F_MACSRC_RND; } else if (strcmp(f, "MACDST_RND") == 0) { info->flags |= F_MACDST_RND; } else if (strcmp(f, "!MACDST_RND") == 0) { info->flags &= ~F_MACDST_RND; } else { sprintf(result, "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s", f, "IPSRC_RND, IPDST_RND, UDPSRC_RND, UDPDST_RND, MACSRC_RND, MACDST_RND\n"); return count; } sprintf(result, "OK: flags=0x%x", info->flags); return count; } if (!strcmp(name, "dst_min") || !strcmp(name, "dst")) { len = strn_len(&user_buffer[i], sizeof(info->dst_min) - 1); if (len < 0) return len; memset(info->dst_min, 0, sizeof(info->dst_min)); if (copy_from_user(info->dst_min, &user_buffer[i], len)) return -EFAULT; if(debug) printk("pg: dst_min set to: %s\n", info->dst_min); i += len; sprintf(result, "OK: dst_min=%s", info->dst_min); return count; } if (!strcmp(name, "dst_max")) { len = strn_len(&user_buffer[i], sizeof(info->dst_max) - 1); if (len < 0) return len; memset(info->dst_max, 0, sizeof(info->dst_max)); if (copy_from_user(info->dst_max, &user_buffer[i], len)) return -EFAULT; if(debug) printk("pg: dst_max set to: %s\n", info->dst_max); i += len; sprintf(result, "OK: dst_max=%s", info->dst_max); return count; } if (!strcmp(name, "src_min")) { len = strn_len(&user_buffer[i], sizeof(info->src_min) - 1); if (len < 0) return len; memset(info->src_min, 0, sizeof(info->src_min)); if (copy_from_user(info->src_min, &user_buffer[i], len)) return -EFAULT; if(debug) printk("pg: src_min set to: %s\n", info->src_min); i += len; sprintf(result, "OK: src_min=%s", info->src_min); return count; } if (!strcmp(name, "src_max")) { len = strn_len(&user_buffer[i], sizeof(info->src_max) - 1); if (len < 0) return len; memset(info->src_max, 0, sizeof(info->src_max)); if (copy_from_user(info->src_max, &user_buffer[i], len)) return -EFAULT; if(debug) printk("pg: src_max set to: %s\n", info->src_max); i += len; sprintf(result, "OK: src_max=%s", info->src_max); return count; } if (!strcmp(name, "dstmac")) { char *v = valstr; unsigned char *m = info->dst_mac; len = strn_len(&user_buffer[i], sizeof(valstr) - 1); if (len < 0) return len; memset(valstr, 0, sizeof(valstr)); if (copy_from_user(valstr, &user_buffer[i], len)) return -EFAULT; i += len; for(*m = 0;*v && m < info->dst_mac + 6; v++) { if (*v >= '0' && *v <= '9') { *m *= 16; *m += *v - '0'; } if (*v >= 'A' && *v <= 'F') { *m *= 16; *m += *v - 'A' + 10; } if (*v >= 'a' && *v <= 'f') { *m *= 16; *m += *v - 'a' + 10; } if (*v == ':') { m++; *m = 0; } } sprintf(result, "OK: dstmac"); return count; } if (!strcmp(name, "srcmac")) { char *v = valstr; unsigned char *m = info->src_mac; len = strn_len(&user_buffer[i], sizeof(valstr) - 1); if (len < 0) return len; memset(valstr, 0, sizeof(valstr)); if (copy_from_user(valstr, &user_buffer[i], len)) return -EFAULT; i += len; for(*m = 0;*v && m < info->src_mac + 6; v++) { if (*v >= '0' && *v <= '9') { *m *= 16; *m += *v - '0'; } if (*v >= 'A' && *v <= 'F') { *m *= 16; *m += *v - 'A' + 10; } if (*v >= 'a' && *v <= 'f') { *m *= 16; *m += *v - 'a' + 10; } if (*v == ':') { m++; *m = 0; } } sprintf(result, "OK: srcmac"); return count; } if (!strcmp(name, "inject") || !strcmp(name, "start")) { if (info->busy) { strcpy(info->result, "Already running...\n"); } else { info->busy = 1; strcpy(info->result, "Starting"); inject(info); info->busy = 0; } return count; } sprintf(info->result, "No such parameter \"%s\"", name); return -EINVAL;}static int create_proc_dir(void){ int len; /* does proc_dir already exists */ len = strlen(PG_PROC_DIR); for (proc_dir = proc_net->subdir; proc_dir; proc_dir=proc_dir->next) { if ((proc_dir->namelen == len) && (! memcmp(proc_dir->name, PG_PROC_DIR, len))) break; } if (!proc_dir) proc_dir = create_proc_entry(PG_PROC_DIR, S_IFDIR, proc_net); if (!proc_dir) return -ENODEV; return 1;}static int remove_proc_dir(void){ remove_proc_entry(PG_PROC_DIR, proc_net); return 1;}static int __init init(void){ int i; printk(version); cycles_calibrate(); if (cpu_speed == 0) { printk("pktgen: Error: your machine does not have working cycle counter.\n"); return -EINVAL; } create_proc_dir(); for (i = 0; i<MAX_PKTGEN; i++) { memset(&(pginfos[i]), 0, sizeof(pginfos[i])); pginfos[i].pkt_size = ETH_ZLEN; pginfos[i].nfrags = 0; pginfos[i].clone_skb = clone_skb_d; pginfos[i].ipg = ipg_d; pginfos[i].count = count_d; pginfos[i].sofar = 0; pginfos[i].hh[12] = 0x08; /* fill in protocol. Rest is filled in later. */ pginfos[i].hh[13] = 0x00; pginfos[i].udp_src_min = 9; /* sink NULL */ pginfos[i].udp_src_max = 9; pginfos[i].udp_dst_min = 9; pginfos[i].udp_dst_max = 9; sprintf(pginfos[i].fname, "net/%s/pg%i", PG_PROC_DIR, i); pginfos[i].proc_ent = create_proc_entry(pginfos[i].fname, 0600, NULL); if (!pginfos[i].proc_ent) { printk("pktgen: Error: cannot create net/%s/pg procfs entry.\n", PG_PROC_DIR); goto cleanup_mem; } pginfos[i].proc_ent->read_proc = proc_read; pginfos[i].proc_ent->write_proc = proc_write; pginfos[i].proc_ent->data = (void*)(long)(i); pginfos[i].proc_ent->owner = THIS_MODULE; sprintf(pginfos[i].busy_fname, "net/%s/pg_busy%i", PG_PROC_DIR, i); pginfos[i].busy_proc_ent = create_proc_entry(pginfos[i].busy_fname, 0, NULL); if (!pginfos[i].busy_proc_ent) { printk("pktgen: Error: cannot create net/%s/pg_busy procfs entry.\n", PG_PROC_DIR); goto cleanup_mem; } pginfos[i].busy_proc_ent->read_proc = proc_busy_read; pginfos[i].busy_proc_ent->data = (void*)(long)(i); } return 0; cleanup_mem: for (i = 0; i<MAX_PKTGEN; i++) { if (strlen(pginfos[i].fname)) { remove_proc_entry(pginfos[i].fname, NULL); } if (strlen(pginfos[i].busy_fname)) { remove_proc_entry(pginfos[i].busy_fname, NULL); } } return -ENOMEM;}static void __exit cleanup(void){ int i; for (i = 0; i<MAX_PKTGEN; i++) { if (strlen(pginfos[i].fname)) { remove_proc_entry(pginfos[i].fname, NULL); } if (strlen(pginfos[i].busy_fname)) { remove_proc_entry(pginfos[i].busy_fname, NULL); } } remove_proc_dir();}module_init(init);module_exit(cleanup);MODULE_AUTHOR("Robert Olsson <robert.olsson@its.uu.se");MODULE_DESCRIPTION("Packet Generator tool");MODULE_LICENSE("GPL");module_param(count_d, int, 0);module_param(ipg_d, int, 0);module_param(cpu_speed, int, 0);module_param(clone_skb_d, int, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -