GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/mopd/mopprobe/../common/loop-bsd.c Lines: 0 43 0.0 %
Date: 2017-11-07 Branches: 0 36 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: loop-bsd.c,v 1.13 2009/10/27 23:59:52 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
#include <errno.h>
28
#include <stdlib.h>
29
#include <string.h>
30
#include <unistd.h>
31
#if defined(__bsdi__) || defined(__FreeBSD__)
32
#include <sys/time.h>
33
#endif
34
#include <net/bpf.h>
35
#include <sys/ioctl.h>
36
37
#include "os.h"
38
#include "common/common.h"
39
#include "common/mopdef.h"
40
41
int
42
mopOpenRC(struct if_info *p, int trans)
43
{
44
#ifndef NORC
45
	return (*(p->iopen))(p->if_name, O_RDWR, MOP_K_PROTO_RC, trans);
46
#else
47
	return (-1);
48
#endif
49
}
50
51
int
52
mopOpenDL(struct if_info *p, int trans)
53
{
54
#ifndef NODL
55
	return (*(p->iopen))(p->if_name, O_RDWR, MOP_K_PROTO_DL, trans);
56
#else
57
	return (-1);
58
#endif
59
}
60
61
void
62
mopReadRC(void)
63
{
64
}
65
66
void
67
mopReadDL(void)
68
{
69
}
70
71
/*
72
 * The list of all interfaces that are being listened to.  loop()
73
 * "selects" on the descriptors in this list.
74
 */
75
struct if_info *iflist;
76
77
void   mopProcess(struct if_info *, u_char *);
78
79
/*
80
 * Loop indefinitely listening for MOP requests on the
81
 * interfaces in 'iflist'.
82
 */
83
void
84
Loop(void)
85
{
86
	u_char		*buf, *bp, *ep;
87
	int		 cc;
88
	fd_set		 fds, listeners;
89
	int		 bufsize, maxfd = 0;
90
	struct if_info	*ii;
91
92
	if (iflist == 0) {
93
		syslog(LOG_ERR, "no interfaces");
94
		exit(0);
95
	}
96
	if (iflist->fd != -1)
97
		if (ioctl(iflist->fd, BIOCGBLEN, (caddr_t)&bufsize) < 0) {
98
			syslog(LOG_ERR, "BIOCGBLEN: %m");
99
			exit(0);
100
		}
101
102
	buf = malloc(bufsize);
103
	if (buf == 0) {
104
		syslog(LOG_ERR, "malloc: %m");
105
		exit(0);
106
	}
107
	/*
108
         * Find the highest numbered file descriptor for select().
109
         * Initialize the set of descriptors to listen to.
110
         */
111
	FD_ZERO(&fds);
112
	for (ii = iflist; ii; ii = ii->next)
113
		if (ii->fd != -1) {
114
			FD_SET(ii->fd, &fds);
115
			if (ii->fd > maxfd)
116
				maxfd = ii->fd;
117
		}
118
119
	while (1) {
120
		listeners = fds;
121
		if (select(maxfd + 1, &listeners, NULL, NULL, NULL) < 0) {
122
			syslog(LOG_ERR, "select: %m");
123
			exit(0);
124
		}
125
		for (ii = iflist; ii; ii = ii->next)
126
			if (ii->fd != -1) {
127
				if (!FD_ISSET(ii->fd, &listeners))
128
					continue;
129
again:
130
			cc = read(ii->fd, buf, bufsize);
131
			/* Don't choke when we get ptraced */
132
			if (cc < 0 && errno == EINTR)
133
				goto again;
134
			/* Due to a SunOS bug, after 2^31 bytes, the file
135
			 * offset overflows and read fails with EINVAL.  The
136
			 * lseek() to 0 will fix things. */
137
			if (cc < 0) {
138
				if (errno == EINVAL && (lseek(ii->fd, 0,
139
				    SEEK_CUR) + bufsize) < 0) {
140
					lseek(ii->fd, 0, SEEK_SET);
141
					goto again;
142
				}
143
				syslog(LOG_ERR, "read: %m");
144
				exit(0);
145
			}
146
			/* Loop through the packet(s) */
147
#define bhp ((struct bpf_hdr *)bp)
148
			bp = buf;
149
			ep = bp + cc;
150
			while (bp < ep) {
151
				int caplen, hdrlen;
152
153
				caplen = bhp->bh_caplen;
154
				hdrlen = bhp->bh_hdrlen;
155
				mopProcess(ii, bp + hdrlen);
156
				bp += BPF_WORDALIGN(hdrlen + caplen);
157
			}
158
		}
159
	}
160
}