Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/netinet/accf_dns.c
39475 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (C) 2007 David Malone <[email protected]>
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
#define ACCEPT_FILTER_MOD
30
31
#include <sys/param.h>
32
#include <sys/kernel.h>
33
#include <sys/mbuf.h>
34
#include <sys/module.h>
35
#include <sys/signalvar.h>
36
#include <sys/sysctl.h>
37
#include <sys/socketvar.h>
38
39
/* check for full DNS request */
40
static int sohasdns(struct socket *so, void *arg, int waitflag);
41
42
ACCEPT_FILTER_DEFINE(accf_dns, "dnsready", sohasdns, NULL, NULL, 1);
43
44
struct packet {
45
struct mbuf *m; /* Current mbuf. */
46
struct mbuf *n; /* nextpkt mbuf. */
47
unsigned long moff; /* Offset of the beginning of m. */
48
unsigned long offset; /* Which offset we are working at. */
49
unsigned long len; /* The number of bytes we have to play with. */
50
};
51
52
#define DNS_OK 0
53
#define DNS_WAIT -1
54
#define DNS_RUN -2
55
56
/* check we can skip over various parts of DNS request */
57
static int skippacket(struct sockbuf *sb);
58
59
static int
60
sohasdns(struct socket *so, void *arg, int waitflag)
61
{
62
struct sockbuf *sb = &so->so_rcv;
63
64
/* If the socket is full, we're ready. */
65
if (sbused(sb) >= sb->sb_hiwat || sb->sb_mbcnt >= sb->sb_mbmax)
66
goto ready;
67
68
/* Check to see if we have a request. */
69
if (skippacket(sb) == DNS_WAIT)
70
return (SU_OK);
71
72
ready:
73
return (SU_ISCONNECTED);
74
}
75
76
#define GET8(p, val) do { \
77
if (p->offset < p->moff) \
78
return DNS_RUN; \
79
while (p->offset >= p->moff + p->m->m_len) { \
80
p->moff += p->m->m_len; \
81
p->m = p->m->m_next; \
82
if (p->m == NULL) { \
83
p->m = p->n; \
84
p->n = p->m->m_nextpkt; \
85
} \
86
if (p->m == NULL) \
87
return DNS_WAIT; \
88
} \
89
val = *(mtod(p->m, unsigned char *) + (p->offset - p->moff)); \
90
p->offset++; \
91
} while (0)
92
93
#define GET16(p, val) do { \
94
unsigned int v0, v1; \
95
GET8(p, v0); \
96
GET8(p, v1); \
97
val = v0 * 0x100 + v1; \
98
} while (0)
99
100
static int
101
skippacket(struct sockbuf *sb) {
102
unsigned long packlen;
103
struct packet q, *p = &q;
104
105
if (sbavail(sb) < 2)
106
return DNS_WAIT;
107
108
q.m = sb->sb_mb;
109
q.n = q.m->m_nextpkt;
110
q.moff = 0;
111
q.offset = 0;
112
q.len = sbavail(sb);
113
114
GET16(p, packlen);
115
if (packlen + 2 > q.len)
116
return DNS_WAIT;
117
118
return DNS_OK;
119
}
120
121