xref: /netbsd-src/share/man/man9/mbuf.9 (revision c38e7cc395b1472a774ff828e46123de44c628e9)
1.\"	$NetBSD: mbuf.9,v 1.63 2018/04/28 08:34:45 maxv Exp $
2.\"
3.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
4.\" All rights reserved.
5.\"
6.\" This documentation is derived from text contributed to The NetBSD Foundation
7.\" by S.P.Zeidler (aka stargazer).
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\"    notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\"    notice, this list of conditions and the following disclaimer in the
16.\"    documentation and/or other materials provided with the distribution.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28.\" POSSIBILITY OF SUCH DAMAGE.
29.\"
30.Dd April 28, 2018
31.Dt MBUF 9
32.Os
33.Sh NAME
34.Nm mbuf ,
35.Nm m_get ,
36.Nm m_gethdr ,
37.Nm m_devget ,
38.Nm m_copym ,
39.Nm m_copypacket ,
40.Nm m_copydata ,
41.Nm m_copyback ,
42.Nm m_copyback_cow ,
43.Nm m_cat ,
44.Nm m_dup ,
45.Nm m_makewritable ,
46.Nm m_pulldown ,
47.Nm m_pullup ,
48.Nm m_copyup ,
49.Nm m_split ,
50.Nm m_adj ,
51.Nm m_apply ,
52.Nm m_free ,
53.Nm m_freem ,
54.Nm mtod ,
55.Nm MGET ,
56.Nm MGETHDR ,
57.Nm MEXTMALLOC ,
58.Nm MEXTADD ,
59.Nm MCLGET ,
60.Nm M_COPY_PKTHDR ,
61.Nm M_MOVE_PKTHDR ,
62.Nm M_ALIGN ,
63.Nm MH_ALIGN ,
64.Nm M_LEADINGSPACE ,
65.Nm M_TRAILINGSPACE ,
66.Nm M_PREPEND ,
67.Nm MCHTYPE
68.Nd "functions and macros for managing memory used by networking code"
69.Sh SYNOPSIS
70.In sys/mbuf.h
71.Ft struct mbuf *
72.Fn m_get "int how" "int type"
73.Ft struct mbuf *
74.Fn m_gethdr "int how" "int type"
75.Ft struct mbuf *
76.Fn m_devget "char *buf" "int totlen" "int off0" "struct ifnet *ifp" "void (*copy)(const void *, void *, size_t)"
77.Ft struct mbuf *
78.Fn m_copym "struct mbuf *m" "int off" "int len" "int wait"
79.Ft struct mbuf *
80.Fn m_copypacket "struct mbuf *m" "int how"
81.Ft void
82.Fn m_copydata "struct mbuf *m" "int off" "int len" "void *cp"
83.Ft void
84.Fn m_copyback "struct mbuf *m0" "int off" "int len" "void *cp"
85.Ft struct mbuf *
86.Fn m_copyback_cow "struct mbuf *m0" "int off" "int len" "void *cp" "int how"
87.Ft int
88.Fn m_makewritable "struct mbuf **mp" "int off" "int len" "int how"
89.Ft void
90.Fn m_cat "struct mbuf *m" "struct mbuf *n"
91.Ft struct mbuf *
92.Fn m_dup "struct mbuf *m" "int off" "int len" "int wait"
93.Ft struct mbuf *
94.Fn m_pulldown "struct mbuf *m" "int off" "int len" "int *offp"
95.Ft struct mbuf *
96.Fn m_pullup "struct mbuf *n" "int len"
97.Ft struct mbuf *
98.Fn m_copyup "struct mbuf *m" "int len" "int dstoff"
99.Ft struct mbuf *
100.Fn m_split "struct mbuf *m0" "int len" "int wait"
101.Ft void
102.Fn m_adj "struct mbuf *mp" "int req_len"
103.Ft int
104.Fn m_apply "struct mbuf *m" "int off" "int len" "int *f(void *, void *, unsigned int)" "void *arg"
105.Ft struct mbuf *
106.Fn m_free "struct mbuf *m"
107.Ft void
108.Fn m_freem "struct mbuf *m"
109.Ft datatype
110.Fn mtod "struct mbuf *m" "datatype"
111.Ft void
112.Fn MGET "struct mbuf *m" "int how" "int type"
113.Ft void
114.Fn MGETHDR "struct mbuf *m" "int how" "int type"
115.Ft void
116.Fn MEXTMALLOC "struct mbuf *m" "int len" "int how"
117.Ft void
118.Fn MEXTADD "struct mbuf *m" "void *buf" "int size" "int type" "void (*free)(struct mbuf *, void *, size_t, void *)" "void *arg"
119.Ft void
120.Fn MCLGET "struct mbuf *m" "int how"
121.Ft void
122.Fn M_COPY_PKTHDR "struct mbuf *to" "struct mbuf *from"
123.Ft void
124.Fn M_MOVE_PKTHDR "struct mbuf *to" "struct mbuf *from"
125.Ft void
126.Fn M_ALIGN "struct mbuf *m" "int len"
127.Ft void
128.Fn MH_ALIGN "struct mbuf *m" "int len"
129.Ft int
130.Fn M_LEADINGSPACE "struct mbuf *m"
131.Ft int
132.Fn M_TRAILINGSPACE "struct mbuf *m"
133.Ft void
134.Fn M_PREPEND "struct mbuf *m" "int plen" "int how"
135.Ft void
136.Fn MCHTYPE "struct mbuf *m" "int type"
137.Sh DESCRIPTION
138The
139.Nm
140functions and macros provide an easy and consistent way to handle
141a networking stack's memory management needs.
142An
143.Nm
144consists of a header and a data area.
145It is of a fixed size,
146.Dv MSIZE
147.Pq defined in Aq Pa machine/param.h ,
148which includes overhead.
149The header contains a pointer to the next
150.Nm
151in the
152.Sq "mbuf chain" ,
153a pointer to the next
154.Sq "mbuf chain" ,
155a pointer to the data area, the amount of data in this mbuf, its type
156and a
157.Dv flags
158field.
159.Pp
160The
161.Dv type
162variable can signify:
163.Bl -tag -compact -offset indent -width "XXXXXXXXXXX"
164.It Dv MT_FREE
165the mbuf should be on the ``free'' list
166.It Dv MT_DATA
167data was dynamically allocated
168.It Dv MT_HEADER
169data is a packet header
170.It Dv MT_SONAME
171data is a socket name
172.It Dv MT_SOOPTS
173data is socket options
174.It Dv MT_FTABLE
175data is the fragment reassembly header
176.It Dv MT_CONTROL
177mbuf contains ancillary \&(protocol control\&) data
178.It Dv MT_OOBDATA
179mbuf contains out-of-band data.
180.El
181.Pp
182The
183.Dv flags
184variable contains information describing the
185.Nm ,
186notably:
187.Bl -tag -compact -offset indent -width "XXXXXXXXXXX"
188.It Dv M_EXT
189has external storage
190.It Dv M_PKTHDR
191is start of record
192.It Dv M_EOR
193is end of record
194.El
195.Pp
196If an
197.Nm
198designates the start of a record
199.Pq Dv M_PKTHDR ,
200its
201.Dv flags
202field may contain additional information describing the content of
203the record:
204.Bl -tag -compact -offset indent -width "XXXXXXXXXXX"
205.It Dv M_BCAST
206sent/received as link-level broadcast
207.It Dv M_MCAST
208sent/received as link-level multicast
209.It Dv M_LINK0 ,
210.It Dv M_LINK1 ,
211.It Dv M_LINK2
212three link-level specific flags.
213.El
214.Pp
215An
216.Nm
217may add a single
218.Sq "mbuf cluster"
219of
220.Dv MCLBYTES
221bytes
222.Pq also defined in Aq Pa machine/param.h ,
223which has no additional overhead
224and is used instead of the internal data area; this is done when at least
225.Dv MINCLSIZE
226bytes of data must be stored.
227.Pp
228When the
229.Dv M_EXT
230flag is raised for an mbuf,
231the external storage area could be shared among multiple mbufs.
232Be careful when you attempt to overwrite the data content of the mbuf.
233.Bl -tag -width compact
234.It Fn m_get "int how" "int type"
235Allocates an mbuf and initializes it to contain internal data.
236The
237.Fa how
238parameter is a choice of
239.Dv M_WAIT / M_DONTWAIT
240from caller.
241.Dv M_WAIT
242means the call cannot fail, but may take forever.
243The
244.Fa type
245parameter is an mbuf type.
246.It Fn m_gethdr "int how" "int type"
247Allocates an mbuf and initializes it to contain a packet header and internal
248data.
249The
250.Fa how
251parameter is a choice of
252.Dv M_WAIT / M_DONTWAIT
253from caller.
254The
255.Fa type
256parameter is an mbuf type.
257.It Fn m_devget "char *buf" "int totlen" "int off0" "struct ifnet *ifp" "void (*copy)(const void *, void *, size_t)"
258Copies
259.Fa len
260bytes from device local memory into mbufs using copy routine
261.Fa copy .
262If parameter
263.Fa off
264is non-zero, the packet is supposed to be trailer-encapsulated and
265.Fa off
266bytes plus the type and length fields will be skipped before copying.
267Returns the top of the mbuf chain it created.
268.It Fn m_copym "struct mbuf *m" "int off" "int len" "int wait"
269Creates a copy of an mbuf chain starting
270.Fa off
271bytes from the beginning, continuing for
272.Fa len
273bytes.
274If the
275.Fa len
276requested is
277.Dv M_COPYALL ,
278the complete mbuf chain will be copied.
279The
280.Fa wait
281parameter is a choice of
282.Dv M_WAIT / M_DONTWAIT
283from caller.
284.It Fn m_copypacket "struct mbuf *m" "int how"
285Copies an entire packet, including header.
286This function is an optimization of the common case
287.Li m_copym ( m , 0 , Dv M_COPYALL , Fa how ) .
288However, contrary to
289.Fn m_copym ,
290a header must be present.
291It is incorrect to use
292.Fn m_copypacket
293with an mbuf that does not have a header.
294.It Fn m_copydata "struct mbuf *m" "int off" "int len" "void *cp"
295Copies
296.Fa len
297bytes data from mbuf chain
298.Fa m
299into the buffer
300.Fa cp ,
301starting
302.Fa off
303bytes from the beginning.
304.It Fn m_copyback "struct mbuf *m0" "int off" "int len" "void *cp"
305Copies
306.Fa len
307bytes data from buffer
308.Fa cp
309back into the mbuf chain
310.Fa m0 ,
311starting
312.Fa off
313bytes from the beginning of the chain, extending the mbuf chain if necessary.
314.Fn m_copyback
315can only fail when extending the chain.
316The caller should check for this kind of failure
317by checking the resulting length of the chain in that case.
318It is an error to use
319.Fn m_copyback
320on read-only mbufs.
321.It Fn m_copyback_cow "struct mbuf *m0" "int off" "int len" "void *cp" \
322"int how"
323Copies
324.Fa len
325bytes data from buffer
326.Fa cp
327back into the mbuf chain
328.Fa m0
329as
330.Fn m_copyback
331does.
332Unlike
333.Fn m_copyback ,
334it is safe to use
335.Fn m_copyback_cow
336on read-only mbufs.
337If needed,
338.Fn m_copyback_cow
339automatically allocates new mbufs and adjusts the chain.
340On success, it returns a pointer to the resulting mbuf chain,
341and frees the original mbuf
342.Fa m0 .
343Otherwise, it returns
344.Dv NULL .
345The
346.Fa how
347parameter is a choice of
348.Dv M_WAIT / M_DONTWAIT
349from the caller.
350Unlike
351.Fn m_copyback ,
352extending the mbuf chain isn't supported.
353It is an error to attempt to extend the mbuf chain using
354.Fn m_copyback_cow .
355.It Fn m_makewritable "struct mbuf **mp" "int off" "int len" "int how"
356Rearranges an mbuf chain so that
357.Fa len
358bytes from offset
359.Fa off
360are writable.
361When it meets read-only mbufs, it allocates new mbufs, adjusts the chain as
362.Fn m_copyback_cow
363does, and copies the original content into them.
364.Fn m_makewritable
365does
366.Em not
367guarantee that all
368.Fa len
369bytes at
370.Fa off
371are consecutive.
372The
373.Fa how
374parameter is a choice of
375.Dv M_WAIT / M_DONTWAIT
376from the caller.
377.Fn m_makewritable
378preserves the contents of the mbuf chain even in the case of failure.
379It updates a pointer to the mbuf chain pointed to by
380.Fa mp .
381It returns 0 on success.
382Otherwise, it returns an error code, typically
383.Er ENOBUFS .
384.It Fn m_cat "struct mbuf *m" "struct mbuf *n"
385Concatenates mbuf chain
386.Fa n
387to
388.Fa m .
389Both chains must be of the same type; packet headers will
390.Em not
391be updated if present.
392.It Fn m_dup "struct mbuf *m" "int off" "int len" "int wait"
393Similarly to
394.Fn m_copym ,
395the function creates a copy of an mbuf chain starting
396.Fa off
397bytes from the beginning, continuing for
398.Fa len
399bytes.
400While
401.Fn m_copym
402tries to share external storage for mbufs with
403.Dv M_EXT
404flag,
405.Fn m_dup
406will deep-copy the whole data content into new mbuf chain
407and avoids shared external storage.
408.It Fn m_pulldown "struct mbuf *m" "int off" "int len" "int *offp"
409Rearranges an mbuf chain so that
410.Fa len
411bytes from offset
412.Fa off
413are contiguous and in the data area of an mbuf.
414The return value points to an mbuf in the middle of the mbuf chain
415.Fa m .
416If we call the return value
417.Fa n ,
418the contiguous data region is available at
419.Li "mtod(n, void *) + *offp" ,
420or
421.Li "mtod(n, void *)"
422if
423.Fa offp
424is
425.Dv NULL .
426The top of the mbuf chain
427.Fa m ,
428and mbufs up to
429.Fa off ,
430will not be modified.
431On successful return, it is guaranteed that the mbuf pointed to by
432.Fa n
433does not have a shared external storage,
434therefore it is safe to update the contiguous region.
435Returns
436.Dv NULL
437and frees the mbuf chain on failure.
438.Fa len
439must be smaller than or equal to
440.Dv MCLBYTES .
441.It Fn m_pullup "struct mbuf *m" "int len"
442Rearranges an mbuf chain so that
443.Fa len
444bytes are contiguous
445and in the data area of an mbuf (so that
446.Fn mtod
447will work for a structure of size
448.Fa len ) .
449Returns the resulting
450mbuf chain on success, frees it and returns
451.Dv NULL
452on failure.
453If there is room, it will add up to
454.Dv max_protohdr
455-
456.Fa len
457extra bytes to the
458contiguous region to possibly avoid being called again.
459.Fa len
460must be smaller or equal than
461.Dv MHLEN .
462.It Fn m_copyup "struct mbuf *m" "int len" "int dstoff"
463Similar to
464.Fn m_pullup
465but copies
466.Fa len
467bytes of data into a new mbuf at
468.Fa dstoff
469bytes into the mbuf.
470The
471.Fa dstoff
472argument aligns the data and leaves room for a link layer header.
473Returns the new
474mbuf chain on success, and frees the mbuf chain and returns
475.Dv NULL
476on failure.
477Note that
478the function does not allocate mbuf clusters, so
479.Fa len + dstoff
480must be less than
481.Dv MHLEN .
482.It Fn m_split "struct mbuf *m0" "int len" "int wait"
483Partitions an mbuf chain in two pieces, returning the tail,
484which is all but the first
485.Fa len
486bytes.
487In case of failure, it returns
488.Dv NULL
489and restores the chain to its original state.
490.It Fn m_adj "struct mbuf *mp" "int req_len"
491Shaves off
492.Fa req_len
493bytes from head or tail of the (valid) data area.
494If
495.Fa req_len
496is greater than zero, front bytes are being shaved off, if it's smaller,
497from the back (and if it is zero, the mbuf will stay bearded).
498This function does not move data in any way, but is used to manipulate the
499data area pointer and data length variable of the mbuf in a non-clobbering
500way.
501.It Fn m_apply "struct mbuf *m" "int off" "int len" "int (*f)(void *, void *, unsigned int)" "void *arg"
502Apply function
503.Fa f
504to the data in an mbuf chain starting
505.Fa off
506bytes from the beginning, continuing for
507.Fa len
508bytes.
509Neither
510.Fa off
511nor
512.Fa len
513may be negative.
514.Fa arg
515will be supplied as first argument for
516.Fa f ,
517the second argument will be the pointer to the data buffer of a
518packet (starting after
519.Fa off
520bytes in the stream), and the third argument is the amount
521of data in bytes in this call.
522If
523.Fa f
524returns something not equal to zero
525.Fn m_apply
526will bail out, returning the return code of
527.Fa f .
528Upon successful completion it will return zero.
529.It Fn m_free "struct mbuf *m"
530Frees mbuf
531.Fa m .
532.It Fn m_freem "struct mbuf *m"
533Frees the mbuf chain beginning with
534.Fa m .
535This function contains the elementary sanity check for a
536.Dv NULL
537pointer.
538.It Fn mtod "struct mbuf *m" "datatype"
539Returns a pointer to the data contained in the specified mbuf
540.Fa m ,
541type-casted to the specified data type
542.Fa datatype .
543Implemented as a macro.
544.It Fn MGET "struct mbuf *m" "int how" "int type"
545Allocates mbuf
546.Fa m
547and initializes it to contain internal data.
548See
549.Fn m_get .
550Implemented as a macro.
551.It Fn MGETHDR "struct mbuf *m" "int how" "int type"
552Allocates mbuf
553.Fa m
554and initializes it to contain a packet header.
555See
556.Fn m_gethdr .
557Implemented as a macro.
558.It Fn MEXTMALLOC "struct mbuf *m" "int len" "int how"
559Allocates external storage of size
560.Fa len
561for mbuf
562.Fa m .
563The
564.Fa how
565parameter is a choice of
566.Dv M_WAIT / M_DONTWAIT
567from caller.
568The flag
569.Dv M_EXT
570is set upon success.
571Implemented as a macro.
572.It Fn MEXTADD "struct mbuf *m" "void *buf" "int size" "int type" "void (*free)(struct mbuf *, void *, size_t, void *)" "void *arg"
573Adds pre-allocated external storage
574.Fa buf
575to a normal mbuf
576.Fa m ;
577the parameters
578.Fa size ,
579.Fa type ,
580.Fa free
581and
582.Fa arg
583describe the external storage.
584.Fa size
585is the size of the storage,
586.Fa type
587describes its
588.Xr malloc 9
589type,
590.Fa free
591is a free routine (if not the usual one), and
592.Fa arg
593is a possible argument to the free routine.
594The flag
595.Dv M_EXT
596is set upon success.
597Implemented as a macro.
598If a free routine is specified, it will be called when the mbuf is freed.
599In the case of former, the first argument for a free routine is the mbuf
600.Fa m
601and the routine is expected to free it in addition to the external storage
602pointed by second argument.
603In the case of latter, the first argument for the routine is NULL.
604.It Fn MCLGET "struct mbuf *m" "int how"
605Allocates and adds an mbuf cluster to a normal mbuf
606.Fa m .
607The
608.Fa how
609parameter is a choice of
610.Dv M_WAIT / M_DONTWAIT
611from caller.
612The flag
613.Dv M_EXT
614is set upon success.
615Implemented as a macro.
616.It Fn M_COPY_PKTHDR "struct mbuf *to" "struct mbuf *from"
617Copies the mbuf pkthdr from mbuf
618.Fa from
619to mbuf
620.Fa to .
621.Fa from
622must have the type flag
623.Dv M_PKTHDR
624set, and
625.Fa to
626must be empty.
627Implemented as a macro.
628.It Fn M_MOVE_PKTHDR "struct mbuf *to" "struct mbuf *from"
629Moves the mbuf pkthdr from mbuf
630.Fa from
631to mbuf
632.Fa to .
633.Fa from
634must have the type flag
635.Dv M_PKTHDR
636set, and
637.Fa to
638must be empty.
639The flag
640.Dv M_PKTHDR
641in mbuf
642.Fa from
643will be cleared.
644.It Fn M_ALIGN "struct mbuf *m" "int len"
645Sets the data pointer of a newly allocated mbuf
646.Fa m
647to
648.Fa len
649bytes from the end of the mbuf data area, so that
650.Fa len
651bytes of data written to the mbuf
652.Fa m ,
653starting at the data pointer, will be aligned to the end of the data area.
654Implemented as a macro.
655.It Fn MH_ALIGN "struct mbuf *m" "int len"
656Sets the data pointer of a newly allocated packetheader mbuf
657.Fa m
658to
659.Fa len
660bytes from the end of the mbuf data area, so that
661.Fa len
662bytes of data written to the mbuf
663.Fa m ,
664starting at the data pointer, will be aligned to the end of the data area.
665Implemented as a macro.
666.It Fn M_LEADINGSPACE "struct mbuf *m"
667Returns the amount of space available before the current start of valid
668data in mbuf
669.Fa m .
670Returns 0 if the mbuf data part is shared across multiple mbufs
671.Pq i.e. not writable .
672Implemented as a macro.
673.It Fn M_TRAILINGSPACE "struct mbuf *m"
674Returns the amount of space available after the current end of valid
675data in mbuf
676.Fa m .
677Returns 0 if the mbuf data part is shared across multiple mbufs
678.Pq i.e. not writable .
679Implemented as a macro.
680.It Fn M_PREPEND "struct mbuf *m" "int plen" "int how"
681Prepends space of size
682.Fa plen
683to mbuf
684.Fa m .
685If a new mbuf must be allocated,
686.Fa how
687specifies whether to wait.
688If
689.Fa how
690is
691.Dv M_DONTWAIT
692and allocation fails, the original mbuf chain is freed and
693.Fa m
694is set to
695.Dv NULL .
696It is illegal for the
697.Fa plen
698parameter to be greater than
699.Dv MHLEN .
700Implemented as a macro.
701.It Fn MCHTYPE "struct mbuf *m" "int type"
702Change mbuf
703.Fa m
704to new type
705.Fa type .
706Implemented as a macro.
707.El
708.Sh CODE REFERENCES
709The
710.Nm
711management functions are implemented within the file
712.Pa sys/kern/uipc_mbuf.c .
713Function prototypes, and the functions implemented as macros
714are located in
715.Pa sys/sys/mbuf.h .
716.Sh SEE ALSO
717.Pa /usr/share/doc/smm/18.net ,
718.Xr netstat 1 ,
719.Xr m_tag 9 ,
720.Xr malloc 9
721.Rs
722.%A Jun-ichiro Hagino
723.%T "Mbuf issues in 4.4BSD IPv6/IPsec support (experiences from KAME IPv6/IPsec implementation)"
724.%B "Proceedings of the freenix track: 2000 USENIX annual technical conference"
725.%D June 2000
726.Re
727.Sh AUTHORS
728.An -nosplit
729The original mbuf data structures were designed by Rob Gurwitz
730when he did the initial TCP/IP implementation at BBN.
731.Pp
732Further extensions and enhancements were made by Bill Joy, Sam Leffler,
733and Mike Karels at CSRG.
734.Pp
735Current implementation of external storage by
736.An Matt Thomas
737.Aq matt@3am-software.com
738and
739.An Jason R. Thorpe
740.Aq thorpej@NetBSD.org .
741