1 /* $OpenBSD: loop.c,v 1.7 2006/04/17 16:23:01 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1993-95 Mats O Jansson. 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 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #ifndef lint 28 static const char rcsid[] = "$OpenBSD: loop.c,v 1.7 2006/04/17 16:23:01 deraadt Exp $"; 29 #endif 30 31 #include "os.h" 32 #include "common/common.h" 33 #include "common/mopdef.h" 34 35 /* 36 * The list of all interfaces that are being listened to. loop() 37 * "selects" on the descriptors in this list. 38 */ 39 struct if_info *iflist; 40 u_char buf[BUFSIZE]; 41 42 void mopProcess (/* struct if_info *, u_char * */); 43 44 int 45 mopOpenRC(p, trans) 46 struct if_info *p; 47 int trans; 48 { 49 #ifndef NORC 50 int fd; 51 52 fd = (*(p->iopen))(p->if_name, 53 O_RDWR, 54 MOP_K_PROTO_RC, 55 trans); 56 if (fd >= 0) { 57 pfAddMulti(fd, p->if_name, rc_mcst); 58 pfEthAddr(fd, p->eaddr); 59 } 60 61 return fd; 62 #else 63 return -1; 64 #endif 65 } 66 67 int 68 mopOpenDL(p, trans) 69 struct if_info *p; 70 int trans; 71 { 72 #ifndef NODL 73 int fd; 74 75 fd = (*(p->iopen))(p->if_name, 76 O_RDWR, 77 MOP_K_PROTO_DL, 78 trans); 79 if (fd >= 0) { 80 pfAddMulti(fd, p->if_name, dl_mcst); 81 pfEthAddr(fd, p->eaddr); 82 } 83 84 return fd; 85 #else 86 return -1; 87 #endif 88 } 89 90 void 91 mopReadRC(p, fd) 92 struct if_info *p; 93 int fd; 94 { 95 int cc; 96 97 if ((cc = pfRead(fd, buf+HDRSIZ, BUFSIZE-HDRSIZ)) < 0) { 98 return; 99 } 100 101 if (cc == 0) 102 return; 103 104 mopProcess(p, buf+HDRSIZ); 105 106 return; 107 } 108 109 void 110 mopReadDL(p, fd) 111 struct if_info *p; 112 int fd; 113 { 114 int cc; 115 116 if ((cc = pfRead(fd, buf+HDRSIZ, BUFSIZE-HDRSIZ)) < 0) { 117 return; 118 } 119 120 if (cc == 0) 121 return; 122 123 mopProcess(p, buf+HDRSIZ); 124 125 return; 126 } 127 128 /* 129 * Loop indefinitely listening for MOP requests on the 130 * interfaces in 'iflist'. 131 */ 132 void 133 Loop() 134 { 135 fd_set fds, listeners; 136 int maxfd = 0; 137 struct if_info *ii; 138 139 if (iflist == 0) { 140 fprintf(stderr,"no interfaces"); 141 exit(0); 142 } 143 144 /* 145 * Find the highest numbered file descriptor for select(). 146 * Initialize the set of descriptors to listen to. 147 */ 148 FD_ZERO(&fds); 149 for (ii = iflist; ii; ii = ii->next) { 150 if (ii->fd != -1) { 151 FD_SET(ii->fd, &fds); 152 if (ii->fd > maxfd) 153 maxfd = ii->fd; 154 } 155 } 156 while (1) { 157 listeners = fds; 158 if (select(maxfd + 1, &listeners, (fd_set *) 0, 159 (fd_set *) 0, (struct timeval *) 0) < 0) { 160 fprintf(stderr, "select: %s", strerror(errno)); 161 exit(0); 162 } 163 for (ii = iflist; ii; ii = ii->next) { 164 if (ii->fd != -1) { 165 if (FD_ISSET(ii->fd, &listeners)) 166 (*(ii->read))(ii,ii->fd); 167 } 168 } 169 } 170 } 171 172 173 174 175 176