* Handle an mbuf received on the "lower" or "orphan" hook. */
| 660 | * Handle an mbuf received on the "lower" or "orphan" hook. |
| 661 | */ |
| 662 | static int |
| 663 | ng_ether_rcv_lower(hook_p hook, item_p item) |
| 664 | { |
| 665 | struct mbuf *m; |
| 666 | const node_p node = NG_HOOK_NODE(hook); |
| 667 | const priv_p priv = NG_NODE_PRIVATE(node); |
| 668 | struct ifnet *const ifp = priv->ifp; |
| 669 | |
| 670 | NGI_GET_M(item, m); |
| 671 | NG_FREE_ITEM(item); |
| 672 | |
| 673 | /* Check whether interface is ready for packets */ |
| 674 | |
| 675 | if (!((ifp->if_flags & IFF_UP) && |
| 676 | (ifp->if_drv_flags & IFF_DRV_RUNNING))) { |
| 677 | NG_FREE_M(m); |
| 678 | return (ENETDOWN); |
| 679 | } |
| 680 | |
| 681 | /* Make sure header is fully pulled up */ |
| 682 | if (m->m_pkthdr.len < sizeof(struct ether_header)) { |
| 683 | NG_FREE_M(m); |
| 684 | return (EINVAL); |
| 685 | } |
| 686 | if (m->m_len < sizeof(struct ether_header) |
| 687 | && (m = m_pullup(m, sizeof(struct ether_header))) == NULL) |
| 688 | return (ENOBUFS); |
| 689 | |
| 690 | /* Drop in the MAC address if desired */ |
| 691 | if (priv->autoSrcAddr) { |
| 692 | /* Make the mbuf writable if it's not already */ |
| 693 | if (!M_WRITABLE(m) |
| 694 | && (m = m_pullup(m, sizeof(struct ether_header))) == NULL) |
| 695 | return (ENOBUFS); |
| 696 | |
| 697 | /* Overwrite source MAC address */ |
| 698 | bcopy(IF_LLADDR(ifp), |
| 699 | mtod(m, struct ether_header *)->ether_shost, |
| 700 | ETHER_ADDR_LEN); |
| 701 | } |
| 702 | |
| 703 | /* Send it on its way */ |
| 704 | return ether_output_frame(ifp, m); |
| 705 | } |
| 706 | |
| 707 | /* |
| 708 | * Handle an mbuf received on the "upper" hook. |
nothing calls this directly
no test coverage detected