Home | History | Annotate | Download | only in commands
      1 /*
      2  * Copyright (C) 2007 Michael Brown <mbrown (at) 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 <stdint.h>
     23 #include <stdlib.h>
     24 #include <stdio.h>
     25 #include <errno.h>
     26 #include <stddef.h>
     27 #include <string.h>
     28 #include <assert.h>
     29 #include <getopt.h>
     30 #include <gpxe/netdevice.h>
     31 #include <gpxe/in.h>
     32 #include <gpxe/command.h>
     33 #include <usr/dhcpmgmt.h>
     34 
     35 /** @file
     36  *
     37  * DHCP management commands
     38  *
     39  */
     40 
     41 /**
     42  * "dhcp" command syntax message
     43  *
     44  * @v argv		Argument list
     45  */
     46 static void dhcp_syntax ( char **argv ) {
     47 	printf ( "Usage:\n"
     48 		 "  %s <interface>\n"
     49 		 "\n"
     50 		 "Configure a network interface using DHCP\n",
     51 		 argv[0] );
     52 }
     53 
     54 /**
     55  * The "dhcp" command
     56  *
     57  * @v argc		Argument count
     58  * @v argv		Argument list
     59  * @ret rc		Exit code
     60  */
     61 static int dhcp_exec ( int argc, char **argv ) {
     62 	static struct option longopts[] = {
     63 		{ "help", 0, NULL, 'h' },
     64 		{ NULL, 0, NULL, 0 },
     65 	};
     66 	const char *netdev_txt;
     67 	struct net_device *netdev;
     68 	int c;
     69 	int rc;
     70 
     71 	/* Parse options */
     72 	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
     73 		switch ( c ) {
     74 		case 'h':
     75 			/* Display help text */
     76 		default:
     77 			/* Unrecognised/invalid option */
     78 			dhcp_syntax ( argv );
     79 			return 1;
     80 		}
     81 	}
     82 
     83 	/* Need exactly one interface name remaining after the options */
     84 	if ( optind != ( argc - 1 ) ) {
     85 		dhcp_syntax ( argv );
     86 		return 1;
     87 	}
     88 	netdev_txt = argv[optind];
     89 
     90 	/* Parse arguments */
     91 	netdev = find_netdev ( netdev_txt );
     92 	if ( ! netdev ) {
     93 		printf ( "No such interface: %s\n", netdev_txt );
     94 		return 1;
     95 	}
     96 
     97 	/* Perform DHCP */
     98 	if ( ( rc = dhcp ( netdev ) ) != 0 ) {
     99 		printf ( "Could not configure %s: %s\n", netdev->name,
    100 			 strerror ( rc ) );
    101 		return 1;
    102 	}
    103 
    104 	return 0;
    105 }
    106 
    107 /**
    108  * "pxebs" command syntax message
    109  *
    110  * @v argv		Argument list
    111  */
    112 static void pxebs_syntax ( char **argv ) {
    113 	printf ( "Usage:\n"
    114 		 "  %s <interface> <server_type>\n"
    115 		 "\n"
    116 		 "Perform PXE Boot Server discovery\n",
    117 		 argv[0] );
    118 }
    119 
    120 /**
    121  * The "pxebs" command
    122  *
    123  * @v argc		Argument count
    124  * @v argv		Argument list
    125  * @ret rc		Exit code
    126  */
    127 static int pxebs_exec ( int argc, char **argv ) {
    128 	static struct option longopts[] = {
    129 		{ "help", 0, NULL, 'h' },
    130 		{ NULL, 0, NULL, 0 },
    131 	};
    132 	const char *netdev_txt;
    133 	const char *pxe_type_txt;
    134 	struct net_device *netdev;
    135 	unsigned int pxe_type;
    136 	char *end;
    137 	int c;
    138 	int rc;
    139 
    140 	/* Parse options */
    141 	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
    142 		switch ( c ) {
    143 		case 'h':
    144 			/* Display help text */
    145 		default:
    146 			/* Unrecognised/invalid option */
    147 			pxebs_syntax ( argv );
    148 			return 1;
    149 		}
    150 	}
    151 	if ( optind != ( argc - 2 ) ) {
    152 		pxebs_syntax ( argv );
    153 		return 1;
    154 	}
    155 	netdev_txt = argv[optind];
    156 	pxe_type_txt = argv[ optind + 1 ];
    157 
    158 	/* Parse arguments */
    159 	netdev = find_netdev ( netdev_txt );
    160 	if ( ! netdev ) {
    161 		printf ( "No such interface: %s\n", netdev_txt );
    162 		return 1;
    163 	}
    164 	pxe_type = strtoul ( pxe_type_txt, &end, 0 );
    165 	if ( *end ) {
    166 		printf ( "Bad server type: %s\n", pxe_type_txt );
    167 		return 1;
    168 	}
    169 
    170 	/* Perform Boot Server Discovery */
    171 	if ( ( rc = pxebs ( netdev, pxe_type ) ) != 0 ) {
    172 		printf ( "Could not discover boot server on %s: %s\n",
    173 			 netdev->name, strerror ( rc ) );
    174 		return 1;
    175 	}
    176 
    177 	return 0;
    178 }
    179 
    180 /** DHCP management commands */
    181 struct command dhcp_commands[] __command = {
    182 	{
    183 		.name = "dhcp",
    184 		.exec = dhcp_exec,
    185 	},
    186 	{
    187 		.name = "pxebs",
    188 		.exec = pxebs_exec,
    189 	},
    190 };
    191