* Receive data on a hook */
| 1003 | * Receive data on a hook |
| 1004 | */ |
| 1005 | static int |
| 1006 | ngs_rcvdata(hook_p hook, item_p item) |
| 1007 | { |
| 1008 | struct ngsock *const priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); |
| 1009 | struct ngpcb *const pcbp = priv->datasock; |
| 1010 | struct socket *so; |
| 1011 | struct sockaddr_ng *addr; |
| 1012 | char *addrbuf[NG_HOOKSIZ + 4]; |
| 1013 | int addrlen; |
| 1014 | struct mbuf *m; |
| 1015 | |
| 1016 | NGI_GET_M(item, m); |
| 1017 | NG_FREE_ITEM(item); |
| 1018 | |
| 1019 | /* If there is no data socket, black-hole it. */ |
| 1020 | if (pcbp == NULL) { |
| 1021 | NG_FREE_M(m); |
| 1022 | return (0); |
| 1023 | } |
| 1024 | so = pcbp->ng_socket; |
| 1025 | |
| 1026 | /* Get the return address into a sockaddr. */ |
| 1027 | addrlen = strlen(NG_HOOK_NAME(hook)); /* <= NG_HOOKSIZ - 1 */ |
| 1028 | addr = (struct sockaddr_ng *) addrbuf; |
| 1029 | addr->sg_len = addrlen + 3; |
| 1030 | addr->sg_family = AF_NETGRAPH; |
| 1031 | bcopy(NG_HOOK_NAME(hook), addr->sg_data, addrlen); |
| 1032 | addr->sg_data[addrlen] = '\0'; |
| 1033 | |
| 1034 | /* Try to tell the socket which hook it came in on. */ |
| 1035 | SOCKBUF_LOCK(&so->so_rcv); |
| 1036 | if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)addr, m, |
| 1037 | NULL) == 0) { |
| 1038 | SOCKBUF_UNLOCK(&so->so_rcv); |
| 1039 | m_freem(m); |
| 1040 | TRAP_ERROR; |
| 1041 | return (ENOBUFS); |
| 1042 | } |
| 1043 | |
| 1044 | /* sorwakeup_locked () releases the lock internally. */ |
| 1045 | sorwakeup_locked(so); |
| 1046 | return (0); |
| 1047 | } |
| 1048 | |
| 1049 | /* |
| 1050 | * Hook disconnection |
nothing calls this directly
no test coverage detected