1*02f520acSplunky /* $NetBSD: packet.c,v 1.2 2009/05/02 20:07:51 plunky Exp $ */
21fc74d21Splunky
31fc74d21Splunky /*-
41fc74d21Splunky * Copyright (c) 2008 Iain Hibbert
51fc74d21Splunky * All rights reserved.
61fc74d21Splunky *
71fc74d21Splunky * Redistribution and use in source and binary forms, with or without
81fc74d21Splunky * modification, are permitted provided that the following conditions
91fc74d21Splunky * are met:
101fc74d21Splunky * 1. Redistributions of source code must retain the above copyright
111fc74d21Splunky * notice, this list of conditions and the following disclaimer.
121fc74d21Splunky * 2. Redistributions in binary form must reproduce the above copyright
131fc74d21Splunky * notice, this list of conditions and the following disclaimer in the
141fc74d21Splunky * documentation and/or other materials provided with the distribution.
151fc74d21Splunky *
161fc74d21Splunky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
171fc74d21Splunky * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
181fc74d21Splunky * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
191fc74d21Splunky * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
201fc74d21Splunky * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
211fc74d21Splunky * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
221fc74d21Splunky * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
231fc74d21Splunky * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
241fc74d21Splunky * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
251fc74d21Splunky * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
261fc74d21Splunky */
271fc74d21Splunky
281fc74d21Splunky #include <sys/cdefs.h>
29*02f520acSplunky __RCSID("$NetBSD: packet.c,v 1.2 2009/05/02 20:07:51 plunky Exp $");
301fc74d21Splunky
311fc74d21Splunky #include "btpand.h"
321fc74d21Splunky
331fc74d21Splunky packet_t *
packet_alloc(channel_t * chan)341fc74d21Splunky packet_alloc(channel_t *chan)
351fc74d21Splunky {
361fc74d21Splunky packet_t *pkt;
371fc74d21Splunky
381fc74d21Splunky pkt = malloc(sizeof(packet_t) + chan->mru);
391fc74d21Splunky if (pkt == NULL) {
401fc74d21Splunky log_err("%s() failed: %m", __func__);
411fc74d21Splunky return NULL;
421fc74d21Splunky }
431fc74d21Splunky
441fc74d21Splunky memset(pkt, 0, sizeof(packet_t));
451fc74d21Splunky STAILQ_INIT(&pkt->extlist);
461fc74d21Splunky pkt->ptr = pkt->buf;
471fc74d21Splunky
481fc74d21Splunky pkt->chan = chan;
491fc74d21Splunky chan->refcnt++;
501fc74d21Splunky
511fc74d21Splunky return pkt;
521fc74d21Splunky }
531fc74d21Splunky
541fc74d21Splunky void
packet_free(packet_t * pkt)551fc74d21Splunky packet_free(packet_t *pkt)
561fc74d21Splunky {
571fc74d21Splunky exthdr_t *eh;
581fc74d21Splunky
591fc74d21Splunky if (pkt->refcnt-- > 0)
601fc74d21Splunky return;
611fc74d21Splunky
621fc74d21Splunky while ((eh = STAILQ_FIRST(&pkt->extlist)) != NULL) {
631fc74d21Splunky STAILQ_REMOVE_HEAD(&pkt->extlist, next);
641fc74d21Splunky free(eh);
651fc74d21Splunky }
661fc74d21Splunky
671fc74d21Splunky pkt->chan->refcnt--;
681fc74d21Splunky if (pkt->chan->refcnt == 0)
691fc74d21Splunky channel_free(pkt->chan);
701fc74d21Splunky
711fc74d21Splunky free(pkt);
721fc74d21Splunky }
731fc74d21Splunky
741fc74d21Splunky void
packet_adj(packet_t * pkt,size_t size)751fc74d21Splunky packet_adj(packet_t *pkt, size_t size)
761fc74d21Splunky {
771fc74d21Splunky
78*02f520acSplunky assert(pkt->refcnt == 0);
79*02f520acSplunky assert(pkt->len >= size);
801fc74d21Splunky
811fc74d21Splunky pkt->ptr += size;
821fc74d21Splunky pkt->len -= size;
831fc74d21Splunky }
841fc74d21Splunky
851fc74d21Splunky pkthdr_t *
pkthdr_alloc(packet_t * pkt)861fc74d21Splunky pkthdr_alloc(packet_t *pkt)
871fc74d21Splunky {
881fc74d21Splunky pkthdr_t *ph;
891fc74d21Splunky
901fc74d21Splunky ph = malloc(sizeof(pkthdr_t));
911fc74d21Splunky if (ph == NULL) {
921fc74d21Splunky log_err("%s() failed: %m", __func__);
931fc74d21Splunky return NULL;
941fc74d21Splunky }
951fc74d21Splunky
961fc74d21Splunky ph->data = pkt;
971fc74d21Splunky pkt->refcnt++;
981fc74d21Splunky
991fc74d21Splunky return ph;
1001fc74d21Splunky }
1011fc74d21Splunky
1021fc74d21Splunky void
pkthdr_free(pkthdr_t * ph)1031fc74d21Splunky pkthdr_free(pkthdr_t *ph)
1041fc74d21Splunky {
1051fc74d21Splunky
1061fc74d21Splunky packet_free(ph->data);
1071fc74d21Splunky free(ph);
1081fc74d21Splunky }
109