An mbuf currently has a header structure that defines the type of the mbuf and where data is stored.
TYPE mh_hdrT = RECORD mh_next : T; mh_nextpkt : T; mh_data : Word.T; (* ADDRESS; *) mh_len : Ctypes.long; mh_type : Ctypes.int; mh_flags : Ctypes.int; mh_union : ARRAY [0..3] OF ARRAY [1..BYTESIZE(Ctypes.long)] OF CHAR; END; TYPE MbufT = RECORD mh_hdr : mh_hdrT; M_dat : ARRAY [1..MLEN] OF CHAR; END; TYPE T = UNTRACED REF MbufT;Mbufs can be linked together using the
mh_next and
mh_nextpkt members. The mh_data members
points to the data in the mbuf and the mh_len member
specifies its length. It is possible for the data pointer to point
internally at the MbufT.M_dat array, or it can point to
external data. The mh_type member specifies the type of
data contained in the mbuf. In SPIN this typically is either
Mbuf.MT_DATA or Mbuf.MT_HEADER. The
mh_flags member defines how the mbuf should be treated
when it is freed. The last member mh_union is
unused.
At the moment clients should only access the data contained by the
mbuf using the Mbuf.Array function.
PROCEDURE m_copydata(
mbuf : T;
off : CARDINAL;
len : CARDINAL;
cp : T);
off bytes from
the beginning, continuing for len bytes, into the
indicated buffer.
PROCEDURE m_copym(
mbuf : T;
off : CARDINAL;
len : CARDINAL;
wait : HowT):T;
off bytes from
the beginning, continuing for len bytes. If len is
M_COPYALL, copy to end of mbuf. The wait parameter is a
choice of M_WAIT/M_DONTWAIT from caller.
PROCEDURE m_free(mbuf : T):T;
PROCEDURE m_freem(mbuf : T);
m_free for each
mbuf in the chain.
PROCEDURE m_get(
canwait : HowT;
type : Ctypes.int):T;
PROCEDURE m_getclr(
canwait : HowT;
type : Ctypes.int):T;
PROCEDURE m_gethdr(
canwait : HowT;
type : Ctypes.int):T;
PROCEDURE m_length(mbuf : T):CARDINAL;
PROCEDURE m_prepend(
mbuf : T;
len : CARDINAL;
how : HowT):T;
M_PREPEND. Allocate new mbuf
to prepend to chain, copy junk along.
PROCEDURE m_pullup(
mbuf : T;
len : CARDINAL):T;
max_protohdr-len extra bytes to the
contiguous region in an attempt to avoid being called next time.
PROCEDURE M_PREPEND(
mbuf : T;
plen : CARDINAL;
how : HowT):T;
M_DONTWAIT and allocation fails, the original mbuf chain
is freed and m is set to NULL.
PROCEDURE M_ALIGN(
mbuf : T;
len : CARDINAL);
m_data member of a newly-allocated mbuf
(m_get) to place an object of the specified size at
the aligned end of the mbuf.
PROCEDURE MH_ALIGN(
mbuf : T;
len : CARDINAL);
m_gethdr or
initialized by M_COPY_PKTHDR.
MclGetOa procedure, which will
allocate an mbuf that wraps up the user supplied buffer. This feature
enables applications to send data without requiring additional copies.
The user can provide a method suite that act on the mbuf. For
example,
VAR m: Mbuf.T;
data : REF ARRAY OF CHAR;
BEGIN
data := NEW(REF ARRAY OF CHAR, 8000);
m := Mbuf.MclGetOa(data, 8000, methods, NIL);
END;
The MclGetOa procedure takes the newly allocated array as
its first argument. It is possible to specify separatedly the lenght
of the buffer that the mbuf to be less than or equal to the size of
the actual array. As the third argument the user can provide some
methods that the networking code should uses instead of the default
implementations. The current methods supported are free and checksum.
TYPE freeprocT = (* EPHEMERAL *) PROCEDURE (
ext_buf : REF ARRAY OF CHAR;
ext_size : CARDINAL;
ext_arg : REFANY);
TYPE csumprocT = (* EPHEMERAL *) PROCEDURE (
ext_buf : REF ARRAY OF CHAR;
ext_size : CARDINAL;
ext_arg : REFANY;
offset : CARDINAL;
csum : Ctypes.unsigned_short): Ctypes.unsigned_short;
TYPE Methods = REF RECORD
free: freeprocT;
csum: csumprocT;
END;
Finally, an additional optional argument can be stored with the mbuf
that is passed back up to the methods.