1 /*- 2 * Copyright (c) 2010-2011 Monthadar Al Jaberi, TerraNet AB 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 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 * 29 * $FreeBSD$ 30 */ 31 #include "if_wtapvar.h" 32 #include "if_medium.h" 33 34 void 35 init_medium(struct wtap_medium *md) 36 { 37 38 DWTAP_PRINTF("%s\n", __func__); 39 STAILQ_INIT(&md->md_pktbuf); 40 mtx_init(&md->md_mtx, "wtap_medium mtx", NULL, MTX_DEF | MTX_RECURSE); 41 42 /* Event handler for sending packets between wtaps */ 43 struct eventhandler *eh = (struct eventhandler *) 44 malloc(sizeof(struct eventhandler), M_WTAP, M_NOWAIT | M_ZERO); 45 eh->tq = taskqueue_create("wtap_tx_taskq", M_NOWAIT | M_ZERO, 46 taskqueue_thread_enqueue, &eh->tq); 47 taskqueue_start_threads(&eh->tq, 1, PI_NET, "%s taskq", "wtap_medium"); 48 md->tx_handler = eh; 49 /* Mark medium closed by default */ 50 md->open = 0; 51 } 52 53 void 54 deinit_medium(struct wtap_medium *md) 55 { 56 57 DWTAP_PRINTF("%s\n", __func__); 58 taskqueue_free(md->tx_handler->tq); 59 free(md->tx_handler, M_WTAP); 60 } 61 62 int 63 medium_transmit(struct wtap_medium *md, int id, struct mbuf*m) 64 { 65 66 mtx_lock(&md->md_mtx); 67 if (md->open == 0){ 68 DWTAP_PRINTF("[%d] dropping m=%p\n", id, m); 69 m_free(m); 70 mtx_unlock(&md->md_mtx); 71 return 0; 72 } 73 74 DWTAP_PRINTF("[%d] transmiting m=%p\n", id, m); 75 struct packet *p = (struct packet *)malloc(sizeof(struct packet), 76 M_WTAP_PACKET, M_ZERO | M_NOWAIT); 77 p->id = id; 78 p->m = m; 79 80 STAILQ_INSERT_TAIL(&md->md_pktbuf, p, pf_list); 81 taskqueue_enqueue(md->tx_handler->tq, &md->tx_handler->proc); 82 mtx_unlock(&md->md_mtx); 83 84 return 0; 85 } 86 87 struct packet * 88 medium_get_next_packet(struct wtap_medium *md) 89 { 90 struct packet *p; 91 92 mtx_lock(&md->md_mtx); 93 p = STAILQ_FIRST(&md->md_pktbuf); 94 if (p == NULL){ 95 mtx_unlock(&md->md_mtx); 96 return NULL; 97 } 98 99 STAILQ_REMOVE_HEAD(&md->md_pktbuf, pf_list); 100 mtx_unlock(&md->md_mtx); 101 return p; 102 } 103 104 void 105 medium_open(struct wtap_medium *md) 106 { 107 108 mtx_lock(&md->md_mtx); 109 md->open = 1; 110 mtx_unlock(&md->md_mtx); 111 } 112 113 void 114 medium_close(struct wtap_medium *md) 115 { 116 117 mtx_lock(&md->md_mtx); 118 md->open = 0; 119 mtx_unlock(&md->md_mtx); 120 } 121