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 }
int ci_tcp_getpeername(citp_socket* ep, struct sockaddr* name, socklen_t* namelen) { ci_sock_cmn* s = ep->s; int rc; CHECK_TEP_NNL(ep); /* If we're not connected... */ if( ! (s->b.state & CI_TCP_STATE_SYNCHRONISED) || s->b.state == CI_TCP_TIME_WAIT ) CI_SET_ERROR(rc, ENOTCONN); else if( name == NULL || namelen == NULL ) CI_SET_ERROR(rc, EFAULT); else { ci_addr_to_user(name, namelen, s->domain, S_TCP_HDR(s)->tcp_dest_be16, s->pkt.ip.ip_daddr_be32); rc = 0; } return rc; }
/*! \todo we can simplify this a lot by letting the kernel have it! */ int ci_udp_getpeername(citp_socket*ep, struct sockaddr* name, socklen_t* namelen) { ci_udp_state* us; CHECK_UEP(ep); us = SOCK_TO_UDP(ep->s); /* * At first, it's necessary to check whether socket is connected or * not, since we can return ENOTCONN even if name and/or namelen are * not valid. */ if( udp_raddr_be32(us) == 0 ) { RET_WITH_ERRNO(ENOTCONN); } else if( name == NULL || namelen == NULL ) { RET_WITH_ERRNO(EFAULT); } else { ci_addr_to_user(name, namelen, ep->s->domain, udp_rport_be16(us), udp_raddr_be32(us)); return 0; } }