GadgetSeed  0.9.6
com_net.c
[詳解]
1 /** @file
2  @brief ネット関連コマンド
3 
4  @date 2011.05.08
5  @author Takashi SHUDO
6 
7  @section net_command netコマンド
8 
9  net コマンドには以下のサブコマンドがあります。
10 
11  | サブコマンド | 機能 | 詳細 |
12  |:------------------|:------------------------------|:----------------------|
13  | arp | @copybrief com_net_arp | @ref com_net_arp |
14  | ip | @copybrief com_net_ip | @ref com_net_ip |
15  | dhcp | @copybrief com_net_dhcp | @ref com_net_dhcp |
16  | up | @copybrief com_net_up | @ref com_net_up |
17  | down | @copybrief com_net_down | @ref com_net_down |
18  | dns | @copybrief com_net_dns | @ref com_net_dns |
19  | httpget | @copybrief com_net_httpget | @ref com_net_httpget |
20 */
21 
22 #include "shell.h"
23 #include "device.h"
24 #include "str.h"
25 #include "tprintf.h"
26 #include "net.h"
27 
28 #ifdef GSC_COMP_ENABLE_FATFS
29 #include "file.h"
30 #endif
31 
32 #include "device/ether_ioctl.h"
33 
34 #include "lwip/etharp.h"
35 #include "lwip/tcpip.h"
36 #include "lwip/dhcp.h"
37 #include "lwip/netifapi.h"
38 #include "lwip/netdb.h"
39 #include "lwip/dns.h"
40 
41 //#define DEBUGTBITS 0x02
42 #include "dtprintf.h"
43 
44 
45 extern struct netif netif;
46 
47 
48 static int arp(int argc, uchar *argv[]);
49 
50 /**
51  @brief ARPテーブルを表示する
52 */
53 static const struct st_shell_command com_net_arp = {
54  .name = "arp",
55  .command = arp,
56  .usage_str = "",
57  .manual_str = "Display ARP tables",
58 };
59 
60 static int arp(int argc, uchar *argv[])
61 {
62  int i;
63 
64  tprintf("Address HW Address\n");
65  tprintf("--------------- -----------------\n");
66  for(i=0; i<ARP_TABLE_SIZE; i++) {
67  ip4_addr_t *ip;
68  struct netif *nif;
69  struct eth_addr *ethaddr;
70 
71  if(etharp_get_entry(i, &ip, &nif, &ethaddr) != 0) {
72  tprintf("%15s", ip4addr_ntoa(ip));
73  tprintf(" %02X:%02X:%02X:%02X:%02X:%02X\n",
74  (int)ethaddr->addr[0],
75  (int)ethaddr->addr[1],
76  (int)ethaddr->addr[2],
77  (int)ethaddr->addr[3],
78  (int)ethaddr->addr[4],
79  (int)ethaddr->addr[5]);
80  }
81  }
82 
83  return 0;
84 }
85 
86 
87 static int ip(int argc, uchar *argv[]);
88 
89 /**
90  @brief IPアドレス、ネットマスク、デフォルトゲートウェイを設定する
91 */
92 static const struct st_shell_command com_net_ip = {
93  .name = "ip",
94  .command = ip,
95  .usage_str = "[ip_address] [mask <mask_address>] [gw <gw_address>]",
96  .manual_str = "Set network address",
97 };
98 
99 static int ip(int argc, uchar *argv[])
100 {
101  const ip4_addr_t *addr;
102  ip4_addr_t ipaddr = {.addr = 0}, netmask = {.addr = 0}, gateway = {.addr = 0};
103 
104  tprintf("MAC Address : %02X:%02X:%02X:%02X:%02X:%02X\n",
105  netif.hwaddr[0],
106  netif.hwaddr[1],
107  netif.hwaddr[2],
108  netif.hwaddr[3],
109  netif.hwaddr[4],
110  netif.hwaddr[5]);
111 
112  if(argc == 1) {
113  int stat;
114 
115  stat = net_status();
116  if(stat & IORTN_BIT_ETHER_LINK_UP) {
117  tprintf("Link UP,");
118  } else {
119  tprintf("Link Down,");
120  }
121  if(stat & IORTN_BIT_ETHER_100M) {
122  tprintf(" 100baseT");
123  } else {
124  tprintf(" 10baseT");
125  }
126  if(stat & IORTN_BIT_ETHER_FULLDUPLEX) {
127  tprintf("/Full");
128  } else {
129  tprintf("/Half");
130  }
131  tprintf("\n");
132 
133  addr = netif_ip4_addr(&netif);
134  tprintf("IP Address : %s\n", ip4addr_ntoa(addr));
135  addr = netif_ip4_netmask(&netif);
136  tprintf("Netmask : %s\n", ip4addr_ntoa(addr));
137  addr = netif_ip4_gw(&netif);
138  tprintf("Gateway : %s\n", ip4addr_ntoa(addr));
139 
140  return 0;
141  } else if(argc == 2) {
142  if(ip4addr_aton((char *)argv[1], &ipaddr) == 0) {
143  goto error;
144  }
145  } else if((argc == 4) || (argc == 6)) {
146  int i, opt = 1;
147 
148  if(ip4addr_aton((char *)argv[1], &ipaddr) == 0) {
149  goto error;
150  }
151 
152  if(argc == 6) {
153  opt = 2;
154  }
155 
156  for(i=0; i<opt; i++) {
157  if(strcomp((uchar *)"mask", argv[2+i*2]) == 0) {
158  if(ip4addr_aton((char *)argv[3+i*2], &netmask) == 0) {
159  goto error;
160  }
161  } else if(strcomp((uchar *)"gw", argv[2+i*2]) == 0) {
162  if(ip4addr_aton((char *)argv[3+i*2], &gateway) == 0) {
163  goto error;
164  }
165  } else {
166  goto error;
167  }
168  }
169  }
170 
171  // Set IP, MASK, GW
172  if(ipaddr.addr != 0) {
173  tprintf("IP = %s\n", ip4addr_ntoa(&ipaddr));
174  } else {
175  addr = netif_ip4_addr(&netif);
176  ipaddr = *addr;
177  }
178  if(netmask.addr != 0) {
179  tprintf("MASK = %s\n", ip4addr_ntoa(&netmask));
180  } else {
181  addr = netif_ip4_addr(&netif);
182  netmask = *addr;
183  }
184  if(gateway.addr != 0) {
185  tprintf("GW = %s\n", ip4addr_ntoa(&gateway));
186  } else {
187  addr = netif_ip4_addr(&netif);
188  gateway = *addr;
189  }
190 
191 
192  netif_set_addr(&netif, &ipaddr, &netmask, &gateway);
193 
194  return 0;
195 
196 error:
197  print_command_usage(&com_net_ip);
198 
199  return 0;
200 }
201 
202 static int dhcp(int argc, uchar *argv[]);
203 
204 /**
205  @brief DHCPによりIPアドレス、ネットマスク、デフォルトゲートウェイを設定する
206 */
207 static const struct st_shell_command com_net_dhcp = {
208  .name = "dhcp",
209  .command = dhcp,
210  .usage_str = "[ip_address]",
211  .manual_str = "Start DHCP client",
212 };
213 
214 static int dhcp(int argc, uchar *argv[])
215 {
216  err_t rt = ERR_OK;
217  dhcp_start(&netif);
218  if(rt == ERR_OK) {
219  tprintf("DHCP OK\n");
220  } else {
221  tprintf("DHCP Error\n");
222  }
223 
224  return 0;
225 }
226 
227 
228 static int up(int argc, uchar *argv[]);
229 
230 /**
231  @brief ネットワークインタフェースをリンクアップする
232 */
233 static const struct st_shell_command com_net_up = {
234  .name = "up",
235  .command = up,
236  .manual_str = "Link up network",
237 };
238 
239 static int up(int argc, uchar *argv[])
240 {
241  link_up_net();
242 
243  return 0;
244 }
245 
246 
247 static int down(int argc, uchar *argv[]);
248 
249 /**
250  @brief ネットワークインタフェースをリンクダウンする
251 */
252 static const struct st_shell_command com_net_down = {
253  .name = "down",
254  .command = down,
255  .manual_str = "Link down network",
256 };
257 
258 static int down(int argc, uchar *argv[])
259 {
260  link_down_net();
261 
262  return 0;
263 }
264 
265 
266 static int dns(int argc, uchar *argv[]);
267 
268 /**
269  @brief DNSサーバアドレスを設定する
270 */
271 static const struct st_shell_command com_net_dns = {
272  .name = "dns",
273  .command = dns,
274  .usage_str = "[[dns_ip_address] dns_ip_address2]",
275  .manual_str = "Set DNS address",
276 };
277 
278 static int dns(int argc, uchar *argv[])
279 {
280  const ip_addr_t *addr;
281  ip_addr_t dnsaddr;
282  char *ipstr;
283  int i;
284 
285  if(argc > 1) {
286  if(ipaddr_aton((char *)argv[1], &dnsaddr) == 0) {
287  goto error;
288  }
289  dns_setserver(0, &dnsaddr);
290  if(argc > 2) {
291  if(ipaddr_aton((char *)argv[2], &dnsaddr) == 0) {
292  goto error;
293  }
294  dns_setserver(1, &dnsaddr);
295  }
296  }
297 
298  for(i=0; i<DNS_MAX_SERVERS; i++) {
299  addr = dns_getserver(i);
300  ipstr = ip4addr_ntoa(addr);
301  tprintf("%s\n", ipstr);
302  }
303 
304  return 0;
305 
306 error:
307  print_command_usage(&com_net_dns);
308 
309  return 0;
310 }
311 
312 
313 #ifndef GSC_TARGET_SYSTEM_EMU
314 static int httpget(int argc, uchar *argv[]);
315 
316 /**
317  @brief 指定したURLを表示、またはファイル保存する。
318 */
319 static const struct st_shell_command com_net_httpget = {
320  .name = "httpget",
321  .command = httpget,
322 #ifdef GSC_COMP_ENABLE_FATFS
323  .usage_str = "<URL> [file]",
324 #else
325  .usage_str = "<URL>",
326 #endif
327  .manual_str = "get from URL",
328 };
329 
330 #define MAX_BUF 255
331 
332 static int httpget(int argc, uchar *argv[])
333 {
334  int rtn = 0;
335  struct addrinfo *ainfo = 0;
336  int sock;
337  char send_buf[MAX_BUF + 1];
338  uchar url[MAX_BUF + 1] = {0};
339  uchar path[MAX_BUF + 1] = {0};
340  uchar *p;
341  int fd = 0;
342  int flg_fw = 0;
343 
344  if(argc < 2) {
345  print_command_usage(&com_net_httpget);
346  return 0;
347  }
348 
349 #ifdef GSC_COMP_ENABLE_FATFS
350  if(argc > 2) {
351  fd = open_file((uchar *)argv[2], FA_WRITE | FA_CREATE_ALWAYS);
352  if(fd < 0) {
353  tprintf("Cannot open file \"%s\"\n", argv[2]);
354  return 0;
355  } else {
356  flg_fw = 1;
357  }
358  }
359 #endif
360 
361  strncopy(url, argv[1], MAX_BUF);
362  p = strchar(url, (uchar)'/');
363  if(p != 0) {
364  *p = 0;
365  strncopy(path, p+1, MAX_BUF);
366  }
367 
368  tprintf("URL : %s\n", url);
369  tprintf("PATH : %s\n", path);
370  if(flg_fw != 0) {
371  tprintf("FILE : %s\n", argv[2]);
372  }
373 
374  rtn = lwip_getaddrinfo((const char *)url, "80", 0, &ainfo);
375 
376  if(rtn == 0) {
377  struct sockaddr_in *addr = (struct sockaddr_in *)ainfo->ai_addr;
378  tprintf("%s %d\n", ainfo->ai_canonname, rtn);
379  tprintf("%s\n", inet_ntoa(addr->sin_addr));
380  tprintf("%d %d %d\n", ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
381  } else {
382  tprintf("error %d\n", rtn);
383  return 0;
384  }
385 
386  sock = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
387  if(sock < 0) {
388  tprintf("lwip_socket error %d\n", sock);
389  lwip_freeaddrinfo(ainfo);
390  return 0;
391  }
392 
393  rtn = lwip_connect(sock, ainfo->ai_addr, ainfo->ai_addrlen);
394  if(rtn != 0) {
395  tprintf("lwip_connect error %d\n", rtn);
396  lwip_freeaddrinfo(ainfo);
397  return 0;
398  }
399 
400  tsnprintf(send_buf, MAX_BUF, "GET /%s HTTP/1.1\r\n", path);
401  DTPRINTF(0x04, send_buf);
402  lwip_write(sock, send_buf, strleng((const uchar *)send_buf));
403 
404  tsnprintf(send_buf, MAX_BUF, "Host: localhost\r\n");
405  DTPRINTF(0x04, send_buf);
406  lwip_write(sock, send_buf, strleng((const uchar *)send_buf));
407 
408  tsnprintf(send_buf, MAX_BUF, "\r\n");
409  DTPRINTF(0x04, send_buf);
410  lwip_write(sock, send_buf, strleng((const uchar *)send_buf));
411 
412  while(1) {
413  char buf[MAX_BUF + 1];
414  int read_size;
415  uchar rd;
416 
417  if(cgetcnw(&rd) != 0) {
418  if(rd == ASCII_CTRL_C) {
419  tprintf("Abort.\n");
420  goto close;
421  }
422  }
423 
424  read_size = lwip_read(sock, buf, MAX_BUF);
425  if(read_size > 0) {
426  buf[read_size] = 0;
427  if(flg_fw != 0) {
428 #ifdef GSC_COMP_ENABLE_FATFS
429  int rt = write_file(fd, buf, read_size);
430  tprintf(".");
431  if(rt != read_size) {
432  tprintf("File write error(%d)\n", rt);
433  goto close;
434  }
435 #endif
436  } else {
437  tprintf("%s", buf);
438  }
439  } else {
440  break;
441  }
442  }
443 
444 close:
445 
446 #ifdef GSC_COMP_ENABLE_FATFS
447  if(flg_fw != 0) {
448  close_file(fd);
449  tprintf("\n");
450  }
451 #endif
452 
453  lwip_close(sock);
454 
455  lwip_freeaddrinfo(ainfo);
456 
457  return 0;
458 }
459 #endif // GSC_TARGET_SYSTEM_EMU
460 
461 
462 static const struct st_shell_command * const com_net_list[] = {
463  &com_net_arp,
464  &com_net_ip,
465  &com_net_dhcp,
466  &com_net_up,
467  &com_net_down,
468  &com_net_dns,
469 #ifndef GSC_TARGET_SYSTEM_EMU
471 #endif
472  0
473 };
474 
475 const struct st_shell_command com_net = {
476  .name = "net",
477  .manual_str = "Network operation commands",
478  .sublist = com_net_list
479 }; ///< ネットワーク情報取得
unsigned char uchar
GadgetSeedの文字(列)は unsigned char 型となる
Definition: str.h:13
static const struct st_shell_command com_net_ip
IPアドレス、ネットマスク、デフォルトゲートウェイを設定する
Definition: com_net.c:92
シェルコマンド構造体
Definition: shell.h:33
コマンドシェル
static const struct st_shell_command com_net_dns
DNSサーバアドレスを設定する
Definition: com_net.c:271
Network API
アプリケーション(タスク)デバッグ用マクロ
#define IORTN_BIT_ETHER_LINK_UP
リンクアップ状態
Definition: ether_ioctl.h:17
int cgetcnw(unsigned char *rd)
標準入力より1文字を取得する(待ち無し)
Definition: console.c:235
文字列処理
t_ssize write_file(int fd, const void *buf, t_size count)
ファイルにデータを書き込む
Definition: file.c:216
int close_file(int fd)
ファイルを閉じる
Definition: file.c:297
ファイル
static const struct st_shell_command com_net_dhcp
DHCPによりIPアドレス、ネットマスク、デフォルトゲートウェイを設定する
Definition: com_net.c:207
static const struct st_shell_command com_net_down
ネットワークインタフェースをリンクダウンする
Definition: com_net.c:252
uchar * strchar(const uchar *str, uchar ch)
文字を検索
Definition: str.c:783
static const struct st_shell_command com_net_arp
ARPテーブルを表示する
Definition: com_net.c:53
int strcomp(const uchar *s1, const uchar *s2)
文字列比較
Definition: str.c:583
int open_file(const uchar *path, int flags)
ファイルを開く
Definition: file.c:144
#define IORTN_BIT_ETHER_FULLDUPLEX
全二重状態
Definition: ether_ioctl.h:18
unsigned int strleng(const uchar *str)
文字列長
Definition: str.c:657
static const struct st_shell_command com_net_up
ネットワークインタフェースをリンクアップする
Definition: com_net.c:233
uchar name[12]
コマンド名文字列
Definition: shell.h:34
int tprintf(const char *fmt,...)
簡易printf
Definition: tprintf.c:85
#define IORTN_BIT_ETHER_100M
通信速度100Mbps
Definition: ether_ioctl.h:19
Etherドライバ ioctl 用マクロ定義
uchar * strncopy(uchar *dest, const uchar *src, unsigned int n)
文字列コピー
Definition: str.c:632
デバイスドライバAPI
static const struct st_shell_command com_net_httpget
指定したURLを表示、またはファイル保存する。
Definition: com_net.c:319
機能限定printf
int tsnprintf(char *str, unsigned int size, const char *fmt,...)
簡易snprintf
Definition: tprintf.c:60