| 1274 | }; |
| 1275 | |
| 1276 | void |
| 1277 | ether_vlan_mtap(struct bpf_if *bp, struct mbuf *m, void *data, u_int dlen) |
| 1278 | { |
| 1279 | struct ether_vlan_header vlan; |
| 1280 | struct mbuf mv, mb; |
| 1281 | |
| 1282 | KASSERT((m->m_flags & M_VLANTAG) != 0, |
| 1283 | ("%s: vlan information not present", __func__)); |
| 1284 | KASSERT(m->m_len >= sizeof(struct ether_header), |
| 1285 | ("%s: mbuf not large enough for header", __func__)); |
| 1286 | bcopy(mtod(m, char *), &vlan, sizeof(struct ether_header)); |
| 1287 | vlan.evl_proto = vlan.evl_encap_proto; |
| 1288 | vlan.evl_encap_proto = htons(ETHERTYPE_VLAN); |
| 1289 | vlan.evl_tag = htons(m->m_pkthdr.ether_vtag); |
| 1290 | m->m_len -= sizeof(struct ether_header); |
| 1291 | m->m_data += sizeof(struct ether_header); |
| 1292 | /* |
| 1293 | * If a data link has been supplied by the caller, then we will need to |
| 1294 | * re-create a stack allocated mbuf chain with the following structure: |
| 1295 | * |
| 1296 | * (1) mbuf #1 will contain the supplied data link |
| 1297 | * (2) mbuf #2 will contain the vlan header |
| 1298 | * (3) mbuf #3 will contain the original mbuf's packet data |
| 1299 | * |
| 1300 | * Otherwise, submit the packet and vlan header via bpf_mtap2(). |
| 1301 | */ |
| 1302 | if (data != NULL) { |
| 1303 | mv.m_next = m; |
| 1304 | mv.m_data = (caddr_t)&vlan; |
| 1305 | mv.m_len = sizeof(vlan); |
| 1306 | mb.m_next = &mv; |
| 1307 | mb.m_data = data; |
| 1308 | mb.m_len = dlen; |
| 1309 | bpf_mtap(bp, &mb); |
| 1310 | } else |
| 1311 | bpf_mtap2(bp, &vlan, sizeof(vlan), m); |
| 1312 | m->m_len += sizeof(struct ether_header); |
| 1313 | m->m_data -= sizeof(struct ether_header); |
| 1314 | } |
| 1315 | |
| 1316 | struct mbuf * |
| 1317 | ether_vlanencap_proto(struct mbuf *m, uint16_t tag, uint16_t proto) |