1 /* 2 * Copyright (c) 2000, 2001 Boris Popov 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Boris Popov. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $FreeBSD: src/sys/sys/mchain.h,v 1.1 2001/02/24 15:44:30 bp Exp $ 33 */ 34 35 /* 36 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 37 * Use is subject to license terms. 38 * 39 * Copyright 2018 Nexenta Systems, Inc. All rights reserved. 40 */ 41 42 #ifndef _MCHAIN_H_ 43 #define _MCHAIN_H_ 44 45 #include <sys/types.h> 46 #include <sys/isa_defs.h> 47 #include <sys/byteorder.h> 48 49 #ifdef _LITTLE_ENDIAN 50 51 /* little-endian values on little-endian */ 52 #define htoles(x) ((uint16_t)(x)) 53 #define letohs(x) ((uint16_t)(x)) 54 #define htolel(x) ((uint32_t)(x)) 55 #define letohl(x) ((uint32_t)(x)) 56 #define htoleq(x) ((uint64_t)(x)) 57 #define letohq(x) ((uint64_t)(x)) 58 59 /* 60 * big-endian values on little-endian (swap) 61 * 62 * Use the BSWAP macros because they're fastest, and they're 63 * available in all environments where we use this header. 64 */ 65 #define htobes(x) BSWAP_16(x) 66 #define betohs(x) BSWAP_16(x) 67 #define htobel(x) BSWAP_32(x) 68 #define betohl(x) BSWAP_32(x) 69 #define htobeq(x) BSWAP_64(x) 70 #define betohq(x) BSWAP_64(x) 71 72 #else /* (BYTE_ORDER == LITTLE_ENDIAN) */ 73 74 /* little-endian values on big-endian (swap) */ 75 #define letohs(x) BSWAP_16(x) 76 #define htoles(x) BSWAP_16(x) 77 #define letohl(x) BSWAP_32(x) 78 #define htolel(x) BSWAP_32(x) 79 #define letohq(x) BSWAP_64(x) 80 #define htoleq(x) BSWAP_64(x) 81 82 /* big-endian values on big-endian */ 83 #define htobes(x) ((uint16_t)(x)) 84 #define betohs(x) ((uint16_t)(x)) 85 #define htobel(x) ((uint32_t)(x)) 86 #define betohl(x) ((uint32_t)(x)) 87 #define htobeq(x) ((uint64_t)(x)) 88 #define betohq(x) ((uint64_t)(x)) 89 #endif /* (BYTE_ORDER == LITTLE_ENDIAN) */ 90 91 92 /* 93 * Additions for Solaris to replace things that came from 94 * <sys/mbuf.h> in the Darwin code. These are mostly just 95 * wrappers for streams functions. See: subr_mchain.c 96 */ 97 98 #if defined(_KERNEL) || defined(_FAKE_KERNEL) 99 100 /* 101 * BSD-style mbuf "shim" for kernel code. Note, this 102 * does NOT implement BSD mbufs in the kernel. Rather, 103 * macros and wrapper functions are used so that code 104 * fomerly using mbuf_t now use STREAMS mblk_t instead. 105 */ 106 107 #include <sys/stream.h> /* mblk_t */ 108 #include <sys/strsun.h> /* MBLKL */ 109 typedef mblk_t mbuf_t; 110 111 /* BEGIN CSTYLED */ 112 /* 113 * BSD-style mbufs, vs SysV-style mblks: 114 * One big difference: the mbuf payload is: 115 * m_data ... (m_data + m_len) 116 * In Unix STREAMS, the mblk payload is: 117 * b_rptr ... b_wptr 118 * 119 * Here are some handy conversion notes: 120 * 121 * struct mbuf struct mblk 122 * m->m_next m->b_cont 123 * m->m_nextpkt m->b_next 124 * m->m_data m->b_rptr 125 * m->m_len MBLKL(m) 126 * m->m_dat[] m->b_datap->db_base 127 * &m->m_dat[MLEN] m->b_datap->db_lim 128 * M_TRAILINGSPACE(m) MBLKTAIL(m) 129 * m_freem(m) freemsg(m) 130 * 131 * Note that mbufs chains also have a special "packet" header, 132 * which has the length of the whole message. In STREAMS one 133 * typically just calls msgdsize(m) to get that. 134 */ 135 /* END CSTYLED */ 136 137 #define mtod(m, t) ((t)((m)->b_rptr)) 138 139 /* length arg for m_copym to "copy all" */ 140 #define M_COPYALL -1 141 142 mblk_t *m_copym(mblk_t *, int, int, int); 143 mblk_t *m_pullup(mblk_t *, int); 144 mblk_t *m_split(mblk_t *, int, int); 145 void m_cat(mblk_t *, mblk_t *); 146 #define m_freem(x) freemsg(x) 147 mblk_t *m_getblk(int, int); 148 int m_fixhdr(mblk_t *m); 149 150 #else /* _KERNEL */ 151 152 /* 153 * BSD-style mbuf work-alike, for user-level. 154 * See libsmbfs mbuf.c 155 */ 156 typedef struct mbuf { 157 int m_len; 158 int m_maxlen; 159 char *m_data; 160 struct mbuf *m_next; 161 } mbuf_t; 162 163 #define mtod(m, t) ((t)(m)->m_data) 164 165 int m_get(int, mbuf_t **); 166 void m_freem(mbuf_t *); 167 168 #endif /* _KERNEL */ 169 170 /* 171 * BSD-style mbchain/mdchain work-alike 172 */ 173 174 /* 175 * Type of copy for mb_{put|get}_mem() 176 */ 177 #define MB_MSYSTEM 0 /* use bcopy() */ 178 #define MB_MUSER 1 /* use copyin()/copyout() */ 179 #define MB_MINLINE 2 /* use an inline copy loop */ 180 #define MB_MZERO 3 /* bzero(), mb_put_mem only */ 181 #define MB_MCUSTOM 4 /* use an user defined function */ 182 183 #if defined(_KERNEL) || defined(_FAKE_KERNEL) 184 185 struct mbchain { 186 mblk_t *mb_top; 187 mblk_t *mb_cur; 188 uint_t mb_count; 189 }; 190 typedef struct mbchain mbchain_t; 191 192 struct mdchain { 193 mblk_t *md_top; /* head of mblk chain */ 194 mblk_t *md_cur; /* current mblk */ 195 uchar_t *md_pos; /* position in md_cur */ 196 /* NB: md_pos is same type as mblk_t b_rptr, b_wptr members. */ 197 }; 198 typedef struct mdchain mdchain_t; 199 200 mblk_t *mb_detach(mbchain_t *mbp); 201 int mb_fixhdr(mbchain_t *mbp); 202 int mb_put_uio(mbchain_t *mbp, uio_t *uiop, size_t size); 203 204 void md_append_record(mdchain_t *mdp, mblk_t *top); 205 void md_next_record(mdchain_t *mdp); 206 int md_get_uio(mdchain_t *mdp, uio_t *uiop, size_t size); 207 208 #else /* _KERNEL */ 209 210 /* 211 * user-level code uses the same struct for both (MB, MD) 212 */ 213 typedef struct mbdata { 214 mbuf_t *mb_top; /* head of mbuf chain */ 215 mbuf_t *mb_cur; /* current mbuf */ 216 char *mb_pos; /* position in mb_cur (get) */ 217 /* NB: mb_pos is same type as mbuf_t m_data member. */ 218 int mb_count; /* bytes marshalled (put) */ 219 } mbdata_t; 220 typedef struct mbdata mbchain_t; 221 typedef struct mbdata mdchain_t; 222 223 #endif /* _KERNEL */ 224 225 int mb_init(mbchain_t *); 226 void mb_initm(mbchain_t *, mbuf_t *); 227 void mb_done(mbchain_t *); 228 void *mb_reserve(mbchain_t *, int size); 229 230 int mb_put_align8(mbchain_t *mbp); 231 int mb_put_padbyte(mbchain_t *mbp); 232 int mb_put_uint8(mbchain_t *, uint8_t); 233 int mb_put_uint16be(mbchain_t *, uint16_t); 234 int mb_put_uint16le(mbchain_t *, uint16_t); 235 int mb_put_uint32be(mbchain_t *, uint32_t); 236 int mb_put_uint32le(mbchain_t *, uint32_t); 237 int mb_put_uint64be(mbchain_t *, uint64_t); 238 int mb_put_uint64le(mbchain_t *, uint64_t); 239 int mb_put_mem(mbchain_t *, const void *, int, int); 240 int mb_put_mbuf(mbchain_t *, mbuf_t *); 241 int mb_put_mbchain(mbchain_t *, mbchain_t *); 242 243 int md_init(mdchain_t *mdp); 244 void md_initm(mdchain_t *mbp, mbuf_t *m); 245 void md_done(mdchain_t *mdp); 246 247 int md_get_uint8(mdchain_t *, uint8_t *); 248 int md_get_uint16be(mdchain_t *, uint16_t *); 249 int md_get_uint16le(mdchain_t *, uint16_t *); 250 int md_get_uint32be(mdchain_t *, uint32_t *); 251 int md_get_uint32le(mdchain_t *, uint32_t *); 252 int md_get_uint64be(mdchain_t *, uint64_t *); 253 int md_get_uint64le(mdchain_t *, uint64_t *); 254 int md_get_mem(mdchain_t *, void *, int, int); 255 int md_get_mbuf(mdchain_t *, int, mbuf_t **); 256 int md_seek(mdchain_t *, uint32_t); 257 uint32_t md_tell(mdchain_t *); 258 259 #endif /* !_MCHAIN_H_ */ 260