예제 #1
0
static int ping_send(void)
{
	uchar *pkt;
	int eth_hdr_size;

	/* XXX always send arp request */

	debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &NetPingIP);

	NetArpWaitPacketIP = NetPingIP;

	eth_hdr_size = NetSetEther(NetTxPacket, NetEtherNullAddr, PROT_IP);
	pkt = (uchar *)NetTxPacket + eth_hdr_size;

	set_icmp_header(pkt, NetPingIP);

	/* size of the waiting packet */
	NetArpWaitTxPacketSize = eth_hdr_size + IP_ICMP_HDR_SIZE;

	/* and do the ARP request */
	NetArpWaitTry = 1;
	NetArpWaitTimerStart = get_timer(0);
	ArpRequest();
	return 1;	/* waiting */
}
예제 #2
0
파일: eth.c 프로젝트: FFalcon/osdev
// ------------------------------------------------------------------------------------------------
void EthSendIntf(NetIntf *intf, const void *dstAddr, u16 etherType, NetBuf *pkt)
{
    // Determine ethernet address by protocol of packet
    const EthAddr *dstEthAddr = 0;

    switch (etherType)
    {
    case ET_ARP:
        dstEthAddr = (const EthAddr *)dstAddr;
        break;

    case ET_IPV4:
        {
            const Ipv4Addr *dstIpv4Addr = (const Ipv4Addr *)dstAddr;

            if (Ipv4AddrEq(dstIpv4Addr, &g_broadcastIpv4Addr) ||
                Ipv4AddrEq(dstIpv4Addr, &intf->broadcastAddr))
            {
                // IP Broadcast -> Ethernet Broacast
                dstEthAddr = &g_broadcastEthAddr;
            }
            else
            {
                // Lookup Ethernet address in ARP cache
                dstEthAddr = ArpLookupEthAddr(dstIpv4Addr);
                if (!dstEthAddr)
                {
                    ArpRequest(intf, dstIpv4Addr, etherType, pkt);
                    return;
                }
            }
        }
        break;

    case ET_IPV6:
        break;
    }

    // Skip packets without a destination
    if (!dstEthAddr)
    {
        ConsolePrint("Dropped packet\n");
        return;
    }

    // Fill in ethernet header
    pkt->start -= sizeof(EthHeader);

    EthHeader *hdr = (EthHeader *)pkt->start;
    hdr->dst = *dstEthAddr;
    hdr->src = intf->ethAddr;
    hdr->etherType = NetSwap16(etherType);

    // Transmit
    EthPrint(pkt);
    intf->devSend(pkt);
}
예제 #3
0
파일: net.c 프로젝트: KunYi/uboot-samx6i
int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport,
		int payload_len)
{
	uchar *pkt;
	int eth_hdr_size;
	int pkt_hdr_size;

	/* make sure the NetTxPacket is initialized (NetInit() was called) */
	assert(NetTxPacket != NULL);
	if (NetTxPacket == NULL)
		return -1;

	/* convert to new style broadcast */
	if (dest == 0)
		dest = 0xFFFFFFFF;

	/* if broadcast, make the ether address a broadcast and don't do ARP */
	if (dest == 0xFFFFFFFF)
		ether = NetBcastAddr;

	pkt = (uchar *)NetTxPacket;

	eth_hdr_size = NetSetEther(pkt, ether, PROT_IP);
	pkt += eth_hdr_size;
	net_set_udp_header(pkt, dest, dport, sport, payload_len);
	pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE;

	/* if MAC address was not discovered yet, do an ARP request */
	if (memcmp(ether, NetEtherNullAddr, 6) == 0) {
		debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &dest);

		/* save the ip and eth addr for the packet to send after arp */
		NetArpWaitPacketIP = dest;
		NetArpWaitPacketMAC = ether;

		/* size of the waiting packet */
		NetArpWaitTxPacketSize = pkt_hdr_size + payload_len;

		/* and do the ARP request */
		NetArpWaitTry = 1;
		NetArpWaitTimerStart = get_timer(0);
		ArpRequest();
		return 1;	/* waiting */
	} else {
		debug_cond(DEBUG_DEV_PKT, "sending UDP to %pI4/%pM\n",
			&dest, ether);
		NetSendPacket(NetTxPacket, pkt_hdr_size + payload_len);
		return 0;	/* transmitted */
	}
}
예제 #4
0
void ArpTimeoutCheck(void)
{
	ulong t;

	if (!NetArpWaitPacketIP)
		return;

	t = get_timer(0);

	/* check for arp timeout */
	if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT) {
		NetArpWaitTry++;

		if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) {
			puts("\nARP Retry count exceeded; starting again\n");
			NetArpWaitTry = 0;
			NetStartAgain();
		} else {
			NetArpWaitTimerStart = t;
			ArpRequest();
		}
	}
}