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

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

NTPクライアント処理を追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 15.0 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 "ntp_cli.h"
63#include "kernel_cfg.h"
64
65extern ntstdio_t ntstdio;
66
67#if defined(SUPPORT_INET6)
68#define DEFAULT_API_PROTO API_PROTO_IPV6
69#else
70#define DEFAULT_API_PROTO API_PROTO_IPV4
71#endif
72extern void ping6(T_IN6_ADDR *addr, uint_t tmo, uint_t len);
73extern void ping4(T_IN4_ADDR *addr, uint_t tmo, uint_t len);
74
75int usrcmd_ping(int argc, char **argv)
76{
77 int_t tmo, size;
78 char apip = DEFAULT_API_PROTO;
79 char *line = argv[1];
80#if defined(SUPPORT_INET6)
81 T_IN6_ADDR addr;
82#if defined(SUPPORT_INET4)
83 T_IN4_ADDR addr4;
84#endif
85#else
86 T_IN4_ADDR addr;
87#endif
88 static const char i6rlp_pmtu_str1[] = " FF1E::1:2 1 1452";
89 static const char i6rlp_pmtu_str2[] = " FF1E::1:2 1 1352";
90 static const char i6rlp_pmtu_str3[] = " fe80::0200:00ff:fe00:0100 1 2";
91
92 if (apip == '1')
93 ntlibc_strcpy(line, i6rlp_pmtu_str1);
94 else if (apip == '2')
95 ntlibc_strcpy(line, i6rlp_pmtu_str2);
96 else if (apip == '3')
97 ntlibc_strcpy(line, i6rlp_pmtu_str3);
98
99#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
100 if ('0' <= *line && *line <= '9') {
101 if (*line == '6')
102 apip = API_PROTO_IPV6;
103 if (*line == '4')
104 apip = API_PROTO_IPV4;
105 line++;
106 }
107#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
108
109 if ((line = lookup_ipaddr(&addr, line, apip)) == NULL) {
110 ntstdio_printf(&ntstdio, "[PING] unknown host.\n");
111 return 0;
112 }
113
114 line = argv[2];
115 if ('0' <= *line && *line <= '9')
116 line = get_int(&tmo, line);
117 else
118 tmo = 3;
119
120 line = argv[3];
121 if ('0' <= *line && *line <= '9')
122 line = get_int(&size, line);
123 else
124 size = 64;
125
126#if defined(SUPPORT_INET6)
127#if defined(SUPPORT_INET4)
128 if (apip == API_PROTO_IPV6) {
129 ntstdio_printf(&ntstdio, "[PING6] size: %d, tmo: %d, host: %s\n", size, tmo, ipv62str(NULL, &addr));
130 ping6(&addr, (uint_t)tmo, (uint_t)size);
131 }
132 else {
133 addr4 = ntohl(addr.s6_addr32[3]);
134 ntstdio_printf(&ntstdio, "[PING4] size: %d, tmo: %d, host: %s\n", size, tmo, ip2str(NULL, &addr4));
135 ping4(&addr4, (uint_t)tmo, (uint_t)size);
136 }
137#else /* of #if defined(SUPPORT_INET4) */
138 ntstdio_printf(&ntstdio, "[PING6] size: %d, tmo: %d, host: %s\n", size, tmo, ipv62str(NULL, &addr));
139 ping6(&addr, (uint_t)tmo, (uint_t)size);
140#endif /* of #if defined(SUPPORT_INET4) */
141#else /* of #if defined(SUPPORT_INET6) */
142 ntstdio_printf(&ntstdio, "[PING4] size: %d, tmo: %d, host: %s\n", size, tmo, ip2str(NULL, &addr));
143 ping4(&addr, (uint_t)tmo, (uint_t)size);
144#endif /* of #if defined(SUPPORT_INET6) */
145
146 return 0;
147}
148
149static void dhcp4c_info()
150{
151 T_IN4_ADDR svaddr;
152 SYSTIM bind_start;
153 ER ret;
154 uint32_t expire, renew, rebind;
155
156 if ((ret = dhcp4c_get_info(&svaddr, &expire, &renew, &rebind, &bind_start)) == E_OK) {
157 ntstdio_printf(&ntstdio, "DHCPv4 server: %hI,\n", &svaddr);
158 ntstdio_printf(&ntstdio, " Renew: %u:%02u:%02u,\n",
159 renew / 3600, (renew / 60) % 60, renew % 60);
160 ntstdio_printf(&ntstdio, " Rebind: %u:%02u:%02u, Expire: %u:%02u:%02u.\n",
161 rebind / 3600, (rebind / 60) % 60, rebind % 60,
162 expire / 3600, (expire / 60) % 60, expire % 60);
163 }
164 else if (ret == E_OBJ)
165 ntstdio_printf(&ntstdio, "DHCPv4 server: not available.\n");
166}
167
168int usrcmd_dhcp4c(int argc, char **argv)
169{
170 ER ret;
171 if (ntlibc_strcmp(argv[1], "rel") == 0) {
172 ret = dhcp4c_rel_info();
173 ntstdio_printf(&ntstdio, "dhcp4c_rel_info %d\n", ret);
174 }
175 else if (ntlibc_strcmp(argv[1], "renew") == 0) {
176 ret = dhcp4c_renew_info();
177 ntstdio_printf(&ntstdio, "dhcp4c_renew_info %d\n", ret);
178 }
179 else {
180 dhcp4c_info();
181 }
182 return 0;
183}
184
185/*
186* s_show_dns_domain_name -- DNS のドメイン名を表示する。
187*/
188
189static uint_t
190s_show_dns_domain_name(uint8_t *hdr, uint_t offset)
191{
192 uint8_t *ptr;
193 uint_t c;
194
195 ptr = hdr + offset;
196 while (*ptr) {
197 if ((*ptr & DNS_MSG_COMP_MARK) == DNS_MSG_COMP_MARK) {
198 s_show_dns_domain_name(hdr, (*ptr & ~DNS_MSG_COMP_MARK) << 8 | *(ptr + 1));
199 ptr += 2;
200 break;
201 }
202 else {
203 for (c = 1; c <= *ptr; c++)
204 ntstdio_printf(&ntstdio, "%c", *(ptr + c));
205 ptr += *ptr + 1;
206 if (*ptr)
207 ntstdio_printf(&ntstdio, ".");
208 }
209 }
210 return ptr - hdr;
211}
212
213/*
214 * show_dns_soa -- DNS の SOA RDATA を表示する。
215 */
216
217static ER_UINT
218show_dns_soa(uint8_t *msg, ER_UINT length, uint_t offset)
219{
220 T_RSLV_SOA soa;
221 ER_UINT error;
222 uint_t rn_offset;
223
224 if ((error = dns_analyze_soa(&soa, offset, msg, length)) < 0)
225 return error;
226
227 ntstdio_printf(&ntstdio, " mname: ");
228 rn_offset = s_show_dns_domain_name(msg, offset);
229 ntstdio_putc(&ntstdio, '\n');
230 ntstdio_printf(&ntstdio, " rname: ");
231 s_show_dns_domain_name(msg, rn_offset);
232 ntstdio_putc(&ntstdio, '\n');
233
234 ntstdio_printf(&ntstdio, " serial: %d\n", soa.serial);
235 ntstdio_printf(&ntstdio, " refresh: %d\n", soa.refresh);
236 ntstdio_printf(&ntstdio, " retry: %d\n", soa.retry);
237 ntstdio_printf(&ntstdio, " expirel: %d\n", soa.expire);
238 ntstdio_printf(&ntstdio, " minimum: %d\n", soa.minimum);
239
240 return E_OK;
241}
242
243/*
244 * show_dns_qdsection -- DNS の Question セクションを表示する。
245 */
246
247static ER_UINT
248show_dns_qdsection(uint8_t *msg, ER_UINT length, T_RSLV_DNS_MSG *rslv)
249{
250 T_RSLV_QD qd;
251 ER_UINT offset, error;
252 int scount;
253
254 ntstdio_printf(&ntstdio, "question section: %d\n", rslv->dns_hdr.qdcount);
255 offset = rslv->qd_offset;
256 for (scount = 1; scount <= rslv->dns_hdr.qdcount; scount++) {
257 if ((error = dns_analyze_qd(&qd, offset, msg, length)) < 0)
258 return error;
259
260 ntstdio_printf(&ntstdio, "%2d: ", scount);
261 s_show_dns_domain_name(msg, offset);
262 ntstdio_printf(&ntstdio, "\n type: %-4s, class: %2s\n", dns_strtype(qd.type), dns_strclass(qd.class));
263 offset = error;
264 }
265
266 return E_OK;
267}
268
269/*
270 * show_dns_section -- DNS の各セクションを表示する。
271 */
272
273static ER_UINT
274show_dns_section(uint8_t *msg, ER_UINT length, uint_t scount, uint_t offset, char *title)
275{
276 T_RSLV_RR rr;
277 T_IN4_ADDR in4_addr;
278 ER_UINT error;
279 int count, dcount, col;
280 T_IN6_ADDR in6_addr;
281
282 ntstdio_printf(&ntstdio, "%10s section: %d\n", title, scount);
283 for (count = 1; count <= scount; count++) {
284 if ((error = dns_analyze_rr(&rr, offset, msg, length)) < 0)
285 return error;
286
287 ntstdio_printf(&ntstdio, "%2d: ", count);
288 s_show_dns_domain_name(msg, offset);
289 ntstdio_printf(&ntstdio, "\n type: %-4s, class: %2s, TTL: %2d, len: %3d, offset: 0x%02x\n",
290 dns_strtype(rr.type), dns_strclass(rr.class), rr.ttl, rr.rdlength, rr.rdata_offset);
291
292 switch (rr.type) {
293 case DNS_TYPE_A:
294 memcpy((void*)&in4_addr, (void*)(msg + rr.rdata_offset), sizeof(in4_addr));
295 in4_addr = ntohl(in4_addr);
296 ntstdio_printf(&ntstdio, " IPv4 addr: %hI\n", &in4_addr);
297 break;
298 case DNS_TYPE_NS:
299 ntstdio_printf(&ntstdio, " host: ");
300 s_show_dns_domain_name(msg, rr.rdata_offset);
301 ntstdio_putc(&ntstdio, '\n');
302 break;
303 case DNS_TYPE_CNAME:
304 ntstdio_printf(&ntstdio, " host: ");
305 s_show_dns_domain_name(msg, rr.rdata_offset);
306 ntstdio_putc(&ntstdio, '\n');
307 break;
308 case DNS_TYPE_SOA:
309 show_dns_soa(msg, length, rr.rdata_offset);
310 break;
311 case DNS_TYPE_PTR:
312 ntstdio_printf(&ntstdio, " PTR: ");
313 s_show_dns_domain_name(msg, rr.rdata_offset);
314 ntstdio_putc(&ntstdio, '\n');
315 break;
316 case DNS_TYPE_AAAA:
317 memcpy((void*)&in6_addr, (void*)(msg + rr.rdata_offset), sizeof(in6_addr));
318 ntstdio_printf(&ntstdio, " IPv6 addr: %lI\n", &in6_addr);
319 break;
320 default:
321 ntstdio_printf(&ntstdio, " data: ");
322 col = 32;
323 for (dcount = 0; dcount < rr.rdlength; dcount++) {
324 ntstdio_printf(&ntstdio, "%02x", *(msg + rr.rdata_offset + dcount));
325 if (--col == 0) {
326 ntstdio_printf(&ntstdio, "\n ");
327 col = 32;
328 }
329 }
330 ntstdio_putc(&ntstdio, '\n');
331 break;
332 }
333 }
334
335 return E_OK;
336}
337/*
338 * dns_info -- DNS 情報の表示
339 */
340
341static void dns_info()
342{
343#if defined(SUPPORT_INET6)
344 T_IN6_ADDR in6_addr;
345#endif
346#if defined(SUPPORT_INET4)
347 T_IN4_ADDR in4_addr;
348#endif
349
350#if defined(SUPPORT_INET6)
351
352 ntstdio_printf(&ntstdio, "domain name: %s\n", dns_in6_get_dname());
353
354#else /* of #if defined(SUPPORT_INET6) */
355
356 ntstdio_printf(&ntstdio, "domain name: %s\n", dns_in4_get_dname());
357
358#endif /* of #if defined(SUPPORT_INET6) */
359
360#if defined(SUPPORT_INET6)
361 dns_in6_get_addr(&in6_addr);
362 ntstdio_printf(&ntstdio, "IPv6 DNS server: ");
363 if (IN6_IS_ADDR_UNSPECIFIED(&in6_addr))
364 ntstdio_printf(&ntstdio, "not available.\n");
365 else
366 ntstdio_printf(&ntstdio, "%lI.\n", &in6_addr);
367#endif /* of #if defined(SUPPORT_INET6) */
368
369#if defined(SUPPORT_INET4)
370 dns_in4_get_addr(&in4_addr);
371 ntstdio_printf(&ntstdio, "IPv4 DNS server: ");
372 if (in4_addr == IPV4_ADDRANY)
373 ntstdio_printf(&ntstdio, "not available.\n");
374 else
375 ntstdio_printf(&ntstdio, "%hI.\n", &in4_addr);
376#endif /* of #if defined(SUPPORT_INET4) */
377}
378
379/*
380 * name_lookup -- ホスト名-IP アドレス変換
381 */
382
383const char *rcode_str[] = {
384 "no error",
385 "format error",
386 "server error",
387 "name error",
388 "not implement",
389 "refused",
390};
391
392int usrcmd_dnsc(int argc, char **argv)
393{
394 char *line = argv[1];
395 static char hostname[DBG_LINE_SIZE + 1];
396
397 T_RSLV_DNS_MSG rslv;
398 ER_UINT length, offset;
399 ER error;
400 uint_t flags = 0;
401 uint8_t *msg;
402
403 if (ntlibc_strcmp(line, "info") == 0) {
404 dns_info();
405 return 0;
406 }
407
408 /* コマンドのオプションを設定する。*/
409 line = skip_blanks(resolv_options(&flags, line, DEFAULT_API_PROTO));
410 if ((flags & (DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4)) == 0) {
411 ntstdio_printf(&ntstdio, "DNS server not available.\n");
412 return 0;
413 }
414
415 /* 照会するホスト名・IP アドレスを解析する。*/
416 resolv_hoststr(&flags, hostname, sizeof(hostname), line);
417
418 /* 正引きでも逆引きでもプロトコル上は正引きを指定する。*/
419 flags |= DNS_LUP_OPCODE_FORWARD;
420
421 /* IPv6 アドレス、または IPv4 アドレスが指定された時は、照会タイプは PTR に設定する。*/
422 if (((flags & DNS_LUP_FLAGS_NAME_MASK) == DNS_LUP_FLAGS_NAME_IPV6) ||
423 ((flags & DNS_LUP_FLAGS_NAME_MASK) == DNS_LUP_FLAGS_NAME_IPV4))
424 flags = (flags & ~DNS_LUP_FLAGS_QTYPE_MASK) | DNS_LUP_FLAGS_QTYPE_PTR;
425
426 if ((error = tget_mpf(MPF_RSLV_SRBUF, (void*)&msg, TMO_FEVR)) != E_OK) {
427 ntstdio_printf(&ntstdio, "get buffer error: %s.\n", itron_strerror(error));
428 return 0;
429 }
430
431 if ((length = dns_lookup_host(flags | DNS_LUP_FLAGS_MSG, line, msg, DNS_UDP_MSG_LENGTH, &rslv)) < 0) {
432 //ntstdio_printf(&ntstdio, "error: %s.\n", itron_strerror(length));
433 goto err_ret;
434 }
435
436 dly_tsk(1 * 1000);
437 ntstdio_printf(&ntstdio, "DNS header: flags: ");
438 if (rslv.dns_hdr.code & (DNS_QR_RESPONSE | DNS_AUTHORITATIVE |
439 DNS_TRUN_CATION | DNS_RECURSION_DESIRED | DNS_RECURSION_AVAILABLE)) {
440 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_QR_RESPONSE) ? "QR," : "");
441 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_AUTHORITATIVE) ? "AA," : "");
442 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_TRUN_CATION) ? "TC," : "");
443 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_RECURSION_DESIRED) ? "RD," : "");
444 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_RECURSION_AVAILABLE) ? "RA," : "");
445 ntstdio_printf(&ntstdio, " ");
446 }
447 ntstdio_printf(&ntstdio, "opcode: ");
448 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_OPCODE_REVERSE) ? "RV" : "FW");
449 ntstdio_printf(&ntstdio, (rslv.dns_hdr.code & DNS_OPCODE_STATUS) ? ",ST" : "");
450 ntstdio_printf(&ntstdio, ", rcode: %s.\n",
451 (rslv.dns_hdr.code & DNS_RCODE_MASK) > DNS_RCODE_REFUSED
452 ? "6" : rcode_str[rslv.dns_hdr.code & DNS_RCODE_MASK]);
453
454 if ((offset = show_dns_qdsection(msg, length, &rslv)) < 0) {
455 ntstdio_printf(&ntstdio, "msg error: %s.\n", itron_strerror(offset));
456 }
457 if ((offset = show_dns_section(msg, length, rslv.dns_hdr.ancount, rslv.an_offset, "answer")) < 0) {
458 ntstdio_printf(&ntstdio, "msg error: %s.\n", itron_strerror(offset));
459 }
460 if ((offset = show_dns_section(msg, length, rslv.dns_hdr.nscount, rslv.ns_offset, "authority")) < 0) {
461 ntstdio_printf(&ntstdio, "msg error: %s.\n", itron_strerror(offset));
462 }
463 if ((offset = show_dns_section(msg, length, rslv.dns_hdr.arcount, rslv.ar_offset, "additional")) < 0) {
464 ntstdio_printf(&ntstdio, "msg error: %s.\n", itron_strerror(offset));
465 }
466
467err_ret:
468 if ((error = rel_mpf(MPF_RSLV_SRBUF, msg)) != E_OK)
469 ntstdio_printf(&ntstdio, "release buffer error: %s.\n", itron_strerror(error));
470 return 0;
471}
472
473int usrcmd_ntpc(int argc, char **argv)
474{
475 ntp_cli_execute();
476 return 0;
477}
Note: See TracBrowser for help on using the repository browser.