// 接收处理ARP帧 void arp_accept(u8 *data, u32 plen) { arp_frm *arp_recv = (arp_frm *)data; if(plen >= ARP_FRMLEN) { ARP_DBP("Recv %d.%d.%d.%d ARP ", arp_recv->src_ip.inb[0], arp_recv->src_ip.inb[1], arp_recv->src_ip.inb[2], arp_recv->src_ip.inb[3]); // 添加源IP、MAC至ARP缓存表 arp_addlist(arp_recv->src_ip.inw, arp_recv->src_mac); if(htons(arp_recv->operation) == ARP_TYPE_REQ) { ARP_DBP("Request %d.%d.%d.%d\r\n", arp_recv->dst_ip.inb[0], arp_recv->dst_ip.inb[1], arp_recv->dst_ip.inb[2], arp_recv->dst_ip.inb[3]); if(arp_recv->dst_ip.inw == local.ip.inw) { ARP_DBP("Req Local IP. ARP Reply\r\n"); arp_reply(arp_recv); } } else if(htons(arp_recv->operation) == ARP_TYPE_REP) { ARP_DBP("Reply\r\n"); } } }
//---------------------------------------------------------------------------- //Check Packet and call Stack for TCP or UDP void check_packet (void) { struct Ethernet_Header *ethernet; //Pointer auf Ethernet_Header struct IP_Header *ip; //Pointer auf IP_Header struct TCP_Header *tcp; //Pointer auf TCP_Header struct ICMP_Header *icmp; //Pointer auf ICMP_Header ethernet = (struct Ethernet_Header *)ð_buffer[ETHER_OFFSET]; ip = (struct IP_Header *)ð_buffer[IP_OFFSET]; tcp = (struct TCP_Header *)ð_buffer[TCP_OFFSET]; icmp = (struct ICMP_Header *)ð_buffer[ICMP_OFFSET]; if(ethernet->EnetPacketType == HTONS(0x0806) ) //ARP { arp_reply(); // check arp packet request/reply } else { if( ethernet->EnetPacketType == HTONS(0x0800) ) // if IP { if( ip->IP_Destaddr == *((unsigned long*)&myip[0]) ) // if my IP address { arp_entry_add(); ///Refresh des ARP Eintrages if(ip->IP_Proto == PROT_ICMP) { switch ( icmp->ICMP_Type ) { case (8): //Ping reqest icmp_send(ip->IP_Srcaddr,0,0,icmp->ICMP_SeqNum,icmp->ICMP_Id); break; case (0): //Ping reply if ((*((unsigned long*)&ping.ip1[0])) == ip->IP_Srcaddr) { ping.result |= 0x01; } DEBUG("%i", (ip->IP_Srcaddr&0x000000FF) ); DEBUG(".%i", ((ip->IP_Srcaddr&0x0000FF00)>>8 )); DEBUG(".%i", ((ip->IP_Srcaddr&0x00FF0000)>>16)); DEBUG(".%i :",((ip->IP_Srcaddr&0xFF000000)>>24)); break; } return; } else { if( ip->IP_Proto == PROT_TCP ) tcp_socket_process(); if( ip->IP_Proto == PROT_UDP ) udp_socket_process(); } } else if (ip->IP_Destaddr == (unsigned long)0xffffffff ) // if broadcast
static void service_arp_queue(struct netpoll_info *npi) { struct sk_buff *skb; if (unlikely(!npi)) return; skb = skb_dequeue(&npi->arp_tx); while (skb != NULL) { arp_reply(skb); skb = skb_dequeue(&npi->arp_tx); } }
void rq_process(struct in_addr ipaddr, int ifindex) { RQ_ENTRY *cur_entry; RQ_ENTRY *prev_entry = NULL; pthread_mutex_lock(&arptab_mutex); parseproc(); processarp(0); pthread_mutex_unlock(&arptab_mutex); pthread_mutex_lock(&req_queue_mutex); cur_entry = req_queue; /* Walk through the list */ while (cur_entry != NULL) { if ( ipaddr.s_addr == *((long *) cur_entry->req_frame.arp.arp_tpa) && ifindex != cur_entry->req_if.sll_ifindex ) { if (debug) printf("Found %s in request queue\n", inet_ntoa(ipaddr)); arp_reply(&cur_entry->req_frame, &cur_entry->req_if); /* Delete entry from the linked list */ if (cur_entry == req_queue_tail) req_queue_tail = prev_entry; if (prev_entry != NULL) prev_entry->next = cur_entry->next; else req_queue = cur_entry->next; free(cur_entry); cur_entry = prev_entry; req_queue_len--; } if (cur_entry != NULL) { prev_entry = cur_entry; cur_entry = cur_entry->next; } } pthread_mutex_unlock(&req_queue_mutex); }
//---------------------------------------------------------------------------- //Check Packet and call Stack for TCP or UDP void check_packet (void) { //Pointer auf Ethernet_Header struct Ethernet_Header *ethernet; ethernet = (struct Ethernet_Header *)ð_buffer[ETHER_OFFSET]; //Pointer auf IP_Header struct IP_Header *ip; ip = (struct IP_Header *)ð_buffer[IP_OFFSET]; #if USE_PING //Pointer auf ICMP_Header struct ICMP_Header *icmp; icmp = (struct ICMP_Header *)ð_buffer[ICMP_OFFSET]; #endif if(ETHERNET_ARP_DATAGRAMM) { //Erzeugt ein ARP Reply Packet arp_reply(); } else { if(ETHERNET_IP_DATAGRAMM && IF_MYIP) { arp_entry_add(); //Refresh des ARP Eintrages #if USE_PING //Ist protokoll Byte = 1 dann ist es ein ICMP Packet if(IP_ICMP_PACKET) { switch ( icmp->ICMP_Type ) { case (0x08): //Echo-Request empfangen, erzeugen eines ICMP Reply Packet (PING Echo) icmp_send(ip->IP_Srcaddr,0x00,0x00,icmp->ICMP_SeqNum,icmp->ICMP_Id); break; case (0x00): //Echo-Reply Packet empfangen, Empfang melden //TODO: Erst Sequenznummer vergleichen?, Zeitmessung? DEBUG_WRITE("%i",(ip->IP_Srcaddr&0x000000FF)); DEBUG_WRITE(".%i",((ip->IP_Srcaddr&0x0000FF00)>>8)); DEBUG_WRITE(".%i",((ip->IP_Srcaddr&0x00FF0000)>>16)); DEBUG_WRITE(".%i",((ip->IP_Srcaddr&0xFF000000)>>24)); DEBUG_WRITE(": PONG!\r\n"); break; } return; } else #endif { if(IP_UDP_PACKET) udp_socket_process(); } }
/* * Returns 0 if this is the packet we're waiting for * else -1 (and errno == 0) */ int arprecv(struct nbuf *nbuf) { int n = nbuf->len; struct ether_arp *ah = nbuf->nh.arph; errno = 0; /* XXX */ if (n < 0 || n < sizeof(struct ether_arp)) { return (-1); } /* Ethernet address now checked in readether() */ if (ah->arp_hrd != htons(ARPHRD_ETHER) || ah->arp_pro != htons(ETHERTYPE_IP) || ah->arp_hln != sizeof(ah->arp_sha) || ah->arp_pln != sizeof(ah->arp_spa) ) { return (-1); } if (ah->arp_op == htons(ARPOP_REQUEST)) { arp_reply(nbuf); return (-1); } if (ah->arp_op != htons(ARPOP_REPLY)) { return (-1); } /* Is the reply from the source we want? */ if (bcmp(&arp_list[arp_num].addr, ah->arp_spa, sizeof(ah->arp_spa))) { return (-1); } /* We don't care who the reply was sent to. */ /* We have our answer. */ return (0); }
/* * Receive a UDP packet and validate it is for us. * Caller leaves room for the headers (Ether, IP, UDP) */ ssize_t readudp(struct iodesc *d, void *pkt, size_t len, time_t tleft) { ssize_t n; size_t hlen; struct ip *ip; struct udphdr *uh; struct udpiphdr *ui; struct ip tip; u_int16_t etype; /* host order */ #ifdef NET_DEBUG if (debug) printf("readudp: called\n"); #endif uh = (struct udphdr *)pkt - 1; ip = (struct ip *)uh - 1; n = readether(d, ip, len + sizeof(*ip) + sizeof(*uh), tleft, &etype); if (n < 0 || (size_t)n < sizeof(*ip) + sizeof(*uh)) return -1; /* Ethernet address checks now in readether() */ /* Need to respond to ARP requests. */ if (etype == ETHERTYPE_ARP) { struct arphdr *ah = (void *)ip; if (ah->ar_op == htons(ARPOP_REQUEST)) { /* Send ARP reply */ arp_reply(d, ah); } return -1; } if (etype != ETHERTYPE_IP) { #ifdef NET_DEBUG if (debug) printf("readudp: not IP. ether_type=%x\n", etype); #endif return -1; } /* Check ip header */ if (ip->ip_v != IPVERSION || ip->ip_p != IPPROTO_UDP) { /* half char */ #ifdef NET_DEBUG if (debug) printf("readudp: IP version or not UDP. ip_v=%d ip_p=%d\n", ip->ip_v, ip->ip_p); #endif return -1; } hlen = ip->ip_hl << 2; if (hlen < sizeof(*ip) || in_cksum(ip, hlen) != 0) { #ifdef NET_DEBUG if (debug) printf("readudp: short hdr or bad cksum.\n"); #endif return -1; } NTOHS(ip->ip_len); if (n < ip->ip_len) { #ifdef NET_DEBUG if (debug) printf("readudp: bad length %d < %d.\n", n, ip->ip_len); #endif return -1; } if (d->myip.s_addr && ip->ip_dst.s_addr != d->myip.s_addr) { #ifdef NET_DEBUG if (debug) { printf("readudp: bad saddr %s != ", inet_ntoa(d->myip)); printf("%s\n", inet_ntoa(ip->ip_dst)); } #endif return -1; } /* If there were ip options, make them go away */ if (hlen != sizeof(*ip)) { bcopy(((u_char *)ip) + hlen, uh, len - hlen); ip->ip_len = sizeof(*ip); n -= hlen - sizeof(*ip); } if (uh->uh_dport != d->myport) { #ifdef NET_DEBUG if (debug) printf("readudp: bad dport %d != %d\n", d->myport, ntohs(uh->uh_dport)); #endif return -1; } if (uh->uh_sum) { n = ntohs(uh->uh_ulen) + sizeof(*ip); if (n > RECV_SIZE - ETHER_SIZE) { printf("readudp: huge packet, udp len %ld\n", (long)n); return -1; } /* Check checksum (must save and restore ip header) */ tip = *ip; ui = (struct udpiphdr *)ip; bzero(ui->ui_x1, sizeof(ui->ui_x1)); ui->ui_len = uh->uh_ulen; if (in_cksum(ui, n) != 0) { #ifdef NET_DEBUG if (debug) printf("readudp: bad cksum\n"); #endif *ip = tip; return -1; } *ip = tip; } NTOHS(uh->uh_dport); NTOHS(uh->uh_sport); NTOHS(uh->uh_ulen); if (uh->uh_ulen < sizeof(*uh)) { #ifdef NET_DEBUG if (debug) printf("readudp: bad udp len %d < %d\n", uh->uh_ulen, sizeof(*uh)); #endif return -1; } n -= sizeof(*ip) + sizeof(*uh); return (n); }
int process_rx_packet(uint8_t *pu8Packet, uint32_t u32Len) { ARP_PACKET *arp = (ARP_PACKET *)pu8Packet; IP_PACKET *ip = (IP_PACKET *)pu8Packet; UDP_PACKET *udp = (UDP_PACKET *)pu8Packet; if (pu8Packet[0] == 0xFF) { /* this is a broadcast packet */ /* * We manage the ARP reply process here. * In the following code, if we have received a ARP request, * we send ARP reply immediately. */ if ((!COMPARE_IP(arp->au8TargetIP, g_au8IpAddr)) && (arp->u16Type == SWAP16(PROTOCOL_ARP)) && (arp->u16Operation == SWAP16(ARP_REQUEST))) { arp_reply(arp->su8SenderIP, arp->au8SenderHA); } return 0; } else { /* this is a multicast or unicast packet */ /* * This is a unicast packet to us. */ if ((ip->u8Prot == IP_PRO_TCP) && (!COMPARE_IP(ip->au8DestIP, g_au8IpAddr))) { // write me: process TCP packets here return 0; } if ((ip->u8Prot == IP_PRO_UDP) && (udp->u16SrcPort == SWAP16(67))) { // This is a DHCP packet... s_u32PktRdy = u32Len; memcpy(au8RxBuf, pu8Packet, u32Len); return 0; } if ((ip->u8Prot == IP_PRO_UDP) && (!COMPARE_IP(ip->au8DestIP, g_au8IpAddr))) { // write me: process UDP packets here return 0; } /* * Check ICMP Echo Request packet - * if matched, we reply it right here */ if ((ip->u8Prot == IP_PRO_ICMP) && (!COMPARE_IP(ip->au8DestIP, g_au8IpAddr)) && (pu8Packet[34] == 0x08)) { IP_PACKET *tx_ip; /* duplicate packet then modify it */ memcpy((char *)&au8TxBuf[0], (char *)&pu8Packet[0], u32Len); tx_ip = (IP_PACKET *)&au8TxBuf[0]; memcpy((char *)tx_ip->au8DestMac, (char *)ip->au8SrcMac, 6); memcpy((char *)tx_ip->au8SrcMac, (char *)g_au8MacAddr, 6); tx_ip->u16Type = SWAP16(PROTOCOL_IP); tx_ip->u8VerHLen = 0x45; /* fixed value, do not change it */ tx_ip->u8ToS = 0; /* no special priority */ tx_ip->u16TLen = SWAP16(60); tx_ip->u16ID = SWAP16(s_u16IpPacketId); tx_ip->u16Frag = 0; tx_ip->u8TTL = 64; tx_ip->u8Prot = IP_PRO_ICMP; tx_ip->u16HdrChksum = 0; memcpy((char *)tx_ip->au8SrcIP, (char *)g_au8IpAddr, 4); memcpy((char *)tx_ip->au8DestIP, (char *)ip->au8SrcIP, 4); tx_ip->u16HdrChksum = ~chksum((uint16_t *)&tx_ip->u8VerHLen, 10); /* 20 bytes */ s_u16IpPacketId++; /* ICMP reply */ au8TxBuf[34] = 0; /* ICMP checksum */ au8TxBuf[36] = 0; au8TxBuf[37] = 0; *(uint16_t *)&au8TxBuf[36] = ~chksum((uint16_t *)&au8TxBuf[34], (u32Len - 34) / 2); EMAC_SendPkt(au8TxBuf, u32Len); return 0; } } return 0; }
/* * reads an IP packet * WARNING: the old version stripped the IP options, if there were * any. Because we have absolutely no idea if the upper layer needs * these or not, it's best to leave them there. * * The size returned is the size indicated in the header. */ ssize_t readip(struct iodesc * d, void *pkt, size_t len, time_t tleft, u_int8_t proto) { ssize_t n; size_t hlen; struct ip *ip; u_int16_t etype; ip = (struct ip *) pkt - 1; n = readether(d, ip, len + sizeof(*ip), tleft, &etype); if (n == -1 || (size_t) n < sizeof(*ip)) return -1; if (etype == ETHERTYPE_ARP) { struct arphdr *ah = (void *) ip; if (ah->ar_op == htons(ARPOP_REQUEST)) { /* Send ARP reply */ arp_reply(d, ah); } return -1; } if (etype != ETHERTYPE_IP) { #ifdef NET_DEBUG if (debug) printf("readip: not IP. ether_type=%x\n", etype); #endif return -1; } /* Check ip header */ if (ip->ip_v != IPVERSION || ip->ip_p != proto) { /* half char */ #ifdef NET_DEBUG if (debug) { printf("readip: wrong IP version or wrong proto " "ip_v=%d ip_p=%d\n", ip->ip_v, ip->ip_p); } #endif return -1; } hlen = ip->ip_hl << 2; if (hlen < sizeof(*ip) || ip_cksum(ip, hlen) != 0) { #ifdef NET_DEBUG if (debug) printf("readip: short hdr or bad cksum.\n"); #endif return -1; } if (n < ntohs(ip->ip_len)) { #ifdef NET_DEBUG if (debug) printf("readip: bad length %d < %d.\n", (int) n, ntohs(ip->ip_len)); #endif return -1; } if (d->myip.s_addr && ip->ip_dst.s_addr != d->myip.s_addr) { #ifdef NET_DEBUG if (debug) { printf("readip: bad saddr %s != ", inet_ntoa(d->myip)); printf("%s\n", inet_ntoa(ip->ip_dst)); } #endif return -1; } return (ntohs(ip->ip_len) - 20); }
void incoming_arp(VCC *vcc,struct atmarphdr *hdr,int len) { ITF *itf; ENTRY *entry; void *sha,*ssa,*spa,*tha,*tsa,*tpa; struct sockaddr_atmsvc source,target; uint32_t src_ip,tgt_ip; unsigned char *here; if (len < hdr->data-(unsigned char *) hdr) { diag(COMPONENT,DIAG_ERROR,"got truncated ARP packet (%d bytes)",len); return; } if (hdr->ar_hrd != htons(ARPHRD_ATM)) { diag(COMPONENT,DIAG_ERROR,"unknown hw protocol 0x%04x", ntohs(hdr->ar_hrd)); return; } if (hdr->ar_pro != htons(ETH_P_IP)) { diag(COMPONENT,DIAG_ERROR,"unknown upper protocol 0x%04x", ntohs(hdr->ar_pro)); return; } if (!(hdr->ar_shtl & TL_LEN)) hdr->ar_shtl = 0; /* paranoia */ if (!(hdr->ar_thtl & TL_LEN)) hdr->ar_thtl = 0; here = hdr->data; sha = get_addr(&here,hdr->ar_shtl & TL_LEN); ssa = get_addr(&here,hdr->ar_sstl & TL_LEN); spa = get_addr(&here,hdr->ar_spln); tha = get_addr(&here,hdr->ar_thtl & TL_LEN); tsa = get_addr(&here,hdr->ar_tstl & TL_LEN); tpa = get_addr(&here,hdr->ar_tpln); if (here-(unsigned char *) hdr > len) { diag(COMPONENT,DIAG_ERROR,"message too short (got %d, need %d)",len, here-(unsigned char *) hdr); return; } set_addr(&source,sha,ssa,hdr->ar_shtl,hdr->ar_sstl); set_addr(&target,tha,tsa,hdr->ar_thtl,hdr->ar_tstl); src_ip = get_ip(spa); tgt_ip = get_ip(tpa); { unsigned char *ipp; char buffer[MAX_ATM_ADDR_LEN+1]; ipp = (unsigned char *) &src_ip; diag(COMPONENT,DIAG_DEBUG," SRC IP: %d.%d.%d.%d",ipp[0],ipp[1],ipp[2], ipp[3]); if (atm2text(buffer,MAX_ATM_ADDR_LEN+1,(struct sockaddr *) &source,pretty) >= 0) diag(COMPONENT,DIAG_DEBUG," SRC ATM: %s",buffer); ipp = (unsigned char *) &tgt_ip; diag(COMPONENT,DIAG_DEBUG," DST IP: %d.%d.%d.%d",ipp[0],ipp[1],ipp[2], ipp[3]); if (atm2text(buffer,MAX_ATM_ADDR_LEN+1,(struct sockaddr *) &target,pretty) >= 0) diag(COMPONENT,DIAG_DEBUG," DST ATM: %s",buffer); } switch (ntohs(hdr->ar_op)) { case ARPOP_REQUEST: diag(COMPONENT,DIAG_DEBUG,"got ARP_REQ"); if (learn(vcc,src_ip,&source)) break; entry = NULL; itf = lookup_itf_by_ip(tgt_ip); entry = itf ? lookup_ip(itf,tgt_ip) : NULL; if (entry && entry->state == as_valid && (entry->flags & ATF_PUBL)) { if (entry->addr) arp_reply(vcc,tgt_ip,entry->addr,src_ip,&source); else arp_nak(vcc,tgt_ip,src_ip,&source); } else { if (itf && itf->local_ip == tgt_ip) arp_reply(vcc,tgt_ip,NULL,src_ip,&source); else arp_nak(vcc,tgt_ip,src_ip,&source); } break; case ARPOP_REPLY: diag(COMPONENT,DIAG_DEBUG,"got ARP_REP"); if (!vcc->entry || !(vcc->entry->flags & ATF_ARPSRV)) { diag(COMPONENT,DIAG_ERROR,"got ARP response from charlatan"); break; } (void) learn(NULL,src_ip,&source); break; case ARPOP_InREQUEST: diag(COMPONENT,DIAG_DEBUG,"got InARP_REQ"); if (!learn(vcc,src_ip,&source)) inarp_reply(vcc,src_ip,&source); break; case ARPOP_InREPLY: diag(COMPONENT,DIAG_DEBUG,"got InARP_REP"); (void) learn(vcc,src_ip,&source); break; case ARPOP_NAK: diag(COMPONENT,DIAG_DEBUG,"got ARP_NAK"); if (!vcc->entry || !(vcc->entry->flags & ATF_ARPSRV)) { diag(COMPONENT,DIAG_ERROR,"got ARP response from charlatan"); break; } learn_nak(tgt_ip); break; default: diag(COMPONENT,DIAG_ERROR,"unrecognized ARP op 0x%x", ntohs(hdr->ar_op)); } }
//---------------------------------------------------------------------------- //ETH get data void eth_get_data (void) { if(eth.timer) { tcp_timer_call(); arp_timer_call(); eth.timer = 0; } if(eth.data_present) { #if USE_ENC28J60 while(ETH_INT_ACTIVE) { #endif #if USE_RTL8019 if ( (ReadRTL(RTL_ISR)&(1<<OVW)) != 0) { DEBUG ("Overrun!\n"); } if ( (ReadRTL(RTL_ISR) & (1<<PRX)) != 0) { unsigned char ByteH = 0; unsigned char ByteL = 1; while (ByteL != ByteH) //(!= bedeutet ungleich) { #endif unsigned int packet_length; packet_length = ETH_PACKET_RECEIVE(MTU_SIZE,eth_buffer); if(packet_length > 0) { eth_buffer[packet_length+1] = 0; check_packet(); } #if USE_RTL8019 //auslesen des Empfangsbuffer BNRY = CURR ByteL = ReadRTL(BNRY); //auslesen NIC Register bnry WriteRTL ( CR ,(1<<STA|1<<RD2|1<<PS0)); ByteH = ReadRTL(CURR); //auslesen NIC Register curr WriteRTL ( CR ,(1<<STA|1<<RD2)); } #endif } #if USE_RTL8019 Networkcard_INT_RES(); Networkcard_Start(); #endif eth.data_present = 0; ETH_INT_ENABLE; } return; } //---------------------------------------------------------------------------- //Check Packet and call Stack for TCP or UDP void check_packet (void) { struct Ethernet_Header *ethernet; //Pointer auf Ethernet_Header struct IP_Header *ip; //Pointer auf IP_Header struct TCP_Header *tcp; //Pointer auf TCP_Header struct ICMP_Header *icmp; //Pointer auf ICMP_Header ethernet = (struct Ethernet_Header *)ð_buffer[ETHER_OFFSET]; ip = (struct IP_Header *)ð_buffer[IP_OFFSET]; tcp = (struct TCP_Header *)ð_buffer[TCP_OFFSET]; icmp = (struct ICMP_Header *)ð_buffer[ICMP_OFFSET]; if(ethernet->EnetPacketType == HTONS(0x0806) ) //ARP { arp_reply(); // check arp packet request/reply } else { if( ethernet->EnetPacketType == HTONS(0x0800) ) // if IP { if( ip->IP_Destaddr == *((unsigned long*)&myip[0]) ) // if my IP address { arp_entry_add(); ///Refresh des ARP Eintrages if(ip->IP_Proto == PROT_ICMP) { switch ( icmp->ICMP_Type ) { case (8): //Ping reqest icmp_send(ip->IP_Srcaddr,0,0,icmp->ICMP_SeqNum,icmp->ICMP_Id); break; case (0): //Ping reply if ((*((unsigned long*)&ping.ip1[0])) == ip->IP_Srcaddr) { ping.result |= 0x01; } DEBUG("%i", (ip->IP_Srcaddr&0x000000FF) ); DEBUG(".%i", ((ip->IP_Srcaddr&0x0000FF00)>>8 )); DEBUG(".%i", ((ip->IP_Srcaddr&0x00FF0000)>>16)); DEBUG(".%i :",((ip->IP_Srcaddr&0xFF000000)>>24)); break; } return; } else { if( ip->IP_Proto == PROT_TCP ) tcp_socket_process(); if( ip->IP_Proto == PROT_UDP ) udp_socket_process(); } } else if (ip->IP_Destaddr == (unsigned long)0xffffffff || ip->IP_Destaddr == *((unsigned long*)&broadcast_ip[0]) ) // if broadcast { if( ip->IP_Proto == PROT_UDP ) udp_socket_process(); } }
/* * Returns 0 if this is the packet we're waiting for * else -1 (and errno == 0) */ static ssize_t arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra) { ssize_t n; struct ether_arp *ah; uint16_t etype; /* host order */ void *ptr; #ifdef ARP_DEBUG if (debug) printf("arprecv: "); #endif ptr = NULL; n = readether(d, &ptr, (void **)&ah, tleft, &etype); errno = 0; /* XXX */ if (n == -1 || n < sizeof (struct ether_arp)) { #ifdef ARP_DEBUG if (debug) printf("bad len=%d\n", n); #endif free(ptr); return (-1); } if (etype != ETHERTYPE_ARP) { #ifdef ARP_DEBUG if (debug) printf("not arp type=%d\n", etype); #endif free(ptr); return (-1); } /* Ethernet address now checked in readether() */ if (ah->arp_hrd != htons(ARPHRD_ETHER) || ah->arp_pro != htons(ETHERTYPE_IP) || ah->arp_hln != sizeof (ah->arp_sha) || ah->arp_pln != sizeof (ah->arp_spa)) { #ifdef ARP_DEBUG if (debug) printf("bad hrd/pro/hln/pln\n"); #endif free(ptr); return (-1); } if (ah->arp_op == htons(ARPOP_REQUEST)) { #ifdef ARP_DEBUG if (debug) printf("is request\n"); #endif arp_reply(d, ah); free(ptr); return (-1); } if (ah->arp_op != htons(ARPOP_REPLY)) { #ifdef ARP_DEBUG if (debug) printf("not ARP reply\n"); #endif free(ptr); return (-1); } /* Is the reply from the source we want? */ if (bcmp(&arp_list[arp_num].addr, ah->arp_spa, sizeof (ah->arp_spa))) { #ifdef ARP_DEBUG if (debug) printf("unwanted address\n"); #endif free(ptr); return (-1); } /* We don't care who the reply was sent to. */ /* We have our answer. */ #ifdef ARP_DEBUG if (debug) printf("got it\n"); #endif *pkt = ptr; *payload = ah; return (n); }