1706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*-
2706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org>
3706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *          based on work by Toshiharu OHNO <tony-o@iij.ad.jp>
4706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *                           Internet Initiative Japan, Inc (IIJ)
5706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * All rights reserved.
6706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
7706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Redistribution and use in source and binary forms, with or without
8706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * modification, are permitted provided that the following conditions
9706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * are met:
10706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 1. Redistributions of source code must retain the above copyright
11706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    notice, this list of conditions and the following disclaimer.
12706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 2. Redistributions in binary form must reproduce the above copyright
13706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    notice, this list of conditions and the following disclaimer in the
14706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *    documentation and/or other materials provided with the distribution.
15706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
16706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * SUCH DAMAGE.
27706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *
28706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * $FreeBSD: src/usr.sbin/ppp/mbuf.c,v 1.46.26.1 2010/12/21 17:10:29 kensmith Exp $
29706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */
30706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
31706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/types.h>
32706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
33706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdarg.h>
34706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdio.h>
35706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdlib.h>
36706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <string.h>
37706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sysexits.h>
38706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <termios.h>
39706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
40706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "defs.h"
41706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "command.h"
42706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mbuf.h"
43706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "log.h"
44706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "descriptor.h"
45706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "prompt.h"
46706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "main.h"
47706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
48706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define BUCKET_CHUNK	20
49706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define BUCKET_HASH	256
50706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
51706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mbucket;
52706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
53706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mfree {
54706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mbucket *next;
55706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  size_t count;
56706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh};
57706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
58706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic struct mbucket {
59706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  union {
60706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    struct mbuf m;
61706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    struct mfree f;
62706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } u;
63706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} *bucket[(M_MAXLEN + sizeof(struct mbuf)) / BUCKET_HASH];
64706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
65706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define M_BINDEX(sz)	(((sz) + sizeof(struct mbuf) - 1) / BUCKET_HASH)
66706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define M_BUCKET(sz)	(bucket + M_BINDEX(sz))
67706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define M_ROUNDUP(sz)	((M_BINDEX(sz) + 1) * BUCKET_HASH)
68706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
69706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic struct memmap {
70706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mbuf *queue;
71706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  size_t fragments;
72706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  size_t octets;
73706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} MemMap[MB_MAX + 1];
74706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
75706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic unsigned long long mbuf_Mallocs, mbuf_Frees;
76706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
77706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehsize_t
78706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehm_length(struct mbuf *bp)
79706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
80706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  size_t len;
81706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
82706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  for (len = 0; bp; bp = bp->m_next)
83706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    len += bp->m_len;
84706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return len;
85706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
86706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
87706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic const char *
88706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmbuftype(int type)
89706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
90706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  static const char * const mbufdesc[MB_MAX] = {
91706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "ip in", "ip out", "ipv6 in", "ipv6 out", "nat in", "nat out",
92706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "mp in", "mp out", "vj in", "vj out", "icompd in", "icompd out",
93706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "compd in", "compd out", "lqr in", "lqr out", "echo in", "echo out",
94706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "proto in", "proto out", "acf in", "acf out", "sync in", "sync out",
95706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "hdlc in", "hdlc out", "async in", "async out", "cbcp in", "cbcp out",
96706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "chap in", "chap out", "pap in", "pap out", "ccp in", "ccp out",
97706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    "ipcp in", "ipcp out", "ipv6cp in", "ipv6cp out", "lcp in", "lcp out"
98706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  };
99706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
100706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return type < 0 || type >= MB_MAX ? "unknown" : mbufdesc[type];
101706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
102706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
103706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mbuf *
104706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehm_get(size_t m_len, int type)
105706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
106706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mbucket **mb;
107706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mbuf *bp;
108706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  size_t size;
109706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
110706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (type > MB_MAX) {
111706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "Bad mbuf type %d\n", type);
112706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    type = MB_UNKNOWN;
113706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
114706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
115706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (m_len > M_MAXLEN || m_len == 0) {
116706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogERROR, "Request for mbuf size %lu (\"%s\") denied !\n",
117706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh               (u_long)m_len, mbuftype(type));
118706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    AbortProgram(EX_OSERR);
119706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
120706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
121706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  mb = M_BUCKET(m_len);
122706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  size = M_ROUNDUP(m_len);
123706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
124706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (*mb) {
125706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /* We've got some free blocks of the right size */
126706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bp = &(*mb)->u.m;
127706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (--(*mb)->u.f.count == 0)
128706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      *mb = (*mb)->u.f.next;
129706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    else {
130706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      ((struct mbucket *)((char *)*mb + size))->u.f.count = (*mb)->u.f.count;
131706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      *mb = (struct mbucket *)((char *)*mb + size);
132706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      (*mb)->u.f.next = NULL;
133706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
134706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else {
135706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    /*
136706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     * Allocate another chunk of mbufs, use the first and put the rest on
137706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     * the free list
138706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh     */
139706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *mb = (struct mbucket *)malloc(BUCKET_CHUNK * size);
140706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (*mb == NULL) {
141706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      log_Printf(LogALERT, "Failed to allocate memory (%lu)\n",
142706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                 (unsigned long)BUCKET_CHUNK * size);
143706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      AbortProgram(EX_OSERR);
144706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
145706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bp = &(*mb)->u.m;
146706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *mb = (struct mbucket *)((char *)*mb + size);
147706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    (*mb)->u.f.count = BUCKET_CHUNK - 1;
148706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    (*mb)->u.f.next = NULL;
149706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
150706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
151706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  mbuf_Mallocs++;
152706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
153706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  memset(bp, '\0', sizeof(struct mbuf));
154706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  bp->m_size = size - sizeof *bp;
155706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  bp->m_len = m_len;
156706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  bp->m_type = type;
157706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
158706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  MemMap[type].fragments++;
159706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  MemMap[type].octets += bp->m_size;
160706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
161706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return bp;
162706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
163706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
164706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mbuf *
165706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehm_free(struct mbuf *bp)
166706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
167706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mbucket **mb, *f;
168706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mbuf *nbp;
169706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
170706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if ((f = (struct mbucket *)bp) != NULL) {
171706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    MemMap[bp->m_type].fragments--;
172706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    MemMap[bp->m_type].octets -= bp->m_size;
173706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
174706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    nbp = bp->m_next;
175706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    mb = M_BUCKET(bp->m_size);
176706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    f->u.f.next = *mb;
177706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    f->u.f.count = 1;
178706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    *mb = f;
179706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
180706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    mbuf_Frees++;
181706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bp = nbp;
182706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
183706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
184706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return bp;
185706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
186706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
187706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
188706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehm_freem(struct mbuf *bp)
189706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
190706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  while (bp)
191706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bp = m_free(bp);
192706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
193706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
194706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mbuf *
195706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmbuf_Read(struct mbuf *bp, void *v, size_t len)
196706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
197706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int nb;
198706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char *ptr = v;
199706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
200706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  while (bp && len > 0) {
201706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (len > bp->m_len)
202706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      nb = bp->m_len;
203706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    else
204706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      nb = len;
205706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (nb) {
206706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      memcpy(ptr, MBUF_CTOP(bp), nb);
207706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      ptr += nb;
208706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      bp->m_len -= nb;
209706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      len -= nb;
210706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      bp->m_offset += nb;
211706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
212706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (bp->m_len == 0)
213706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      bp = m_free(bp);
214706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
215706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
216706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  while (bp && bp->m_len == 0)
217706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bp = m_free(bp);
218706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
219706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return bp;
220706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
221706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
222706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehsize_t
223706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmbuf_View(struct mbuf *bp, void *v, size_t len)
224706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
225706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  size_t nb, l = len;
226706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  u_char *ptr = v;
227706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
228706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  while (bp && l > 0) {
229706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (l > bp->m_len)
230706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      nb = bp->m_len;
231706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    else
232706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      nb = l;
233706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    memcpy(ptr, MBUF_CTOP(bp), nb);
234706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    ptr += nb;
235706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    l -= nb;
236706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bp = bp->m_next;
237706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
238706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
239706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return len - l;
240706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
241706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
242706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mbuf *
243706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehm_prepend(struct mbuf *bp, const void *ptr, size_t len, u_short extra)
244706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
245706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mbuf *head;
246706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
247706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (bp && bp->m_offset) {
248706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (bp->m_offset >= len) {
249706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      bp->m_offset -= len;
250706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      bp->m_len += len;
251706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (ptr)
252706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        memcpy(MBUF_CTOP(bp), ptr, len);
253706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return bp;
254706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
255706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    len -= bp->m_offset;
256706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (ptr)
257706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      memcpy(bp + 1, (const char *)ptr + len, bp->m_offset);
258706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bp->m_len += bp->m_offset;
259706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bp->m_offset = 0;
260706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
261706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
262706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  head = m_get(len + extra, bp ? bp->m_type : MB_UNKNOWN);
263706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  head->m_offset = extra;
264706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  head->m_len -= extra;
265706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (ptr)
266706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    memcpy(MBUF_CTOP(head), ptr, len);
267706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  head->m_next = bp;
268706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
269706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return head;
270706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
271706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
272706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mbuf *
273706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehm_adj(struct mbuf *bp, ssize_t n)
274706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
275706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (n > 0) {
276706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    while (bp) {
277706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if ((size_t)n < bp->m_len) {
278706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        bp->m_len = n;
279706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        bp->m_offset += n;
280706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        return bp;
281706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
282706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      n -= bp->m_len;
283706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      bp = m_free(bp);
284706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
285706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else {
286706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if ((n = m_length(bp) + n) <= 0) {
287706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      m_freem(bp);
288706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      return NULL;
289706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
290706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    for (; bp; bp = bp->m_next, n -= bp->m_len)
291706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if ((size_t)n < bp->m_len) {
292706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        bp->m_len = n;
293706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        m_freem(bp->m_next);
294706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        bp->m_next = NULL;
295706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        break;
296706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
297706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
298706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
299706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return bp;
300706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
301706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
302706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
303706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmbuf_Write(struct mbuf *bp, const void *ptr, size_t m_len)
304706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
305706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  size_t plen;
306706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int nb;
307706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
308706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  plen = m_length(bp);
309706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (plen < m_len)
310706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    m_len = plen;
311706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
312706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  while (m_len > 0) {
313706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    nb = (m_len < bp->m_len) ? m_len : bp->m_len;
314706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    memcpy(MBUF_CTOP(bp), ptr, nb);
315706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    m_len -= bp->m_len;
316706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bp = bp->m_next;
317706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
318706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
319706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
320706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint
321706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmbuf_Show(struct cmdargs const *arg)
322706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
323706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  int i;
324706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
325706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "Fragments (octets) in use:\n");
326706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  for (i = 0; i < MB_MAX; i += 2)
327706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(arg->prompt, "%10.10s: %04lu (%06lu)\t"
328706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  "%10.10s: %04lu (%06lu)\n",
329706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	          mbuftype(i), (u_long)MemMap[i].fragments,
330706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  (u_long)MemMap[i].octets, mbuftype(i+1),
331706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  (u_long)MemMap[i+1].fragments, (u_long)MemMap[i+1].octets);
332706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
333706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (i == MB_MAX)
334706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    prompt_Printf(arg->prompt, "%10.10s: %04lu (%06lu)\n",
335706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  mbuftype(i), (u_long)MemMap[i].fragments,
336706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                  (u_long)MemMap[i].octets);
337706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
338706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  prompt_Printf(arg->prompt, "Mallocs: %llu,   Frees: %llu\n",
339706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                mbuf_Mallocs, mbuf_Frees);
340706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
341706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return 0;
342706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
343706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
344706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mbuf *
345706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehm_dequeue(struct mqueue *q)
346706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
347706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mbuf *bp;
348706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
349706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  log_Printf(LogDEBUG, "m_dequeue: queue len = %lu\n", (u_long)q->len);
350706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  bp = q->top;
351706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (bp) {
352706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    q->top = q->top->m_nextpkt;
353706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    q->len--;
354706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (q->top == NULL) {
355706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      q->last = q->top;
356706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (q->len)
357706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh	log_Printf(LogERROR, "m_dequeue: Not zero (%lu)!!!\n",
358706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh                   (u_long)q->len);
359706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
360706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bp->m_nextpkt = NULL;
361706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
362706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
363706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return bp;
364706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
365706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
366706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
367706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehm_enqueue(struct mqueue *queue, struct mbuf *bp)
368706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
369706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (bp != NULL) {
370706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (queue->last) {
371706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      queue->last->m_nextpkt = bp;
372706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      queue->last = bp;
373706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    } else
374706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      queue->last = queue->top = bp;
375706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    queue->len++;
376706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    log_Printf(LogDEBUG, "m_enqueue: len = %lu\n", (unsigned long)queue->len);
377706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
378706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
379706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
380706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mbuf *
381706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehm_pullup(struct mbuf *bp)
382706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
383706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  /* Put it all in one contigous (aligned) mbuf */
384706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
385706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (bp != NULL) {
386706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (bp->m_next != NULL) {
387706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      struct mbuf *nbp;
388706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      u_char *cp;
389706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
390706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      nbp = m_get(m_length(bp), bp->m_type);
391706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
392706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      for (cp = MBUF_CTOP(nbp); bp; bp = m_free(bp)) {
393706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        memcpy(cp, MBUF_CTOP(bp), bp->m_len);
394706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        cp += bp->m_len;
395706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      }
396706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      bp = nbp;
397706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
398706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef __i386__	/* Do any other archs not care about alignment ? */
399706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    else if ((bp->m_offset & (sizeof(long) - 1)) != 0) {
400706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      bcopy(MBUF_CTOP(bp), bp + 1, bp->m_len);
401706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      bp->m_offset = 0;
402706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
403706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif
404706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  }
405706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
406706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return bp;
407706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
408706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
409706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid
410706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehm_settype(struct mbuf *bp, int type)
411706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
412706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  for (; bp; bp = bp->m_next)
413706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (type != bp->m_type) {
414706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      MemMap[bp->m_type].fragments--;
415706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      MemMap[bp->m_type].octets -= bp->m_size;
416706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      bp->m_type = type;
417706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      MemMap[type].fragments++;
418706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      MemMap[type].octets += bp->m_size;
419706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    }
420706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
421706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
422706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mbuf *
423706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehm_append(struct mbuf *bp, const void *v, size_t sz)
424706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{
425706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  struct mbuf *m = bp;
426706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
427706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  if (m) {
428706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    while (m->m_next)
429706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      m = m->m_next;
430706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    if (m->m_size - m->m_len >= sz) {
431706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      if (v)
432706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh        memcpy((char *)(m + 1) + m->m_len, v, sz);
433706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      m->m_len += sz;
434706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    } else
435706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh      m->m_next = m_prepend(NULL, v, sz, 0);
436706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  } else
437706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh    bp = m_prepend(NULL, v, sz, 0);
438706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh
439706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh  return bp;
440706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}
441