/*
  Last updated : Mon Sep 23 16:22:27 1996
  Modified by JSP from code by Charles Hawkins <ceh@eng.cam.ac.uk>,

    J.S.Peatfield@damtp.cam.ac.uk

  Copyright (c) University of Cambridge, 1993-1996
  See the file NOTICE for conditions of use and distribution.

  $Revision: 1.3 $
  $Date: 1998/12/15 03:43:00 $
*/

/* Standard headers */
#include <stdio.h>
#include <netinet/in.h>
#include <net/if.h>
#include <getopt.h>
#include <stdlib.h>
#include <errno.h>

#include "bootpc.h"

FILE * logfile = stderr ;

int main(int argc,
	 char *argv[])
{
  struct ifreq ifr;
  int timeout_wait = 70;
  int waitformore=-1 ; /* How long to wait after 1st reply for more replies */
  int givenhwaddr, i, serverbcast=0;
  char *device, *bootfile, *server ;
  int returniffail=0, printflag = BP_PRINT_OUT ;

/* defaults unless overridden by command line options 10/02/94  JSP */
  device = "eth0" ;             /* first ethernet card */
  bootfile = "" ;               /* No bootfile by default */
  server = "255.255.255.255" ;  /* i.e broadcast to everyone */
  givenhwaddr = 0 ;             /* i.e. use our real HW address */

  while (1) {
    int option_index = 0, option ;
    static struct option long_options[] = {
      {"bootfile", 1, 0, 1},
      {"dev", 1, 0, 2},
      {"verbose", 0, 0, 3},
      {"debug", 0, 0, 4},
      {"server", 1, 0, 5},
      {"hwaddr", 1, 0, 6},
      {"returniffail", 0, 0, 7},
      {"timeoutwait", 1, 0, 8},
      {"waitformore",1, 0, 9},
      {"in2host", 1, 0, 10},
      {"serverbcast",0, 0, 11},
      {"help", 0, 0, 100},
      {0, 0, 0, 0},
    } ;

    option = getopt_long (argc, argv, "", long_options, &option_index);

    if (option == -1)
      break ;

    switch (option) {
    case 1:  /* New bootfile */
      bootfile = optarg ;
      if (strlen(bootfile) > 127) { /* buffer space for 128 only */
	if (bootp_verbose)
	  logMessage("Bootfile %s too long, truncating", bootfile) ;
	bootfile[127] = 0;
      }
      break ;
    case 2:  /* New device */
      device = optarg ;
      if (strlen(device) > IFNAMSIZ-1) {  /* only IFNAMSIZ space in struct */
	if (bootp_verbose)
	  logMessage("device name %s too long, truncating", device) ;
	device[IFNAMSIZ -1] = 0;
      }
      break ;
    case 3:
      bootp_verbose = 1 ;
      break ;
    case 4:
      bootp_debug = 1 ;
      break ;
    case 5:
      server = optarg ;
      break ;
    case 6:
      /* This MAY be useful for some types of bootp_debugging, however all
	 the bootpd programs I have reply to the hardware address
	 given here, thus we never see the replies.  Other bootpds may
	 not so it may be possible to use this to test a bootpd will
	 respond for another HW address.  17/08/94  JSP */
      { int error, count ;
	unsigned int value ;

	for (i=0; i < IFHWADDRLEN; ++i) {  /* get the MAC address from user */
	  error = sscanf(optarg, "%2x%n%*[ :.]%n", &value,&count,&count) ;
	  ifr.use_hwaddr[i] = value ;
	  if (error <= 0) {   /* Not enough given */
	    if (bootp_debug)
	      logMessage("Ran out of numbers in hwaddr, ignoring") ;
	    break ;
	  }
	  optarg += count ;
	}
	givenhwaddr = 1 ;
      }
      break ;
    case 7:
      returniffail = 1 ;
      break ;
    case 8:
      timeout_wait = atoi(optarg) ;
      break ;
    case 9:
      waitformore = atoi(optarg) ;
      break ;
    case 10:
      /* used for the reverse lookup to hostname */
      return in2host(optarg, printflag) ;
      break ;
    case 11:
      serverbcast = 1 ;
      break ;
    case 100:
      logMessage("%s is used to find the IP number and other setup\n"
		 "information for a machine", argv[0]) ;
    default:
      logMessage("\t%s", BPCVERSION) ;
      logMessage(
		 "Usage: %s\t[--dev device] [--bootfile file] [--bootp_verbose]\n"
		 "\t\t[--server address] [--hwaddr mac-address]\n"
		 "\t\t[--timeoutwait seconds] [--serverbcast]\n"
		 "\t\t[--waitformore seconds]\n"
		 "\t\t[--in2host address]\n"
		 "\t\t[--help] [--returniffail]", argv[0]) ;
      exit (1) ;
    }
  }

  if (bootp_verbose) {
    logMessage("\t%s\n\tdevice=%s  bootfile=%s timeout=%d\n",
	       BPCVERSION, device, bootfile, timeout_wait ) ;
  }


  return performBootp(device, server, bootfile, timeout_wait,
		      givenhwaddr, &ifr,
		      waitformore, returniffail,
		      printflag, serverbcast) ;
}

#include <stdarg.h>
void doLogMessage(char * s, ...) {
    va_list args;

    va_start(args, s);
    fprintf(logfile, "* ");
    vfprintf(logfile, s, args);
    fprintf(logfile, "\n");
    va_end(args);
}
