* Common length and type checks are done here, * then the protocol-specific routine is called. */
| 676 | * then the protocol-specific routine is called. |
| 677 | */ |
| 678 | static void |
| 679 | arpintr(struct mbuf *m) |
| 680 | { |
| 681 | struct arphdr *ar; |
| 682 | struct ifnet *ifp; |
| 683 | char *layer; |
| 684 | int hlen; |
| 685 | |
| 686 | ifp = m->m_pkthdr.rcvif; |
| 687 | |
| 688 | if (m->m_len < sizeof(struct arphdr) && |
| 689 | ((m = m_pullup(m, sizeof(struct arphdr))) == NULL)) { |
| 690 | ARP_LOG(LOG_NOTICE, "packet with short header received on %s\n", |
| 691 | if_name(ifp)); |
| 692 | return; |
| 693 | } |
| 694 | ar = mtod(m, struct arphdr *); |
| 695 | |
| 696 | /* Check if length is sufficient */ |
| 697 | if (m->m_len < arphdr_len(ar)) { |
| 698 | m = m_pullup(m, arphdr_len(ar)); |
| 699 | if (m == NULL) { |
| 700 | ARP_LOG(LOG_NOTICE, "short packet received on %s\n", |
| 701 | if_name(ifp)); |
| 702 | return; |
| 703 | } |
| 704 | ar = mtod(m, struct arphdr *); |
| 705 | } |
| 706 | |
| 707 | hlen = 0; |
| 708 | layer = ""; |
| 709 | switch (ntohs(ar->ar_hrd)) { |
| 710 | case ARPHRD_ETHER: |
| 711 | hlen = ETHER_ADDR_LEN; /* RFC 826 */ |
| 712 | layer = "ethernet"; |
| 713 | break; |
| 714 | case ARPHRD_INFINIBAND: |
| 715 | hlen = 20; /* RFC 4391, INFINIBAND_ALEN */ |
| 716 | layer = "infiniband"; |
| 717 | break; |
| 718 | case ARPHRD_IEEE1394: |
| 719 | hlen = 0; /* SHALL be 16 */ /* RFC 2734 */ |
| 720 | layer = "firewire"; |
| 721 | |
| 722 | /* |
| 723 | * Restrict too long hardware addresses. |
| 724 | * Currently we are capable of handling 20-byte |
| 725 | * addresses ( sizeof(lle->ll_addr) ) |
| 726 | */ |
| 727 | if (ar->ar_hln >= 20) |
| 728 | hlen = 16; |
| 729 | break; |
| 730 | default: |
| 731 | ARP_LOG(LOG_NOTICE, |
| 732 | "packet with unknown hardware format 0x%02d received on " |
| 733 | "%s\n", ntohs(ar->ar_hrd), if_name(ifp)); |
| 734 | m_freem(m); |
| 735 | return; |
nothing calls this directly
no test coverage detected