]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/Arp.cc
20bc0ac64d563c28c8d1620e6190bc6a3f9f98ec
[thirdparty/squid.git] / src / acl / Arp.cc
1 /*
2 * DEBUG: section 28 Access Control
3 * AUTHOR: Duane Wessels
4 *
5 * SQUID Web Proxy Cache http://www.squid-cache.org/
6 * ----------------------------------------------------------
7 *
8 * Squid is the result of efforts by numerous individuals from
9 * the Internet community; see the CONTRIBUTORS file for full
10 * details. Many organizations have provided support for Squid's
11 * development; see the SPONSORS file for full details. Squid is
12 * Copyrighted (C) 2001 by the Regents of the University of
13 * California; see the COPYRIGHT file for full details. Squid
14 * incorporates software developed and/or copyrighted by other
15 * sources; see the CREDITS file for full details.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
30 *
31 *
32 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
33 */
34
35 #include "squid.h"
36
37 #if USE_SQUID_EUI
38
39 #include "acl/Arp.h"
40 #include "acl/FilledChecklist.h"
41 #include "Debug.h"
42 #include "eui/Eui48.h"
43 #include "ip/Address.h"
44 #include "protos.h"
45 #include "wordlist.h"
46
47 static void aclParseArpList(SplayNode<Eui::Eui48 *> **curlist);
48 static int aclMatchArp(SplayNode<Eui::Eui48 *> **dataptr, Ip::Address &c);
49 static SplayNode<Eui::Eui48 *>::SPLAYCMP aclArpCompare;
50 static SplayNode<Eui::Eui48 *>::SPLAYWALKEE aclDumpArpListWalkee;
51
52
53 ACL *
54 ACLARP::clone() const
55 {
56 return new ACLARP(*this);
57 }
58
59 ACLARP::ACLARP (char const *theClass) : data (NULL), class_ (theClass)
60 {}
61
62 ACLARP::ACLARP (ACLARP const & old) : data (NULL), class_ (old.class_)
63 {
64 /* we don't have copy constructors for the data yet */
65 assert (!old.data);
66 }
67
68 ACLARP::~ACLARP()
69 {
70 if (data)
71 data->destroy(SplayNode<Eui::Eui48*>::DefaultFree);
72 }
73
74 char const *
75 ACLARP::typeString() const
76 {
77 return class_;
78 }
79
80 bool
81 ACLARP::empty () const
82 {
83 return data->empty();
84 }
85
86 /* ==== BEGIN ARP ACL SUPPORT ============================================= */
87
88 /*
89 * From: dale@server.ctam.bitmcnit.bryansk.su (Dale)
90 * To: wessels@nlanr.net
91 * Subject: Another Squid patch... :)
92 * Date: Thu, 04 Dec 1997 19:55:01 +0300
93 * ============================================================================
94 *
95 * Working on setting up a proper firewall for a network containing some
96 * Win'95 computers at our Univ, I've discovered that some smart students
97 * avoid the restrictions easily just changing their IP addresses in Win'95
98 * Contol Panel... It has been getting boring, so I took Squid-1.1.18
99 * sources and added a new acl type for hard-wired access control:
100 *
101 * acl <name> arp <Ethernet address> ...
102 *
103 * For example,
104 *
105 * acl students arp 00:00:21:55:ed:22 00:00:21:ff:55:38
106 *
107 * NOTE: Linux code by David Luyer <luyer@ucs.uwa.edu.au>.
108 * Original (BSD-specific) code no longer works.
109 * Solaris code by R. Gancarz <radekg@solaris.elektrownia-lagisza.com.pl>
110 */
111
112 Eui::Eui48 *
113 aclParseArpData(const char *t)
114 {
115 char buf[256];
116 Eui::Eui48 *q = new Eui::Eui48;
117 debugs(28, 5, "aclParseArpData: " << t);
118
119 if (sscanf(t, "%[0-9a-fA-F:]", buf) != 1) {
120 debugs(28, DBG_CRITICAL, "aclParseArpData: Bad ethernet address: '" << t << "'");
121 safe_free(q);
122 return NULL;
123 }
124
125 if (!q->decode(buf)) {
126 debugs(28, DBG_CRITICAL, "" << cfg_filename << " line " << config_lineno << ": " << config_input_line);
127 debugs(28, DBG_CRITICAL, "aclParseArpData: Ignoring invalid ARP acl entry: can't parse '" << buf << "'");
128 safe_free(q);
129 return NULL;
130 }
131
132 return q;
133 }
134
135
136 /*******************/
137 /* aclParseArpList */
138 /*******************/
139 void
140 ACLARP::parse()
141 {
142 aclParseArpList(&data);
143 }
144
145 void
146 aclParseArpList(SplayNode<Eui::Eui48 *> **curlist)
147 {
148 char *t = NULL;
149 SplayNode<Eui::Eui48*> **Top = curlist;
150 Eui::Eui48 *q = NULL;
151
152 while ((t = strtokFile())) {
153 if ((q = aclParseArpData(t)) == NULL)
154 continue;
155
156 *Top = (*Top)->insert(q, aclArpCompare);
157 }
158 }
159
160 int
161 ACLARP::match(ACLChecklist *cl)
162 {
163 ACLFilledChecklist *checklist = Filled(cl);
164
165 /* IPv6 does not do ARP */
166 if (!checklist->src_addr.IsIPv4()) {
167 debugs(14, 3, "ACLARP::match: IPv4 Required for ARP Lookups. Skipping " << checklist->src_addr );
168 return 0;
169 }
170
171 return aclMatchArp(&data, checklist->src_addr);
172 }
173
174 /***************/
175 /* aclMatchArp */
176 /***************/
177 int
178 aclMatchArp(SplayNode<Eui::Eui48 *> **dataptr, Ip::Address &c)
179 {
180 Eui::Eui48 result;
181 SplayNode<Eui::Eui48 *> **Top = dataptr;
182
183 if (result.lookup(c)) {
184 /* Do ACL match lookup */
185 *Top = (*Top)->splay(&result, aclArpCompare);
186 debugs(28, 3, "aclMatchArp: '" << c << "' " << (splayLastResult ? "NOT found" : "found"));
187 return (0 == splayLastResult);
188 }
189
190 /*
191 * Address was not found on any interface
192 */
193 debugs(28, 3, "aclMatchArp: " << c << " NOT found");
194 return 0;
195 }
196
197 static int
198 aclArpCompare(Eui::Eui48 * const &a, Eui::Eui48 * const &b)
199 {
200 return memcmp(a, b, sizeof(Eui::Eui48));
201 }
202
203 static void
204 aclDumpArpListWalkee(Eui::Eui48 * const &node, void *state)
205 {
206 static char buf[48];
207 node->encode(buf, 48);
208 wordlistAdd((wordlist **)state, buf);
209 }
210
211 wordlist *
212 ACLARP::dump() const
213 {
214 wordlist *w = NULL;
215 data->walk(aclDumpArpListWalkee, &w);
216 return w;
217 }
218
219 /* ==== END ARP ACL SUPPORT =============================================== */
220
221 #endif /* USE_SQUID_EUI */