| 1624 | } |
| 1625 | |
| 1626 | static int |
| 1627 | register_send(struct ip6_hdr *ip6, struct mif6 *mif, struct mbuf *m) |
| 1628 | { |
| 1629 | #ifdef MRT6DEBUG |
| 1630 | char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; |
| 1631 | #endif |
| 1632 | struct mbuf *mm; |
| 1633 | int i, len = m->m_pkthdr.len; |
| 1634 | static struct sockaddr_in6 sin6 = { sizeof(sin6), AF_INET6 }; |
| 1635 | struct mrt6msg *im6; |
| 1636 | |
| 1637 | MRT6_DLOG(DEBUG_ANY, "src %s dst %s", |
| 1638 | ip6_sprintf(ip6bufs, &ip6->ip6_src), |
| 1639 | ip6_sprintf(ip6bufd, &ip6->ip6_dst)); |
| 1640 | PIM6STAT_INC(pim6s_snd_registers); |
| 1641 | |
| 1642 | /* Make a copy of the packet to send to the user level process. */ |
| 1643 | mm = m_gethdr(M_NOWAIT, MT_DATA); |
| 1644 | if (mm == NULL) |
| 1645 | return (ENOBUFS); |
| 1646 | mm->m_data += max_linkhdr; |
| 1647 | mm->m_len = sizeof(struct ip6_hdr); |
| 1648 | |
| 1649 | if ((mm->m_next = m_copym(m, 0, M_COPYALL, M_NOWAIT)) == NULL) { |
| 1650 | m_freem(mm); |
| 1651 | return (ENOBUFS); |
| 1652 | } |
| 1653 | i = MHLEN - M_LEADINGSPACE(mm); |
| 1654 | if (i > len) |
| 1655 | i = len; |
| 1656 | mm = m_pullup(mm, i); |
| 1657 | if (mm == NULL) |
| 1658 | return (ENOBUFS); |
| 1659 | /* TODO: check it! */ |
| 1660 | mm->m_pkthdr.len = len + sizeof(struct ip6_hdr); |
| 1661 | |
| 1662 | /* |
| 1663 | * Send message to routing daemon |
| 1664 | */ |
| 1665 | sin6.sin6_addr = ip6->ip6_src; |
| 1666 | |
| 1667 | im6 = mtod(mm, struct mrt6msg *); |
| 1668 | im6->im6_msgtype = MRT6MSG_WHOLEPKT; |
| 1669 | im6->im6_mbz = 0; |
| 1670 | |
| 1671 | im6->im6_mif = mif - mif6table; |
| 1672 | |
| 1673 | /* iif info is not given for reg. encap.n */ |
| 1674 | MRT6STAT_INC(mrt6s_upcalls); |
| 1675 | |
| 1676 | if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) { |
| 1677 | MRT6_DLOG(DEBUG_ANY, "ip6_mrouter socket queue full"); |
| 1678 | MRT6STAT_INC(mrt6s_upq_sockfull); |
| 1679 | return (ENOBUFS); |
| 1680 | } |
| 1681 | return (0); |
| 1682 | } |
| 1683 |
no test coverage detected