1 /*
2 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 FILE_LICENCE ( GPL2_OR_LATER );
20
21 #include <stdio.h>
22 #include <getopt.h>
23 #include <gpxe/netdevice.h>
24 #include <gpxe/command.h>
25 #include <usr/ifmgmt.h>
26 #include <hci/ifmgmt_cmd.h>
27
28 /** @file
29 *
30 * Network interface management commands
31 *
32 */
33
34 /** Options shared by all if<xxx> commands */
35 static struct option ifcommon_longopts[] = {
36 { "help", 0, NULL, 'h' },
37 { NULL, 0, NULL, 0 },
38 };
39
40 /**
41 * Print syntax of if<xxx> command
42 *
43 * @v argv Command arguments
44 * @v verb Verb describing the action of the command
45 */
ifcommon_syntax(char ** argv,const char * verb)46 static void ifcommon_syntax ( char **argv, const char *verb ) {
47 printf ( "Usage:\n"
48 " %s [<interface>] [<interface>...]\n"
49 "\n"
50 "%s the specified network interfaces\n",
51 argv[0], verb );
52 }
53
54 /**
55 * Execute if<xxx> command over all network devices
56 *
57 * @v payload Command to execute
58 * @ret rc Exit code
59 */
ifcommon_do_all(int (* payload)(struct net_device *))60 static int ifcommon_do_all ( int ( * payload ) ( struct net_device * ) ) {
61 struct net_device *netdev;
62 int rc = 0;
63
64 /* Execute payload for each network device */
65 for_each_netdev ( netdev ) {
66 if ( payload ( netdev ) != 0 )
67 rc = 1;
68 }
69 return rc;
70 }
71
72 /**
73 * Execute if<xxx> command over list of network devices
74 *
75 * @v payload Command to execute
76 * @ret rc Exit code
77 */
ifcommon_do_list(int (* payload)(struct net_device *),char ** list,unsigned int count)78 static int ifcommon_do_list ( int ( * payload ) ( struct net_device * ),
79 char **list, unsigned int count ) {
80 const char *netdev_name;
81 struct net_device *netdev;
82 int rc = 0;
83
84 while ( count-- ) {
85 netdev_name = *(list++);
86 netdev = find_netdev ( netdev_name );
87 if ( ! netdev ) {
88 printf ( "%s: no such interface\n", netdev_name );
89 rc = 1;
90 continue;
91 }
92 if ( payload ( netdev ) != 0 )
93 rc = 1;
94 }
95 return rc;
96 }
97
98 /**
99 * Execute if<xxx> command
100 *
101 * @v argc Argument count
102 * @v argv Argument list
103 * @v payload Command to execute
104 * @v verb Verb describing the action of the command
105 * @ret rc Exit code
106 */
ifcommon_exec(int argc,char ** argv,int (* payload)(struct net_device *),const char * verb)107 int ifcommon_exec ( int argc, char **argv,
108 int ( * payload ) ( struct net_device * ),
109 const char *verb ) {
110 int c;
111
112 /* Parse options */
113 while ( ( c = getopt_long ( argc, argv, "h", ifcommon_longopts,
114 NULL ) ) >= 0 ) {
115 switch ( c ) {
116 case 'h':
117 /* Display help text */
118 default:
119 /* Unrecognised/invalid option */
120 ifcommon_syntax ( argv, verb );
121 return 1;
122 }
123 }
124
125 if ( optind == argc ) {
126 return ifcommon_do_all ( payload );
127 } else {
128 return ifcommon_do_list ( payload, &argv[optind],
129 ( argc - optind ) );
130 }
131 }
132
133 /* "ifopen" command */
134
ifopen_payload(struct net_device * netdev)135 static int ifopen_payload ( struct net_device *netdev ) {
136 return ifopen ( netdev );
137 }
138
ifopen_exec(int argc,char ** argv)139 static int ifopen_exec ( int argc, char **argv ) {
140 return ifcommon_exec ( argc, argv, ifopen_payload, "Open" );
141 }
142
143 /* "ifclose" command */
144
ifclose_payload(struct net_device * netdev)145 static int ifclose_payload ( struct net_device *netdev ) {
146 ifclose ( netdev );
147 return 0;
148 }
149
ifclose_exec(int argc,char ** argv)150 static int ifclose_exec ( int argc, char **argv ) {
151 return ifcommon_exec ( argc, argv, ifclose_payload, "Close" );
152 }
153
154 /* "ifstat" command */
155
ifstat_payload(struct net_device * netdev)156 static int ifstat_payload ( struct net_device *netdev ) {
157 ifstat ( netdev );
158 return 0;
159 }
160
ifstat_exec(int argc,char ** argv)161 static int ifstat_exec ( int argc, char **argv ) {
162 return ifcommon_exec ( argc, argv,
163 ifstat_payload, "Display status of" );
164 }
165
166 /** Interface management commands */
167 struct command ifmgmt_commands[] __command = {
168 {
169 .name = "ifopen",
170 .exec = ifopen_exec,
171 },
172 {
173 .name = "ifclose",
174 .exec = ifclose_exec,
175 },
176 {
177 .name = "ifstat",
178 .exec = ifstat_exec,
179 },
180 };
181