xref: /openbsd-src/usr.sbin/mopd/otherOS/loop.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
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