MBCHAIN(9)

๐Ÿ’– mbchain(9) โ€” the Kernel Developer's Manual, but make it cute ๐Ÿ’–

okay bestie, welcome to mbchain(9), section 9 of the Kernel Developer's Manual, where we build mbuf chains out of literally every data type you can think of. it's giving arts-and-crafts but for network packets. ๐Ÿงšโœจ


๐ŸŒธ NAME ๐ŸŒธ

mbchain, mb_init, mb_initm, mb_done, mb_detach, mb_fixhdr, mb_reserve, mb_put_uint8, mb_put_uint16be, mb_put_uint16le, mb_put_uint32be, mb_put_uint32le, mb_put_int64be, mb_put_int64le, mb_put_mem, mb_put_mbuf, mb_put_uio โ€” a whole squad of functions whose entire job is building an mbuf chain from various data types ๐Ÿซถ


โœจ SYNOPSIS โœจ

first, the setup. you either compile it in or you load it, no biggie:

options LIBMCHAIN
kldload libmchain

then the includes, the whole trio, don't skip any:

#include <sys/param.h>
#include <sys/uio.h>
#include <sys/mchain.h>

and now the roster ๐Ÿ’…:

int
mb_init(struct mbchain *mbp);

void
mb_initm(struct mbchain *mbp, struct mbuf *m);

void
mb_done(struct mbchain *mbp);

struct mbuf *
mb_detach(struct mbchain *mbp);

int
mb_fixhdr(struct mbchain *mbp);

caddr_t
mb_reserve(struct mbchain *mbp, int size);

int
mb_put_uint8(struct mbchain *mbp, uint8_t x);

int
mb_put_uint16be(struct mbchain *mbp, uint16_t x);

int
mb_put_uint16le(struct mbchain *mbp, uint16_t x);

int
mb_put_uint32be(struct mbchain *mbp, uint32_t x);

int
mb_put_uint32le(struct mbchain *mbp, uint32_t x);

int
mb_put_int64be(struct mbchain *mbp, int64_t x);

int
mb_put_int64le(struct mbchain *mbp, int64_t x);

int
mb_put_mem(struct mbchain *mbp, c_caddr_t source, int size, int type);

int
mb_put_mbuf(struct mbchain *mbp, struct mbuf *m);

int
mb_put_uio(struct mbchain *mbp, struct uio *uiop, int size);

๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

so these functions compose mbuf chains out of various data types. that's the whole vibe. ๐ŸŽ€

the mbchain structure is your working context โ€” your lil workspace โ€” and you have to initialize it with a call to either mb_init() or mb_initm(). it has these fields:

  • mb_top (struct mbuf *) โ€” a pointer to the top of the constructed mbuf chain. the head of the operation, the main character ๐Ÿ‘‘
  • mb_cur (struct mbuf *) โ€” a pointer to the currently filled mbuf. the one we're actively working on rn
  • mb_mleft (int) โ€” number of bytes left in the current mbuf
  • mb_count (int) โ€” total number of bytes placed in the mbuf chain
  • mb_copy (mb_copy_t *) โ€” a user-defined function to perform a copy into mbuf; super useful if any unusual data conversion is necessary
  • mb_udata (void *) โ€” user-supplied data which can be used in the mb_copy function

okay now the functions, one by one, no skipping ๐Ÿ’–

mb_done() disposes of an mbuf chain pointed to by the mbp->mb_top field and sets the field to NULL. clean up your mess, queen.

mb_detach() returns the value of the mbp->mb_top field and sets its value to NULL. it's like handing you the chain and walking away. no strings attached.

mb_fixhdr() recalculates the length of an mbuf chain and updates the m_pkthdr.len field of the first mbuf in the chain. it returns the calculated length. math girlies rise ๐Ÿงฎโœจ

mb_reserve() makes sure that the object of the length specified by the size argument will fit in the current mbuf (mbuf allocation is performed if necessary), and advances all pointers as if the real data was placed. the returned value will point to the beginning of the reserved space.

โš ๏ธ note that the size of the object should not exceed MLEN bytes. don't be greedy bestie.

all the mb_put_*() functions perform an actual copy of the data into the mbuf chain. functions with the le or be suffixes will perform conversion to the little- or big-endian data formats. endianness said periodt. ๐Ÿ’…

mb_put_mem() copies size bytes of data specified by the source argument to an mbuf chain. the type argument specifies the method used to perform the copy, and can be one of these:

  • MB_MSYSTEM โ€” use bcopy() function.
  • MB_MUSER โ€” use copyin(9) function.
  • MB_MINLINE โ€” use an โ€œinlineโ€ loop which does not call any function.
  • MB_MZERO โ€” do not copy any data, but just fill the destination with zero bytes. zero thoughts, head empty ๐Ÿ“
  • MB_MCUSTOM โ€” call function specified by the mbp->mb_copy field.

๐Ÿ˜ญ RETURN VALUES ๐Ÿ˜ญ

all int functions except mb_fixhdr() return zero if successful and an error code otherwise.

๐Ÿ’€ note: after failure of any function, an mbuf chain is left in the broken state, and only mb_done() function can safely be called to destroy it. like. only that one. do not try anything else. it's giving fragile.

๐ŸŒˆ EXAMPLES ๐ŸŒˆ

here's the lil glow-up in action:

struct mbchain *mbp;
struct mbuf *m;

mb_init(mbp);
mb_put_uint8(mbp, 33);
mb_put_uint16le(mbp, length);
m = m_copym(mbp->mb_top, 0, M_COPYALL, M_WAIT);
send(m);
mb_done(mbp);

see how clean that is? init, put, copy, send, done. ate and left no crumbs ๐Ÿ”ฅ


๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

mbuf(9), mdchain(9) โ€” go read those too, they're the friends of the family iykyk


๐Ÿซถ AUTHORS ๐Ÿซถ

this manual page was written by Boris Popov <bp@FreeBSD.org>. legend behavior, honestly. thank you for your service ๐Ÿ’œ


and that's a wrap bestie!! this page came to you from Debian, dated February 20, 2001, and it's MBCHAIN(9) all day long. go build some mbuf chains, you've got this. mwah ๐Ÿ’‹โœจ

๐Ÿ“ฆ where this page comes from