104d19802SAdrian Chadd /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni *
404d19802SAdrian Chadd * Copyright (c) 2010-2011 Monthadar Al Jaberi, TerraNet AB
504d19802SAdrian Chadd * All rights reserved.
604d19802SAdrian Chadd *
704d19802SAdrian Chadd * Redistribution and use in source and binary forms, with or without
804d19802SAdrian Chadd * modification, are permitted provided that the following conditions
904d19802SAdrian Chadd * are met:
1004d19802SAdrian Chadd * 1. Redistributions of source code must retain the above copyright
1104d19802SAdrian Chadd * notice, this list of conditions and the following disclaimer,
1204d19802SAdrian Chadd * without modification.
1304d19802SAdrian Chadd * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1404d19802SAdrian Chadd * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
1504d19802SAdrian Chadd * redistribution must be conditioned upon including a substantially
1604d19802SAdrian Chadd * similar Disclaimer requirement for further binary redistribution.
1704d19802SAdrian Chadd *
1804d19802SAdrian Chadd * NO WARRANTY
1904d19802SAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2004d19802SAdrian Chadd * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2104d19802SAdrian Chadd * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
2204d19802SAdrian Chadd * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
2304d19802SAdrian Chadd * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
2404d19802SAdrian Chadd * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2504d19802SAdrian Chadd * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2604d19802SAdrian Chadd * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2704d19802SAdrian Chadd * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2804d19802SAdrian Chadd * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2904d19802SAdrian Chadd * THE POSSIBILITY OF SUCH DAMAGES.
3004d19802SAdrian Chadd */
3104d19802SAdrian Chadd #include "if_wtapvar.h"
3204d19802SAdrian Chadd #include "if_medium.h"
3304d19802SAdrian Chadd
3404d19802SAdrian Chadd void
init_medium(struct wtap_medium * md)3504d19802SAdrian Chadd init_medium(struct wtap_medium *md)
3604d19802SAdrian Chadd {
3704d19802SAdrian Chadd
3804d19802SAdrian Chadd DWTAP_PRINTF("%s\n", __func__);
3904d19802SAdrian Chadd STAILQ_INIT(&md->md_pktbuf);
4004d19802SAdrian Chadd mtx_init(&md->md_mtx, "wtap_medium mtx", NULL, MTX_DEF | MTX_RECURSE);
4104d19802SAdrian Chadd
4204d19802SAdrian Chadd /* Event handler for sending packets between wtaps */
4304d19802SAdrian Chadd struct eventhandler *eh = (struct eventhandler *)
4404d19802SAdrian Chadd malloc(sizeof(struct eventhandler), M_WTAP, M_NOWAIT | M_ZERO);
4504d19802SAdrian Chadd eh->tq = taskqueue_create("wtap_tx_taskq", M_NOWAIT | M_ZERO,
4604d19802SAdrian Chadd taskqueue_thread_enqueue, &eh->tq);
4704d19802SAdrian Chadd taskqueue_start_threads(&eh->tq, 1, PI_NET, "%s taskq", "wtap_medium");
4804d19802SAdrian Chadd md->tx_handler = eh;
4904d19802SAdrian Chadd /* Mark medium closed by default */
5004d19802SAdrian Chadd md->open = 0;
5104d19802SAdrian Chadd }
5204d19802SAdrian Chadd
5304d19802SAdrian Chadd void
deinit_medium(struct wtap_medium * md)5404d19802SAdrian Chadd deinit_medium(struct wtap_medium *md)
5504d19802SAdrian Chadd {
5604d19802SAdrian Chadd
5704d19802SAdrian Chadd DWTAP_PRINTF("%s\n", __func__);
5804d19802SAdrian Chadd taskqueue_free(md->tx_handler->tq);
5904d19802SAdrian Chadd free(md->tx_handler, M_WTAP);
6004d19802SAdrian Chadd }
6104d19802SAdrian Chadd
6204d19802SAdrian Chadd int
medium_transmit(struct wtap_medium * md,int id,struct mbuf * m)6304d19802SAdrian Chadd medium_transmit(struct wtap_medium *md, int id, struct mbuf*m)
6404d19802SAdrian Chadd {
6504d19802SAdrian Chadd
6604d19802SAdrian Chadd mtx_lock(&md->md_mtx);
6704d19802SAdrian Chadd if (md->open == 0){
6804d19802SAdrian Chadd DWTAP_PRINTF("[%d] dropping m=%p\n", id, m);
6904d19802SAdrian Chadd m_free(m);
7004d19802SAdrian Chadd mtx_unlock(&md->md_mtx);
7104d19802SAdrian Chadd return 0;
7204d19802SAdrian Chadd }
7304d19802SAdrian Chadd
7404d19802SAdrian Chadd DWTAP_PRINTF("[%d] transmiting m=%p\n", id, m);
7504d19802SAdrian Chadd struct packet *p = (struct packet *)malloc(sizeof(struct packet),
7604d19802SAdrian Chadd M_WTAP_PACKET, M_ZERO | M_NOWAIT);
7704d19802SAdrian Chadd p->id = id;
7804d19802SAdrian Chadd p->m = m;
7904d19802SAdrian Chadd
8004d19802SAdrian Chadd STAILQ_INSERT_TAIL(&md->md_pktbuf, p, pf_list);
8104d19802SAdrian Chadd taskqueue_enqueue(md->tx_handler->tq, &md->tx_handler->proc);
8204d19802SAdrian Chadd mtx_unlock(&md->md_mtx);
8304d19802SAdrian Chadd
8404d19802SAdrian Chadd return 0;
8504d19802SAdrian Chadd }
8604d19802SAdrian Chadd
8704d19802SAdrian Chadd struct packet *
medium_get_next_packet(struct wtap_medium * md)8804d19802SAdrian Chadd medium_get_next_packet(struct wtap_medium *md)
8904d19802SAdrian Chadd {
9004d19802SAdrian Chadd struct packet *p;
9104d19802SAdrian Chadd
9204d19802SAdrian Chadd mtx_lock(&md->md_mtx);
9304d19802SAdrian Chadd p = STAILQ_FIRST(&md->md_pktbuf);
9404d19802SAdrian Chadd if (p == NULL){
9504d19802SAdrian Chadd mtx_unlock(&md->md_mtx);
9604d19802SAdrian Chadd return NULL;
9704d19802SAdrian Chadd }
9804d19802SAdrian Chadd
9904d19802SAdrian Chadd STAILQ_REMOVE_HEAD(&md->md_pktbuf, pf_list);
10004d19802SAdrian Chadd mtx_unlock(&md->md_mtx);
10104d19802SAdrian Chadd return p;
10204d19802SAdrian Chadd }
10304d19802SAdrian Chadd
10404d19802SAdrian Chadd void
medium_open(struct wtap_medium * md)10504d19802SAdrian Chadd medium_open(struct wtap_medium *md)
10604d19802SAdrian Chadd {
10704d19802SAdrian Chadd
10804d19802SAdrian Chadd mtx_lock(&md->md_mtx);
10904d19802SAdrian Chadd md->open = 1;
11004d19802SAdrian Chadd mtx_unlock(&md->md_mtx);
11104d19802SAdrian Chadd }
11204d19802SAdrian Chadd
11304d19802SAdrian Chadd void
medium_close(struct wtap_medium * md)11404d19802SAdrian Chadd medium_close(struct wtap_medium *md)
11504d19802SAdrian Chadd {
11604d19802SAdrian Chadd
11704d19802SAdrian Chadd mtx_lock(&md->md_mtx);
11804d19802SAdrian Chadd md->open = 0;
11904d19802SAdrian Chadd mtx_unlock(&md->md_mtx);
12004d19802SAdrian Chadd }
121