source: asp3_tinet_ecnl_rx/trunk/ntshell/src/netcmd.c@ 337

Last change on this file since 337 was 337, checked in by coas-nagasima, 6 years ago

ASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 14.9 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
5 * Tomakomai National College of Technology, JAPAN
6 *
7 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
12 * スコード中に含まれていること.
13 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
16 * の無保証規定を掲載すること.
17 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
19 * と.
20 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
22 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
23 * 報告すること.
24 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
28 * 免責すること.
29 *
30 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
34 * の責任を負わない.
35 *
36 * @(#) $Id$
37 */
38#include "shellif.h"
39#include <kernel.h>
40#include <t_stdlib.h>
41#include <sil.h>
42#include <string.h>
43#include "syssvc/serial.h"
44#include "syssvc/syslog.h"
45#include <tinet_config.h>
46#include <netinet/in.h>
47#include <netinet/in_itron.h>
48#include <tinet_nic_defs.h>
49#include <tinet_cfg.h>
50#include <netinet/in_var.h>
51#include <net/ethernet.h>
52#include <net/if6_var.h>
53#include <net/net.h>
54#include <net/if_var.h>
55#include <netinet/udp_var.h>
56#include <netapp/netapp_var.h>
57#include <netapp/netapp.h>
58#include <netapp/dhcp4_cli.h>
59#include <netapp/resolver.h>
60#include "core/ntlibc.h"
61#include "util/ntstdio.h"
62#include "kernel_cfg.h"
63
64extern ntstdio_t ntstdio;
65
66#if defined(SUPPORT_INET6)
67#define DEFAULT_API_PROTO API_PROTO_IPV6
68#else
69#define DEFAULT_API_PROTO API_PROTO_IPV4
70#endif
71extern void ping6(T_IN6_ADDR *addr, uint_t tmo, uint_t len);
72extern void ping4(T_IN4_ADDR *addr, uint_t tmo, uint_t len);
73
74int usrcmd_ping(int argc, char **argv)
75{
76 int_t tmo, size;
77 char apip = DEFAULT_API_PROTO;
78 char *line = argv[1];
79#if defined(SUPPORT_INET6)
80 T_IN6_ADDR addr;
81#if defined(SUPPORT_INET4)
82 T_IN4_ADDR addr4;
83#endif
84#else
85 T_IN4_ADDR addr;
86#endif
87 static const char i6rlp_pmtu_str1[] = " FF1E::1:2 1 1452";
88 static const char i6rlp_pmtu_str2[] = " FF1E::1:2 1 1352";
89 static const char i6rlp_pmtu_str3[] = " fe80::0200:00ff:fe00:0100 1 2";
90
91 if (apip == '1')
92 ntlibc_strcpy(line, i6rlp_pmtu_str1);
93 else if (apip == '2')
94 ntlibc_strcpy(line, i6rlp_pmtu_str2);
95 else if (apip == '3')
96 ntlibc_strcpy(line, i6rlp_pmtu_str3);
97
98#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
99 if ('0' <= *line && *line <= '9') {
100 if (*line == '6')
101 apip = API_PROTO_IPV6;
102 if (*line == '4')
103 apip = API_PROTO_IPV4;
104 line++;
105 }
106#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
107
108 if ((line = lookup_ipaddr(&addr, line, apip)) == NULL) {
109 ntstdio_printf(&ntstdio, "[PING] unknown host.\n");
110 return 0;
111 }
112
113 line = argv[2];
114 if ('0' <= *line && *line <= '9')
115 line = get_int(&tmo, line);
116 else
117 tmo = 3;
118
119 line = argv[3];
120 if ('0' <= *line && *line <= '9')
121 line = get_int(&size, line);
122 else
123 size = 64;
124
125#if defined(SUPPORT_INET6)
126#if defined(SUPPORT_INET4)
127 if (apip == API_PROTO_IPV6) {
128 ntstdio_printf(&ntstdio, "[PING6] size: %d, tmo: %d, host: %s\n", size, tmo, ipv62str(NULL, &addr));
129 ping6(&addr, (uint_t)tmo, (uint_t)size);
130 }
131 else {
132 addr4 = ntohl(addr.s6_addr32[3]);
133 ntstdio_printf(&ntstdio, "[PING4] size: %d, tmo: %d, host: %s\n", size, tmo, ip2str(NULL, &addr4));
134 ping4(&addr4, (uint_t)tmo, (uint_t)size);
135 }
136#else /* of #if defined(SUPPORT_INET4) */
137 ntstdio_printf(&ntstdio, "[PING6] size: %d, tmo: %d, host: %s\n", size, tmo, ipv62str(NULL, &addr));
138 ping6(&addr, (uint_t)tmo, (uint_t)size);
139#endif /* of #if defined(SUPPORT_INET4) */
140#else /* of #if defined(SUPPORT_INET6) */
141 ntstdio_printf(&ntstdio, "[PING4] size: %d, tmo: %d, host: %s\n", size, tmo, ip2str(NULL, &addr));
142 ping4(&addr, (uint_t)tmo, (uint_t)size);
143#endif /* of #if defined(SUPPORT_INET6) */
144
145 return 0;
146}
147
148static void dhcp4c_info()
149{
150 T_IN4_ADDR svaddr;
151 SYSTIM bind_start;
152 ER ret;
153 uint32_t expire, renew, rebind;
154
155 if ((ret = dhcp4c_get_info(&svaddr, &expire, &renew, &rebind, &bind_start)) == E_OK) {
156 ntstdio_printf(&ntstdio, "DHCPv4 server: %hI,\n", &svaddr);
157 ntstdio_printf(&ntstdio, " Renew: %u:%02u:%02u,\n",
158 renew / 3600, (renew / 60) % 60, renew % 60);
159 ntstdio_printf(&ntstdio, " Rebind: %u:%02u:%02u, Expire: %u:%02u:%02u.\n",
160 rebind / 3600, (rebind / 60) % 60, rebind % 60,
161 expire / 3600, (expire / 60) % 60, expire % 60);
162 }
163 else if (ret == E_OBJ)
164 ntstdio_printf(&ntstdio, "DHCPv4 server: not available.\n");
165}
166
167int usrcmd_dhcp4c(int argc, char **argv)
168{
169 ER ret;
170 if (ntlibc_strcmp(argv[1], "rel") == 0) {
171 ret = dhcp4c_rel_info();
172 ntstdio_printf(&ntstdio, "dhcp4c_rel_info %d\n", ret);
173 }
174 else if (ntlibc_strcmp(argv[1], "renew") == 0) {
175 ret = dhcp4c_renew_info();
176 ntstdio_printf(&ntstdio, "dhcp4c_renew_info %d\n", ret);
177 }
178 else {
179 dhcp4c_info();
180 }
181 return 0;
182}
183
184/*
185* s_show_dns_domain_name -- DNS のドメイン名を表示する。
186*/
187
188static uint_t
189s_show_dns_domain_name(uint8_t *hdr, uint_t offset)
190{
191 uint8_t *ptr;
192 uint_t c;
193
194 ptr = hdr + offset;
195 while (*ptr) {
196 if ((*ptr & DNS_MSG_COMP_MARK) == DNS_MSG_COMP_MARK) {
197 s_show_dns_domain_name(hdr, (*ptr & ~DNS_MSG_COMP_MARK) << 8 | *(ptr + 1));
198 ptr += 2;
199 break;
200 }
201 else {
202 for (c = 1; c <= *ptr; c++)
203 ntstdio_printf(&ntstdio, "%c", *(ptr + c));
204 ptr += *ptr + 1;
205 if (*ptr)
206 ntstdio_printf(&ntstdio, ".");
207 }
208 }
209 return ptr - hdr;
210}
211
212/*
213 * show_dns_soa -- DNS の SOA RDATA を表示する。
214 */
215
216static ER_UINT
217show_dns_soa(uint8_t *msg, ER_UINT length, uint_t offset)
218{
219 T_RSLV_SOA soa;
220 ER_UINT error;
221 uint_t rn_offset;
222
223 if ((error = dns_analyze_soa(&soa, offset, msg, length)) < 0)
224 return error;
225
226 ntstdio_printf(&ntstdio, " mname: ");
227 rn_offset = s_show_dns_domain_name(msg, offset);
228 ntstdio_putc(&ntstdio, '\n');
229 ntstdio_printf(&ntstdio, " rname: ");
230 s_show_dns_domain_name(msg, rn_offset);
231 ntstdio_putc(&ntstdio, '\n');
232
233 ntstdio_printf(&ntstdio, " serial: %d\n", soa.serial);
234 ntstdio_printf(&ntstdio, " refresh: %d\n", soa.refresh);
235 ntstdio_printf(&ntstdio, " retry: %d\n", soa.retry);
236 ntstdio_printf(&ntstdio, " expirel: %d\n", soa.expire);
237 ntstdio_printf(&ntstdio, " minimum: %d\n", soa.minimum);
238
239 return E_OK;
240}
241
242/*
243 * show_dns_qdsection -- DNS の Question セクションを表示する。
244 */
245
246static ER_UINT
247show_dns_qdsection(uint8_t *msg, ER_UINT length, T_RSLV_DNS_MSG *rslv)
248{
249 T_RSLV_QD qd;
250 ER_UINT offset, error;
251 int scount;
252
253 ntstdio_printf(&ntstdio, "question section: %d\n", rslv->dns_hdr.qdcount);
254 offset = rslv->qd_offset;
255 for (scount = 1; scount <= rslv->dns_hdr.qdcount; scount++) {
256 if ((error = dns_analyze_qd(&qd, offset, msg, length)) < 0)
257 return error;
258
259 ntstdio_printf(&ntstdio, "%2d: ", scount);
260 s_show_dns_domain_name(msg, offset);
261 ntstdio_printf(&ntstdio, "\n type: %-4s, class: %2s\n", dns_strtype(qd.type), dns_strclass(qd.class));
262 offset = error;
263 }
264
265 return E_OK;
266}
267
268/*
269 * show_dns_section -- DNS の各セクションを表示する。
270 */
271
272static ER_UINT
273show_dns_section(uint8_t *msg, ER_UINT length, uint_t scount, uint_t offset, char *title)
274{
275 T_RSLV_RR rr;
276 T_IN4_ADDR in4_addr;
277 ER_UINT error;
278 int count, dcount, col;
279 T_IN6_ADDR in6_addr;
280
281 ntstdio_printf(&ntstdio, "%10s section: %d\n", title, scount);
282 for (count = 1; count <= scount; count++) {
283 if ((error = dns_analyze_rr(&rr, offset, msg, length)) < 0)
284 return error;
285
286 ntstdio_printf(&ntstdio, "%2d: ", count);
287 s_show_dns_domain_name(msg, offset);
288 ntstdio_printf(&ntstdio, "\n type: %-4s, class: %2s, TTL: %2d, len: %3d, offset: 0x%02x\n",
289 dns_strtype(rr.type), dns_strclass(rr.class), rr.ttl, rr.rdlength, rr.rdata_offset);
290
291 switch (rr.type) {
292 case DNS_TYPE_A:
293 memcpy((void*)&in4_addr, (void*)(msg + rr.rdata_offset), sizeof(in4_addr));
294 in4_addr = ntohl(in4_addr);
295 ntstdio_printf(&ntstdio, " IPv4 addr: %hI\n", &in4_addr);
296 break;
297 case DNS_TYPE_NS:
298 ntstdio_printf(&ntstdio, " host: ");
299 s_show_dns_domain_name(msg, rr.rdata_offset);
300 ntstdio_putc(&ntstdio, '\n');
301 break;
302 case DNS_TYPE_CNAME:
303 ntstdio_printf(&ntstdio, " host: ");
304 s_show_dns_domain_name(msg, rr.rdata_offset);
305 ntstdio_putc(&ntstdio, '\n');
306 break;
307 case DNS_TYPE_SOA:
308 show_dns_soa(msg, length, rr.rdata_offset);
309 break;
310 case DNS_TYPE_PTR:
311 ntstdio_printf(&ntstdio, " PTR: ");
312 s_show_dns_domain_name(msg, rr.rdata_offset);
313 ntstdio_putc(&ntstdio, '\n');
314 break;
315 case DNS_TYPE_AAAA:
316 memcpy((void*)&in6_addr, (void*)(msg + rr.rdata_offset), sizeof(in6_addr));
317 ntstdio_printf(&ntstdio, " IPv6 addr: %lI\n", &in6_addr);
318 break;
319 default:
320 ntstdio_printf(&ntstdio, " data: ");
321 col = 32;
322 for (dcount = 0; dcount < rr.rdlength; dcount++) {
323 ntstdio_printf(&ntstdio, "%02x", *(msg + rr.rdata_offset + dcount));
324 if (--col == 0) {
325 ntstdio_printf(&ntstdio, "\n ");
326 col = 32;
327 }
328 }
329 ntstdio_putc(&ntstdio, '\n');
330 break;
331 }
332 }
333
334 return E_OK;
335}
336/*
337 * dns_info -- DNS 情報の表示
338 */
339
340static void dns_info()
341{
342#if defined(SUPPORT_INET6)
343 T_IN6_ADDR in6_addr;
344#endif
345#if defined(SUPPORT_INET4)
346 T_IN4_ADDR in4_addr;
347#endif
348
349#if defined(SUPPORT_INET6)
350
351 ntstdio_printf(&ntstdio, "domain name: %s\n", dns_in6_get_dname());
352
353#else /* of #if defined(SUPPORT_INET6) */
354
355 ntstdio_printf(&ntstdio, "domain name: %s\n", dns_in4_get_dname());
356
357#endif /* of #if defined(SUPPORT_INET6) */
358
359#if defined(SUPPORT_INET6)
360 dns_in6_get_addr(&in6_addr);
361 ntstdio_printf(&ntstdio, "IPv6 DNS server: ");
362 if (IN6_IS_ADDR_UNSPECIFIED(&in6_addr))
363 ntstdio_printf(&ntstdio, "not available.\n");
364 else
365 ntstdio_printf(&ntstdio, "%lI.\n", &in6_addr);
366#endif /* of #if defined(SUPPORT_INET6) */
367
368#if defined(SUPPORT_INET4)
369 dns_in4_get_addr(&in4_addr);
370 ntstdio_printf(&ntstdio, "IPv4 DNS server: ");
371 if (in4_addr == IPV4_ADDRANY)
372 ntstdio_printf(&ntstdio, "not available.\n");
373 else
374 ntstdio_printf(&ntstdio, "%hI.\n", &in4_addr);
375#endif /* of #if defined(SUPPORT_INET4) */
376}
377
378/*
379 * name_lookup -- ホスト名-IP アドレス変換
380 */
381
382const char *rcode_str[] = {
383 "no error",
384 "format error",
385 "server error",
386 "name error",
387 "not implement",
388 "refused",
389};
390
391int usrcmd_dnsc(int argc, char **argv)
392{
393 char *line = argv[1];
394 static char hostname[DBG_LINE_SIZE + 1];
395
396 T_RSLV_DNS_MSG rslv;
397 ER_UINT length, offset;
398 ER error;
399 uint_t flags = 0;
400 uint8_t *msg;
401
402 if (ntlibc_strcmp(line, "info") == 0) {
403 dns_info();
404 return 0;
405 }
406
407 /* コマンドのオプションを設定する。*/
408 line = skip_blanks(resolv_options(&flags, line, DEFAULT_API_PROTO));
409 if ((flags & (DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4)) == 0) {
410 ntstdio_printf(&ntstdio, "DNS server not available.\n");
411 return 0;
412 }
413
414 /* 照会するホスト名・IP アドレスを解析する。*/
415 resolv_hoststr(&flags, hostname, sizeof(hostname), line);
416
417 /* 正引きでも逆引きでもプロトコル上は正引きを指定する。*/
418 flags |= DNS_LUP_OPCODE_FORWARD;
419
420 /* IPv6 アドレス、または IPv4 アドレスが指定された時は、照会タイプは PTR に設定する。*/
421 if (((flags & DNS_LUP_FLAGS_NAME_MASK) == DNS_LUP_FLAGS_NAME_IPV6) ||
422 ((flags & DNS_LUP_FLAGS_NAME_MASK) == DNS_LUP_FLAGS_NAME_IPV4))
423 flags = (flags & ~DNS_LUP_FLAGS_QTYPE_MASK) | DNS_LUP_FLAGS_QTYPE_PTR;
424
425 if ((error = tget_mpf(MPF_RSLV_SRBUF, (void*)&msg, TMO_FEVR)) != E_OK) {
426 ntstdio_printf(&ntstdio, "get buffer error: %s.\n", itron_strerror(error));
427 return 0;
428 }
429
430 if ((length = dns_lookup_host(flags | DNS_LUP_FLAGS_MSG, line, msg, DNS_UDP_MSG_LENGTH, &rslv)) < 0) {
431 //ntstdio_printf(&ntstdio, "error: %s.\n", itron_strerror(length));
432 goto err_ret;
433 }
434
435 dly_tsk(1 * 1000);
436 ntstdio_printf(&ntstdio, "DNS header: flags: ");
437 if (rslv.dns_hdr.code & (DNS_QR_RESPONSE | DNS_AUTHORITATIVE |
438 DNS_TRUN_CATION | DNS_RECURSION_DESIRED | DNS_RECURSION_AVAILABLE)) {
439 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_QR_RESPONSE) ? "QR," : "");
440 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_AUTHORITATIVE) ? "AA," : "");
441 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_TRUN_CATION) ? "TC," : "");
442 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_RECURSION_DESIRED) ? "RD," : "");
443 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_RECURSION_AVAILABLE) ? "RA," : "");
444 ntstdio_printf(&ntstdio, " ");
445 }
446 ntstdio_printf(&ntstdio, "opcode: ");
447 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_OPCODE_REVERSE) ? "RV" : "FW");
448 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_OPCODE_STATUS) ? ",ST" : "");
449 ntstdio_printf(&ntstdio, ", rcode: %s.\n",
450 (rslv.dns_hdr.code & DNS_RCODE_MASK) > DNS_RCODE_REFUSED
451 ? "6" : rcode_str[rslv.dns_hdr.code & DNS_RCODE_MASK]);
452
453 if ((offset = show_dns_qdsection(msg, length, &rslv)) < 0) {
454 ntstdio_printf(&ntstdio, "msg error: %s.\n", itron_strerror(offset));
455 }
456 if ((offset = show_dns_section(msg, length, rslv.dns_hdr.ancount, rslv.an_offset, "answer")) < 0) {
457 ntstdio_printf(&ntstdio, "msg error: %s.\n", itron_strerror(offset));
458 }
459 if ((offset = show_dns_section(msg, length, rslv.dns_hdr.nscount, rslv.ns_offset, "authority")) < 0) {
460 ntstdio_printf(&ntstdio, "msg error: %s.\n", itron_strerror(offset));
461 }
462 if ((offset = show_dns_section(msg, length, rslv.dns_hdr.arcount, rslv.ar_offset, "additional")) < 0) {
463 ntstdio_printf(&ntstdio, "msg error: %s.\n", itron_strerror(offset));
464 }
465
466err_ret:
467 if ((error = rel_mpf(MPF_RSLV_SRBUF, msg)) != E_OK)
468 ntstdio_printf(&ntstdio, "release buffer error: %s.\n", itron_strerror(error));
469 return 0;
470}
Note: See TracBrowser for help on using the repository browser.