/** * Put an IP_RECVTTL control message into msg ancillary data buffer. */ ci_inline void ip_cmsg_recv_ttl(const ci_ip_pkt_fmt *pkt, struct cmsg_state *cmsg_state) { int ttl = oo_ip_hdr_const(pkt)->ip_ttl; ci_put_cmsg(cmsg_state, IPPROTO_IP, IP_TTL, sizeof(ttl), &ttl); }
/** * Put an IP_RECVTOS control message into msg ancillary data buffer. */ ci_inline void ip_cmsg_recv_tos(const ci_ip_pkt_fmt *pkt, struct cmsg_state *cmsg_state) { int tos = oo_ip_hdr_const(pkt)->ip_tos; ci_put_cmsg(cmsg_state, IPPROTO_IP, IP_TOS, sizeof(tos), &tos); }
ci_inline void ci_udp_recvmsg_fill_msghdr(ci_netif* ni, ci_msghdr* msg, const ci_ip_pkt_fmt* pkt, ci_sock_cmn* s) { #ifndef __KERNEL__ const ci_udp_hdr* udp; const ci_ip4_hdr* ip; if( msg != NULL ) { if( msg->msg_name != NULL ) { if( pkt->flags & CI_PKT_FLAG_RX_INDIRECT ) pkt = PKT_CHK_NNL(ni, pkt->frag_next); ip = oo_ip_hdr_const(pkt); udp = (const ci_udp_hdr*) ((char*) ip + CI_IP4_IHL(ip)); ci_addr_to_user(CI_SA(msg->msg_name), &msg->msg_namelen, s->domain, udp->udp_source_be16, ip->ip_saddr_be32); } } #endif }
/** * Put an IP_PKTINFO control message into msg ancillary data buffer. */ static void ip_cmsg_recv_pktinfo(ci_netif* netif, const ci_ip_pkt_fmt* pkt, struct cmsg_state *cmsg_state) { /* TODO: This is horribly inefficient -- two system calls. Could be made * cheap with a user-level llap table. */ struct in_pktinfo info; ci_uint32 addr; int hwport; addr = oo_ip_hdr_const(pkt)->ip_daddr_be32; info.ipi_addr.s_addr = addr; /* Set the ifindex the pkt was received at. */ { ci_ifid_t ifindex = 0; int rc = 0; hwport = netif->state->intf_i_to_hwport[pkt->intf_i]; rc = cicp_llap_find(CICP_HANDLE(netif), &ifindex, CI_HWPORT_ID(hwport), pkt->vlan); if( rc != 0 ) LOG_E(ci_log("%s: cicp_llap_find(intf_i=%d, hwport=%d) failed rc=%d", __FUNCTION__, pkt->intf_i, hwport, rc)); info.ipi_ifindex = ifindex; } /* RFC1122: The specific-destination address is defined to be the * destination address in the IP header unless the header contains a * broadcast or multicast address, in which case the specific-destination * is an IP address assigned to the physical interface on which the * datagram arrived. */ /*\ FIXME: we should drop the packet if this call fails */ cicp_ipif_pktinfo_query(CICP_HANDLE(netif), netif, OO_PKT_P(pkt), info.ipi_ifindex, &info.ipi_spec_dst.s_addr ); ci_put_cmsg(cmsg_state, IPPROTO_IP, IP_PKTINFO, sizeof(info), &info); }