netboot.c (3911B)
1 /* $Id: //depot/blt/util/netboot.c#3 $ 2 ** 3 ** Copyright 1998 Brian J. Swetland 4 ** All rights reserved. 5 ** 6 ** Redistribution and use in source and binary forms, with or without 7 ** modification, are permitted provided that the following conditions 8 ** are met: 9 ** 1. Redistributions of source code must retain the above copyright 10 ** notice, this list of conditions, and the following disclaimer. 11 ** 2. Redistributions in binary form must reproduce the above copyright 12 ** notice, this list of conditions, and the following disclaimer in the 13 ** documentation and/or other materials provided with the distribution. 14 ** 3. The name of the author may not be used to endorse or promote products 15 ** derived from this software without specific prior written permission. 16 ** 17 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 #include <stdio.h> 29 30 #include <sys/types.h> 31 #include <sys/socket.h> 32 #include <sys/stat.h> 33 #include <fcntl.h> 34 #include <netinet/in.h> 35 #include <sys/time.h> 36 #include <unistd.h> 37 38 #include "../netboot/netboot.h" 39 40 int main(int argc, char *argv[]) 41 { 42 struct sockaddr_in dst,src; 43 char buf[128]; 44 net_boot nb,nbr; 45 int fd; 46 struct timeval timeout; 47 int s,l,i; 48 fd_set read_fds; 49 50 if(argc != 3) { 51 fprintf(stderr,"usage: test <filename> <addr>\n"); 52 exit(1); 53 54 } 55 dst.sin_family = AF_INET; 56 dst.sin_addr.s_addr = inet_addr(argv[2]); 57 dst.sin_port = htons(NETBOOT_PORT); 58 59 src.sin_family = AF_INET; 60 src.sin_addr.s_addr = htonl(INADDR_ANY); 61 src.sin_port = htons(NETBOOT_PORT); 62 63 if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 64 perror("socket"); 65 66 if(bind(s, (struct sockaddr *) &src, sizeof(src)) == -1) 67 perror("bind"); 68 69 fprintf(stderr,"loading ["); 70 71 fd = open(argv[1],O_RDONLY); 72 73 i = 0; 74 75 while(read(fd,&(nb.data),1024) > 0){ 76 nb.cmd = htons(NETBOOT_CMD_LOAD); 77 nb.blk = htons(i); 78 79 retry: 80 if(sendto(s, &nb, sizeof(nb), 0, (struct sockaddr *) &dst, sizeof(dst)) 81 == -1){ 82 perror("sendto"); 83 } 84 85 timeout.tv_sec = 1; 86 timeout.tv_usec = 0; 87 FD_ZERO(&read_fds); 88 FD_SET(s,&read_fds); 89 90 if(select(s+1, &read_fds, NULL, NULL, &timeout) == 1){ 91 92 if(recvfrom(s,&nbr,sizeof(nbr),0,NULL,NULL) < 0) { 93 fprintf(stderr,"e"); 94 goto retry; 95 } 96 if(nbr.cmd != htons(NETBOOT_CMD_ACK)) { 97 fprintf(stderr,"e"); 98 goto retry; 99 } 100 if(nbr.blk != nb.blk) { 101 fprintf(stderr,"e"); 102 goto retry; 103 } 104 fprintf(stderr,"."); 105 } else { 106 fprintf(stderr,"T"); 107 goto retry; 108 } 109 i++; 110 } 111 112 nb.cmd = htons(NETBOOT_CMD_EXEC); 113 nb.blk = htons(0); 114 115 if(sendto(s, &nb, 4, 0, (struct sockaddr *) &dst, sizeof(dst)) 116 == -1){ 117 perror("sendto"); 118 } 119 120 /* if(recvfrom(s,&nb,sizeof(nb),0,NULL,NULL) < 0) perror("recvfrom"); 121 if(nb.cmd == htons(NETBOOT_CMD_ACK)) fprintf(stderr,"!");*/ 122 123 fprintf(stderr,"] done\n"); 124 125 close(s); 126 127 return 0; 128 129 }