bpf_filter.c
上传用户:tjescc
上传日期:2021-02-23
资源大小:419k
文件大小:11k
源码类别:

Telnet服务器

开发平台:

Unix_Linux

  1. /*-
  2.  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
  3.  * The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * This code is derived from the Stanford/CMU enet packet filter,
  6.  * (net/enet.c) distributed as part of 4.3BSD, and code contributed
  7.  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 
  8.  * Berkeley Laboratory.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  * 3. All advertising materials mentioning features or use of this software
  19.  *    must display the following acknowledgement:
  20.  * This product includes software developed by the University of
  21.  * California, Berkeley and its contributors.
  22.  * 4. Neither the name of the University nor the names of its contributors
  23.  *    may be used to endorse or promote products derived from this software
  24.  *    without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36.  * SUCH DAMAGE.
  37.  *
  38.  * @(#)bpf.c 7.5 (Berkeley) 7/15/91
  39.  */
  40. #if !(defined(lint) || defined(KERNEL))
  41. static const char rcsid[] =
  42.     "@(#) $Header: /usr/local/cvs/nessus-libraries/libpcap-nessus/net/bpf_filter.c,v 1.3 2003/02/06 20:28:10 renaud Exp $ (LBL)";
  43. #endif
  44. #include <sys/param.h>
  45. #include <sys/types.h>
  46. #include <sys/time.h>
  47. #include "net/bpf.h"
  48. #ifndef KERNEL
  49. #include <stdlib.h>
  50. #endif
  51. #define int32 bpf_int32
  52. #define u_int32 bpf_u_int32
  53. #ifndef LBL_ALIGN
  54. #if defined(sparc) || defined(mips) || defined(ibm032) || 
  55.     defined(__alpha) || defined(__hpux)
  56. #define LBL_ALIGN
  57. #endif
  58. #endif
  59. #ifndef LBL_ALIGN
  60. #include <netinet/in.h>
  61. #define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p))
  62. #define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p))
  63. #else
  64. #define EXTRACT_SHORT(p)
  65. ((u_short)
  66. ((u_short)*((u_char *)p+0)<<8|
  67.  (u_short)*((u_char *)p+1)<<0))
  68. #define EXTRACT_LONG(p)
  69. ((u_int32)*((u_char *)p+0)<<24|
  70.  (u_int32)*((u_char *)p+1)<<16|
  71.  (u_int32)*((u_char *)p+2)<<8|
  72.  (u_int32)*((u_char *)p+3)<<0)
  73. #endif
  74. #ifdef KERNEL
  75. #include <sys/mbuf.h>
  76. #define MINDEX(len, m, k) 
  77. len = m->m_len; 
  78. while (k >= len) { 
  79. k -= len; 
  80. m = m->m_next; 
  81. if (m == 0) 
  82. return 0; 
  83. len = m->m_len; 
  84. }
  85. static int
  86. m_xword(m, k, err)
  87. register struct mbuf *m;
  88. register int k, *err;
  89. {
  90. register int len;
  91. register u_char *cp, *np;
  92. register struct mbuf *m0;
  93. MINDEX(len, m, k);
  94. cp = mtod(m, u_char *) + k;
  95. if (len - k >= 4) {
  96. *err = 0;
  97. return EXTRACT_LONG(cp);
  98. }
  99. m0 = m->m_next;
  100. if (m0 == 0 || m0->m_len + len - k < 4)
  101. goto bad;
  102. *err = 0;
  103. np = mtod(m0, u_char *);
  104. switch (len - k) {
  105. case 1:
  106. return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2];
  107. case 2:
  108. return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1];
  109. default:
  110. return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0];
  111. }
  112.     bad:
  113. *err = 1;
  114. return 0;
  115. }
  116. static int
  117. m_xhalf(m, k, err)
  118. register struct mbuf *m;
  119. register int k, *err;
  120. {
  121. register int len;
  122. register u_char *cp;
  123. register struct mbuf *m0;
  124. MINDEX(len, m, k);
  125. cp = mtod(m, u_char *) + k;
  126. if (len - k >= 2) {
  127. *err = 0;
  128. return EXTRACT_SHORT(cp);
  129. }
  130. m0 = m->m_next;
  131. if (m0 == 0)
  132. goto bad;
  133. *err = 0;
  134. return (cp[0] << 8) | mtod(m0, u_char *)[0];
  135.  bad:
  136. *err = 1;
  137. return 0;
  138. }
  139. #endif
  140. /*
  141.  * Execute the filter program starting at pc on the packet p
  142.  * wirelen is the length of the original packet
  143.  * buflen is the amount of data present
  144.  */
  145. u_int
  146. bpf_filter(pc, p, wirelen, buflen)
  147. register struct bpf_insn *pc;
  148. register u_char *p;
  149. u_int wirelen;
  150. register u_int buflen;
  151. {
  152. register u_int32 A, X;
  153. register int k;
  154. int32 mem[BPF_MEMWORDS];
  155. if (pc == 0)
  156. /*
  157.  * No filter means accept all.
  158.  */
  159. return (u_int)-1;
  160. A = 0;
  161. X = 0;
  162. --pc;
  163. while (1) {
  164. ++pc;
  165. switch (pc->code) {
  166. default:
  167. #ifdef KERNEL
  168. return 0;
  169. #else
  170. abort();
  171. #endif
  172. case BPF_RET|BPF_K:
  173. return (u_int)pc->k;
  174. case BPF_RET|BPF_A:
  175. return (u_int)A;
  176. case BPF_LD|BPF_W|BPF_ABS:
  177. k = pc->k;
  178. if (k + sizeof(int32) > buflen) {
  179. #ifdef KERNEL
  180. int merr;
  181. if (buflen != 0)
  182. return 0;
  183. A = m_xword((struct mbuf *)p, k, &merr);
  184. if (merr != 0)
  185. return 0;
  186. continue;
  187. #else
  188. return 0;
  189. #endif
  190. }
  191. A = EXTRACT_LONG(&p[k]);
  192. continue;
  193. case BPF_LD|BPF_H|BPF_ABS:
  194. k = pc->k;
  195. if (k + sizeof(short) > buflen) {
  196. #ifdef KERNEL
  197. int merr;
  198. if (buflen != 0)
  199. return 0;
  200. A = m_xhalf((struct mbuf *)p, k, &merr);
  201. continue;
  202. #else
  203. return 0;
  204. #endif
  205. }
  206. A = EXTRACT_SHORT(&p[k]);
  207. continue;
  208. case BPF_LD|BPF_B|BPF_ABS:
  209. k = pc->k;
  210. if (k >= buflen) {
  211. #ifdef KERNEL
  212. register struct mbuf *m;
  213. register int len;
  214. if (buflen != 0)
  215. return 0;
  216. m = (struct mbuf *)p;
  217. MINDEX(len, m, k);
  218. A = mtod(m, u_char *)[k];
  219. continue;
  220. #else
  221. return 0;
  222. #endif
  223. }
  224. A = p[k];
  225. continue;
  226. case BPF_LD|BPF_W|BPF_LEN:
  227. A = wirelen;
  228. continue;
  229. case BPF_LDX|BPF_W|BPF_LEN:
  230. X = wirelen;
  231. continue;
  232. case BPF_LD|BPF_W|BPF_IND:
  233. k = X + pc->k;
  234. if (k + sizeof(int32) > buflen) {
  235. #ifdef KERNEL
  236. int merr;
  237. if (buflen != 0)
  238. return 0;
  239. A = m_xword((struct mbuf *)p, k, &merr);
  240. if (merr != 0)
  241. return 0;
  242. continue;
  243. #else
  244. return 0;
  245. #endif
  246. }
  247. A = EXTRACT_LONG(&p[k]);
  248. continue;
  249. case BPF_LD|BPF_H|BPF_IND:
  250. k = X + pc->k;
  251. if (k + sizeof(short) > buflen) {
  252. #ifdef KERNEL
  253. int merr;
  254. if (buflen != 0)
  255. return 0;
  256. A = m_xhalf((struct mbuf *)p, k, &merr);
  257. if (merr != 0)
  258. return 0;
  259. continue;
  260. #else
  261. return 0;
  262. #endif
  263. }
  264. A = EXTRACT_SHORT(&p[k]);
  265. continue;
  266. case BPF_LD|BPF_B|BPF_IND:
  267. k = X + pc->k;
  268. if (k >= buflen) {
  269. #ifdef KERNEL
  270. register struct mbuf *m;
  271. register int len;
  272. if (buflen != 0)
  273. return 0;
  274. m = (struct mbuf *)p;
  275. MINDEX(len, m, k);
  276. A = mtod(m, u_char *)[k];
  277. continue;
  278. #else
  279. return 0;
  280. #endif
  281. }
  282. A = p[k];
  283. continue;
  284. case BPF_LDX|BPF_MSH|BPF_B:
  285. k = pc->k;
  286. if (k >= buflen) {
  287. #ifdef KERNEL
  288. register struct mbuf *m;
  289. register int len;
  290. if (buflen != 0)
  291. return 0;
  292. m = (struct mbuf *)p;
  293. MINDEX(len, m, k);
  294. X = (mtod(m, char *)[k] & 0xf) << 2;
  295. continue;
  296. #else
  297. return 0;
  298. #endif
  299. }
  300. X = (p[pc->k] & 0xf) << 2;
  301. continue;
  302. case BPF_LD|BPF_IMM:
  303. A = pc->k;
  304. continue;
  305. case BPF_LDX|BPF_IMM:
  306. X = pc->k;
  307. continue;
  308. case BPF_LD|BPF_MEM:
  309. A = mem[pc->k];
  310. continue;
  311. case BPF_LDX|BPF_MEM:
  312. X = mem[pc->k];
  313. continue;
  314. case BPF_ST:
  315. mem[pc->k] = A;
  316. continue;
  317. case BPF_STX:
  318. mem[pc->k] = X;
  319. continue;
  320. case BPF_JMP|BPF_JA:
  321. pc += pc->k;
  322. continue;
  323. case BPF_JMP|BPF_JGT|BPF_K:
  324. pc += (A > pc->k) ? pc->jt : pc->jf;
  325. continue;
  326. case BPF_JMP|BPF_JGE|BPF_K:
  327. pc += (A >= pc->k) ? pc->jt : pc->jf;
  328. continue;
  329. case BPF_JMP|BPF_JEQ|BPF_K:
  330. pc += (A == pc->k) ? pc->jt : pc->jf;
  331. continue;
  332. case BPF_JMP|BPF_JSET|BPF_K:
  333. pc += (A & pc->k) ? pc->jt : pc->jf;
  334. continue;
  335. case BPF_JMP|BPF_JGT|BPF_X:
  336. pc += (A > X) ? pc->jt : pc->jf;
  337. continue;
  338. case BPF_JMP|BPF_JGE|BPF_X:
  339. pc += (A >= X) ? pc->jt : pc->jf;
  340. continue;
  341. case BPF_JMP|BPF_JEQ|BPF_X:
  342. pc += (A == X) ? pc->jt : pc->jf;
  343. continue;
  344. case BPF_JMP|BPF_JSET|BPF_X:
  345. pc += (A & X) ? pc->jt : pc->jf;
  346. continue;
  347. case BPF_ALU|BPF_ADD|BPF_X:
  348. A += X;
  349. continue;
  350. case BPF_ALU|BPF_SUB|BPF_X:
  351. A -= X;
  352. continue;
  353. case BPF_ALU|BPF_MUL|BPF_X:
  354. A *= X;
  355. continue;
  356. case BPF_ALU|BPF_DIV|BPF_X:
  357. if (X == 0)
  358. return 0;
  359. A /= X;
  360. continue;
  361. case BPF_ALU|BPF_AND|BPF_X:
  362. A &= X;
  363. continue;
  364. case BPF_ALU|BPF_OR|BPF_X:
  365. A |= X;
  366. continue;
  367. case BPF_ALU|BPF_LSH|BPF_X:
  368. A <<= X;
  369. continue;
  370. case BPF_ALU|BPF_RSH|BPF_X:
  371. A >>= X;
  372. continue;
  373. case BPF_ALU|BPF_ADD|BPF_K:
  374. A += pc->k;
  375. continue;
  376. case BPF_ALU|BPF_SUB|BPF_K:
  377. A -= pc->k;
  378. continue;
  379. case BPF_ALU|BPF_MUL|BPF_K:
  380. A *= pc->k;
  381. continue;
  382. case BPF_ALU|BPF_DIV|BPF_K:
  383. A /= pc->k;
  384. continue;
  385. case BPF_ALU|BPF_AND|BPF_K:
  386. A &= pc->k;
  387. continue;
  388. case BPF_ALU|BPF_OR|BPF_K:
  389. A |= pc->k;
  390. continue;
  391. case BPF_ALU|BPF_LSH|BPF_K:
  392. A <<= pc->k;
  393. continue;
  394. case BPF_ALU|BPF_RSH|BPF_K:
  395. A >>= pc->k;
  396. continue;
  397. case BPF_ALU|BPF_NEG:
  398. A = -A;
  399. continue;
  400. case BPF_MISC|BPF_TAX:
  401. X = A;
  402. continue;
  403. case BPF_MISC|BPF_TXA:
  404. A = X;
  405. continue;
  406. }
  407. }
  408. }
  409. #ifdef KERNEL
  410. /*
  411.  * Return true if the 'fcode' is a valid filter program.
  412.  * The constraints are that each jump be forward and to a valid
  413.  * code.  The code must terminate with either an accept or reject. 
  414.  * 'valid' is an array for use by the routine (it must be at least
  415.  * 'len' bytes long).  
  416.  *
  417.  * The kernel needs to be able to verify an application's filter code.
  418.  * Otherwise, a bogus program could easily crash the system.
  419.  */
  420. int
  421. bpf_validate(f, len)
  422. struct bpf_insn *f;
  423. int len;
  424. {
  425. register int i;
  426. register struct bpf_insn *p;
  427. for (i = 0; i < len; ++i) {
  428. /*
  429.  * Check that that jumps are forward, and within 
  430.  * the code block.
  431.  */
  432. p = &f[i];
  433. if (BPF_CLASS(p->code) == BPF_JMP) {
  434. register int from = i + 1;
  435. if (BPF_OP(p->code) == BPF_JA) {
  436. if (from + p->k >= (unsigned)len)
  437. return 0;
  438. }
  439. else if (from + p->jt >= len || from + p->jf >= len)
  440. return 0;
  441. }
  442. /*
  443.  * Check that memory operations use valid addresses.
  444.  */
  445. if ((BPF_CLASS(p->code) == BPF_ST ||
  446.      (BPF_CLASS(p->code) == BPF_LD && 
  447.       (p->code & 0xe0) == BPF_MEM)) &&
  448.     (p->k >= BPF_MEMWORDS || p->k < 0))
  449. return 0;
  450. /*
  451.  * Check for constant division by 0.
  452.  */
  453. if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
  454. return 0;
  455. }
  456. return BPF_CLASS(f[len - 1].code) == BPF_RET;
  457. }
  458. #endif