blob: 76ac156754d7a9f01cad8a3d060b9e8732246c2a [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (c) 2014 Chris Anderson
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#include "minip-internal.h"
25
26#include <lib/console.h>
27#include <kernel/thread.h>
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#include <platform.h>
32#include <kernel/timer.h>
33#include <err.h>
34
35#if WITH_LIB_CONSOLE
36
37uint32_t str_ip_to_int(const char *s, size_t len)
38{
39 uint8_t ip[4] = { 0, 0, 0, 0 };
40 uint8_t pos = 0, i = 0;
41
42 while (pos < len) {
43 char c = s[pos];
44 if (c == '.') {
45 i++;
46 } else {
47 ip[i] *= 10;
48 ip[i] += c - '0';
49 }
50 pos++;
51 }
52
53 return IPV4_PACK(ip);
54}
55
56void arp_usage(void) {
57 printf("arp list print arp table\n");
58 printf("arp query <ipv4 address> query arp address\n");
59}
60
61static int cmd_arp(int argc, const cmd_args *argv)
62{
63 const char *cmd;
64
65 if (argc == 1) {
66 arp_usage();
67 return -1;
68 }
69
70 cmd = argv[1].str;
71 if (argc == 2 && strncmp(cmd, "list", sizeof("list")) == 0) {
72 arp_cache_dump();
73 } else if (argc == 3 && strncmp(cmd, "query", sizeof("query")) == 0) {
74 const char *addr_s = argv[2].str;
75 uint32_t addr = str_ip_to_int(addr_s, strlen(addr_s));
76
77 arp_send_request(addr);
78 } else {
79 arp_usage();
80 }
81
82 return 0;
83}
84
85static int cmd_minip(int argc, const cmd_args *argv)
86{
87 if (argc == 1) {
88minip_usage:
89 printf("minip commands\n");
90 printf("mi [a]rp dump arp table\n");
91 printf("mi [s]tatus print ip status\n");
92 printf("mi [t]est [dest] [port] [cnt] send <cnt> test packets to the dest:port\n");
93 } else {
94 switch(argv[1].str[0]) {
95
96 case 'a':
97 arp_cache_dump();
98 break;
99
100 case 's': {
101 uint32_t ipaddr = minip_get_ipaddr();
102
103 printf("hostname: %s\n", minip_get_hostname());
104 printf("ip: %u.%u.%u.%u\n", IPV4_SPLIT(ipaddr));
105 }
106 break;
107 case 't': {
108 uint32_t count = 1;
109 uint32_t host = 0x0100000A; // 10.0.0.1
110 uint32_t port = 1025;
111 udp_socket_t *handle;
112
113 switch (argc) {
114 case 5:
115 count = argv[4].u;
116 case 4:
117 port = argv[3].u;
118 case 3:
119 host = str_ip_to_int(argv[2].str, strlen(argv[2].str));
120 break;
121 }
122
123 if (udp_open(host, port, port, &handle) != NO_ERROR) {
124 printf("udp_open to %u.%u.%u.%u:%u failed\n", IPV4_SPLIT(host), port);
125 return -1;
126 }
127
128#define BUFSIZE 1470
129 uint8_t *buf;
130
131 buf = malloc(BUFSIZE);
132 if (!buf) {
133 udp_close(handle);
134 return -1;
135 }
136
137 memset(buf, 0x00, BUFSIZE);
138 printf("sending %u packet(s) to %u.%u.%u.%u:%u\n", count, IPV4_SPLIT(host), port);
139
140 lk_time_t t = current_time();
141 uint32_t failures = 0;
142 for (uint32_t i = 0; i < count; i++) {
143 if (udp_send(buf, BUFSIZE, handle) != 0) {
144 failures++;
145 }
146 buf[128]++;
147 }
148 t = current_time() - t;
149 printf("%d pkts failed\n", failures);
150 uint64_t total_count = (uint64_t)count * BUFSIZE;
151 printf("wrote %llu bytes in %u msecs (%llu bytes/sec)\n",
152 total_count, (uint32_t)t, total_count * 1000 / t);
153
154 free(buf);
155 udp_close(handle);
156#undef BUFSIZE
157 }
158 break;
159 default:
160 goto minip_usage;
161 }
162 }
163
164 return 0;
165}
166
167STATIC_COMMAND_START
168STATIC_COMMAND("arp", "arp commands", &cmd_arp)
169STATIC_COMMAND("mi", "minip commands", &cmd_minip)
170STATIC_COMMAND_END(minip);
171#endif
172
173// vim: set ts=4 sw=4 expandtab: