Example #1
0
ssize_t
Recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
               SA *sa, socklen_t *salenptr, void *dstaddrp)
{
    ssize_t		n;

    n = recvfrom_flags(fd, ptr, nbytes, flagsp, sa, salenptr, dstaddrp);
    if (n < 0)
        err_quit("recvfrom_flags error");

    return(n);
}
Example #2
0
// This routine is called when the main loop detects that data is available on a socket.
static void SocketDataReady(mDNS *const m, PosixNetworkInterface *intf, int skt)
	{
	mDNSAddr   senderAddr, destAddr;
	mDNSIPPort senderPort;
	ssize_t                 packetLen;
	DNSMessage              packet;
	struct my_in_pktinfo    packetInfo;
	struct sockaddr_storage from;
	socklen_t               fromLen;
	int                     flags;
	mDNSBool                reject;

	assert(m    != NULL);
	assert(intf != NULL);
	assert(skt  >= 0);

	fromLen = sizeof(from);
	flags   = 0;
	packetLen = recvfrom_flags(skt, &packet, sizeof(packet), &flags, (struct sockaddr *) &from, &fromLen, &packetInfo);

	if (packetLen >= 0)
		{
		SockAddrTomDNSAddr((struct sockaddr*)&from, &senderAddr, &senderPort);
		SockAddrTomDNSAddr((struct sockaddr*)&packetInfo.ipi_addr, &destAddr, NULL);

		// If we have broken IP_RECVDSTADDR functionality (so far
		// I've only seen this on OpenBSD) then apply a hack to
		// convince mDNS Core that this isn't a spoof packet.
		// Basically what we do is check to see whether the
		// packet arrived as a multicast and, if so, set its
		// destAddr to the mDNS address.
		//
		// I must admit that I could just be doing something
		// wrong on OpenBSD and hence triggering this problem
		// but I'm at a loss as to how.
		//
		// If this platform doesn't have IP_PKTINFO or IP_RECVDSTADDR, then we have
		// no way to tell the destination address or interface this packet arrived on,
		// so all we can do is just assume it's a multicast

		#if HAVE_BROKEN_RECVDSTADDR || (!defined(IP_PKTINFO) && !defined(IP_RECVDSTADDR))
			if ( (destAddr.NotAnInteger == 0) && (flags & MSG_MCAST) )
				{
				destAddr.type == senderAddr.type;
				if      (senderAddr.type == mDNSAddrType_IPv4) destAddr.ip.v4 = AllDNSLinkGroup;
				else if (senderAddr.type == mDNSAddrType_IPv6) destAddr.ip.v6 = AllDNSLinkGroupv6;
				}
		#endif

		// We only accept the packet if the interface on which it came
		// in matches the interface associated with this socket.
		// We do this match by name or by index, depending on which
		// information is available.  recvfrom_flags sets the name
		// to "" if the name isn't available, or the index to -1
		// if the index is available.  This accomodates the various
		// different capabilities of our target platforms.

		reject = mDNSfalse;
		if      ( packetInfo.ipi_ifname[0] != 0 ) reject = (strcmp(packetInfo.ipi_ifname, intf->intfName) != 0);
		else if ( packetInfo.ipi_ifindex != -1 )  reject = (packetInfo.ipi_ifindex != intf->index);

		if (reject)
			{
			verbosedebugf("SocketDataReady ignored a packet from %#a to %#a on interface %s/%d expecting %#a/%s/%d",
				&senderAddr, &destAddr, packetInfo.ipi_ifname, packetInfo.ipi_ifindex,
				&intf->coreIntf.ip, intf->intfName, intf->index);
			packetLen = -1;
			num_pkts_rejected++;
			if (num_pkts_rejected > (num_pkts_accepted + 1) * (num_registered_interfaces + 1) * 2)
				{
				fprintf(stderr,
					"*** WARNING: Received %d packets; Accepted %d packets; Rejected %d packets because of interface mismatch\n",
					num_pkts_accepted + num_pkts_rejected, num_pkts_accepted, num_pkts_rejected);
				num_pkts_accepted = 0;
				num_pkts_rejected = 0;
				}
			}
		else
			{
			verbosedebugf("SocketDataReady got a packet from %#a to %#a on interface %#a/%s/%d",
				&senderAddr, &destAddr, &intf->coreIntf.ip, intf->intfName, intf->index);
			num_pkts_accepted++;
			}
		}

	if (packetLen >= 0 && packetLen < (ssize_t)sizeof(DNSMessageHeader))
		{
		debugf("SocketDataReady packet length (%d) too short", packetLen);
		packetLen = -1;
		}

	if (packetLen >= 0)
		mDNSCoreReceive(m, &packet, (mDNSu8 *)&packet + packetLen,
			&senderAddr, senderPort, &destAddr, MulticastDNSPort, intf->coreIntf.InterfaceID, 255);
	}