summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bootpd/bootptest.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bootpd/bootptest.c')
-rw-r--r--usr.sbin/bootpd/bootptest.c500
1 files changed, 0 insertions, 500 deletions
diff --git a/usr.sbin/bootpd/bootptest.c b/usr.sbin/bootpd/bootptest.c
deleted file mode 100644
index bc235ac..0000000
--- a/usr.sbin/bootpd/bootptest.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * bootptest.c - Test out a bootp server.
- *
- * This simple program was put together from pieces taken from
- * various places, including the CMU BOOTP client and server.
- * The packet printing routine is from the Berkeley "tcpdump"
- * program with some enhancements I added. The print-bootp.c
- * file was shared with my copy of "tcpdump" and therefore uses
- * some unusual utility routines that would normally be provided
- * by various parts of the tcpdump program. Gordon W. Ross
- *
- * Boilerplate:
- *
- * This program includes software developed by the University of
- * California, Lawrence Berkeley Laboratory and its contributors.
- * (See the copyright notice in print-bootp.c)
- *
- * The remainder of this program is public domain. You may do
- * whatever you like with it except claim that you wrote it.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * HISTORY:
- *
- * 12/02/93 Released version 1.4 (with bootp-2.3.2)
- * 11/05/93 Released version 1.3
- * 10/14/93 Released version 1.2
- * 10/11/93 Released version 1.1
- * 09/28/93 Released version 1.0
- * 09/93 Original developed by Gordon W. Ross <gwr@mc.com>
- */
-
-char *usage = "bootptest [-h] server-name [vendor-data-template-file]";
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-
-#include <net/if.h>
-#include <netinet/in.h>
-#include <arpa/inet.h> /* inet_ntoa */
-
-#include <stdlib.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <netdb.h>
-#include <assert.h>
-
-#include "bootp.h"
-#include "bootptest.h"
-#include "getif.h"
-#include "patchlevel.h"
-
-#define LOG_ERR 1
-#define BUFLEN 1024
-#define WAITSECS 1
-#define MAXWAIT 10
-
-int vflag = 1;
-int tflag = 0;
-int thiszone;
-char *progname;
-unsigned char *packetp;
-unsigned char *snapend;
-int snaplen;
-
-
-/*
- * IP port numbers for client and server obtained from /etc/services
- */
-
-u_short bootps_port, bootpc_port;
-
-
-/*
- * Internet socket and interface config structures
- */
-
-struct sockaddr_in sin_server; /* where to send requests */
-struct sockaddr_in sin_client; /* for bind and listen */
-struct sockaddr_in sin_from; /* Packet source */
-u_char eaddr[16]; /* Ethernet address */
-
-/*
- * General
- */
-
-int debug = 1; /* Debugging flag (level) */
-char hostname[64];
-char *sndbuf; /* Send packet buffer */
-char *rcvbuf; /* Receive packet buffer */
-
-/*
- * Vendor magic cookies for CMU and RFC1048
- */
-
-unsigned char vm_cmu[4] = VM_CMU;
-unsigned char vm_rfc1048[4] = VM_RFC1048;
-short secs; /* How long client has waited */
-
-char *get_errmsg();
-extern void bootp_print();
-
-/*
- * Initialization such as command-line processing is done, then
- * the receiver loop is started. Die when interrupted.
- */
-
-main(argc, argv)
- int argc;
- char **argv;
-{
- struct bootp *bp;
- struct servent *sep;
- struct hostent *hep;
-
- char *servername = NULL;
- char *vendor_file = NULL;
- char *bp_file = NULL;
- int32 server_addr; /* inet addr, network order */
- int s; /* Socket file descriptor */
- int n, tolen, fromlen, recvcnt;
- int use_hwa = 0;
- int32 vend_magic;
- int32 xid;
-
- progname = strrchr(argv[0], '/');
- if (progname)
- progname++;
- else
- progname = argv[0];
- argc--;
- argv++;
-
- if (debug)
- printf("%s: version %s.%d\n", progname, VERSION, PATCHLEVEL);
-
- /*
- * Verify that "struct bootp" has the correct official size.
- * (Catch evil compilers that do struct padding.)
- */
- assert(sizeof(struct bootp) == BP_MINPKTSZ);
-
- sndbuf = malloc(BUFLEN);
- rcvbuf = malloc(BUFLEN);
- if (!sndbuf || !rcvbuf) {
- printf("malloc failed\n");
- exit(1);
- }
-
- /* default magic number */
- bcopy(vm_rfc1048, (char*)&vend_magic, 4);
-
- /* Handle option switches. */
- while (argc > 0) {
- if (argv[0][0] != '-')
- break;
- switch (argv[0][1]) {
-
- case 'f': /* File name to reqest. */
- if (argc < 2)
- goto error;
- argc--; argv++;
- bp_file = *argv;
- break;
-
- case 'h': /* Use hardware address. */
- use_hwa = 1;
- break;
-
- case 'm': /* Magic number value. */
- if (argc < 2)
- goto error;
- argc--; argv++;
- vend_magic = inet_addr(*argv);
- break;
-
- error:
- default:
- puts(usage);
- exit(1);
-
- }
- argc--;
- argv++;
- }
-
- /* Get server name (or address) for query. */
- if (argc > 0) {
- servername = *argv;
- argc--;
- argv++;
- }
- /* Get optional vendor-data-template-file. */
- if (argc > 0) {
- vendor_file = *argv;
- argc--;
- argv++;
- }
- if (!servername) {
- printf("missing server name.\n");
- puts(usage);
- exit(1);
- }
- /*
- * Create a socket.
- */
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- perror("socket");
- exit(1);
- }
- /*
- * Get server's listening port number
- */
- sep = getservbyname("bootps", "udp");
- if (sep) {
- bootps_port = ntohs((u_short) sep->s_port);
- } else {
- fprintf(stderr, "udp/bootps: unknown service -- using port %d\n",
- IPPORT_BOOTPS);
- bootps_port = (u_short) IPPORT_BOOTPS;
- }
-
- /*
- * Set up server socket address (for send)
- */
- if (servername) {
- if (isdigit(servername[0]))
- server_addr = inet_addr(servername);
- else {
- hep = gethostbyname(servername);
- if (!hep) {
- fprintf(stderr, "%s: unknown host\n", servername);
- exit(1);
- }
- bcopy(hep->h_addr, &server_addr, sizeof(server_addr));
- }
- } else {
- /* Get broadcast address */
- /* XXX - not yet */
- server_addr = INADDR_ANY;
- }
- sin_server.sin_family = AF_INET;
- sin_server.sin_port = htons(bootps_port);
- sin_server.sin_addr.s_addr = server_addr;
-
- /*
- * Get client's listening port number
- */
- sep = getservbyname("bootpc", "udp");
- if (sep) {
- bootpc_port = ntohs(sep->s_port);
- } else {
- fprintf(stderr, "udp/bootpc: unknown service -- using port %d\n",
- IPPORT_BOOTPC);
- bootpc_port = (u_short) IPPORT_BOOTPC;
- }
-
- /*
- * Set up client socket address (for listen)
- */
- sin_client.sin_family = AF_INET;
- sin_client.sin_port = htons(bootpc_port);
- sin_client.sin_addr.s_addr = INADDR_ANY;
-
- /*
- * Bind client socket to BOOTPC port.
- */
- if (bind(s, (struct sockaddr *) &sin_client, sizeof(sin_client)) < 0) {
- perror("bind BOOTPC port");
- if (errno == EACCES)
- fprintf(stderr, "You need to run this as root\n");
- exit(1);
- }
- /*
- * Build a request.
- */
- bp = (struct bootp *) sndbuf;
- bzero(bp, sizeof(*bp));
- bp->bp_op = BOOTREQUEST;
- xid = (int32) getpid();
- bp->bp_xid = (u_int32) htonl(xid);
- if (bp_file)
- strncpy(bp->bp_file, bp_file, BP_FILE_LEN);
-
- /*
- * Fill in the hardware address (or client IP address)
- */
- if (use_hwa) {
- struct ifreq *ifr;
-
- ifr = getif(s, &sin_server.sin_addr);
- if (!ifr) {
- printf("No interface for %s\n", servername);
- exit(1);
- }
- if (getether(ifr->ifr_name, eaddr)) {
- printf("Can not get ether addr for %s\n", ifr->ifr_name);
- exit(1);
- }
- /* Copy Ethernet address into request packet. */
- bp->bp_htype = 1;
- bp->bp_hlen = 6;
- bcopy(eaddr, bp->bp_chaddr, bp->bp_hlen);
- } else {
- /* Fill in the client IP address. */
- gethostname(hostname, sizeof(hostname));
- hep = gethostbyname(hostname);
- if (!hep) {
- printf("Can not get my IP address\n");
- exit(1);
- }
- bcopy(hep->h_addr, &bp->bp_ciaddr, hep->h_length);
- }
-
- /*
- * Copy in the default vendor data.
- */
- bcopy((char*)&vend_magic, bp->bp_vend, 4);
- if (vend_magic)
- bp->bp_vend[4] = TAG_END;
-
- /*
- * Read in the "options" part of the request.
- * This also determines the size of the packet.
- */
- snaplen = sizeof(*bp);
- if (vendor_file) {
- int fd = open(vendor_file, 0);
- if (fd < 0) {
- perror(vendor_file);
- exit(1);
- }
- /* Compute actual space for options. */
- n = BUFLEN - sizeof(*bp) + BP_VEND_LEN;
- n = read(fd, bp->bp_vend, n);
- close(fd);
- if (n < 0) {
- perror(vendor_file);
- exit(1);
- }
- printf("read %d bytes of vendor template\n", n);
- if (n > BP_VEND_LEN) {
- printf("warning: extended options in use (len > %d)\n",
- BP_VEND_LEN);
- snaplen += (n - BP_VEND_LEN);
- }
- }
- /*
- * Set globals needed by print_bootp
- * (called by send_request)
- */
- packetp = (unsigned char *) eaddr;
- snapend = (unsigned char *) sndbuf + snaplen;
-
- /* Send a request once per second while waiting for replies. */
- recvcnt = 0;
- bp->bp_secs = secs = 0;
- send_request(s);
- while (1) {
- struct timeval tv;
- int readfds;
-
- tv.tv_sec = WAITSECS;
- tv.tv_usec = 0L;
- readfds = (1 << s);
- n = select(s + 1, (fd_set *) & readfds, NULL, NULL, &tv);
- if (n < 0) {
- perror("select");
- break;
- }
- if (n == 0) {
- /*
- * We have not received a response in the last second.
- * If we have ever received any responses, exit now.
- * Otherwise, bump the "wait time" field and re-send.
- */
- if (recvcnt > 0)
- exit(0);
- secs += WAITSECS;
- if (secs > MAXWAIT)
- break;
- bp->bp_secs = htons(secs);
- send_request(s);
- continue;
- }
- fromlen = sizeof(sin_from);
- n = recvfrom(s, rcvbuf, BUFLEN, 0,
- (struct sockaddr *) &sin_from, &fromlen);
- if (n <= 0) {
- continue;
- }
- if (n < sizeof(struct bootp)) {
- printf("received short packet\n");
- continue;
- }
- recvcnt++;
-
- /* Print the received packet. */
- printf("Recvd from %s", inet_ntoa(sin_from.sin_addr));
- /* set globals needed by bootp_print() */
- snaplen = n;
- snapend = (unsigned char *) rcvbuf + snaplen;
- bootp_print(rcvbuf, n, sin_from.sin_port, 0);
- putchar('\n');
- /*
- * This no longer exits immediately after receiving
- * one response because it is useful to know if the
- * client might get multiple responses. This code
- * will now listen for one second after a response.
- */
- }
- fprintf(stderr, "no response from %s\n", servername);
- exit(1);
-}
-
-send_request(s)
- int s;
-{
- /* Print the request packet. */
- printf("Sending to %s", inet_ntoa(sin_server.sin_addr));
- bootp_print(sndbuf, snaplen, sin_from.sin_port, 0);
- putchar('\n');
-
- /* Send the request packet. */
- if (sendto(s, sndbuf, snaplen, 0,
- (struct sockaddr *) &sin_server,
- sizeof(sin_server)) < 0)
- {
- perror("sendto server");
- exit(1);
- }
-}
-
-/*
- * Print out a filename (or other ascii string).
- * Return true if truncated.
- */
-int
-printfn(s, ep)
- register u_char *s, *ep;
-{
- register u_char c;
-
- putchar('"');
- while (c = *s++) {
- if (s > ep) {
- putchar('"');
- return (1);
- }
- if (!isascii(c)) {
- c = toascii(c);
- putchar('M');
- putchar('-');
- }
- if (!isprint(c)) {
- c ^= 0x40; /* DEL to ?, others to alpha */
- putchar('^');
- }
- putchar(c);
- }
- putchar('"');
- return (0);
-}
-
-/*
- * Convert an IP addr to a string.
- * (like inet_ntoa, but ina is a pointer)
- */
-char *
-ipaddr_string(ina)
- struct in_addr *ina;
-{
- static char b[24];
- u_char *p;
-
- p = (u_char *) ina;
- sprintf(b, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
- return (b);
-}
-
-/*
- * Local Variables:
- * tab-width: 4
- * c-indent-level: 4
- * c-argdecl-indent: 4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: -4
- * c-label-offset: -4
- * c-brace-offset: 0
- * End:
- */
OpenPOWER on IntegriCloud