1*aca3beaaSApple OSS Distributions /*
2*aca3beaaSApple OSS Distributions * Copyright (c) 2016-2022 Apple Inc. All rights reserved.
3*aca3beaaSApple OSS Distributions *
4*aca3beaaSApple OSS Distributions * @APPLE_LICENSE_HEADER_START@
5*aca3beaaSApple OSS Distributions *
6*aca3beaaSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*aca3beaaSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*aca3beaaSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*aca3beaaSApple OSS Distributions * compliance with the License. Please obtain a copy of the License at
10*aca3beaaSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this
11*aca3beaaSApple OSS Distributions * file.
12*aca3beaaSApple OSS Distributions *
13*aca3beaaSApple OSS Distributions * The Original Code and all software distributed under the License are
14*aca3beaaSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15*aca3beaaSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16*aca3beaaSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17*aca3beaaSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18*aca3beaaSApple OSS Distributions * Please see the License for the specific language governing rights and
19*aca3beaaSApple OSS Distributions * limitations under the License.
20*aca3beaaSApple OSS Distributions *
21*aca3beaaSApple OSS Distributions * @APPLE_LICENSE_HEADER_END@
22*aca3beaaSApple OSS Distributions */
23*aca3beaaSApple OSS Distributions
24*aca3beaaSApple OSS Distributions #include <sys/cdefs.h>
25*aca3beaaSApple OSS Distributions #include <sys/systm.h>
26*aca3beaaSApple OSS Distributions #include <sys/param.h>
27*aca3beaaSApple OSS Distributions #include <sys/types.h>
28*aca3beaaSApple OSS Distributions #include <sys/mcache.h>
29*aca3beaaSApple OSS Distributions #include <kern/kern_types.h>
30*aca3beaaSApple OSS Distributions #include <net/pf_pbuf.h>
31*aca3beaaSApple OSS Distributions #include <net/pfvar.h>
32*aca3beaaSApple OSS Distributions #include <netinet/in.h>
33*aca3beaaSApple OSS Distributions
34*aca3beaaSApple OSS Distributions void
pbuf_init_mbuf(pbuf_t * pbuf,struct mbuf * m,struct ifnet * ifp)35*aca3beaaSApple OSS Distributions pbuf_init_mbuf(pbuf_t *pbuf, struct mbuf *m, struct ifnet *ifp)
36*aca3beaaSApple OSS Distributions {
37*aca3beaaSApple OSS Distributions VERIFY((m->m_flags & M_PKTHDR) != 0);
38*aca3beaaSApple OSS Distributions
39*aca3beaaSApple OSS Distributions pbuf->pb_type = PBUF_TYPE_MBUF;
40*aca3beaaSApple OSS Distributions pbuf->pb_mbuf = m;
41*aca3beaaSApple OSS Distributions pbuf->pb_ifp = ifp;
42*aca3beaaSApple OSS Distributions pbuf->pb_next = NULL;
43*aca3beaaSApple OSS Distributions pbuf_sync(pbuf);
44*aca3beaaSApple OSS Distributions }
45*aca3beaaSApple OSS Distributions
46*aca3beaaSApple OSS Distributions void
pbuf_init_memory(pbuf_t * pbuf,const struct pbuf_memory * mp,struct ifnet * ifp)47*aca3beaaSApple OSS Distributions pbuf_init_memory(pbuf_t *pbuf, const struct pbuf_memory *mp, struct ifnet *ifp)
48*aca3beaaSApple OSS Distributions {
49*aca3beaaSApple OSS Distributions pbuf->pb_type = PBUF_TYPE_MEMORY;
50*aca3beaaSApple OSS Distributions pbuf->pb_memory = *mp;
51*aca3beaaSApple OSS Distributions pbuf->pb_ifp = ifp;
52*aca3beaaSApple OSS Distributions pbuf->pb_next = NULL;
53*aca3beaaSApple OSS Distributions pbuf_sync(pbuf);
54*aca3beaaSApple OSS Distributions }
55*aca3beaaSApple OSS Distributions
56*aca3beaaSApple OSS Distributions void
pbuf_destroy(pbuf_t * pbuf)57*aca3beaaSApple OSS Distributions pbuf_destroy(pbuf_t *pbuf)
58*aca3beaaSApple OSS Distributions {
59*aca3beaaSApple OSS Distributions if (pbuf->pb_type == PBUF_TYPE_MBUF) {
60*aca3beaaSApple OSS Distributions if (pbuf->pb_mbuf) {
61*aca3beaaSApple OSS Distributions m_freem(pbuf->pb_mbuf);
62*aca3beaaSApple OSS Distributions pbuf->pb_mbuf = NULL;
63*aca3beaaSApple OSS Distributions }
64*aca3beaaSApple OSS Distributions } else if (pbuf->pb_type == PBUF_TYPE_MEMORY) {
65*aca3beaaSApple OSS Distributions VERIFY(pbuf->pb_memory.pm_buffer != NULL);
66*aca3beaaSApple OSS Distributions (void) (pbuf->pb_memory.pm_action)(&pbuf->pb_memory,
67*aca3beaaSApple OSS Distributions PBUF_ACTION_DESTROY);
68*aca3beaaSApple OSS Distributions } else {
69*aca3beaaSApple OSS Distributions VERIFY(pbuf->pb_type == PBUF_TYPE_ZOMBIE);
70*aca3beaaSApple OSS Distributions }
71*aca3beaaSApple OSS Distributions
72*aca3beaaSApple OSS Distributions memset(pbuf, 0, sizeof(*pbuf));
73*aca3beaaSApple OSS Distributions }
74*aca3beaaSApple OSS Distributions
75*aca3beaaSApple OSS Distributions void
pbuf_sync(pbuf_t * pbuf)76*aca3beaaSApple OSS Distributions pbuf_sync(pbuf_t *pbuf)
77*aca3beaaSApple OSS Distributions {
78*aca3beaaSApple OSS Distributions if (pbuf->pb_type == PBUF_TYPE_MBUF) {
79*aca3beaaSApple OSS Distributions struct mbuf *m = pbuf->pb_mbuf;
80*aca3beaaSApple OSS Distributions
81*aca3beaaSApple OSS Distributions VERIFY(m != NULL);
82*aca3beaaSApple OSS Distributions VERIFY(m->m_flags & M_PKTHDR);
83*aca3beaaSApple OSS Distributions
84*aca3beaaSApple OSS Distributions pbuf->pb_data = mtod(m, void *);
85*aca3beaaSApple OSS Distributions pbuf->pb_packet_len = m->m_pkthdr.len;
86*aca3beaaSApple OSS Distributions pbuf->pb_contig_len = m->m_len;
87*aca3beaaSApple OSS Distributions pbuf->pb_csum_flags = &m->m_pkthdr.csum_flags;
88*aca3beaaSApple OSS Distributions pbuf->pb_csum_data = &m->m_pkthdr.csum_data;
89*aca3beaaSApple OSS Distributions pbuf->pb_proto = &m->m_pkthdr.pkt_proto;
90*aca3beaaSApple OSS Distributions pbuf->pb_flowsrc = &m->m_pkthdr.pkt_flowsrc;
91*aca3beaaSApple OSS Distributions pbuf->pb_flowid = &m->m_pkthdr.pkt_flowid;
92*aca3beaaSApple OSS Distributions pbuf->pb_flow_gencnt = &m->m_pkthdr.comp_gencnt;
93*aca3beaaSApple OSS Distributions pbuf->pb_flags = &m->m_pkthdr.pkt_flags;
94*aca3beaaSApple OSS Distributions pbuf->pb_pftag = m_pftag(m);
95*aca3beaaSApple OSS Distributions pbuf->pb_pf_fragtag = pf_find_fragment_tag(m);
96*aca3beaaSApple OSS Distributions ASSERT((pbuf->pb_pf_fragtag == NULL) ||
97*aca3beaaSApple OSS Distributions (pbuf->pb_pftag->pftag_flags & PF_TAG_REASSEMBLED));
98*aca3beaaSApple OSS Distributions } else if (pbuf->pb_type == PBUF_TYPE_MEMORY) {
99*aca3beaaSApple OSS Distributions struct pbuf_memory *nm = &pbuf->pb_memory;
100*aca3beaaSApple OSS Distributions
101*aca3beaaSApple OSS Distributions VERIFY(nm->pm_buffer != NULL);
102*aca3beaaSApple OSS Distributions VERIFY(nm->pm_buffer_len != 0);
103*aca3beaaSApple OSS Distributions VERIFY(nm->pm_len != 0);
104*aca3beaaSApple OSS Distributions VERIFY(nm->pm_len <= nm->pm_buffer_len);
105*aca3beaaSApple OSS Distributions VERIFY(nm->pm_offset < nm->pm_len);
106*aca3beaaSApple OSS Distributions
107*aca3beaaSApple OSS Distributions pbuf->pb_data = &nm->pm_buffer[nm->pm_offset];
108*aca3beaaSApple OSS Distributions pbuf->pb_packet_len = nm->pm_len;
109*aca3beaaSApple OSS Distributions pbuf->pb_contig_len = nm->pm_len;
110*aca3beaaSApple OSS Distributions pbuf->pb_csum_flags = &nm->pm_csum_flags;
111*aca3beaaSApple OSS Distributions pbuf->pb_csum_data = &nm->pm_csum_data;
112*aca3beaaSApple OSS Distributions pbuf->pb_proto = &nm->pm_proto;
113*aca3beaaSApple OSS Distributions pbuf->pb_flowsrc = &nm->pm_flowsrc;
114*aca3beaaSApple OSS Distributions pbuf->pb_flowid = &nm->pm_flowid;
115*aca3beaaSApple OSS Distributions pbuf->pb_flow_gencnt = &nm->pm_flow_gencnt;
116*aca3beaaSApple OSS Distributions pbuf->pb_flags = &nm->pm_flags;
117*aca3beaaSApple OSS Distributions pbuf->pb_pftag = &nm->pm_pftag;
118*aca3beaaSApple OSS Distributions pbuf->pb_pf_fragtag = &nm->pm_pf_fragtag;
119*aca3beaaSApple OSS Distributions } else {
120*aca3beaaSApple OSS Distributions panic("%s: bad pb_type: %d", __func__, pbuf->pb_type);
121*aca3beaaSApple OSS Distributions }
122*aca3beaaSApple OSS Distributions }
123*aca3beaaSApple OSS Distributions
124*aca3beaaSApple OSS Distributions struct mbuf *
pbuf_to_mbuf(pbuf_t * pbuf,boolean_t release_ptr)125*aca3beaaSApple OSS Distributions pbuf_to_mbuf(pbuf_t *pbuf, boolean_t release_ptr)
126*aca3beaaSApple OSS Distributions {
127*aca3beaaSApple OSS Distributions struct mbuf *m = NULL;
128*aca3beaaSApple OSS Distributions
129*aca3beaaSApple OSS Distributions pbuf_sync(pbuf);
130*aca3beaaSApple OSS Distributions
131*aca3beaaSApple OSS Distributions if (pbuf->pb_type == PBUF_TYPE_MBUF) {
132*aca3beaaSApple OSS Distributions m = pbuf->pb_mbuf;
133*aca3beaaSApple OSS Distributions if (release_ptr) {
134*aca3beaaSApple OSS Distributions pbuf->pb_mbuf = NULL;
135*aca3beaaSApple OSS Distributions }
136*aca3beaaSApple OSS Distributions } else if (pbuf->pb_type == PBUF_TYPE_MEMORY) {
137*aca3beaaSApple OSS Distributions boolean_t fragtag = FALSE;
138*aca3beaaSApple OSS Distributions
139*aca3beaaSApple OSS Distributions if (pbuf->pb_packet_len > (u_int)MHLEN) {
140*aca3beaaSApple OSS Distributions if (pbuf->pb_packet_len > (u_int)MCLBYTES) {
141*aca3beaaSApple OSS Distributions printf("%s: packet too big for cluster (%u)\n",
142*aca3beaaSApple OSS Distributions __func__, pbuf->pb_packet_len);
143*aca3beaaSApple OSS Distributions return NULL;
144*aca3beaaSApple OSS Distributions }
145*aca3beaaSApple OSS Distributions m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR);
146*aca3beaaSApple OSS Distributions } else {
147*aca3beaaSApple OSS Distributions m = m_gethdr(M_DONTWAIT, MT_DATA);
148*aca3beaaSApple OSS Distributions }
149*aca3beaaSApple OSS Distributions if (m == NULL) {
150*aca3beaaSApple OSS Distributions goto done;
151*aca3beaaSApple OSS Distributions }
152*aca3beaaSApple OSS Distributions
153*aca3beaaSApple OSS Distributions m_copyback(m, 0, pbuf->pb_packet_len, pbuf->pb_data);
154*aca3beaaSApple OSS Distributions m->m_pkthdr.csum_flags = *pbuf->pb_csum_flags;
155*aca3beaaSApple OSS Distributions m->m_pkthdr.csum_data = *pbuf->pb_csum_data;
156*aca3beaaSApple OSS Distributions m->m_pkthdr.pkt_proto = *pbuf->pb_proto;
157*aca3beaaSApple OSS Distributions m->m_pkthdr.pkt_flowsrc = *pbuf->pb_flowsrc;
158*aca3beaaSApple OSS Distributions m->m_pkthdr.pkt_flowid = *pbuf->pb_flowid;
159*aca3beaaSApple OSS Distributions m->m_pkthdr.comp_gencnt = *pbuf->pb_flow_gencnt;
160*aca3beaaSApple OSS Distributions m->m_pkthdr.pkt_flags = *pbuf->pb_flags;
161*aca3beaaSApple OSS Distributions
162*aca3beaaSApple OSS Distributions if (pbuf->pb_pftag != NULL) {
163*aca3beaaSApple OSS Distributions struct pf_mtag *pftag = m_pftag(m);
164*aca3beaaSApple OSS Distributions
165*aca3beaaSApple OSS Distributions ASSERT(pftag != NULL);
166*aca3beaaSApple OSS Distributions *pftag = *pbuf->pb_pftag;
167*aca3beaaSApple OSS Distributions fragtag =
168*aca3beaaSApple OSS Distributions ((pftag->pftag_flags & PF_TAG_REASSEMBLED) != 0);
169*aca3beaaSApple OSS Distributions }
170*aca3beaaSApple OSS Distributions
171*aca3beaaSApple OSS Distributions if (fragtag && pbuf->pb_pf_fragtag != NULL) {
172*aca3beaaSApple OSS Distributions if (pf_copy_fragment_tag(m, pbuf->pb_pf_fragtag,
173*aca3beaaSApple OSS Distributions M_NOWAIT) == NULL) {
174*aca3beaaSApple OSS Distributions m_freem(m);
175*aca3beaaSApple OSS Distributions m = NULL;
176*aca3beaaSApple OSS Distributions goto done;
177*aca3beaaSApple OSS Distributions }
178*aca3beaaSApple OSS Distributions }
179*aca3beaaSApple OSS Distributions }
180*aca3beaaSApple OSS Distributions
181*aca3beaaSApple OSS Distributions done:
182*aca3beaaSApple OSS Distributions if (release_ptr) {
183*aca3beaaSApple OSS Distributions pbuf_destroy(pbuf);
184*aca3beaaSApple OSS Distributions }
185*aca3beaaSApple OSS Distributions return m;
186*aca3beaaSApple OSS Distributions }
187*aca3beaaSApple OSS Distributions
188*aca3beaaSApple OSS Distributions struct mbuf *
pbuf_clone_to_mbuf(pbuf_t * pbuf)189*aca3beaaSApple OSS Distributions pbuf_clone_to_mbuf(pbuf_t *pbuf)
190*aca3beaaSApple OSS Distributions {
191*aca3beaaSApple OSS Distributions struct mbuf *m = NULL;
192*aca3beaaSApple OSS Distributions
193*aca3beaaSApple OSS Distributions pbuf_sync(pbuf);
194*aca3beaaSApple OSS Distributions
195*aca3beaaSApple OSS Distributions if (pbuf->pb_type == PBUF_TYPE_MBUF) {
196*aca3beaaSApple OSS Distributions m = m_copy(pbuf->pb_mbuf, 0, M_COPYALL);
197*aca3beaaSApple OSS Distributions } else if (pbuf->pb_type == PBUF_TYPE_MEMORY) {
198*aca3beaaSApple OSS Distributions m = pbuf_to_mbuf(pbuf, FALSE);
199*aca3beaaSApple OSS Distributions } else {
200*aca3beaaSApple OSS Distributions panic("%s: bad pb_type: %d", __func__, pbuf->pb_type);
201*aca3beaaSApple OSS Distributions }
202*aca3beaaSApple OSS Distributions
203*aca3beaaSApple OSS Distributions return m;
204*aca3beaaSApple OSS Distributions }
205*aca3beaaSApple OSS Distributions
206*aca3beaaSApple OSS Distributions void *
pbuf_ensure_writable(pbuf_t * pbuf,size_t len)207*aca3beaaSApple OSS Distributions pbuf_ensure_writable(pbuf_t *pbuf, size_t len)
208*aca3beaaSApple OSS Distributions {
209*aca3beaaSApple OSS Distributions if (pbuf->pb_type == PBUF_TYPE_MBUF) {
210*aca3beaaSApple OSS Distributions struct mbuf *m = pbuf->pb_mbuf;
211*aca3beaaSApple OSS Distributions
212*aca3beaaSApple OSS Distributions if (m_makewritable(&pbuf->pb_mbuf, 0, len, M_DONTWAIT)) {
213*aca3beaaSApple OSS Distributions return NULL;
214*aca3beaaSApple OSS Distributions }
215*aca3beaaSApple OSS Distributions
216*aca3beaaSApple OSS Distributions if (pbuf->pb_mbuf == NULL) {
217*aca3beaaSApple OSS Distributions pbuf_destroy(pbuf);
218*aca3beaaSApple OSS Distributions return NULL;
219*aca3beaaSApple OSS Distributions }
220*aca3beaaSApple OSS Distributions
221*aca3beaaSApple OSS Distributions if (m != pbuf->pb_mbuf) {
222*aca3beaaSApple OSS Distributions pbuf_sync(pbuf);
223*aca3beaaSApple OSS Distributions }
224*aca3beaaSApple OSS Distributions } else if (pbuf->pb_type != PBUF_TYPE_MEMORY) {
225*aca3beaaSApple OSS Distributions panic("%s: bad pb_type: %d", __func__, pbuf->pb_type);
226*aca3beaaSApple OSS Distributions }
227*aca3beaaSApple OSS Distributions
228*aca3beaaSApple OSS Distributions return pbuf->pb_data;
229*aca3beaaSApple OSS Distributions }
230*aca3beaaSApple OSS Distributions
231*aca3beaaSApple OSS Distributions void *
pbuf_resize_segment(pbuf_t * pbuf,int off,int olen,int nlen)232*aca3beaaSApple OSS Distributions pbuf_resize_segment(pbuf_t *pbuf, int off, int olen, int nlen)
233*aca3beaaSApple OSS Distributions {
234*aca3beaaSApple OSS Distributions void *rv = NULL;
235*aca3beaaSApple OSS Distributions
236*aca3beaaSApple OSS Distributions VERIFY(off >= 0);
237*aca3beaaSApple OSS Distributions VERIFY((u_int)off <= pbuf->pb_packet_len);
238*aca3beaaSApple OSS Distributions
239*aca3beaaSApple OSS Distributions if (pbuf->pb_type == PBUF_TYPE_MBUF) {
240*aca3beaaSApple OSS Distributions struct mbuf *m, *n;
241*aca3beaaSApple OSS Distributions
242*aca3beaaSApple OSS Distributions VERIFY(pbuf->pb_mbuf != NULL);
243*aca3beaaSApple OSS Distributions
244*aca3beaaSApple OSS Distributions m = pbuf->pb_mbuf;
245*aca3beaaSApple OSS Distributions
246*aca3beaaSApple OSS Distributions if (off > 0) {
247*aca3beaaSApple OSS Distributions /* Split the mbuf chain at the specified boundary */
248*aca3beaaSApple OSS Distributions if ((n = m_split(m, off, M_DONTWAIT)) == NULL) {
249*aca3beaaSApple OSS Distributions return NULL;
250*aca3beaaSApple OSS Distributions }
251*aca3beaaSApple OSS Distributions } else {
252*aca3beaaSApple OSS Distributions n = m;
253*aca3beaaSApple OSS Distributions }
254*aca3beaaSApple OSS Distributions
255*aca3beaaSApple OSS Distributions /* Trim old length */
256*aca3beaaSApple OSS Distributions m_adj(n, olen);
257*aca3beaaSApple OSS Distributions
258*aca3beaaSApple OSS Distributions /* Prepend new length */
259*aca3beaaSApple OSS Distributions if (M_PREPEND(n, nlen, M_DONTWAIT, 0) == NULL) {
260*aca3beaaSApple OSS Distributions /* mbuf is freed by M_PREPEND in this case */
261*aca3beaaSApple OSS Distributions pbuf->pb_mbuf = NULL;
262*aca3beaaSApple OSS Distributions pbuf_destroy(pbuf);
263*aca3beaaSApple OSS Distributions return NULL;
264*aca3beaaSApple OSS Distributions }
265*aca3beaaSApple OSS Distributions
266*aca3beaaSApple OSS Distributions rv = mtod(n, void *);
267*aca3beaaSApple OSS Distributions
268*aca3beaaSApple OSS Distributions if (off > 0) {
269*aca3beaaSApple OSS Distributions /* Merge the two chains */
270*aca3beaaSApple OSS Distributions int mlen;
271*aca3beaaSApple OSS Distributions
272*aca3beaaSApple OSS Distributions mlen = n->m_pkthdr.len;
273*aca3beaaSApple OSS Distributions m_cat(m, n);
274*aca3beaaSApple OSS Distributions m->m_pkthdr.len += mlen;
275*aca3beaaSApple OSS Distributions } else {
276*aca3beaaSApple OSS Distributions /* The new mbuf becomes the packet header */
277*aca3beaaSApple OSS Distributions pbuf->pb_mbuf = n;
278*aca3beaaSApple OSS Distributions }
279*aca3beaaSApple OSS Distributions
280*aca3beaaSApple OSS Distributions pbuf_sync(pbuf);
281*aca3beaaSApple OSS Distributions } else if (pbuf->pb_type == PBUF_TYPE_MEMORY) {
282*aca3beaaSApple OSS Distributions struct pbuf_memory *nm = &pbuf->pb_memory;
283*aca3beaaSApple OSS Distributions u_int true_offset, move_len;
284*aca3beaaSApple OSS Distributions int delta_len;
285*aca3beaaSApple OSS Distributions uint8_t *psrc, *pdst;
286*aca3beaaSApple OSS Distributions
287*aca3beaaSApple OSS Distributions delta_len = nlen - olen;
288*aca3beaaSApple OSS Distributions VERIFY(nm->pm_offset + (nm->pm_len + delta_len) <=
289*aca3beaaSApple OSS Distributions nm->pm_buffer_len);
290*aca3beaaSApple OSS Distributions
291*aca3beaaSApple OSS Distributions true_offset = (u_int)off + nm->pm_offset;
292*aca3beaaSApple OSS Distributions rv = &nm->pm_buffer[true_offset];
293*aca3beaaSApple OSS Distributions psrc = &nm->pm_buffer[true_offset + (u_int)olen];
294*aca3beaaSApple OSS Distributions pdst = &nm->pm_buffer[true_offset + (u_int)nlen];
295*aca3beaaSApple OSS Distributions move_len = pbuf->pb_packet_len - ((u_int)off + olen);
296*aca3beaaSApple OSS Distributions memmove(pdst, psrc, move_len);
297*aca3beaaSApple OSS Distributions
298*aca3beaaSApple OSS Distributions nm->pm_len += delta_len;
299*aca3beaaSApple OSS Distributions
300*aca3beaaSApple OSS Distributions VERIFY((nm->pm_len + nm->pm_offset) <= nm->pm_buffer_len);
301*aca3beaaSApple OSS Distributions
302*aca3beaaSApple OSS Distributions pbuf_sync(pbuf);
303*aca3beaaSApple OSS Distributions } else {
304*aca3beaaSApple OSS Distributions panic("pbuf_csum_flags_get: bad pb_type: %d", pbuf->pb_type);
305*aca3beaaSApple OSS Distributions }
306*aca3beaaSApple OSS Distributions return rv;
307*aca3beaaSApple OSS Distributions }
308*aca3beaaSApple OSS Distributions
309*aca3beaaSApple OSS Distributions void *
pbuf_contig_segment(pbuf_t * pbuf,int off,int len)310*aca3beaaSApple OSS Distributions pbuf_contig_segment(pbuf_t *pbuf, int off, int len)
311*aca3beaaSApple OSS Distributions {
312*aca3beaaSApple OSS Distributions void *rv = NULL;
313*aca3beaaSApple OSS Distributions
314*aca3beaaSApple OSS Distributions VERIFY(off >= 0);
315*aca3beaaSApple OSS Distributions VERIFY(len >= 0);
316*aca3beaaSApple OSS Distributions VERIFY((u_int)(off + len) <= pbuf->pb_packet_len);
317*aca3beaaSApple OSS Distributions
318*aca3beaaSApple OSS Distributions /*
319*aca3beaaSApple OSS Distributions * Note: If this fails, then the pbuf is destroyed. This is a
320*aca3beaaSApple OSS Distributions * side-effect of m_pulldown().
321*aca3beaaSApple OSS Distributions *
322*aca3beaaSApple OSS Distributions * PF expects this behaviour so it's not a real problem.
323*aca3beaaSApple OSS Distributions */
324*aca3beaaSApple OSS Distributions if (pbuf->pb_type == PBUF_TYPE_MBUF) {
325*aca3beaaSApple OSS Distributions struct mbuf *n;
326*aca3beaaSApple OSS Distributions int moff;
327*aca3beaaSApple OSS Distributions
328*aca3beaaSApple OSS Distributions n = m_pulldown(pbuf->pb_mbuf, off, len, &moff);
329*aca3beaaSApple OSS Distributions if (n == NULL) {
330*aca3beaaSApple OSS Distributions /* mbuf is freed by m_pulldown() in this case */
331*aca3beaaSApple OSS Distributions pbuf->pb_mbuf = NULL;
332*aca3beaaSApple OSS Distributions pbuf_destroy(pbuf);
333*aca3beaaSApple OSS Distributions return NULL;
334*aca3beaaSApple OSS Distributions }
335*aca3beaaSApple OSS Distributions
336*aca3beaaSApple OSS Distributions pbuf_sync(pbuf);
337*aca3beaaSApple OSS Distributions
338*aca3beaaSApple OSS Distributions rv = (void *)(mtod(n, uint8_t *) + moff);
339*aca3beaaSApple OSS Distributions } else if (pbuf->pb_type == PBUF_TYPE_MEMORY) {
340*aca3beaaSApple OSS Distributions /*
341*aca3beaaSApple OSS Distributions * This always succeeds since memory pbufs are fully contig.
342*aca3beaaSApple OSS Distributions */
343*aca3beaaSApple OSS Distributions rv = (void *)(uintptr_t)(((uint8_t *)pbuf->pb_data)[off]);
344*aca3beaaSApple OSS Distributions } else {
345*aca3beaaSApple OSS Distributions panic("%s: bad pb_type: %d", __func__, pbuf->pb_type);
346*aca3beaaSApple OSS Distributions }
347*aca3beaaSApple OSS Distributions
348*aca3beaaSApple OSS Distributions return rv;
349*aca3beaaSApple OSS Distributions }
350*aca3beaaSApple OSS Distributions
351*aca3beaaSApple OSS Distributions void
pbuf_copy_back(pbuf_t * pbuf,int off,int len,void * src)352*aca3beaaSApple OSS Distributions pbuf_copy_back(pbuf_t *pbuf, int off, int len, void *src)
353*aca3beaaSApple OSS Distributions {
354*aca3beaaSApple OSS Distributions VERIFY(off >= 0);
355*aca3beaaSApple OSS Distributions VERIFY(len >= 0);
356*aca3beaaSApple OSS Distributions VERIFY((u_int)(off + len) <= pbuf->pb_packet_len);
357*aca3beaaSApple OSS Distributions
358*aca3beaaSApple OSS Distributions if (pbuf->pb_type == PBUF_TYPE_MBUF) {
359*aca3beaaSApple OSS Distributions m_copyback(pbuf->pb_mbuf, off, len, src);
360*aca3beaaSApple OSS Distributions } else if (pbuf->pb_type == PBUF_TYPE_MEMORY) {
361*aca3beaaSApple OSS Distributions if (len) {
362*aca3beaaSApple OSS Distributions memcpy(&((uint8_t *)pbuf->pb_data)[off], src, len);
363*aca3beaaSApple OSS Distributions }
364*aca3beaaSApple OSS Distributions } else {
365*aca3beaaSApple OSS Distributions panic("%s: bad pb_type: %d", __func__, pbuf->pb_type);
366*aca3beaaSApple OSS Distributions }
367*aca3beaaSApple OSS Distributions }
368*aca3beaaSApple OSS Distributions
369*aca3beaaSApple OSS Distributions void
pbuf_copy_data(pbuf_t * pbuf,int off,int len,void * dst)370*aca3beaaSApple OSS Distributions pbuf_copy_data(pbuf_t *pbuf, int off, int len, void *dst)
371*aca3beaaSApple OSS Distributions {
372*aca3beaaSApple OSS Distributions VERIFY(off >= 0);
373*aca3beaaSApple OSS Distributions VERIFY(len >= 0);
374*aca3beaaSApple OSS Distributions VERIFY((u_int)(off + len) <= pbuf->pb_packet_len);
375*aca3beaaSApple OSS Distributions
376*aca3beaaSApple OSS Distributions if (pbuf->pb_type == PBUF_TYPE_MBUF) {
377*aca3beaaSApple OSS Distributions m_copydata(pbuf->pb_mbuf, off, len, dst);
378*aca3beaaSApple OSS Distributions } else if (pbuf->pb_type == PBUF_TYPE_MEMORY) {
379*aca3beaaSApple OSS Distributions if (len) {
380*aca3beaaSApple OSS Distributions memcpy(dst, &((uint8_t *)pbuf->pb_data)[off], len);
381*aca3beaaSApple OSS Distributions }
382*aca3beaaSApple OSS Distributions } else {
383*aca3beaaSApple OSS Distributions panic("%s: bad pb_type: %d", __func__, pbuf->pb_type);
384*aca3beaaSApple OSS Distributions }
385*aca3beaaSApple OSS Distributions }
386*aca3beaaSApple OSS Distributions
387*aca3beaaSApple OSS Distributions uint16_t
pbuf_inet_cksum(const pbuf_t * pbuf,uint32_t nxt,uint32_t off,uint32_t len)388*aca3beaaSApple OSS Distributions pbuf_inet_cksum(const pbuf_t *pbuf, uint32_t nxt, uint32_t off, uint32_t len)
389*aca3beaaSApple OSS Distributions {
390*aca3beaaSApple OSS Distributions uint16_t sum = 0;
391*aca3beaaSApple OSS Distributions
392*aca3beaaSApple OSS Distributions if (pbuf->pb_type == PBUF_TYPE_MBUF) {
393*aca3beaaSApple OSS Distributions sum = inet_cksum(pbuf->pb_mbuf, nxt, off, len);
394*aca3beaaSApple OSS Distributions } else if (pbuf->pb_type == PBUF_TYPE_MEMORY) {
395*aca3beaaSApple OSS Distributions sum = inet_cksum_buffer(pbuf->pb_data, nxt, off, len);
396*aca3beaaSApple OSS Distributions } else {
397*aca3beaaSApple OSS Distributions panic("%s: bad pb_type: %d", __func__, pbuf->pb_type);
398*aca3beaaSApple OSS Distributions }
399*aca3beaaSApple OSS Distributions
400*aca3beaaSApple OSS Distributions return sum;
401*aca3beaaSApple OSS Distributions }
402*aca3beaaSApple OSS Distributions
403*aca3beaaSApple OSS Distributions uint16_t
pbuf_inet6_cksum(const pbuf_t * pbuf,uint32_t nxt,uint32_t off,uint32_t len)404*aca3beaaSApple OSS Distributions pbuf_inet6_cksum(const pbuf_t *pbuf, uint32_t nxt, uint32_t off, uint32_t len)
405*aca3beaaSApple OSS Distributions {
406*aca3beaaSApple OSS Distributions uint16_t sum = 0;
407*aca3beaaSApple OSS Distributions
408*aca3beaaSApple OSS Distributions if (pbuf->pb_type == PBUF_TYPE_MBUF) {
409*aca3beaaSApple OSS Distributions sum = inet6_cksum(pbuf->pb_mbuf, nxt, off, len);
410*aca3beaaSApple OSS Distributions } else if (pbuf->pb_type == PBUF_TYPE_MEMORY) {
411*aca3beaaSApple OSS Distributions sum = inet6_cksum_buffer(pbuf->pb_data, nxt, off, len);
412*aca3beaaSApple OSS Distributions } else {
413*aca3beaaSApple OSS Distributions panic("%s: bad pb_type: %d", __func__, pbuf->pb_type);
414*aca3beaaSApple OSS Distributions }
415*aca3beaaSApple OSS Distributions
416*aca3beaaSApple OSS Distributions return sum;
417*aca3beaaSApple OSS Distributions }
418*aca3beaaSApple OSS Distributions
419*aca3beaaSApple OSS Distributions mbuf_svc_class_t
pbuf_get_service_class(const pbuf_t * pbuf)420*aca3beaaSApple OSS Distributions pbuf_get_service_class(const pbuf_t *pbuf)
421*aca3beaaSApple OSS Distributions {
422*aca3beaaSApple OSS Distributions if (pbuf->pb_type == PBUF_TYPE_MBUF) {
423*aca3beaaSApple OSS Distributions return m_get_service_class(pbuf->pb_mbuf);
424*aca3beaaSApple OSS Distributions }
425*aca3beaaSApple OSS Distributions
426*aca3beaaSApple OSS Distributions VERIFY(pbuf->pb_type == PBUF_TYPE_MEMORY);
427*aca3beaaSApple OSS Distributions
428*aca3beaaSApple OSS Distributions return MBUF_SC_BE;
429*aca3beaaSApple OSS Distributions }
430*aca3beaaSApple OSS Distributions
431*aca3beaaSApple OSS Distributions void *
pbuf_get_packet_buffer_address(const pbuf_t * pbuf)432*aca3beaaSApple OSS Distributions pbuf_get_packet_buffer_address(const pbuf_t *pbuf)
433*aca3beaaSApple OSS Distributions {
434*aca3beaaSApple OSS Distributions VERIFY(pbuf != NULL);
435*aca3beaaSApple OSS Distributions
436*aca3beaaSApple OSS Distributions if (pbuf->pb_type == PBUF_TYPE_MBUF) {
437*aca3beaaSApple OSS Distributions return pbuf->pb_mbuf;
438*aca3beaaSApple OSS Distributions } else {
439*aca3beaaSApple OSS Distributions return pbuf->pb_memory.pm_buffer;
440*aca3beaaSApple OSS Distributions }
441*aca3beaaSApple OSS Distributions }
442