extractedLnx/linux-2.6.14/net/core/pktgen.c_proc_if_write.c
static int proc_if_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;
struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
char* pg_result = NULL;
int tmp = 0;
char buf[128];
pg_result = &(pkt_dev->result[0]);
if (count < 1) {
printk("pktgen: wrong command format\n");
return -EINVAL;
}
max = count - i;
tmp = count_trail_chars(&user_buffer[i], max);
if (tmp < 0) {
printk("pktgen: illegal format\n");
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) {
char tb[count + 1];
if (copy_from_user(tb, user_buffer, count))
return -EFAULT;
tb[count] = 0;
printk("pktgen: %s,%lu buffer -:%s:-\n", name, count, tb);
}
if (!strcmp(name, "min_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;
if (value != pkt_dev->min_pkt_size) {
pkt_dev->min_pkt_size = value;
pkt_dev->cur_pkt_size = value;
}
sprintf(pg_result, "OK: min_pkt_size=%u", pkt_dev->min_pkt_size);
return count;
}
if (!strcmp(name, "max_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;
if (value != pkt_dev->max_pkt_size) {
pkt_dev->max_pkt_size = value;
pkt_dev->cur_pkt_size = value;
}
sprintf(pg_result, "OK: max_pkt_size=%u", pkt_dev->max_pkt_size);
return count;
}
/* Shortcut for min = max */
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;
if (value != pkt_dev->min_pkt_size) {
pkt_dev->min_pkt_size = value;
pkt_dev->max_pkt_size = value;
pkt_dev->cur_pkt_size = value;
}
sprintf(pg_result, "OK: pkt_size=%u", pkt_dev->min_pkt_size);
return count;
}
if (!strcmp(name, "debug")) {
len = num_arg(&user_buffer[i], 10, &value);
if (len < 0) { return len; }
i += len;
debug = value;
sprintf(pg_result, "OK: debug=%u", debug);
return count;
}
if (!strcmp(name, "frags")) {
len = num_arg(&user_buffer[i], 10, &value);
if (len < 0) { return len; }
i += len;
pkt_dev->nfrags = value;
sprintf(pg_result, "OK: frags=%u", pkt_dev->nfrags);
return count;
}
if (!strcmp(name, "delay")) {
len = num_arg(&user_buffer[i], 10, &value);
if (len < 0) { return len; }
i += len;
if (value == 0x7FFFFFFF) {
pkt_dev->delay_us = 0x7FFFFFFF;
pkt_dev->delay_ns = 0;
} else {
pkt_dev->delay_us = value / 1000;
pkt_dev->delay_ns = value % 1000;
}
sprintf(pg_result, "OK: delay=%u", 1000*pkt_dev->delay_us+pkt_dev->delay_ns);
return count;
}
if (!strcmp(name, "udp_src_min")) {
len = num_arg(&user_buffer[i], 10, &value);
if (len < 0) { return len; }
i += len;
if (value != pkt_dev->udp_src_min) {
pkt_dev->udp_src_min = value;
pkt_dev->cur_udp_src = value;
}
sprintf(pg_result, "OK: udp_src_min=%u", pkt_dev->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;
if (value != pkt_dev->udp_dst_min) {
pkt_dev->udp_dst_min = value;
pkt_dev->cur_udp_dst = value;
}
sprintf(pg_result, "OK: udp_dst_min=%u", pkt_dev->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;
if (value != pkt_dev->udp_src_max) {
pkt_dev->udp_src_max = value;
pkt_dev->cur_udp_src = value;
}
sprintf(pg_result, "OK: udp_src_max=%u", pkt_dev->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;
if (value != pkt_dev->udp_dst_max) {
pkt_dev->udp_dst_max = value;
pkt_dev->cur_udp_dst = value;
}
sprintf(pg_result, "OK: udp_dst_max=%u", pkt_dev->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;
pkt_dev->clone_skb = value;
sprintf(pg_result, "OK: clone_skb=%d", pkt_dev->clone_skb);
return count;
}
if (!strcmp(name, "count")) {
len = num_arg(&user_buffer[i], 10, &value);
if (len < 0) { return len; }
i += len;
pkt_dev->count = value;
sprintf(pg_result, "OK: count=%llu",
(unsigned long long) pkt_dev->count);
return count;
}
if (!strcmp(name, "src_mac_count")) {
len = num_arg(&user_buffer[i], 10, &value);
if (len < 0) { return len; }
i += len;
if (pkt_dev->src_mac_count != value) {
pkt_dev->src_mac_count = value;
pkt_dev->cur_src_mac_offset = 0;
}
sprintf(pg_result, "OK: src_mac_count=%d", pkt_dev->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;
if (pkt_dev->dst_mac_count != value) {
pkt_dev->dst_mac_count = value;
pkt_dev->cur_dst_mac_offset = 0;
}
sprintf(pg_result, "OK: dst_mac_count=%d", pkt_dev->dst_mac_count);
return count;
}
if (!strcmp(name, "flag")) {
char f[32];
memset(f, 0, 32);
len = strn_len(&user_buffer[i], sizeof(f) - 1);
if (len < 0) { return len; }
if (copy_from_user(f, &user_buffer[i], len))
return -EFAULT;
i += len;
if (strcmp(f, "IPSRC_RND") == 0)
pkt_dev->flags |= F_IPSRC_RND;
else if (strcmp(f, "!IPSRC_RND") == 0)
pkt_dev->flags &= ~F_IPSRC_RND;
else if (strcmp(f, "TXSIZE_RND") == 0)
pkt_dev->flags |= F_TXSIZE_RND;
else if (strcmp(f, "!TXSIZE_RND") == 0)
pkt_dev->flags &= ~F_TXSIZE_RND;
else if (strcmp(f, "IPDST_RND") == 0)
pkt_dev->flags |= F_IPDST_RND;
else if (strcmp(f, "!IPDST_RND") == 0)
pkt_dev->flags &= ~F_IPDST_RND;
else if (strcmp(f, "UDPSRC_RND") == 0)
pkt_dev->flags |= F_UDPSRC_RND;
else if (strcmp(f, "!UDPSRC_RND") == 0)
pkt_dev->flags &= ~F_UDPSRC_RND;
else if (strcmp(f, "UDPDST_RND") == 0)
pkt_dev->flags |= F_UDPDST_RND;
else if (strcmp(f, "!UDPDST_RND") == 0)
pkt_dev->flags &= ~F_UDPDST_RND;
else if (strcmp(f, "MACSRC_RND") == 0)
pkt_dev->flags |= F_MACSRC_RND;
else if (strcmp(f, "!MACSRC_RND") == 0)
pkt_dev->flags &= ~F_MACSRC_RND;
else if (strcmp(f, "MACDST_RND") == 0)
pkt_dev->flags |= F_MACDST_RND;
else if (strcmp(f, "!MACDST_RND") == 0)
pkt_dev->flags &= ~F_MACDST_RND;
else {
sprintf(pg_result, "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
f,
"IPSRC_RND, IPDST_RND, TXSIZE_RND, UDPSRC_RND, UDPDST_RND, MACSRC_RND, MACDST_RND\n");
return count;
}
sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags);
return count;
}
if (!strcmp(name, "dst_min") || !strcmp(name, "dst")) {
len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_min) - 1);
if (len < 0) { return len; }
if (copy_from_user(buf, &user_buffer[i], len))
return -EFAULT;
buf[len] = 0;
if (strcmp(buf, pkt_dev->dst_min) != 0) {
memset(pkt_dev->dst_min, 0, sizeof(pkt_dev->dst_min));
strncpy(pkt_dev->dst_min, buf, len);
pkt_dev->daddr_min = in_aton(pkt_dev->dst_min);
pkt_dev->cur_daddr = pkt_dev->daddr_min;
}
if(debug)
printk("pktgen: dst_min set to: %s\n", pkt_dev->dst_min);
i += len;
sprintf(pg_result, "OK: dst_min=%s", pkt_dev->dst_min);
return count;
}
if (!strcmp(name, "dst_max")) {
len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_max) - 1);
if (len < 0) { return len; }
if (copy_from_user(buf, &user_buffer[i], len))
return -EFAULT;
buf[len] = 0;
if (strcmp(buf, pkt_dev->dst_max) != 0) {
memset(pkt_dev->dst_max, 0, sizeof(pkt_dev->dst_max));
strncpy(pkt_dev->dst_max, buf, len);
pkt_dev->daddr_max = in_aton(pkt_dev->dst_max);
pkt_dev->cur_daddr = pkt_dev->daddr_max;
}
if(debug)
printk("pktgen: dst_max set to: %s\n", pkt_dev->dst_max);
i += len;
sprintf(pg_result, "OK: dst_max=%s", pkt_dev->dst_max);
return count;
}
if (!strcmp(name, "dst6")) {
len = strn_len(&user_buffer[i], sizeof(buf) - 1);
if (len < 0) return len;
pkt_dev->flags |= F_IPV6;
if (copy_from_user(buf, &user_buffer[i], len))
return -EFAULT;
buf[len] = 0;
scan_ip6(buf, pkt_dev->in6_daddr.s6_addr);
fmt_ip6(buf, pkt_dev->in6_daddr.s6_addr);
ipv6_addr_copy(&pkt_dev->cur_in6_daddr, &pkt_dev->in6_daddr);
if(debug)
printk("pktgen: dst6 set to: %s\n", buf);
i += len;
sprintf(pg_result, "OK: dst6=%s", buf);
return count;
}
if (!strcmp(name, "dst6_min")) {
len = strn_len(&user_buffer[i], sizeof(buf) - 1);
if (len < 0) return len;
pkt_dev->flags |= F_IPV6;
if (copy_from_user(buf, &user_buffer[i], len))
return -EFAULT;
buf[len] = 0;
scan_ip6(buf, pkt_dev->min_in6_daddr.s6_addr);
fmt_ip6(buf, pkt_dev->min_in6_daddr.s6_addr);
ipv6_addr_copy(&pkt_dev->cur_in6_daddr, &pkt_dev->min_in6_daddr);
if(debug)
printk("pktgen: dst6_min set to: %s\n", buf);
i += len;
sprintf(pg_result, "OK: dst6_min=%s", buf);
return count;
}
if (!strcmp(name, "dst6_max")) {
len = strn_len(&user_buffer[i], sizeof(buf) - 1);
if (len < 0) return len;
pkt_dev->flags |= F_IPV6;
if (copy_from_user(buf, &user_buffer[i], len))
return -EFAULT;
buf[len] = 0;
scan_ip6(buf, pkt_dev->max_in6_daddr.s6_addr);
fmt_ip6(buf, pkt_dev->max_in6_daddr.s6_addr);
if(debug)
printk("pktgen: dst6_max set to: %s\n", buf);
i += len;
sprintf(pg_result, "OK: dst6_max=%s", buf);
return count;
}
if (!strcmp(name, "src6")) {
len = strn_len(&user_buffer[i], sizeof(buf) - 1);
if (len < 0) return len;
pkt_dev->flags |= F_IPV6;
if (copy_from_user(buf, &user_buffer[i], len))
return -EFAULT;
buf[len] = 0;
scan_ip6(buf, pkt_dev->in6_saddr.s6_addr);
fmt_ip6(buf, pkt_dev->in6_saddr.s6_addr);
ipv6_addr_copy(&pkt_dev->cur_in6_saddr, &pkt_dev->in6_saddr);
if(debug)
printk("pktgen: src6 set to: %s\n", buf);
i += len;
sprintf(pg_result, "OK: src6=%s", buf);
return count;
}
if (!strcmp(name, "src_min")) {
len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_min) - 1);
if (len < 0) { return len; }
if (copy_from_user(buf, &user_buffer[i], len))
return -EFAULT;
buf[len] = 0;
if (strcmp(buf, pkt_dev->src_min) != 0) {
memset(pkt_dev->src_min, 0, sizeof(pkt_dev->src_min));
strncpy(pkt_dev->src_min, buf, len);
pkt_dev->saddr_min = in_aton(pkt_dev->src_min);
pkt_dev->cur_saddr = pkt_dev->saddr_min;
}
if(debug)
printk("pktgen: src_min set to: %s\n", pkt_dev->src_min);
i += len;
sprintf(pg_result, "OK: src_min=%s", pkt_dev->src_min);
return count;
}
if (!strcmp(name, "src_max")) {
len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_max) - 1);
if (len < 0) { return len; }
if (copy_from_user(buf, &user_buffer[i], len))
return -EFAULT;
buf[len] = 0;
if (strcmp(buf, pkt_dev->src_max) != 0) {
memset(pkt_dev->src_max, 0, sizeof(pkt_dev->src_max));
strncpy(pkt_dev->src_max, buf, len);
pkt_dev->saddr_max = in_aton(pkt_dev->src_max);
pkt_dev->cur_saddr = pkt_dev->saddr_max;
}
if(debug)
printk("pktgen: src_max set to: %s\n", pkt_dev->src_max);
i += len;
sprintf(pg_result, "OK: src_max=%s", pkt_dev->src_max);
return count;
}
if (!strcmp(name, "dst_mac")) {
char *v = valstr;
unsigned char old_dmac[6];
unsigned char *m = pkt_dev->dst_mac;
memcpy(old_dmac, pkt_dev->dst_mac, 6);
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 < pkt_dev->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;
}
}
/* Set up Dest MAC */
if (memcmp(old_dmac, pkt_dev->dst_mac, 6) != 0)
memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, 6);
sprintf(pg_result, "OK: dstmac");
return count;
}
if (!strcmp(name, "src_mac")) {
char *v = valstr;
unsigned char *m = pkt_dev->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 < pkt_dev->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(pg_result, "OK: srcmac");
return count;
}
if (!strcmp(name, "clear_counters")) {
pktgen_clear_counters(pkt_dev);
sprintf(pg_result, "OK: Clearing counters.\n");
return count;
}
if (!strcmp(name, "flows")) {
len = num_arg(&user_buffer[i], 10, &value);
if (len < 0) { return len; }
i += len;
if (value > MAX_CFLOWS)
value = MAX_CFLOWS;
pkt_dev->cflows = value;
sprintf(pg_result, "OK: flows=%u", pkt_dev->cflows);
return count;
}
if (!strcmp(name, "flowlen")) {
len = num_arg(&user_buffer[i], 10, &value);
if (len < 0) { return len; }
i += len;
pkt_dev->lflow = value;
sprintf(pg_result, "OK: flowlen=%u", pkt_dev->lflow);
return count;
}
sprintf(pkt_dev->result, "No such parameter \"%s\"", name);
return -EINVAL;
}
Generated by GNU enscript 1.6.4.