static int cmd_ipconfig_update(struct vmm_chardev *cdev, int argc, char **argv) { u8 buf[4]; u8 mask[4]; int rc = VMM_OK; switch(argc) { case 3: str2ipaddr(buf, argv[2]); if(ipv4_class_netmask(buf,mask) != -1) { netstack_set_ipaddr(buf); netstack_set_ipmask(mask); } else { vmm_cprintf(cdev, "ERROR: Invalid IP address\n"); rc = VMM_EINVALID; } break; case 4: str2ipaddr(buf, argv[2]); if(ipv4_class_netmask(buf,mask) != -1) { netstack_set_ipaddr(buf); str2ipaddr(buf, argv[3]); netstack_set_ipmask(buf); } else { vmm_cprintf(cdev, "ERROR: Invalid IP address\n"); rc = VMM_EINVALID; } break; case 5: str2ipaddr(buf, argv[2]); if(ipv4_class_netmask(buf,mask) != -1) { netstack_set_ipaddr(buf); str2ipaddr(buf, argv[3]); netstack_set_ipmask(buf); str2ipaddr(buf, argv[4]); netstack_set_gatewayip(buf); } else { vmm_cprintf(cdev, "ERROR: Invalid IP address\n"); rc = VMM_EINVALID; } break; default: rc = VMM_EINVALID; break; }; return rc; }
static int __init lwip_netstack_init(void) { int rc; struct vmm_netswitch *nsw; struct vmm_devtree_node *node; const char *str; u8 ip[] = {169, 254, 1, 1}; u8 mask[] = {255, 255, 255, 0}; ip_addr_t __ip, __nm, __gw; /* Clear lwIP state */ memset(&lns, 0, sizeof(lns)); /* Get netstack device tree node if available */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_VMMINFO_NODE_NAME VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_VMMNET_NODE_NAME VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_NETSTACK_NODE_NAME); /* Retrive preferred IP address */ if (vmm_devtree_read_string(node, "ipaddr", &str) == VMM_OK) { /* Read ip address from netstack node */ str2ipaddr(ip, str); } /* Retrive preferred IP address */ if (vmm_devtree_read_string(node, "netmask", &str) == VMM_OK) { /* Read network mask from netstack node */ str2ipaddr(mask, str); } /* Retrive preferred netswitch */ if (vmm_devtree_read_string(node, "netswitch", &str) == VMM_OK) { /* Find netswitch with given name */ nsw = vmm_netswitch_find(str); } else { /* Get default netswitch */ nsw = vmm_netswitch_default(); } if (!nsw) { vmm_panic("%s: No netswitch found\n", __func__); } /* Release netstack device tree node */ vmm_devtree_dref_node(node); /* Allocate a netport */ lns.port = vmm_netport_alloc("lwip-netport", VMM_NETPORT_DEF_QUEUE_SIZE); if (!lns.port) { vmm_printf("%s: vmm_netport_alloc() failed\n", __func__); rc = VMM_ENOMEM; goto fail; } /* Setup a netport */ lns.port->mtu = 1500; lns.port->link_changed = lwip_set_link; lns.port->can_receive = lwip_can_receive; lns.port->switch2port_xfer = lwip_switch2port_xfer; lns.port->priv = &lns; /* Register a netport */ rc = vmm_netport_register(lns.port); if (rc) { goto fail1; } /* Initialize lwIP + TCP/IP APIs */ tcpip_init(NULL, NULL); /* Add netif */ IP4_ADDR(&__ip, ip[0],ip[1],ip[2],ip[3]); IP4_ADDR(&__nm, mask[0],mask[1],mask[2],mask[3]); IP4_ADDR(&__gw, ip[0],ip[1],ip[2],ip[3]); netif_add(&lns.nif, &__ip, &__nm, &__gw, &lns, lwip_netstack_netif_init, ethernet_input); /* Set default netif */ netif_set_default(&lns.nif); /* Attach netport with netswitch * Note: This will cause netport link_change() */ rc = vmm_netswitch_port_add(nsw, lns.port); if (rc) { goto fail2; } #if !defined(PING_USE_SOCKETS) /* Initalize RAW PCB for ping */ ping_raw_init(); #endif return VMM_OK; fail2: vmm_netport_unregister(lns.port); fail1: vmm_netport_free(lns.port); fail: return rc; }
static int cmd_ping_exec(struct vmm_chardev *cdev, int argc, char **argv) { u16 sent, rcvd, count = 1, size = 56; struct netstack_echo_reply reply; char ip_addr_str[20]; u32 rtt_usecs, rtt_msecs; u64 min_rtt = -1, max_rtt = 0, avg_rtt = 0; u8 ipaddr[4]; if((argc < 2) || (argc > 4)) { cmd_ping_usage(cdev); return VMM_EFAIL; } if(argc > 2) { count = atoi(argv[2]); } if(argc > 3) { size = atoi(argv[3]); } str2ipaddr(ipaddr, argv[1]); vmm_cprintf(cdev, "PING (%s) %d(%d) bytes of data.\n", argv[1], size, (size + IP4_HLEN + ICMP_HLEN)); netstack_prefetch_arp_mapping(ipaddr); for(sent=0, rcvd=0; sent<count; sent++) { if (!netstack_send_echo(ipaddr, size, sent, &reply)) { if (reply.rtt < min_rtt) min_rtt = reply.rtt; if (reply.rtt > max_rtt) max_rtt = reply.rtt; avg_rtt += reply.rtt; rtt_msecs = udiv64(reply.rtt, 1000); rtt_usecs = umod64(reply.rtt, 1000); ip4addr_to_str(ip_addr_str, (const u8 *)&reply.ripaddr); vmm_cprintf(cdev, "%d bytes from %s: seq=%d " "ttl=%d time=%d.%03dms\n", reply.len, ip_addr_str, reply.seqno, reply.ttl, rtt_msecs, rtt_usecs); rcvd++; } } if (min_rtt == -1) { min_rtt = 0; } if (rcvd) { avg_rtt = udiv64(avg_rtt, rcvd); } else { avg_rtt = 0; } vmm_cprintf(cdev, "\n----- %s ping statistics -----\n", argv[1]); vmm_cprintf(cdev, "%d packets transmitted, %d packets received\n", sent, rcvd); vmm_cprintf(cdev, "round-trip min/avg/max = "); rtt_msecs = udiv64(min_rtt, 1000); rtt_usecs = umod64(min_rtt, 1000); vmm_cprintf(cdev, "%d.%03d/", rtt_msecs, rtt_usecs); rtt_msecs = udiv64(avg_rtt, 1000); rtt_usecs = umod64(avg_rtt, 1000); vmm_cprintf(cdev, "%d.%03d/", rtt_msecs, rtt_usecs); rtt_msecs = udiv64(max_rtt, 1000); rtt_usecs = umod64(max_rtt, 1000); vmm_cprintf(cdev, "%d.%03d ms\n", rtt_msecs, rtt_usecs); return VMM_OK; }