home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume27 / bootptst / part01 < prev    next >
Encoding:
Text File  |  1993-10-11  |  43.1 KB  |  1,660 lines

  1. Newsgroups: comp.sources.unix
  2. From: gwr@mc.com (Gordon W. Ross)
  3. Subject: v27i065: bootptest-1.1 - utility for testing a bootp server, Part01/01
  4. Message-id: <2.750376278.23845@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: gwr@mc.com (Gordon W. Ross)
  9. Posting-Number: Volume 27, Issue 65
  10. Archive-Name: bootptest-1.1/part01
  11.  
  12. bootptest is a program for testing a BOOTP server.
  13.  
  14. This simple program was put together from pieces taken from
  15. various places, including the CMU BOOTP client and server.
  16. The packet printing routine is from the Berkeley "tcpdump"
  17. program with some enhancements I added.  The print-bootp.c
  18. file is shared with my copy of "tcpdump" and therefore uses
  19. some unusual utility routines that would normally be provided
  20. by various parts of the tcpdump program.
  21.  
  22.     Gordon W. Ross          Mercury Computer Systems
  23.     gwr@mc.com              199 Riverneck Road
  24.     508-256-1300            Chelmsford, MA 01824-2820
  25.  
  26. #! /bin/sh
  27. # This is a shell archive.  Remove anything before this line, then unpack
  28. # it by saving it into a file and typing "sh file".  To overwrite existing
  29. # files, type "sh file -c".  You can also feed this as standard input via
  30. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  31. # will see the following message at the end:
  32. #        "End of archive 1 (of 1)."
  33. # Contents:  MANIFEST Makefile README addrtoname.h bootp.h bootptest.c
  34. #   bootptest.man interface.h print-bootp.c util.c vdgencmu.c
  35. #   vdgenstd.c
  36. # Wrapped by vixie@gw.home.vix.com on Mon Oct 11 14:48:33 1993
  37. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  38. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  39.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  40. else
  41. echo shar: Extracting \"'MANIFEST'\" \(486 characters\)
  42. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  43. X   File Name        Archive #    Description
  44. X-----------------------------------------------------------
  45. X MANIFEST                   1    This shipping list
  46. X Makefile                   1    
  47. X README                     1    
  48. X addrtoname.h               1    
  49. X bootp.h                    1    
  50. X bootptest.c                1    
  51. X bootptest.man              1    
  52. X interface.h                1    
  53. X print-bootp.c              1    
  54. X util.c                     1    
  55. X vdgencmu.c                 1    
  56. X vdgenstd.c                 1    
  57. END_OF_FILE
  58. if test 486 -ne `wc -c <'MANIFEST'`; then
  59.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  60. fi
  61. # end of 'MANIFEST'
  62. fi
  63. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  64.   echo shar: Will not clobber existing file \"'Makefile'\"
  65. else
  66. echo shar: Extracting \"'Makefile'\" \(355 characters\)
  67. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  68. X
  69. XCFLAGS=-g
  70. X
  71. Xall: bootptest vdstd
  72. X
  73. XOBJS= bootptest.o print-bootp.o util.o
  74. Xbootptest: $(OBJS)
  75. X    $(CC) -o $@ $(OBJS)
  76. X
  77. X$(OBJS) : interface.h bootp.h
  78. X
  79. Xbootptest.cat : bootptest.man
  80. X    nroff -man $? > $@
  81. X
  82. Xvdcmu : vdgencmu
  83. X    ./vdgencmu > $@
  84. X
  85. Xvdstd : vdgenstd
  86. X    ./vdgenstd > $@
  87. X
  88. Xclean :
  89. X    -rm -f *.o
  90. X    -rm -f core bootptest
  91. X    -rm -f vdcmu vdgencmu
  92. X    -rm -f vdstd vdgenstd
  93. END_OF_FILE
  94. if test 355 -ne `wc -c <'Makefile'`; then
  95.     echo shar: \"'Makefile'\" unpacked with wrong size!
  96. fi
  97. # end of 'Makefile'
  98. fi
  99. if test -f 'README' -a "${1}" != "-c" ; then 
  100.   echo shar: Will not clobber existing file \"'README'\"
  101. else
  102. echo shar: Extracting \"'README'\" \(1073 characters\)
  103. sed "s/^X//" >'README' <<'END_OF_FILE'
  104. X
  105. Xbootptest is a program for testing a BOOTP server.
  106. X
  107. XThis simple program was put together from pieces taken from
  108. Xvarious places, including the CMU BOOTP client and server.
  109. XThe packet printing routine is from the Berkeley "tcpdump"
  110. Xprogram with some enhancements I added.  The print-bootp.c
  111. Xfile is shared with my copy of "tcpdump" and therefore uses
  112. Xsome unusual utility routines that would normally be provided
  113. Xby various parts of the tcpdump program.
  114. X
  115. XBoilerplate:
  116. X
  117. XThis product includes software developed by the University of
  118. XCalifornia, Lawrence Berkeley Laboratory and its contributors.
  119. X(See the copyright notice in print-bootp.c)
  120. X
  121. XThe remainder of this program is public domain.  You may do
  122. Xwhatever you like with it except claim that you wrote it.
  123. X
  124. XTHIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  125. XWARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  126. XMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  127. X
  128. XGordon W. Ross          Mercury Computer Systems
  129. Xgwr@mc.com              199 Riverneck Road
  130. X508-256-1300            Chelmsford, MA 01824-2820
  131. END_OF_FILE
  132. if test 1073 -ne `wc -c <'README'`; then
  133.     echo shar: \"'README'\" unpacked with wrong size!
  134. fi
  135. # end of 'README'
  136. fi
  137. if test -f 'addrtoname.h' -a "${1}" != "-c" ; then 
  138.   echo shar: Will not clobber existing file \"'addrtoname.h'\"
  139. else
  140. echo shar: Extracting \"'addrtoname.h'\" \(1577 characters\)
  141. sed "s/^X//" >'addrtoname.h' <<'END_OF_FILE'
  142. X/*
  143. X * Copyright (c) 1988, 1990 The Regents of the University of California.
  144. X * All rights reserved.
  145. X *
  146. X * Redistribution and use in source and binary forms, with or without
  147. X * modification, are permitted provided that: (1) source code distributions
  148. X * retain the above copyright notice and this paragraph in its entirety, (2)
  149. X * distributions including binary code include the above copyright notice and
  150. X * this paragraph in its entirety in the documentation or other materials
  151. X * provided with the distribution, and (3) all advertising materials mentioning
  152. X * features or use of this software display the following acknowledgement:
  153. X * ``This product includes software developed by the University of California,
  154. X * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  155. X * the University nor the names of its contributors may be used to endorse
  156. X * or promote products derived from this software without specific prior
  157. X * written permission.
  158. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  159. X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  160. X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  161. X *
  162. X * @(#) $Header: addrtoname.h,v 1.5 92/03/17 13:41:37 mccanne Exp $ (LBL)
  163. X */
  164. X
  165. X/* Name to address translation routines. */
  166. X
  167. Xextern char *etheraddr_string();
  168. Xextern char *etherproto_string();
  169. Xextern char *tcpport_string();
  170. Xextern char *udpport_string();
  171. Xextern char *getname();
  172. Xextern char *intoa();
  173. X
  174. Xextern void init_addrtoname();
  175. Xextern void no_foreign_names();
  176. X
  177. X#define ipaddr_string(p) getname((u_char *)(p))
  178. END_OF_FILE
  179. if test 1577 -ne `wc -c <'addrtoname.h'`; then
  180.     echo shar: \"'addrtoname.h'\" unpacked with wrong size!
  181. fi
  182. # end of 'addrtoname.h'
  183. fi
  184. if test -f 'bootp.h' -a "${1}" != "-c" ; then 
  185.   echo shar: Will not clobber existing file \"'bootp.h'\"
  186. else
  187. echo shar: Extracting \"'bootp.h'\" \(4479 characters\)
  188. sed "s/^X//" >'bootp.h' <<'END_OF_FILE'
  189. X#ifndef _BLURB_
  190. X#define _BLURB_
  191. X/************************************************************************
  192. X          Copyright 1988, 1991 by Carnegie Mellon University
  193. X
  194. X                          All Rights Reserved
  195. X
  196. XPermission to use, copy, modify, and distribute this software and its
  197. Xdocumentation for any purpose and without fee is hereby granted, provided
  198. Xthat the above copyright notice appear in all copies and that both that
  199. Xcopyright notice and this permission notice appear in supporting
  200. Xdocumentation, and that the name of Carnegie Mellon University not be used
  201. Xin advertising or publicity pertaining to distribution of the software
  202. Xwithout specific, written prior permission.
  203. X
  204. XCARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  205. XSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
  206. XIN NO EVENT SHALL CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
  207. XDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  208. XPROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  209. XACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  210. XSOFTWARE.
  211. X************************************************************************/
  212. X#endif /* _BLURB_ */
  213. X
  214. X
  215. X/*
  216. X * Bootstrap Protocol (BOOTP).  RFC951 and RFC1048.
  217. X *
  218. X * $Header: /afs/andrew.cmu.edu/netdev/src/cmu/bootp-public/RCS/bootp.h,v 1.3 1991/11/01 10:02:29 ww0n Exp ww0n $
  219. X *
  220. X *
  221. X * This file specifies the "implementation-independent" BOOTP protocol
  222. X * information which is common to both client and server.
  223. X *
  224. X */
  225. X
  226. X
  227. X#define BP_CHADDR_LEN     16
  228. X#define BP_SNAME_LEN     64
  229. X#define BP_FILE_LEN    128
  230. X#define BP_VEND_LEN     64
  231. X
  232. Xstruct bootp {
  233. X    unsigned char    bp_op;            /* packet opcode type */
  234. X    unsigned char    bp_htype;            /* hardware addr type */
  235. X    unsigned char    bp_hlen;            /* hardware addr length */
  236. X    unsigned char    bp_hops;            /* gateway hops */
  237. X    unsigned long    bp_xid;            /* transaction ID */
  238. X    unsigned short   bp_secs;            /* seconds since boot began */
  239. X    unsigned short   bp_unused;
  240. X    struct in_addr   bp_ciaddr;            /* client IP address */
  241. X    struct in_addr   bp_yiaddr;            /* 'your' IP address */
  242. X    struct in_addr   bp_siaddr;            /* server IP address */
  243. X    struct in_addr   bp_giaddr;            /* gateway IP address */
  244. X    unsigned char    bp_chaddr[BP_CHADDR_LEN];    /* client hardware address */
  245. X    unsigned char    bp_sname[BP_SNAME_LEN];    /* server host name */
  246. X    unsigned char    bp_file[BP_FILE_LEN];    /* boot file name */
  247. X    unsigned char    bp_vend[BP_VEND_LEN];    /* vendor-specific area */
  248. X};
  249. X
  250. X/*
  251. X * UDP port numbers, server and client.
  252. X */
  253. X#define    IPPORT_BOOTPS        67
  254. X#define    IPPORT_BOOTPC        68
  255. X
  256. X#define BOOTREPLY        2
  257. X#define BOOTREQUEST        1
  258. X
  259. X
  260. X/*
  261. X * Hardware types from Assigned Numbers RFC.
  262. X */
  263. X#define HTYPE_ETHERNET          1
  264. X#define HTYPE_EXP_ETHERNET      2
  265. X#define HTYPE_AX25          3
  266. X#define HTYPE_PRONET          4
  267. X#define HTYPE_CHAOS          5
  268. X#define HTYPE_IEEE802          6
  269. X#define HTYPE_ARCNET          7
  270. X
  271. X
  272. X
  273. X/*
  274. X * Vendor magic cookie (v_magic) for CMU
  275. X */
  276. X#define VM_CMU        "CMU"
  277. X
  278. X/*
  279. X * Vendor magic cookie (v_magic) for RFC1048
  280. X */
  281. X#define VM_RFC1048    { 99, 130, 83, 99 }
  282. X
  283. X
  284. X
  285. X/*
  286. X * RFC1048 tag values used to specify what information is being supplied in
  287. X * the vendor field of the packet.
  288. X */
  289. X
  290. X#define TAG_PAD            ((unsigned char)   0)
  291. X#define TAG_SUBNET_MASK        ((unsigned char)   1)
  292. X#define TAG_TIME_OFFSET        ((unsigned char)   2)
  293. X#define TAG_GATEWAY        ((unsigned char)   3)
  294. X#define TAG_TIME_SERVER        ((unsigned char)   4)
  295. X#define TAG_NAME_SERVER        ((unsigned char)   5)
  296. X#define TAG_DOMAIN_SERVER    ((unsigned char)   6)
  297. X#define TAG_LOG_SERVER        ((unsigned char)   7)
  298. X#define TAG_COOKIE_SERVER    ((unsigned char)   8)
  299. X#define TAG_LPR_SERVER        ((unsigned char)   9)
  300. X#define TAG_IMPRESS_SERVER    ((unsigned char)  10)
  301. X#define TAG_RLP_SERVER        ((unsigned char)  11)
  302. X#define TAG_HOSTNAME        ((unsigned char)  12)
  303. X#define TAG_BOOTSIZE        ((unsigned char)  13)
  304. X#define TAG_END            ((unsigned char) 255)
  305. X
  306. X
  307. X
  308. X/*
  309. X * "vendor" data permitted for CMU bootp clients.
  310. X */
  311. X
  312. Xstruct cmu_vend {
  313. X    unsigned char    v_magic[4];    /* magic number */
  314. X    unsigned long    v_flags;    /* flags/opcodes, etc. */
  315. X    struct in_addr     v_smask;    /* Subnet mask */
  316. X    struct in_addr     v_dgate;    /* Default gateway */
  317. X    struct in_addr    v_dns1, v_dns2; /* Domain name servers */
  318. X    struct in_addr    v_ins1, v_ins2; /* IEN-116 name servers */
  319. X    struct in_addr    v_ts1, v_ts2;    /* Time servers */
  320. X    unsigned long    v_unused[6];    /* currently unused */
  321. X};
  322. X
  323. X
  324. X/* v_flags values */
  325. X#define VF_SMASK    1    /* Subnet mask field contains valid data */
  326. END_OF_FILE
  327. if test 4479 -ne `wc -c <'bootp.h'`; then
  328.     echo shar: \"'bootp.h'\" unpacked with wrong size!
  329. fi
  330. # end of 'bootp.h'
  331. fi
  332. if test -f 'bootptest.c' -a "${1}" != "-c" ; then 
  333.   echo shar: Will not clobber existing file \"'bootptest.c'\"
  334. else
  335. echo shar: Extracting \"'bootptest.c'\" \(8202 characters\)
  336. sed "s/^X//" >'bootptest.c' <<'END_OF_FILE'
  337. X/*
  338. X * bootptest.c - Test out a bootp server.
  339. X *
  340. X *
  341. X */
  342. Xchar *usage = "bootptest server-name [vendor-data-template-file]";
  343. X
  344. X#include <sys/types.h>
  345. X#include <sys/socket.h>
  346. X#include <sys/ioctl.h>
  347. X#include <sys/file.h>
  348. X#include <sys/time.h>
  349. X#include <sys/stat.h>
  350. X#include <net/if.h>
  351. X#ifdef sun
  352. X#include <sys/sockio.h>
  353. X#include <net/if_arp.h>
  354. X#endif
  355. X#include <netinet/in.h>
  356. X#include <netinet/if_ether.h>
  357. X#include <signal.h>
  358. X#include <stdio.h>
  359. X#include <strings.h>
  360. X#include <errno.h>
  361. X#include <ctype.h>
  362. X#include <netdb.h>
  363. X
  364. Xextern int sys_nerr;
  365. Xextern char *sys_errlist[];
  366. X
  367. X#include "bootp.h"
  368. X#include "interface.h"
  369. X
  370. X#define get_network_errmsg get_errmsg
  371. X#define LOG_ERR 1
  372. X#define BUFLEN 1024
  373. X
  374. Xint vflag = 1;
  375. Xint tflag = 0;
  376. Xint thiszone;
  377. Xchar *program_name;
  378. Xunsigned char *packetp;
  379. Xunsigned char *snapend;
  380. Xint snaplen;
  381. X
  382. X
  383. X/*
  384. X * IP port numbers for client and server obtained from /etc/services
  385. X */
  386. X
  387. Xu_short bootps_port, bootpc_port;
  388. X
  389. X
  390. X/*
  391. X * Internet socket and interface config structures
  392. X */
  393. X
  394. Xstruct sockaddr_in sin_server;
  395. Xstruct sockaddr_in sin_client;
  396. Xstruct sockaddr_in sin_from;    /* Packet source */
  397. Xstruct ifreq ifreq[10];        /* Holds interface configuration */
  398. Xstruct ifconf ifconf;        /* Int. config ioctl block (pnts to ifreq) */
  399. Xstruct arpreq arpreq;        /* Arp request ioctl block */
  400. Xstruct ether_addr eaddr;
  401. X
  402. X/*
  403. X * General
  404. X */
  405. X
  406. Xint debug = 0;                /* Debugging flag (level) */
  407. Xint s;                    /* Socket file descriptor */
  408. Xchar hostname[64];
  409. Xunsigned char buf[BUFLEN];        /* Receive packet buffer */
  410. Xstruct timezone tzp;            /* Time zone offset for clients */
  411. Xstruct timeval tp;            /* Time (extra baggage) */
  412. Xlong secondswest;            /* Time zone offset in seconds */
  413. X
  414. X/*
  415. X * Vendor magic cookies for CMU and RFC1048
  416. X */
  417. X
  418. Xunsigned char vm_cmu[4]        = VM_CMU;
  419. Xunsigned char vm_rfc1048[4] = VM_RFC1048;
  420. X
  421. Xvoid report();
  422. Xchar * get_errmsg();
  423. Xextern void bootp_print();
  424. Xextern struct ether_addr *ether_hostton();
  425. X
  426. X/*
  427. X * Initialization such as command-line processing is done, then
  428. X * the receiver loop is started.  Die when interrupted.
  429. X */
  430. X
  431. Xmain(argc, argv)
  432. X    int argc;
  433. X    char **argv;
  434. X{
  435. X    struct timeval timenow;
  436. X    struct bootp *bp = (struct bootp *) buf;
  437. X    struct servent *sep;
  438. X    struct hostent *hep;
  439. X    
  440. X    int n, tolen, fromlen;
  441. X    int nfound, readfds;
  442. X    char *servername = NULL;
  443. X    char *vendor_file = NULL;
  444. X    long server_addr = INADDR_ANY;
  445. X    
  446. X    program_name = argv[0];
  447. X    
  448. X    /* Get my Ethernet address for the query. */
  449. X    gethostname(hostname, sizeof(hostname));
  450. X    if (ether_hostton(hostname, &eaddr)) {
  451. X    printf("Can not get my ethernet address\n");
  452. X    exit(1);
  453. X    }
  454. X    
  455. X    /* If server name given, query there, otherwise use broadcast. */
  456. X    if (argc <= 1) {
  457. X    printf("missing server name.\n");
  458. X    puts(usage);
  459. X    exit(1);
  460. X    }
  461. X    servername = argv[1];
  462. X    
  463. X    /* vendor-data-template-file */
  464. X    if (argc > 2) vendor_file = argv[2];
  465. X    
  466. X    /*
  467. X     * Create a socket.
  468. X     */
  469. X    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  470. X    report(LOG_ERR, "socket: %s\n", get_network_errmsg());
  471. X    exit(1);
  472. X    }
  473. X    
  474. X    /*
  475. X     * Determine network configuration.
  476. X     */
  477. X    ifconf.ifc_len = sizeof(ifreq);
  478. X    ifconf.ifc_req = ifreq;
  479. X    if ((ioctl(s, SIOCGIFCONF, (caddr_t) &ifconf) < 0) ||
  480. X    (ifconf.ifc_len <= 0)) {
  481. X    report(LOG_ERR, "ioctl: %s\n", get_network_errmsg());
  482. X    exit(1);
  483. X    }
  484. X    /* Find the appropriate interface to use? */
  485. X    
  486. X    /*
  487. X     * Get server's listening port number
  488. X     */
  489. X    sep = getservbyname("bootps", "udp");
  490. X    if (sep) {
  491. X    bootps_port = ntohs((u_short) sep->s_port);
  492. X    } else {
  493. X    report(LOG_ERR,
  494. X           "udp/bootps: unknown service -- assuming port %d\n",
  495. X           IPPORT_BOOTPS);
  496. X    bootps_port = (u_short) IPPORT_BOOTPS;
  497. X    }
  498. X    
  499. X    /*
  500. X     * Set up server socket address.
  501. X     */
  502. X    if (servername) {
  503. X    hep = gethostbyname(servername);
  504. X    if (!hep) {
  505. X        report(LOG_ERR, "gethostbyname(%s)", servername);
  506. X        exit(1);
  507. X    }
  508. X    bcopy(hep->h_addr, &sin_server.sin_addr, sizeof(struct in_addr));
  509. X    } else {
  510. X    /* Get broadcast address */
  511. X    /* XXX - not yet */
  512. X    sin_server.sin_addr.s_addr = INADDR_ANY;
  513. X    }
  514. X    sin_server.sin_family = AF_INET;
  515. X    sin_server.sin_port = htons(bootps_port);
  516. X    
  517. X    /*
  518. X     * Get client's listening port number
  519. X     */
  520. X    sep = getservbyname("bootpc", "udp");
  521. X    if (sep) {
  522. X    bootpc_port = ntohs(sep->s_port);
  523. X    } else {
  524. X    report(LOG_ERR,
  525. X           "udp/bootpc: unknown service -- assuming port %d\n",
  526. X           IPPORT_BOOTPC);
  527. X    bootpc_port = (u_short) IPPORT_BOOTPC;
  528. X    }
  529. X    
  530. X    /*
  531. X     * Set up client socket address.
  532. X     */
  533. X    sin_client.sin_family = AF_INET;
  534. X    sin_client.sin_addr.s_addr = INADDR_ANY;
  535. X    sin_client.sin_port = htons(bootpc_port);
  536. X    
  537. X    /*
  538. X     * Bind client socket to BOOTPC port.
  539. X     */
  540. X    if (bind(s, &sin_client, sizeof(sin_client)) < 0) {
  541. X    perror("bind BOOTPC port");
  542. X    fprintf(stderr, "You need to run this as root\n");
  543. X    exit(1);
  544. X    }
  545. X    
  546. X    /*
  547. X     * Build a request.
  548. X     */
  549. X    bzero(bp, sizeof(*bp));
  550. X    bp->bp_op = BOOTREQUEST;
  551. X    bp->bp_htype = 1;
  552. X    bp->bp_hlen = 6;
  553. X    bp->bp_xid = 2;     /* arbitrary */
  554. X    bp->bp_secs = 4;
  555. X    
  556. X    /*
  557. X     * Make the request look like a broadcast type.
  558. X     * (supply the hardware address, not the client IP address.)
  559. X     */
  560. X    bcopy(&eaddr, bp->bp_chaddr, sizeof(eaddr));
  561. X    bp->bp_siaddr.s_addr = -1;    /* broadcast address */
  562. X
  563. X    /*
  564. X     * Read in the "options" part of the request.
  565. X     * This also determines the size of the packet.
  566. X     */
  567. X    snaplen = sizeof(*bp);
  568. X    if (vendor_file) {
  569. X    int fd = open(vendor_file, 0);
  570. X    if (fd < 0) {
  571. X        perror(vendor_file);
  572. X        exit(1);
  573. X    }
  574. X    /* Compute actual space for options. */
  575. X    n = BUFLEN - sizeof(*bp) + BP_VEND_LEN;
  576. X    n = read(fd, bp->bp_vend, n);
  577. X    close(fd);
  578. X    if (n < 0) {
  579. X        perror(vendor_file);
  580. X        exit(1);
  581. X    }
  582. X    printf("read %d bytes of vendor template\n", n);
  583. X    if (n > BP_VEND_LEN) {
  584. X        printf("warning: extended options in use (len > %d)\n",    
  585. X           BP_VEND_LEN);
  586. X        snaplen += (n - BP_VEND_LEN);
  587. X    }
  588. X    }
  589. X    /* Set the end pointer for bootp_print() */
  590. X    snapend = buf + snaplen;
  591. X    
  592. X    /* This is used by bootp_print() */
  593. X    packetp = (unsigned char*) &eaddr;
  594. X    
  595. X    /* Print the request packet. */
  596. X    printf("Request to %s", inet_ntoa(sin_server.sin_addr));
  597. X    printf(" (port:%d)", bootps_port);
  598. X    bootp_print(bp, snaplen, sin_from.sin_port, 0);
  599. X    putchar('\n');
  600. X    
  601. X    if (sendto(s, buf, snaplen, 0,
  602. X           &sin_server, sizeof(sin_server)) < 0)
  603. X    {
  604. X    perror("sendto server");
  605. X    exit(1);
  606. X    }
  607. X    
  608. X    printf("Receiving...\n");
  609. X    alarm(5);    /* XXX - OK? */
  610. X    
  611. X    while (1) {
  612. X    
  613. X    fromlen = sizeof(sin_from);
  614. X    n = recvfrom(s, buf, sizeof(buf), 0, &sin_from, &fromlen);
  615. X    if (n <= 0) {
  616. X        continue;
  617. X    }
  618. X    
  619. X    if (n < sizeof(struct bootp)) {
  620. X        report(LOG_ERR, "received short packet\n");
  621. X        continue;
  622. X    }
  623. X    
  624. X    /* Print the received packet. */
  625. X    printf("Packet from %s", inet_ntoa(sin_from.sin_addr));
  626. X    printf(" (port:%d)", ntohs(sin_from.sin_port));
  627. X    snaplen = n;
  628. X    snapend = buf + snaplen;
  629. X    bootp_print(bp, n, sin_from.sin_port, 0);
  630. X    putchar('\n');
  631. X    }
  632. X}
  633. X
  634. X
  635. X
  636. X/*
  637. X * This routine reports errors and such via stderr and syslog() if
  638. X * appopriate.  It just helps avoid a lot of "#ifdef SYSLOG" constructs
  639. X * from being scattered throughout the code.
  640. X *
  641. X * The syntax is identical to syslog(3), but %m is not considered special
  642. X * for output to stderr (i.e. you'll see "%m" in the output. . .).  Also,
  643. X * control strings should normally end with \n since newlines aren't
  644. X * automatically generated for stderr output (whereas syslog strips out all
  645. X * newlines and adds its own at the end).
  646. X */
  647. X
  648. X/*VARARGS2*/
  649. Xvoid report(priority, fmt, p0, p1, p2, p3, p4)
  650. X    int priority;
  651. X    char *fmt;
  652. X{
  653. X    fprintf(stderr, "bootpd(pri=%d): ", priority);
  654. X    fprintf(stderr, fmt, p0, p1, p2, p3, p4);
  655. X}
  656. X
  657. X
  658. X/*
  659. X * Return pointer to static string which gives full filesystem error message.
  660. X */
  661. X
  662. Xchar *get_errmsg()
  663. X{
  664. X    static char errmsg[80];
  665. X    
  666. X    if (errno < sys_nerr) {
  667. X    return sys_errlist[errno];
  668. X    } else {
  669. X    sprintf(errmsg, "Error %d", errno);
  670. X    return errmsg;
  671. X    }
  672. X}
  673. X
  674. X#ifndef etheraddr_string
  675. Xchar *etheraddr_string(p)
  676. X    char *p;
  677. X{
  678. X    static char buf[32];
  679. X    sprintf(buf, "%x:%x:%x:%x:%x:%x",
  680. X        p[0],p[1],p[2],p[3],p[4],p[5]);
  681. X    return(buf);
  682. X}
  683. X#endif
  684. END_OF_FILE
  685. if test 8202 -ne `wc -c <'bootptest.c'`; then
  686.     echo shar: \"'bootptest.c'\" unpacked with wrong size!
  687. fi
  688. # end of 'bootptest.c'
  689. fi
  690. if test -f 'bootptest.man' -a "${1}" != "-c" ; then 
  691.   echo shar: Will not clobber existing file \"'bootptest.man'\"
  692. else
  693. echo shar: Extracting \"'bootptest.man'\" \(1066 characters\)
  694. sed "s/^X//" >'bootptest.man' <<'END_OF_FILE'
  695. X.\" bootptest.1
  696. X.TH BOOTPTEST 8 "10 June 1993" "MAINTENANCE COMMANDS"
  697. X.SH NAME
  698. Xbootptest \- send BOOTP queries and print responses
  699. X.SH SYNOPSIS
  700. X.LP
  701. X.B bootptest
  702. X.I server\-name
  703. X.RI [ template-file ]
  704. X.SH DESCRIPTION
  705. X.B bootptest
  706. Xsends a BOOTP query to the host specified as
  707. X.I server\-name
  708. Xand then waits for and prints out all responses
  709. Xuntil an interrupt terminates the program.
  710. X.LP
  711. XThe
  712. X.I template-file
  713. Xmay be specified, in which case
  714. X.B bootptest
  715. Xuses the (binary) contents of this file to initialize the
  716. X.I options
  717. Xarea of the request packet.  This feature may be used to
  718. Xverify that the BOOTP server correctly honors the format
  719. Xof any option template provided in request packets.
  720. X(All response packets should have exactly the same option
  721. Xformat as the request packet if a template was provided.)
  722. X.SH "SEE ALSO"
  723. Xbootpd
  724. X.SH REFERENCES
  725. X.TP
  726. XRFC951
  727. XBOOTSTRAP PROTOCOL (BOOTP)
  728. X.TP
  729. XRFC1048
  730. XBOOTP Vendor Information Extensions
  731. X.TP
  732. XIETF\-DHC\-BOOTP
  733. XClarifications and Extensions for the Bootstrap Protocol
  734. X.TP
  735. XIETF\-DHC\-OPTIONS
  736. XDHCP Options and BOOTP Vendor Extensions
  737. END_OF_FILE
  738. if test 1066 -ne `wc -c <'bootptest.man'`; then
  739.     echo shar: \"'bootptest.man'\" unpacked with wrong size!
  740. fi
  741. # end of 'bootptest.man'
  742. fi
  743. if test -f 'interface.h' -a "${1}" != "-c" ; then 
  744.   echo shar: Will not clobber existing file \"'interface.h'\"
  745. else
  746. echo shar: Extracting \"'interface.h'\" \(845 characters\)
  747. sed "s/^X//" >'interface.h' <<'END_OF_FILE'
  748. X/* interface.h */
  749. X
  750. X/*
  751. X * This is quite unusual, but allows bootptest to borrow print-bootp.c
  752. X * from the tcpdump program without any changes whatsoever.
  753. X *
  754. X * This has been tested on SunOS 4.1.3 only.
  755. X */
  756. X
  757. X#ifndef NTOHL
  758. X#define NTOHL(x) x=ntohl(x)
  759. X#define NTOHS(x) x=ntohs(x)
  760. X#define HTONL(x) x=htonl(x)
  761. X#define HTONS(x) x=htons(x)
  762. X#endif
  763. X
  764. X#define inline /*sorry*/
  765. X
  766. X#define getname(p) inet_ntoa(p)
  767. X#define etheraddr_string(p) ether_ntoa(p)
  768. X
  769. X/* We do not really have both Ethernet addresses. */
  770. X#define ESRC(p) (p)
  771. X#define EDST(p) (p)
  772. X
  773. Xextern int vflag, tflag;
  774. Xextern int thiszone;
  775. X
  776. Xextern char *program_name; /* used to generate self-identifying messages */
  777. X
  778. Xextern int snaplen;
  779. X
  780. X/* global pointers to beginning and end of current packet (during printing) */
  781. Xextern unsigned char *packetp;
  782. Xextern unsigned char *snapend;
  783. X
  784. Xextern char *malloc();
  785. END_OF_FILE
  786. if test 845 -ne `wc -c <'interface.h'`; then
  787.     echo shar: \"'interface.h'\" unpacked with wrong size!
  788. fi
  789. # end of 'interface.h'
  790. fi
  791. if test -f 'print-bootp.c' -a "${1}" != "-c" ; then 
  792.   echo shar: Will not clobber existing file \"'print-bootp.c'\"
  793. else
  794. echo shar: Extracting \"'print-bootp.c'\" \(12363 characters\)
  795. sed "s/^X//" >'print-bootp.c' <<'END_OF_FILE'
  796. X/*
  797. X * Copyright (c) 1988-1990 The Regents of the University of California.
  798. X * All rights reserved.
  799. X *
  800. X * Redistribution and use in source and binary forms, with or without
  801. X * modification, are permitted provided that: (1) source code distributions
  802. X * retain the above copyright notice and this paragraph in its entirety, (2)
  803. X * distributions including binary code include the above copyright notice and
  804. X * this paragraph in its entirety in the documentation or other materials
  805. X * provided with the distribution, and (3) all advertising materials mentioning
  806. X * features or use of this software display the following acknowledgement:
  807. X * ``This product includes software developed by the University of California,
  808. X * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  809. X * the University nor the names of its contributors may be used to endorse
  810. X * or promote products derived from this software without specific prior
  811. X * written permission.
  812. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  813. X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  814. X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  815. X *
  816. X * Format and print bootp packets.
  817. X */
  818. X#ifndef lint
  819. Xstatic char rcsid[] =
  820. X    "@(#) $Header: print-bootp.c,v 1.17 91/11/14 22:21:34 leres Exp $ (LBL)";
  821. X#endif
  822. X
  823. X#include <stdio.h>
  824. X
  825. X#include <sys/param.h>
  826. X#include <sys/types.h>
  827. X#include <sys/socket.h>
  828. X#include <net/if.h>
  829. X#include <netinet/in.h>
  830. X#include <netinet/if_ether.h>
  831. X#include <strings.h>
  832. X#include <ctype.h>
  833. X
  834. X#include "interface.h"
  835. X#include "addrtoname.h"
  836. X#include "bootp.h"
  837. X
  838. X/* These decode the vendor data. */
  839. Xstatic void rfc1048_print();
  840. Xstatic void cmu_print();
  841. Xstatic void other_print();
  842. X
  843. X/*
  844. X * Print bootp requests
  845. X */
  846. Xvoid
  847. Xbootp_print(bp, length, sport, dport)
  848. X    register struct bootp *bp;
  849. X    int length;
  850. X    u_short sport, dport;
  851. X{
  852. X    static char tstr[] = " [|bootp]";
  853. X    static unsigned char vm_cmu[4] = VM_CMU;
  854. X    static unsigned char vm_rfc1048[4] = VM_RFC1048;
  855. X    u_char *ep;
  856. X    int vdlen;
  857. X
  858. X#define TCHECK(var, l) if ((u_char *)&(var) > ep - l) goto trunc
  859. X
  860. X    /* Note funny sized packets */
  861. X    if (length != sizeof(struct bootp))
  862. X        (void)printf(" [len=%d]", length);
  863. X
  864. X    /* 'ep' points to the end of avaible data. */
  865. X    ep = (u_char *)snapend;
  866. X
  867. X    switch (bp->bp_op) {
  868. X
  869. X    case BOOTREQUEST:
  870. X        /* Usually, a request goes from a client to a server */
  871. X        if (sport != IPPORT_BOOTPC || dport != IPPORT_BOOTPS)
  872. X            printf(" (request)");
  873. X        break;
  874. X
  875. X    case BOOTREPLY:
  876. X        /* Usually, a reply goes from a server to a client */
  877. X        if (sport != IPPORT_BOOTPS || dport != IPPORT_BOOTPC)
  878. X            printf(" (reply)");
  879. X        break;
  880. X
  881. X    default:
  882. X        printf(" bootp-#%d", bp->bp_op);
  883. X    }
  884. X
  885. X    NTOHL(bp->bp_xid);
  886. X    NTOHS(bp->bp_secs);
  887. X
  888. X    /* The usual hardware address type is 1 (10Mb Ethernet) */
  889. X    if (bp->bp_htype != 1)
  890. X        printf(" htype-#%d", bp->bp_htype);
  891. X
  892. X    /* The usual length for 10Mb Ethernet address is 6 bytes */
  893. X    if (bp->bp_htype != 1 || bp->bp_hlen != 6)
  894. X        printf(" hlen:%d", bp->bp_hlen);
  895. X
  896. X    /* Only print interesting fields */
  897. X    if (bp->bp_hops)
  898. X        printf(" hops:%d", bp->bp_hops);
  899. X    if (bp->bp_xid)
  900. X        printf(" xid:0x%x", bp->bp_xid);
  901. X    if (bp->bp_secs)
  902. X        printf(" secs:%d", bp->bp_secs);
  903. X
  904. X    /* Client's ip address */
  905. X    TCHECK(bp->bp_ciaddr, sizeof(bp->bp_ciaddr));
  906. X    if (bp->bp_ciaddr.s_addr)
  907. X        printf(" C:%s", ipaddr_string(&bp->bp_ciaddr));
  908. X
  909. X    /* 'your' ip address (bootp client) */
  910. X    TCHECK(bp->bp_yiaddr, sizeof(bp->bp_yiaddr));
  911. X    if (bp->bp_yiaddr.s_addr)
  912. X        printf(" Y:%s", ipaddr_string(&bp->bp_yiaddr));
  913. X
  914. X    /* Server's ip address */
  915. X    TCHECK(bp->bp_siaddr, sizeof(bp->bp_siaddr));
  916. X    if (bp->bp_siaddr.s_addr)
  917. X        printf(" S:%s", ipaddr_string(&bp->bp_siaddr));
  918. X
  919. X    /* Gateway's ip address */
  920. X    TCHECK(bp->bp_giaddr, sizeof(bp->bp_giaddr));
  921. X    if (bp->bp_giaddr.s_addr)
  922. X        printf(" G:%s", ipaddr_string(&bp->bp_giaddr));
  923. X
  924. X    /* Client's Ethernet address */
  925. X    if (bp->bp_htype == 1 && bp->bp_hlen == 6) {
  926. X        register struct ether_header *eh;
  927. X        register char *e;
  928. X
  929. X        TCHECK(bp->bp_chaddr[0], 6);
  930. X        eh = (struct ether_header *)packetp;
  931. X        if (bp->bp_op == BOOTREQUEST)
  932. X            e = (char *)ESRC(eh);
  933. X        else if (bp->bp_op == BOOTREPLY)
  934. X            e = (char *)EDST(eh);
  935. X        else
  936. X            e = 0;
  937. X        if (e == 0 || bcmp((char *)bp->bp_chaddr, e, 6) != 0)
  938. X            printf(" ether %s", etheraddr_string(bp->bp_chaddr));
  939. X    }
  940. X
  941. X    TCHECK(bp->bp_sname[0], sizeof(bp->bp_sname));
  942. X    if (*bp->bp_sname) {
  943. X        printf(" sname ");
  944. X        if (printfn(bp->bp_sname, ep)) {
  945. X            fputs(tstr + 1, stdout);
  946. X            return;
  947. X        }
  948. X    }
  949. X    TCHECK(bp->bp_file[0], sizeof(bp->bp_file));
  950. X    if (*bp->bp_file) {
  951. X        printf(" file ");
  952. X        if (printfn(bp->bp_file, ep)) {
  953. X            fputs(tstr + 1, stdout);
  954. X            return;
  955. X        }
  956. X    }
  957. X
  958. X    /* Don't try to decode the vendor buffer unless we're verbose */
  959. X    if (vflag <= 0)
  960. X        return;
  961. X
  962. X    vdlen = sizeof(bp->bp_vend);
  963. X    /* Vendor data can extend to the end of the packet. */
  964. X    if (vdlen < (ep - bp->bp_vend))
  965. X        vdlen = (ep - bp->bp_vend);
  966. X
  967. X    TCHECK(bp->bp_vend[0], vdlen);
  968. X    printf(" vend");
  969. X    if (!bcmp(bp->bp_vend, vm_rfc1048, sizeof(u_long)))
  970. X        rfc1048_print(bp->bp_vend, vdlen);
  971. X    else if (!bcmp(bp->bp_vend, vm_cmu, sizeof(u_long)))
  972. X        cmu_print(bp->bp_vend, vdlen);
  973. X    else
  974. X        other_print(bp->bp_vend, vdlen);
  975. X
  976. X    return;
  977. Xtrunc:
  978. X    fputs(tstr, stdout);
  979. X#undef TCHECK
  980. X}
  981. X
  982. Xstruct rfc1048dscr {
  983. X    int fmt;    /* option data format (see below). */
  984. X    char *name;
  985. X};
  986. X/* Flags used in the format descriptor field: */
  987. X#define ODF_LIST    0x100    /* multiples of size allowed */
  988. X#define ODF_CHAR    0x200    /* interpret as ASCII */
  989. X#define ODF_INET    0x400    /* interpret as INET address */
  990. X/* Values for the option data format:  */
  991. X#define ODF_OTHER    1|ODF_LIST    /* unknown data format */
  992. X#define ODF_BYTE    1            /* exactly 1 byte */
  993. X#define ODF_STRING    1|ODF_CHAR|ODF_LIST
  994. X#define ODF_SHORT    2            /* short (2 bytes) */
  995. X#define ODF_SLIST    2|ODF_LIST    /* list of shorts */
  996. X#define ODF_LONG    4            /* long (4 bytes) */
  997. X#define ODF_INADDR    4|ODF_INET    /* inet address (just one) */
  998. X#define ODF_INALST    4|ODF_INET|ODF_LIST /* list of addresses */
  999. X
  1000. X/*
  1001. X * These come from RFC-1048 and the IETF draft:
  1002. X *    DHCP Options and BOOTP Vendor Extensions
  1003. X */
  1004. Xstruct rfc1048dscr
  1005. Xrfc1048_opts[] = {
  1006. X    /* These come from RFC-1048: */
  1007. X    ODF_OTHER,    "PAD",    /*  0: Padding - special, no data. */
  1008. X    ODF_INADDR,    "SM",    /*  1: subnet mask (RFC950)*/
  1009. X    ODF_LONG,    "TZ",    /*  2: time offset, seconds from UTC */
  1010. X    ODF_INALST,    "GW",    /*  3: gateways (or routers) */
  1011. X    ODF_INALST,    "TS",    /*  4: time servers (RFC868) */
  1012. X    ODF_INALST,    "INS",    /*  5: IEN name servers (IEN116) */
  1013. X    ODF_INALST,    "DNS",    /*  6: domain name servers (RFC1035) */
  1014. X    ODF_INALST,    "LOG",    /*  7: MIT log servers */
  1015. X    ODF_INALST,    "CS",    /*  8: cookie servers (RFC865) */
  1016. X    ODF_INALST,    "LPR",    /*  9: lpr server (RFC1179) */
  1017. X    ODF_INALST,    "IPS",    /* 10: impress servers (Imagen) */
  1018. X    ODF_INALST,    "RLP",    /* 11: resource location servers (RFC887) */
  1019. X    ODF_STRING,    "HN",    /* 12: host name (ASCII) */
  1020. X    ODF_SHORT,    "BFS",    /* 13: boot file size (in 512 byte blocks) */
  1021. X    /*
  1022. X     * These come from the IETF draft:
  1023. X     * DHCP Options and BOOTP Vendor Extensions
  1024. X     */
  1025. X    ODF_STRING,    "YPD",  /* 14: NIS domain name (Sun YP) */
  1026. X    ODF_INALST,    "YPS",  /* 15: NIS servers (Sun YP) */
  1027. X    ODF_INALST,    "NTP",    /* 16: Network Time Protocol servers */
  1028. X
  1029. X#if 0    /* The rest are not worth recognizing by name. */
  1030. X
  1031. X    /* IP parameters, per-host */
  1032. X    ODF_BYTE,    "IP-forward",    /* 17: IP Forwarding flag */
  1033. X    ODF_BYTE,    "IP-srcroute",    /* 18: IP Source Routing Enable flag */
  1034. X    ODF_INALST,    "IP-filters",    /* 19: IP Policy Filter (addr pairs) */
  1035. X    ODF_SHORT,    "IP-maxudp",    /* 20: IP Max-UDP reassembly size */
  1036. X    ODF_BYTE,    "IP-ttlive",    /* 21: IP Time to Live */
  1037. X    ODF_LONG,    "IP-pmtuage",    /* 22: IP Path MTU aging timeout */
  1038. X    ODF_SLIST,    "IP-pmtutab",    /* 23: IP Path MTU size table */
  1039. X
  1040. X    /* IP parameters, per-interface */
  1041. X    ODF_SHORT,    "IP-mtu-sz",    /* 24: IP MTU size */
  1042. X    ODF_BYTE,    "IP-mtu-sl",    /* 25: IP MTU all subnets local */
  1043. X    ODF_BYTE,    "IP-brc1",    /* 26: IP Broadcast Addr ones flag */
  1044. X    ODF_BYTE,    "IP-mask-d",    /* 27: IP do mask discovery */
  1045. X    ODF_BYTE,    "IP-mask-s",    /* 28: IP do mask supplier */
  1046. X    ODF_BYTE,    "IP-rt-disc",    /* 29: IP do router discovery */
  1047. X    ODF_INADDR,    "IP-rt-sa",    /* 30: IP router solicitation addr */
  1048. X    ODF_INALST,    "IP-routes",    /* 31: IP static routes (dst,router) */
  1049. X
  1050. X    /* Link Layer parameters, per-interface */
  1051. X    ODF_BYTE,    "LL-trailer",    /* 32: do tralier encapsulation */
  1052. X    ODF_LONG,    "LL-arp-tmo",    /* 33: ARP cache timeout */
  1053. X    ODF_BYTE,    "LL-ether2",    /* 34: Ethernet version 2 (IEEE 802.3) */
  1054. X
  1055. X    /* TCP parameters */
  1056. X    ODF_BYTE,    "TCP-def-ttl",    /* 35: default time to live */
  1057. X    ODF_LONG,    "TCP-KA-tmo",    /* 36: keepalive time interval */
  1058. X    ODF_BYTE,    "TCP-KA-junk",    /* 37: keepalive sends extra junk */
  1059. X
  1060. X    /* Dynamic Host Configuration Protocol (DHCP) extensions */
  1061. X    /* todo... */
  1062. X#endif
  1063. X};
  1064. X#define    KNOWN_OPTIONS (sizeof(rfc1048_opts) / sizeof(rfc1048_opts[0]))
  1065. X
  1066. Xstatic void
  1067. Xrfc1048_print(bp, length)
  1068. X    register u_char *bp;
  1069. X    int length;
  1070. X{
  1071. X    u_char tag;
  1072. X    u_char *ep;
  1073. X    register int len, j;
  1074. X    u_long ul;
  1075. X    u_short us;
  1076. X    int fmt;
  1077. X
  1078. X    printf("-rfc1048");
  1079. X
  1080. X    /* Step over magic cookie */
  1081. X    bp += sizeof(long);
  1082. X    /* Setup end pointer */
  1083. X    ep = bp + length;
  1084. X    while (bp < ep) {
  1085. X        tag = *bp++;
  1086. X        /* Check for tags with no data first. */
  1087. X        if (tag == TAG_PAD)
  1088. X            continue;
  1089. X        if (tag == TAG_END)
  1090. X            return;
  1091. X        if (tag < KNOWN_OPTIONS) {
  1092. X            printf(" %s", rfc1048_opts[tag].name);
  1093. X            fmt = rfc1048_opts[tag].fmt;
  1094. X        } else {
  1095. X            printf(" opt%d", tag);
  1096. X            fmt = ODF_OTHER;
  1097. X        }
  1098. X        /* Now scan the length byte. */
  1099. X        len = *bp++;
  1100. X        if (bp + len > ep) {
  1101. X            /* truncated option */
  1102. X            printf(" |(%d>%d)", len, ep-bp);
  1103. X            return;
  1104. X        }
  1105. X        while (len > 0) {
  1106. X            switch (rfc1048_opts[tag].fmt & 3) {
  1107. X            case 1:
  1108. X            case 3:
  1109. X                /* Byte formats */
  1110. X                if (len > 1) printf("(L=%d)", len);
  1111. X                if (fmt & ODF_CHAR) {
  1112. X                    printfn(bp, bp + len);
  1113. X                    bp += len;
  1114. X                    len = 0;
  1115. X                    break;
  1116. X                }
  1117. X                printf(":%d", *bp++); len--;
  1118. X                if (fmt & ODF_LIST) {
  1119. X                    while (len--) printf(".%d", *bp++);
  1120. X                }
  1121. X                break;
  1122. X
  1123. X            case 2:
  1124. X                /* Word formats */
  1125. X                while (len >= 2) {
  1126. X                    bcopy((char*)bp, (char*)&us, 2);
  1127. X                    printf(":%d", ntohs(us));
  1128. X                    bp += 2;
  1129. X                    len -= 2;
  1130. X                    /* break if not list? */
  1131. X                }
  1132. X                break;
  1133. X
  1134. X            case 0:
  1135. X                /* Longword formats */
  1136. X                while (len >= 4) {
  1137. X                    bcopy((char*)bp, (char*)&ul, 4);
  1138. X                    if (fmt & ODF_INET)
  1139. X                        printf(":%s", ipaddr_string(&ul));
  1140. X                    else
  1141. X                        printf(":%d", ntohs(us));
  1142. X                    bp += 4;
  1143. X                    len -= 4;
  1144. X                    /* break if not list? */
  1145. X                }
  1146. X                break;
  1147. X
  1148. X            } /* switch (fmt & 3) */
  1149. X
  1150. X            if (len) {
  1151. X                printf("(junk)");
  1152. X                bp += len;
  1153. X                len = 0;
  1154. X            }
  1155. X
  1156. X        } /* while len > 0 */
  1157. X    } /* while bp < ep */
  1158. X}
  1159. X
  1160. Xstatic void
  1161. Xcmu_print(bp, length)
  1162. X    register u_char *bp;
  1163. X    int length;
  1164. X{
  1165. X    struct cmu_vend *v;
  1166. X    u_char *ep;
  1167. X
  1168. X    printf("-cmu");
  1169. X
  1170. X    v = (struct cmu_vend *) bp;
  1171. X    if (length < sizeof(*v)) {
  1172. X        printf(" |L=%d", length);
  1173. X        return;
  1174. X    }
  1175. X
  1176. X    /* Setup end pointer */
  1177. X    ep = bp + length;
  1178. X
  1179. X    /* Subnet mask */
  1180. X    if (v->v_flags & VF_SMASK) {
  1181. X        printf(" SM:%s", ipaddr_string(&v->v_smask.s_addr));
  1182. X    }
  1183. X
  1184. X    /* Default gateway */
  1185. X    if (v->v_dgate.s_addr)
  1186. X        printf(" GW:%s", ipaddr_string(&v->v_dgate.s_addr));
  1187. X
  1188. X    /* Domain name servers */
  1189. X    if (v->v_dns1.s_addr)
  1190. X        printf(" DNS1:%s", ipaddr_string(&v->v_dns1.s_addr));
  1191. X    if (v->v_dns2.s_addr)
  1192. X        printf(" DNS2:%s", ipaddr_string(&v->v_dns2.s_addr));
  1193. X
  1194. X    /* IEN-116 name servers */
  1195. X    if (v->v_ins1.s_addr)
  1196. X        printf(" INS1:%s", ipaddr_string(&v->v_ins1.s_addr));
  1197. X    if (v->v_ins2.s_addr)
  1198. X        printf(" INS2:%s", ipaddr_string(&v->v_ins2.s_addr));
  1199. X
  1200. X    /* Time servers */
  1201. X    if (v->v_ts1.s_addr)
  1202. X        printf(" TS1:%s", ipaddr_string(&v->v_ts1.s_addr));
  1203. X    if (v->v_ts2.s_addr)
  1204. X        printf(" TS2:%s", ipaddr_string(&v->v_ts2.s_addr));
  1205. X
  1206. X}
  1207. X
  1208. X
  1209. X/*
  1210. X * Print out arbitrary, unknown vendor data.
  1211. X */
  1212. X
  1213. Xstatic void
  1214. Xother_print(bp, length)
  1215. X    register u_char *bp;
  1216. X    int length;
  1217. X{
  1218. X    u_char *ep;        /* end pointer */
  1219. X    u_char *zp;     /* points one past last non-zero byte */
  1220. X    register int i, j;
  1221. X
  1222. X    /* Setup end pointer */
  1223. X    ep = bp + length;
  1224. X
  1225. X    /* Find the last non-zero byte. */
  1226. X    for (zp = ep; zp > bp; zp--) {
  1227. X        if (zp[-1] != 0) break;
  1228. X    }
  1229. X
  1230. X    /* Print the all-zero case in a compact representation. */
  1231. X    if (zp == bp) {
  1232. X        printf("-all-zero");
  1233. X        return;
  1234. X    }
  1235. X
  1236. X    printf("-unknown");
  1237. X
  1238. X    /* Are there enough trailing zeros to make "00..." worthwhile? */
  1239. X    if (zp + 2 > ep)
  1240. X        zp = ep; /* print them all normally */
  1241. X
  1242. X    /* Now just print all the non-zero data. */
  1243. X    while (bp < zp) {
  1244. X        printf(".%02X", *bp);
  1245. X        bp++;
  1246. X    }
  1247. X
  1248. X    if (zp < ep)
  1249. X        printf(".00...");
  1250. X
  1251. X    return;
  1252. X}
  1253. X        
  1254. END_OF_FILE
  1255. if test 12363 -ne `wc -c <'print-bootp.c'`; then
  1256.     echo shar: \"'print-bootp.c'\" unpacked with wrong size!
  1257. fi
  1258. # end of 'print-bootp.c'
  1259. fi
  1260. if test -f 'util.c' -a "${1}" != "-c" ; then 
  1261.   echo shar: Will not clobber existing file \"'util.c'\"
  1262. else
  1263. echo shar: Extracting \"'util.c'\" \(5053 characters\)
  1264. sed "s/^X//" >'util.c' <<'END_OF_FILE'
  1265. X/*
  1266. X * Copyright (c) 1988-1990 The Regents of the University of California.
  1267. X * All rights reserved.
  1268. X *
  1269. X * Redistribution and use in source and binary forms, with or without
  1270. X * modification, are permitted provided that: (1) source code distributions
  1271. X * retain the above copyright notice and this paragraph in its entirety, (2)
  1272. X * distributions including binary code include the above copyright notice and
  1273. X * this paragraph in its entirety in the documentation or other materials
  1274. X * provided with the distribution, and (3) all advertising materials mentioning
  1275. X * features or use of this software display the following acknowledgement:
  1276. X * ``This product includes software developed by the University of California,
  1277. X * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  1278. X * the University nor the names of its contributors may be used to endorse
  1279. X * or promote products derived from this software without specific prior
  1280. X * written permission.
  1281. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  1282. X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  1283. X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1284. X */
  1285. X
  1286. X#ifndef lint
  1287. Xstatic char rcsid[] =
  1288. X    "@(#) $Header: util.c,v 1.12 91/10/28 22:09:31 mccanne Exp $ (LBL)";
  1289. X#endif
  1290. X
  1291. X#include <stdio.h>
  1292. X#ifdef __STDC__
  1293. X#include <stdlib.h>
  1294. X#endif
  1295. X#include <sys/types.h>
  1296. X#include <sys/time.h>
  1297. X#include <ctype.h>
  1298. X#include <varargs.h>
  1299. X#include <sys/file.h>
  1300. X#include <sys/stat.h>
  1301. X
  1302. X#include "interface.h"
  1303. X
  1304. X/* Hex digit to integer. */
  1305. Xstatic inline int
  1306. Xxdtoi(c)
  1307. X{
  1308. X    if (isdigit(c))
  1309. X        return c - '0';
  1310. X    else if (islower(c))
  1311. X        return c - 'a' + 10;
  1312. X    else
  1313. X        return c - 'A' + 10;
  1314. X}
  1315. X
  1316. X/*
  1317. X * Convert string to integer.  Just like atoi(), but checks for 
  1318. X * preceding 0x or 0 and uses hex or octal instead of decimal.
  1319. X */
  1320. Xint
  1321. Xstoi(s)
  1322. X    char *s;
  1323. X{
  1324. X    int base = 10;
  1325. X    int n = 0;
  1326. X
  1327. X    if (*s == '0') {
  1328. X        if (s[1] == 'x' || s[1] == 'X') {
  1329. X            s += 2;
  1330. X            base = 16;
  1331. X        }
  1332. X        else {
  1333. X            base = 8;
  1334. X            s += 1;
  1335. X        }
  1336. X    }
  1337. X    while (*s)
  1338. X        n = n * base + xdtoi(*s++);
  1339. X
  1340. X    return n;
  1341. X}
  1342. X
  1343. X/*
  1344. X * Print out a filename (or other ascii string).
  1345. X * Return true if truncated.
  1346. X */
  1347. Xint
  1348. Xprintfn(s, ep)
  1349. X    register u_char *s, *ep;
  1350. X{
  1351. X    register u_char c;
  1352. X
  1353. X    putchar('"');
  1354. X    while (c = *s++) {
  1355. X        if (s > ep) {
  1356. X            putchar('"');
  1357. X            return(1);
  1358. X        }
  1359. X        if (!isascii(c)) {
  1360. X            c = toascii(c);
  1361. X            putchar('M');
  1362. X            putchar('-');
  1363. X        }
  1364. X        if (!isprint(c)) {
  1365. X            c ^= 0x40;    /* DEL to ?, others to alpha */
  1366. X            putchar('^');
  1367. X        }
  1368. X        putchar(c);
  1369. X    }
  1370. X    putchar('"');
  1371. X    return(0);
  1372. X}
  1373. X
  1374. X/*
  1375. X * Print the timestamp
  1376. X */
  1377. Xvoid
  1378. Xts_print(tvp)
  1379. X    register struct timeval *tvp;
  1380. X{
  1381. X    register int i;
  1382. X
  1383. X    if (tflag > 0) {
  1384. X        /* Default */
  1385. X        i = (tvp->tv_sec + thiszone) % 86400;
  1386. X        (void)printf("%02d:%02d:%02d.%06d ",
  1387. X            i / 3600, (i % 3600) / 60, i % 60, tvp->tv_usec);
  1388. X    } else if (tflag < 0) {
  1389. X        /* Unix timeval style */
  1390. X        (void)printf("%d.%06d ", tvp->tv_sec, tvp->tv_usec);
  1391. X    }
  1392. X}
  1393. X
  1394. X#ifdef NOVFPRINTF
  1395. X/*
  1396. X * Stock 4.3 doesn't have vfprintf. 
  1397. X * This routine is due to Chris Torek.
  1398. X */
  1399. Xvfprintf(f, fmt, args)
  1400. X    FILE *f;
  1401. X    char *fmt;
  1402. X    va_list args;
  1403. X{
  1404. X    int ret;
  1405. X
  1406. X    if ((f->_flag & _IOWRT) == 0) {
  1407. X        if (f->_flag & _IORW)
  1408. X            f->_flag |= _IOWRT;
  1409. X        else
  1410. X            return EOF;
  1411. X    }
  1412. X    ret = _doprnt(fmt, args, f);
  1413. X    return ferror(f) ? EOF : ret;
  1414. X}
  1415. X#endif
  1416. X
  1417. Xstatic char *
  1418. Xstripdir(s)
  1419. X    register char *s;
  1420. X{
  1421. X    register char *cp;
  1422. X    char *rindex();
  1423. X
  1424. X    cp = rindex(s, '/');
  1425. X    return (cp != 0) ? cp + 1 : s;
  1426. X}
  1427. X
  1428. X/* VARARGS */
  1429. Xvoid
  1430. Xerror(va_alist)
  1431. X    va_dcl
  1432. X{
  1433. X    register char *cp;
  1434. X    va_list ap;
  1435. X
  1436. X    (void)fprintf(stderr, "%s: ", stripdir(program_name));
  1437. X
  1438. X    va_start(ap);
  1439. X    cp = va_arg(ap, char *);
  1440. X    (void)vfprintf(stderr, cp, ap);
  1441. X    va_end(ap);
  1442. X    if (*cp) {
  1443. X        cp += strlen(cp);
  1444. X        if (cp[-1] != '\n')
  1445. X            (void)fputc('\n', stderr);
  1446. X    }
  1447. X    exit(1);
  1448. X    /* NOTREACHED */
  1449. X}
  1450. X
  1451. X/* VARARGS */
  1452. Xvoid
  1453. Xwarning(va_alist)
  1454. X    va_dcl
  1455. X{
  1456. X    register char *cp;
  1457. X    va_list ap;
  1458. X
  1459. X    (void)fprintf(stderr, "%s: warning: ", stripdir(program_name));
  1460. X
  1461. X    va_start(ap);
  1462. X    cp = va_arg(ap, char *);
  1463. X    (void)vfprintf(stderr, cp, ap);
  1464. X    va_end(ap);
  1465. X    if (*cp) {
  1466. X        cp += strlen(cp);
  1467. X        if (cp[-1] != '\n')
  1468. X            (void)fputc('\n', stderr);
  1469. X    }
  1470. X}
  1471. X
  1472. X
  1473. X/*
  1474. X * Copy arg vector into a new buffer, concatenating arguments with spaces.
  1475. X */
  1476. Xchar *
  1477. Xcopy_argv(argv)
  1478. X    register char **argv;
  1479. X{
  1480. X    register char **p;
  1481. X    register int len = 0;
  1482. X    char *buf;
  1483. X    char *src, *dst;
  1484. X
  1485. X    p = argv;
  1486. X    if (*p == 0)
  1487. X        return 0;
  1488. X
  1489. X    while (*p)
  1490. X        len += strlen(*p++) + 1;
  1491. X
  1492. X    buf = malloc(len);
  1493. X
  1494. X    p = argv;
  1495. X    dst = buf;
  1496. X    while (src = *p++) {
  1497. X        while (*dst++ = *src++)
  1498. X            ;
  1499. X        dst[-1] = ' ';
  1500. X    }
  1501. X    dst[-1] = '\0';
  1502. X
  1503. X    return buf;
  1504. X}
  1505. X
  1506. Xchar *
  1507. Xread_infile(fname)
  1508. X    char *fname;
  1509. X{
  1510. X    struct stat buf;
  1511. X    int fd;
  1512. X    char *p;
  1513. X
  1514. X    fd = open(fname, O_RDONLY);
  1515. X    if (fd < 0)
  1516. X        error("can't open '%s'", fname);
  1517. X
  1518. X    if (fstat(fd, &buf) < 0)
  1519. X        error("can't state '%s'", fname);
  1520. X
  1521. X    p = malloc((unsigned)buf.st_size);
  1522. X    if (read(fd, p, (int)buf.st_size) != buf.st_size)
  1523. X        error("problem reading '%s'", fname);
  1524. X    
  1525. X    return p;
  1526. X}
  1527. X
  1528. X/*
  1529. X * Left justify 'addr' and return its resulting network mask.
  1530. X */
  1531. Xu_long
  1532. Xnet_mask(addr)
  1533. X    u_long *addr;
  1534. X{
  1535. X    register u_long m = 0xffffffff;
  1536. X
  1537. X    if (*addr)
  1538. X        while ((*addr & 0xff000000) == 0)
  1539. X            *addr <<= 8, m <<= 8;
  1540. X
  1541. X    return m;
  1542. X}
  1543. END_OF_FILE
  1544. if test 5053 -ne `wc -c <'util.c'`; then
  1545.     echo shar: \"'util.c'\" unpacked with wrong size!
  1546. fi
  1547. # end of 'util.c'
  1548. fi
  1549. if test -f 'vdgencmu.c' -a "${1}" != "-c" ; then 
  1550.   echo shar: Will not clobber existing file \"'vdgencmu.c'\"
  1551. else
  1552. echo shar: Extracting \"'vdgencmu.c'\" \(248 characters\)
  1553. sed "s/^X//" >'vdgencmu.c' <<'END_OF_FILE'
  1554. X
  1555. X/* This program creates an option template file in CMU format. */
  1556. X
  1557. Xstruct in_addr { long s_addr; };
  1558. X
  1559. X#include "bootp.h"
  1560. X
  1561. Xstruct cmu_vend vend = {
  1562. X    "CMU",    /* magic number for CMU data */
  1563. X    0
  1564. X};
  1565. X
  1566. X
  1567. Xmain() {
  1568. X    write(1, &vend, sizeof(vend));
  1569. X    exit(0);
  1570. X}
  1571. END_OF_FILE
  1572. if test 248 -ne `wc -c <'vdgencmu.c'`; then
  1573.     echo shar: \"'vdgencmu.c'\" unpacked with wrong size!
  1574. fi
  1575. # end of 'vdgencmu.c'
  1576. fi
  1577. if test -f 'vdgenstd.c' -a "${1}" != "-c" ; then 
  1578.   echo shar: Will not clobber existing file \"'vdgenstd.c'\"
  1579. else
  1580. echo shar: Extracting \"'vdgenstd.c'\" \(665 characters\)
  1581. sed "s/^X//" >'vdgenstd.c' <<'END_OF_FILE'
  1582. X
  1583. X/* This program creates an option template file in RFC 1048 format. */
  1584. X
  1585. Xstruct in_addr { long s_addr; };
  1586. X
  1587. X#include "bootp.h"
  1588. X
  1589. X/* Note that this template uses padding to keep data aligned. */
  1590. Xchar vend[] = {
  1591. X    /* magic number for RFC1048 data */
  1592. X    99, 130, 83, 99,
  1593. X
  1594. X    /* netmask */
  1595. X    0,0,1,4,
  1596. X    0,0,0,0,
  1597. X
  1598. X    /* gateway list */
  1599. X    0,0,3,4,
  1600. X    0,0,0,0,
  1601. X
  1602. X    /* hostname */
  1603. X    0,0, 12, 16,
  1604. X    0,0,0,0,
  1605. X    0,0,0,0,
  1606. X    0,0,0,0,
  1607. X    0,0,0,0,
  1608. X
  1609. X    /* DNS list */
  1610. X    0,0,6,8,
  1611. X    0,0,0,0,
  1612. X    0,0,0,0,
  1613. X
  1614. X#if 1
  1615. X
  1616. X    /* NIS server list */
  1617. X    0,0, 15, 4,
  1618. X    0,0,0,0,
  1619. X
  1620. X    /* NIS domain name */
  1621. X    0,0, 14, 12,
  1622. X    0,0,0,0,
  1623. X    0,0,0,0,
  1624. X    0,0,0,0,
  1625. X
  1626. X#endif
  1627. X
  1628. X    /* end */
  1629. X    255, 0
  1630. X};
  1631. X
  1632. X
  1633. Xmain() {
  1634. X    write(1, vend, sizeof(vend));
  1635. X    exit(0);
  1636. X}
  1637. END_OF_FILE
  1638. if test 665 -ne `wc -c <'vdgenstd.c'`; then
  1639.     echo shar: \"'vdgenstd.c'\" unpacked with wrong size!
  1640. fi
  1641. # end of 'vdgenstd.c'
  1642. fi
  1643. echo shar: End of archive 1 \(of 1\).
  1644. cp /dev/null ark1isdone
  1645. MISSING=""
  1646. for I in 1 ; do
  1647.     if test ! -f ark${I}isdone ; then
  1648.     MISSING="${MISSING} ${I}"
  1649.     fi
  1650. done
  1651. if test "${MISSING}" = "" ; then
  1652.     echo You have the archive.
  1653.     rm -f ark[1-9]isdone
  1654. else
  1655.     echo You still need to unpack the following archives:
  1656.     echo "        " ${MISSING}
  1657. fi
  1658. ##  End of shell archive.
  1659. exit 0
  1660.