diff options
author | Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com> | 2023-10-10 14:33:42 +0000 |
---|---|---|
committer | Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com> | 2023-10-10 14:33:42 +0000 |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/SLOF/lib/libnet/ping.c | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/SLOF/lib/libnet/ping.c')
-rw-r--r-- | roms/SLOF/lib/libnet/ping.c | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/roms/SLOF/lib/libnet/ping.c b/roms/SLOF/lib/libnet/ping.c new file mode 100644 index 000000000..6ff6f9f91 --- /dev/null +++ b/roms/SLOF/lib/libnet/ping.c @@ -0,0 +1,225 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <unistd.h> +#include <ipv4.h> +#include <dhcp.h> +#include <ethernet.h> +#include <sys/socket.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include "args.h" +#include "netapps.h" + +struct ping_args { + union { + char string[4]; + unsigned int integer; + } server_ip; + union { + char string[4]; + unsigned int integer; + } client_ip; + union { + char string[4]; + unsigned int integer; + } gateway_ip; + unsigned int timeout; + unsigned int netmask; +}; + +static void +usage(void) +{ + printf + ("\nping device-path:[device-args,]server-ip,[client-ip[\\nn]],[gateway-ip][,timeout]\n"); + +} + +static int +parse_args(const char *args, struct ping_args *ping_args) +{ + unsigned int argc = get_args_count(args); + char buf[64]; + ping_args->timeout = 10; + if (argc == 0) + /* at least server-ip has to be specified */ + return -1; + if (argc == 1) { + /* probably only server ip is specified */ + argncpy(args, 0, buf, 64); + if (!strtoip(buf, ping_args->server_ip.string)) + return -1; + return 0; + } + /* get first option from list */ + argncpy(args, 0, buf, 64); + if (!strtoip(buf, ping_args->server_ip.string)) { + /* it is not an IP address + * therefore it has to be device-args + * device-args are not supported and just ignored */ + args = get_arg_ptr(args, 1); + argc--; + } + + argncpy(args, 0, buf, 64); + if (!strtoip(buf, ping_args->server_ip.string)) { + /* this should have been the server IP address */ + return -1; + } else { + args = get_arg_ptr(args, 1); + if (!--argc) + return 0; + } + + argncpy(args, 0, buf, 64); + if (!strtoip_netmask(buf, ping_args->client_ip.string, &ping_args->netmask)) { + /* this should have been the client (our) IP address */ + return -1; + } else { + args = get_arg_ptr(args, 1); + if (!--argc) + return 0; + } + argncpy(args, 0, buf, 64); + if (!strtoip(buf, ping_args->gateway_ip.string)) { + /* this should have been the gateway IP address */ + return -1; + } else { + args = get_arg_ptr(args, 1); + if (!--argc) + return 0; + } + argncpy(args, 0, buf, 64); + ping_args->timeout = strtol(args, 0, 10); + return 0; +} + +int ping(char *args_fs, unsigned alen) +{ + short arp_failed = 0; + filename_ip_t fn_ip; + int fd_device; + struct ping_args ping_args; + uint8_t own_mac[6]; + uint32_t netmask; + char args[256]; + int ret = -1; + + memset(&ping_args, 0, sizeof(struct ping_args)); + + if (alen == 0 || alen >= sizeof(args) - 1) { + usage(); + return -1; + } + + /* Convert forth string into NUL-terminated C-string */ + memcpy(args, args_fs, alen); + args[alen] = 0; + + if (parse_args(args, &ping_args)) { + usage(); + return -1; + } + + memset(&fn_ip, 0, sizeof(filename_ip_t)); + + /* Get mac_addr from device */ + printf("\n Reading MAC address from device: "); + fd_device = socket(AF_INET, SOCK_DGRAM, 0, (char *) own_mac); + if (fd_device == -1) { + printf("\nE3000: Could not read MAC address\n"); + return -100; + } else if (fd_device == -2) { + printf("\nE3006: Could not initialize network device\n"); + return -101; + } + + fn_ip.fd = fd_device; + + printf("%02x:%02x:%02x:%02x:%02x:%02x\n", + own_mac[0], own_mac[1], own_mac[2], + own_mac[3], own_mac[4], own_mac[5]); + + // init ethernet layer + set_mac_address(own_mac); + // identify the BOOTP/DHCP server via broadcasts + // don't do this, when using DHCP !!! + // fn_ip.server_ip = 0xFFFFFFFF; + // memset(fn_ip.server_mac, 0xff, 6); + + if (!ping_args.client_ip.integer) { + /* Get ip address for our mac address */ + arp_failed = dhcp(0, &fn_ip, 30, F_IPV4); + + if (arp_failed == -1) { + printf("\n DHCP: Could not get ip address\n"); + goto free_out; + } + + } else { + memcpy(&fn_ip.own_ip, &ping_args.client_ip.integer, 4); + if (ping_args.gateway_ip.integer) + set_ipv4_router(ping_args.gateway_ip.integer); + if (!ping_args.netmask) { + /* Netmask is not provided, assume default according to + * the network class + */ + ping_args.netmask = get_default_ipv4_netmask(ping_args.client_ip.string); + } + set_ipv4_netmask(ping_args.netmask); + + arp_failed = 1; + } + + // reinit network stack + set_ipv4_address(fn_ip.own_ip); + + printf(" Own IP address: %d.%d.%d.%d\n", + ((fn_ip.own_ip >> 24) & 0xFF), ((fn_ip.own_ip >> 16) & 0xFF), + ((fn_ip.own_ip >> 8) & 0xFF), (fn_ip.own_ip & 0xFF)); + + netmask = get_ipv4_netmask(); + if (netmask) { + printf(" Netmask : "); + printf("%d.%d.%d.%d\n", ((netmask >> 24) & 0xFF), ((netmask >> 16) & 0xFF), + ((netmask >> 8) & 0xFF), (netmask & 0xFF)); + } + + memcpy(&fn_ip.server_ip, &ping_args.server_ip.integer, 4); + printf(" Ping to %d.%d.%d.%d ", ((fn_ip.server_ip >> 24) & 0xFF), + ((fn_ip.server_ip >> 16) & 0xFF), + ((fn_ip.server_ip >> 8) & 0xFF), (fn_ip.server_ip & 0xFF)); + + + ping_ipv4(fd_device, fn_ip.server_ip); + + set_timer(TICKS_SEC / 10 * ping_args.timeout); + while(get_timer() > 0) { + receive_ether(fd_device); + if(pong_ipv4() == 0) { + printf("success\n"); + ret = 0; + goto free_out; + } + } + + printf("failed\n"); +free_out: + free(fn_ip.pl_cfgfile); + free(fn_ip.pl_prefix); + close(fn_ip.fd); + + return ret; +} |