| /* |
| * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License as |
| * published by the Free Software Foundation; either version 2 of the |
| * License, or any later version. |
| * |
| * This program is distributed in the hope that it will be useful, but |
| * WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| * 02110-1301, USA. |
| * |
| * You can also choose to distribute this program under the terms of |
| * the Unmodified Binary Distribution Licence (as given in the file |
| * COPYING.UBDL), provided that you have satisfied its requirements. |
| */ |
| |
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); |
| |
| #include <stdio.h> |
| #include <errno.h> |
| #include <getopt.h> |
| #include <ipxe/netdevice.h> |
| #include <ipxe/command.h> |
| #include <ipxe/parseopt.h> |
| #include <usr/ifmgmt.h> |
| #include <hci/ifmgmt_cmd.h> |
| |
| /** @file |
| * |
| * Network interface management commands |
| * |
| */ |
| |
| /** |
| * Execute if<xxx> command |
| * |
| * @v argc Argument count |
| * @v argv Argument list |
| * @v cmd Command descriptor |
| * @v payload Command to execute |
| * @v verb Verb describing the action of the command |
| * @ret rc Return status code |
| */ |
| int ifcommon_exec ( int argc, char **argv, |
| struct ifcommon_command_descriptor *ifcmd ) { |
| struct command_descriptor *cmd = &ifcmd->cmd; |
| uint8_t opts[cmd->len]; |
| struct net_device *netdev; |
| int i; |
| int rc; |
| |
| /* Parse options */ |
| if ( ( rc = parse_options ( argc, argv, cmd, opts ) ) != 0 ) |
| return rc; |
| |
| if ( optind != argc ) { |
| /* Treat arguments as a list of interfaces to try */ |
| for ( i = optind ; i < argc ; i++ ) { |
| if ( ( rc = parse_netdev ( argv[i], &netdev ) ) != 0 ) |
| continue; |
| if ( ( ( rc = ifcmd->payload ( netdev, opts ) ) == 0 ) |
| && ifcmd->stop_on_first_success ) { |
| return 0; |
| } |
| } |
| } else { |
| /* Try all interfaces */ |
| rc = -ENODEV; |
| for_each_netdev ( netdev ) { |
| if ( ( ( rc = ifcmd->payload ( netdev, opts ) ) == 0 ) |
| && ifcmd->stop_on_first_success ) { |
| return 0; |
| } |
| } |
| } |
| |
| return rc; |
| } |
| |
| /** "ifopen" options */ |
| struct ifopen_options {}; |
| |
| /** "ifopen" option list */ |
| static struct option_descriptor ifopen_opts[] = {}; |
| |
| /** |
| * "ifopen" payload |
| * |
| * @v netdev Network device |
| * @v opts Command options |
| * @ret rc Return status code |
| */ |
| static int ifopen_payload ( struct net_device *netdev, |
| struct ifopen_options *opts __unused ) { |
| return ifopen ( netdev ); |
| } |
| |
| /** "ifopen" command descriptor */ |
| static struct ifcommon_command_descriptor ifopen_cmd = |
| IFCOMMON_COMMAND_DESC ( struct ifopen_options, ifopen_opts, |
| 0, MAX_ARGUMENTS, "[<interface>...]", |
| ifopen_payload, 0 ); |
| |
| /** |
| * The "ifopen" command |
| * |
| * @v argc Argument count |
| * @v argv Argument list |
| * @ret rc Return status code |
| */ |
| static int ifopen_exec ( int argc, char **argv ) { |
| return ifcommon_exec ( argc, argv, &ifopen_cmd ); |
| } |
| |
| /** "ifclose" options */ |
| struct ifclose_options {}; |
| |
| /** "ifclose" option list */ |
| static struct option_descriptor ifclose_opts[] = {}; |
| |
| /** |
| * "ifclose" payload |
| * |
| * @v netdev Network device |
| * @v opts Command options |
| * @ret rc Return status code |
| */ |
| static int ifclose_payload ( struct net_device *netdev, |
| struct ifclose_options *opts __unused ) { |
| ifclose ( netdev ); |
| return 0; |
| } |
| |
| /** "ifclose" command descriptor */ |
| static struct ifcommon_command_descriptor ifclose_cmd = |
| IFCOMMON_COMMAND_DESC ( struct ifclose_options, ifclose_opts, |
| 0, MAX_ARGUMENTS, "[<interface>...]", |
| ifclose_payload, 0 ); |
| |
| /** |
| * The "ifclose" command |
| * |
| * @v argc Argument count |
| * @v argv Argument list |
| * @ret rc Return status code |
| */ |
| static int ifclose_exec ( int argc, char **argv ) { |
| return ifcommon_exec ( argc, argv, &ifclose_cmd ); |
| } |
| |
| /** "ifstat" options */ |
| struct ifstat_options {}; |
| |
| /** "ifstat" option list */ |
| static struct option_descriptor ifstat_opts[] = {}; |
| |
| /** |
| * "ifstat" payload |
| * |
| * @v netdev Network device |
| * @v opts Command options |
| * @ret rc Return status code |
| */ |
| static int ifstat_payload ( struct net_device *netdev, |
| struct ifstat_options *opts __unused ) { |
| ifstat ( netdev ); |
| return 0; |
| } |
| |
| /** "ifstat" command descriptor */ |
| static struct ifcommon_command_descriptor ifstat_cmd = |
| IFCOMMON_COMMAND_DESC ( struct ifstat_options, ifstat_opts, |
| 0, MAX_ARGUMENTS, "[<interface>...]", |
| ifstat_payload, 0 ); |
| |
| /** |
| * The "ifstat" command |
| * |
| * @v argc Argument count |
| * @v argv Argument list |
| * @ret rc Return status code |
| */ |
| static int ifstat_exec ( int argc, char **argv ) { |
| return ifcommon_exec ( argc, argv, &ifstat_cmd ); |
| } |
| |
| /** "ifconf" options */ |
| struct ifconf_options { |
| /** Configuration timeout */ |
| unsigned long timeout; |
| /** Configurator */ |
| struct net_device_configurator *configurator; |
| }; |
| |
| /** "ifconf" option list */ |
| static struct option_descriptor ifconf_opts[] = { |
| OPTION_DESC ( "configurator", 'c', required_argument, |
| struct ifconf_options, configurator, |
| parse_netdev_configurator ), |
| OPTION_DESC ( "timeout", 't', required_argument, |
| struct ifconf_options, timeout, |
| parse_timeout ), |
| }; |
| |
| /** |
| * "ifconf" payload |
| * |
| * @v netdev Network device |
| * @v opts Command options |
| * @ret rc Return status code |
| */ |
| static int ifconf_payload ( struct net_device *netdev, |
| struct ifconf_options *opts ) { |
| int rc; |
| |
| /* Attempt configuration */ |
| if ( ( rc = ifconf ( netdev, opts->configurator, |
| opts->timeout ) ) != 0 ) { |
| |
| /* Close device on failure, to avoid memory exhaustion */ |
| netdev_close ( netdev ); |
| |
| return rc; |
| } |
| |
| return 0; |
| } |
| |
| /** "ifconf" command descriptor */ |
| static struct ifcommon_command_descriptor ifconf_cmd = |
| IFCOMMON_COMMAND_DESC ( struct ifconf_options, ifconf_opts, |
| 0, MAX_ARGUMENTS, "[<interface>...]", |
| ifconf_payload, 1 ); |
| |
| /** |
| * The "ifconf" command |
| * |
| * @v argc Argument count |
| * @v argv Argument list |
| * @ret rc Return status code |
| */ |
| int ifconf_exec ( int argc, char **argv ) { |
| return ifcommon_exec ( argc, argv, &ifconf_cmd ); |
| } |
| |
| /** "iflinkwait" option list */ |
| struct iflinkwait_options { |
| /** Link timeout */ |
| unsigned long timeout; |
| }; |
| |
| /** "iflinkwait" option list */ |
| static struct option_descriptor iflinkwait_opts[] = { |
| OPTION_DESC ( "timeout", 't', required_argument, |
| struct iflinkwait_options, timeout, parse_timeout ), |
| }; |
| |
| /** |
| * "iflinkwait" payload |
| * |
| * @v netdev Network device |
| * @v opts Command options |
| * @ret rc Return status code |
| */ |
| static int iflinkwait_payload ( struct net_device *netdev, |
| struct iflinkwait_options *opts ) { |
| int rc; |
| |
| /* Wait for link-up */ |
| if ( ( rc = iflinkwait ( netdev, opts->timeout, 1 ) ) != 0 ) { |
| |
| /* Close device on failure, to avoid memory exhaustion */ |
| netdev_close ( netdev ); |
| |
| return rc; |
| } |
| |
| return 0; |
| } |
| |
| /** "iflinkwait" command descriptor */ |
| static struct ifcommon_command_descriptor iflinkwait_cmd = |
| IFCOMMON_COMMAND_DESC ( struct iflinkwait_options, iflinkwait_opts, |
| 0, MAX_ARGUMENTS, "[<interface>...]", |
| iflinkwait_payload, 1 ); |
| |
| /** |
| * The "iflinkwait" command |
| * |
| * @v argc Argument count |
| * @v argv Argument list |
| * @ret rc Return status code |
| */ |
| static int iflinkwait_exec ( int argc, char **argv ) { |
| return ifcommon_exec ( argc, argv, &iflinkwait_cmd ); |
| } |
| |
| /** Interface management commands */ |
| struct command ifmgmt_commands[] __command = { |
| { |
| .name = "ifopen", |
| .exec = ifopen_exec, |
| }, |
| { |
| .name = "ifclose", |
| .exec = ifclose_exec, |
| }, |
| { |
| .name = "ifstat", |
| .exec = ifstat_exec, |
| }, |
| { |
| .name = "ifconf", |
| .exec = ifconf_exec, |
| }, |
| { |
| .name = "iflinkwait", |
| .exec = iflinkwait_exec, |
| }, |
| }; |