Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / SLOF / clients / net-snk / app / netapps / ping.c
1 /******************************************************************************
2  * Copyright (c) 2004, 2008 IBM Corporation
3  * All rights reserved.
4  * This program and the accompanying materials
5  * are made available under the terms of the BSD License
6  * which accompanies this distribution, and is available at
7  * http://www.opensource.org/licenses/bsd-license.php
8  *
9  * Contributors:
10  *     IBM Corporation - initial implementation
11  *****************************************************************************/
12
13 #include <netlib/ipv4.h>
14 #include <netlib/dhcp.h>
15 #include <netlib/ethernet.h>
16 #include <sys/socket.h>
17 #include <string.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <time.h>
21 #include <netapps/args.h>
22 #include "netapps.h"
23
24 struct ping_args {
25         union {
26                 char string[4];
27                 unsigned int integer;
28         } server_ip;
29         union {
30                 char string[4];
31                 unsigned int integer;
32         } client_ip;
33         union {
34                 char string[4];
35                 unsigned int integer;
36         } gateway_ip;
37         unsigned int timeout;
38 };
39
40 static void
41 usage(void)
42 {
43         printf
44             ("\nping device-path:[device-args,]server-ip,[client-ip],[gateway-ip][,timeout]\n");
45
46 }
47
48 static int
49 parse_args(const char *args, struct ping_args *ping_args)
50 {
51         unsigned int argc = get_args_count(args);
52         char buf[64];
53         ping_args->timeout = 10;
54         if (argc == 0)
55                 /* at least server-ip has to be specified */
56                 return -1;
57         if (argc == 1) {
58                 /* probably only server ip is specified */
59                 argncpy(args, 0, buf, 64);
60                 if (!strtoip(buf, ping_args->server_ip.string))
61                         return -1;
62                 return 0;
63         }
64         /* get first option from list */
65         argncpy(args, 0, buf, 64);
66         if (!strtoip(buf, ping_args->server_ip.string)) {
67                 /* it is not an IP address
68                  * therefore it has to be device-args
69                  * device-args are not supported and just ignored */
70                 args = get_arg_ptr(args, 1);
71                 argc--;
72         }
73
74         argncpy(args, 0, buf, 64);
75         if (!strtoip(buf, ping_args->server_ip.string)) {
76                 /* this should have been the server IP address */
77                 return -1;
78         } else {
79                 args = get_arg_ptr(args, 1);
80                 if (!--argc)
81                         return 0;
82         }
83
84         argncpy(args, 0, buf, 64);
85         if (!strtoip(buf, ping_args->client_ip.string)) {
86                 /* this should have been the client (our) IP address */
87                 return -1;
88         } else {
89                 args = get_arg_ptr(args, 1);
90                 if (!--argc)
91                         return 0;
92         }
93         argncpy(args, 0, buf, 64);
94         if (!strtoip(buf, ping_args->gateway_ip.string)) {
95                 /* this should have been the gateway IP address */
96                 return -1;
97         } else {
98                 args = get_arg_ptr(args, 1);
99                 if (!--argc)
100                         return 0;
101         }
102         argncpy(args, 0, buf, 64);
103         ping_args->timeout = strtol(args, 0, 10);
104         return 0;
105 }
106
107 int
108 ping(int argc, char *argv[])
109 {
110         short arp_failed = 0;
111         filename_ip_t fn_ip;
112         int fd_device;
113         struct ping_args ping_args;
114         uint8_t own_mac[6];
115
116         memset(&ping_args, 0, sizeof(struct ping_args));
117
118         if (argc == 2) {
119                 if (parse_args(argv[1], &ping_args)) {
120                         usage();
121                         return -1;
122                 }
123         } else {
124                 usage();
125                 return -1;
126         }
127
128         memset(&fn_ip, 0, sizeof(filename_ip_t));
129
130         /* Get mac_addr from device */
131         printf("\n  Reading MAC address from device: ");
132         fd_device = socket(0, 0, 0, (char *) own_mac);
133         if (fd_device == -1) {
134                 printf("\nE3000: Could not read MAC address\n");
135                 return -100;
136         } else if (fd_device == -2) {
137                 printf("\nE3006: Could not initialize network device\n");
138                 return -101;
139         }
140
141         fn_ip.fd = fd_device;
142
143         printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
144                own_mac[0], own_mac[1], own_mac[2],
145                own_mac[3], own_mac[4], own_mac[5]);
146
147         // init ethernet layer
148         set_mac_address(own_mac);
149         // identify the BOOTP/DHCP server via broadcasts
150         // don't do this, when using DHCP !!!
151         //  fn_ip.server_ip = 0xFFFFFFFF;
152         //  memset(fn_ip.server_mac, 0xff, 6);
153
154         if (!ping_args.client_ip.integer) {
155                 /* Get ip address for our mac address */
156                 printf("  Requesting IP address via DHCP: ");
157                 arp_failed = dhcp(0, &fn_ip, 30, F_IPV4);
158
159                 if (arp_failed == -1) {
160                         printf("\n  DHCP: Could not get ip address\n");
161                         return -1;
162                 }
163
164         } else {
165                 memcpy(&fn_ip.own_ip, &ping_args.client_ip.integer, 4);
166                 arp_failed = 1;
167                 printf("  Own IP address: ");
168         }
169
170         // reinit network stack
171         set_ipv4_address(fn_ip.own_ip);
172
173         printf("%d.%d.%d.%d\n",
174                ((fn_ip.own_ip >> 24) & 0xFF), ((fn_ip.own_ip >> 16) & 0xFF),
175                ((fn_ip.own_ip >> 8) & 0xFF), (fn_ip.own_ip & 0xFF));
176
177         memcpy(&fn_ip.server_ip, &ping_args.server_ip.integer, 4);
178         printf("  Ping to %d.%d.%d.%d ", ((fn_ip.server_ip >> 24) & 0xFF),
179                ((fn_ip.server_ip >> 16) & 0xFF),
180                ((fn_ip.server_ip >> 8) & 0xFF), (fn_ip.server_ip & 0xFF));
181
182
183         ping_ipv4(fd_device, fn_ip.server_ip);
184
185         set_timer(TICKS_SEC / 10 * ping_args.timeout);
186         while(get_timer() > 0) {
187                 receive_ether(fd_device);
188                 if(pong_ipv4() == 0) {
189                         printf("success\n");
190                         return 0;
191                 }
192         }
193
194         printf("failed\n");
195         return -1;
196 }