| @@ -1,165 +1,165 @@ | | | @@ -1,165 +1,165 @@ |
1 | /* $NetBSD: loop-bsd.c,v 1.12 2016/06/08 01:11:49 christos Exp $ */ | | 1 | /* $NetBSD: loop-bsd.c,v 1.13 2020/04/22 23:55:29 joerg Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1993-95 Mats O Jansson. All rights reserved. | | 4 | * Copyright (c) 1993-95 Mats O Jansson. All rights reserved. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * | | 14 | * |
15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 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 | | 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 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 | | 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 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 | | 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. | | 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | */ | | 25 | */ |
26 | | | 26 | |
27 | #include "port.h" | | 27 | #include "port.h" |
28 | #ifndef lint | | 28 | #ifndef lint |
29 | __RCSID("$NetBSD: loop-bsd.c,v 1.12 2016/06/08 01:11:49 christos Exp $"); | | 29 | __RCSID("$NetBSD: loop-bsd.c,v 1.13 2020/04/22 23:55:29 joerg Exp $"); |
30 | #endif | | 30 | #endif |
31 | | | 31 | |
32 | #include <errno.h> | | 32 | #include <errno.h> |
33 | #include <stdlib.h> | | 33 | #include <stdlib.h> |
34 | #include <strings.h> | | 34 | #include <strings.h> |
35 | #include <unistd.h> | | 35 | #include <unistd.h> |
36 | #if defined(__bsdi__) || defined(__FreeBSD__) || defined(__NetBSD__) | | 36 | #if defined(__bsdi__) || defined(__FreeBSD__) || defined(__NetBSD__) |
37 | #include <sys/time.h> | | 37 | #include <sys/time.h> |
38 | #endif | | 38 | #endif |
39 | #include <net/bpf.h> | | 39 | #include <net/bpf.h> |
40 | #include <sys/ioctl.h> | | 40 | #include <sys/ioctl.h> |
41 | #include <sys/poll.h> | | 41 | #include <sys/poll.h> |
42 | #include <assert.h> | | 42 | #include <assert.h> |
43 | | | 43 | |
44 | #include "os.h" | | 44 | #include "os.h" |
45 | #include "common.h" | | 45 | #include "common.h" |
46 | #include "device.h" | | 46 | #include "device.h" |
47 | #include "mopdef.h" | | 47 | #include "mopdef.h" |
48 | #include "log.h" | | 48 | #include "log.h" |
49 | | | 49 | |
50 | int | | 50 | int |
51 | mopOpenRC(struct if_info *p, int trans) | | 51 | mopOpenRC(struct if_info *p, int trans) |
52 | { | | 52 | { |
53 | #ifndef NORC | | 53 | #ifndef NORC |
54 | return (*(p->iopen))(p->if_name, | | 54 | return (*(p->iopen))(p->if_name, |
55 | O_RDWR, | | 55 | O_RDWR, |
56 | MOP_K_PROTO_RC, | | 56 | MOP_K_PROTO_RC, |
57 | trans); | | 57 | trans); |
58 | #else | | 58 | #else |
59 | return -1; | | 59 | return -1; |
60 | #endif | | 60 | #endif |
61 | } | | 61 | } |
62 | | | 62 | |
63 | int | | 63 | int |
64 | mopOpenDL(struct if_info *p, int trans) | | 64 | mopOpenDL(struct if_info *p, int trans) |
65 | { | | 65 | { |
66 | #ifndef NODL | | 66 | #ifndef NODL |
67 | return (*(p->iopen))(p->if_name, | | 67 | return (*(p->iopen))(p->if_name, |
68 | O_RDWR, | | 68 | O_RDWR, |
69 | MOP_K_PROTO_DL, | | 69 | MOP_K_PROTO_DL, |
70 | trans); | | 70 | trans); |
71 | #else | | 71 | #else |
72 | return -1; | | 72 | return -1; |
73 | #endif | | 73 | #endif |
74 | } | | 74 | } |
75 | | | 75 | |
76 | void | | 76 | void |
77 | mopReadRC(void) | | 77 | mopReadRC(void) |
78 | { | | 78 | { |
79 | } | | 79 | } |
80 | | | 80 | |
81 | void | | 81 | void |
82 | mopReadDL(void) | | 82 | mopReadDL(void) |
83 | { | | 83 | { |
84 | } | | 84 | } |
85 | | | 85 | |
86 | /* | | 86 | /* |
87 | * The list of all interfaces that are being listened to. loop() | | 87 | * The list of all interfaces that are being listened to. loop() |
88 | * "polls" on the descriptors in this list. | | 88 | * "polls" on the descriptors in this list. |
89 | */ | | 89 | */ |
90 | struct if_info *iflist; | | 90 | extern struct if_info *iflist; |
91 | | | 91 | |
92 | void mopProcess(struct if_info *, u_char *); | | 92 | void mopProcess(struct if_info *, u_char *); |
93 | | | 93 | |
94 | /* | | 94 | /* |
95 | * Loop indefinitely listening for MOP requests on the | | 95 | * Loop indefinitely listening for MOP requests on the |
96 | * interfaces in 'iflist'. | | 96 | * interfaces in 'iflist'. |
97 | */ | | 97 | */ |
98 | void | | 98 | void |
99 | Loop(void) | | 99 | Loop(void) |
100 | { | | 100 | { |
101 | u_char *buf, *bp, *ep; | | 101 | u_char *buf, *bp, *ep; |
102 | int cc, n, m; | | 102 | int cc, n, m; |
103 | struct pollfd *set; | | 103 | struct pollfd *set; |
104 | int bufsize; | | 104 | int bufsize; |
105 | struct if_info *ii; | | 105 | struct if_info *ii; |
106 | | | 106 | |
107 | if (iflist == 0) | | 107 | if (iflist == 0) |
108 | mopLogErrX("no interfaces"); | | 108 | mopLogErrX("no interfaces"); |
109 | if (iflist->fd != -1) { | | 109 | if (iflist->fd != -1) { |
110 | if (ioctl(iflist->fd, BIOCGBLEN, (caddr_t) & bufsize) < 0) | | 110 | if (ioctl(iflist->fd, BIOCGBLEN, (caddr_t) & bufsize) < 0) |
111 | mopLogErr("BIOCGBLEN"); | | 111 | mopLogErr("BIOCGBLEN"); |
112 | } else | | 112 | } else |
113 | mopLogErrX("cannot get buffer size"); | | 113 | mopLogErrX("cannot get buffer size"); |
114 | buf = (u_char *) malloc((unsigned) bufsize); | | 114 | buf = (u_char *) malloc((unsigned) bufsize); |
115 | if (buf == 0) | | 115 | if (buf == 0) |
116 | mopLogErr("malloc"); | | 116 | mopLogErr("malloc"); |
117 | /* | | 117 | /* |
118 | * Find the highest numbered file descriptor for poll(). | | 118 | * Find the highest numbered file descriptor for poll(). |
119 | * Initialize the set of descriptors to listen to. | | 119 | * Initialize the set of descriptors to listen to. |
120 | */ | | 120 | */ |
121 | for (ii = iflist, n = 0; ii; ii = ii->next, n++) | | 121 | for (ii = iflist, n = 0; ii; ii = ii->next, n++) |
122 | ; | | 122 | ; |
123 | set = malloc(n * sizeof(*set)); | | 123 | set = malloc(n * sizeof(*set)); |
124 | for (ii = iflist, m = 0; ii; ii = ii->next, m++) { | | 124 | for (ii = iflist, m = 0; ii; ii = ii->next, m++) { |
125 | assert(ii->fd != -1); | | 125 | assert(ii->fd != -1); |
126 | set[m].fd = ii->fd; | | 126 | set[m].fd = ii->fd; |
127 | set[m].events = POLLIN; | | 127 | set[m].events = POLLIN; |
128 | } | | 128 | } |
129 | for (;;) { | | 129 | for (;;) { |
130 | if (poll(set, n, INFTIM) < 0) | | 130 | if (poll(set, n, INFTIM) < 0) |
131 | mopLogErr("poll"); | | 131 | mopLogErr("poll"); |
132 | for (ii = iflist, m = 0; ii; ii = ii->next, m++) { | | 132 | for (ii = iflist, m = 0; ii; ii = ii->next, m++) { |
133 | if (!(set[m].revents & POLLIN)) | | 133 | if (!(set[m].revents & POLLIN)) |
134 | continue; | | 134 | continue; |
135 | again: | | 135 | again: |
136 | cc = read(ii->fd, (char *) buf, bufsize); | | 136 | cc = read(ii->fd, (char *) buf, bufsize); |
137 | /* Don't choke when we get ptraced */ | | 137 | /* Don't choke when we get ptraced */ |
138 | if (cc < 0 && errno == EINTR) | | 138 | if (cc < 0 && errno == EINTR) |
139 | goto again; | | 139 | goto again; |
140 | /* Due to a SunOS bug, after 2^31 bytes, the file | | 140 | /* Due to a SunOS bug, after 2^31 bytes, the file |
141 | * offset overflows and read fails with EINVAL. The | | 141 | * offset overflows and read fails with EINVAL. The |
142 | * lseek() to 0 will fix things. */ | | 142 | * lseek() to 0 will fix things. */ |
143 | if (cc < 0) { | | 143 | if (cc < 0) { |
144 | if (errno == EINVAL && | | 144 | if (errno == EINVAL && |
145 | (lseek(ii->fd, 0, SEEK_CUR) + bufsize) < 0) { | | 145 | (lseek(ii->fd, 0, SEEK_CUR) + bufsize) < 0) { |
146 | (void) lseek(ii->fd, 0, 0); | | 146 | (void) lseek(ii->fd, 0, 0); |
147 | goto again; | | 147 | goto again; |
148 | } | | 148 | } |
149 | mopLogErr("read"); | | 149 | mopLogErr("read"); |
150 | } | | 150 | } |
151 | /* Loop through the packet(s) */ | | 151 | /* Loop through the packet(s) */ |
152 | #define bhp ((struct bpf_hdr *)bp) | | 152 | #define bhp ((struct bpf_hdr *)bp) |
153 | bp = buf; | | 153 | bp = buf; |
154 | ep = bp + cc; | | 154 | ep = bp + cc; |
155 | while (bp < ep) { | | 155 | while (bp < ep) { |
156 | int caplen, hdrlen; | | 156 | int caplen, hdrlen; |
157 | | | 157 | |
158 | caplen = bhp->bh_caplen; | | 158 | caplen = bhp->bh_caplen; |
159 | hdrlen = bhp->bh_hdrlen; | | 159 | hdrlen = bhp->bh_hdrlen; |
160 | mopProcess(ii, bp + hdrlen); | | 160 | mopProcess(ii, bp + hdrlen); |
161 | bp += BPF_WORDALIGN(hdrlen + caplen); | | 161 | bp += BPF_WORDALIGN(hdrlen + caplen); |
162 | } | | 162 | } |
163 | } | | 163 | } |
164 | } | | 164 | } |
165 | } | | 165 | } |