This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
Re: What functions should I call in ethernet drv ?
Hello Gary and others,
I have learned ARP operation.
I've got "TCP/IP illustrated vol2" by W.Richard Stevens.
I have traced to ARP interpreting point.
First I breaked lan91cxx_recv() when received ARP packet,
and next breaked if_ethersubr.c's ether_input(ifp, eh, m) function.
And I traced into ether_demux().
ether_demux(ifp, eh, m)
594: switch (ether_type) {
595: #ifdef INET
596: case ETHERTYPE_IP:
597: if (ipflow_fastforward(m))
598: return;
599: schednetisr(NETISR_IP);
600: inq = &ipintrq;
601: break;
602:
603: case ETHERTYPE_ARP:
604: if (ifp->if_flags & IFF_NOARP) {
605: /* Discard packet if ARP is disabled on interface */
606: m_freem(m);
607: return;
608: }
609: schednetisr(NETISR_ARP);
610: inq = &arpintrq;
611: break;
and I found ether_type==0x0608,so couldn't recognize ARP.
I concluded entering data in little Endian is wrong,
so as a makeshift I amended source next.
First I concocted get_data_byte(struct eth_drv_sc *sc)
to get data exchangedly like I previously sent the coding.
And I alse concocted in cyg_uint16 get_data_short like below
to echange data.
1079: cyg_uint16 get_data_short(struct eth_drv_sc *sc)
1080: {
1081: cyg_uint16 val;
1082:
1083: val = get_data_byte(sc);
1084: //val |= get_data_byte(sc)<<8;
val = val<<8 | get_data_byte(sc); --I concocted to reverse
data.
1085:
1086: return CYG_LE16_TO_CPU(val);
1087: }
I know it's bad coding but as I said this is a makeshift and
I expect your best amended source.(on condition I was right)
Anyway I could continue debugging.
After that I confirmed that following interrrupt,
it entered in if_ether.c's arpintr().
Then I traced into in_arpinput(m), and
according to the book,here send ARP-reply.
My expectancy reached high.
But alas,in in_arpinput(m)
didn't go to the point of sending packet.
The reason was, in first part of coding,
529: in_arpinput(m)
530: struct mbuf *m;
531: {
532: register struct ether_arp *ea;
533: register struct arpcom *ac = (struct arpcom
*)m->m_pkthdr.rcvif;
534: struct ether_header *eh;
535: struct iso88025_header *th = (struct iso88025_header *)0;
536: register struct llinfo_arp *la = 0;
537: register struct rtentry *rt;
538: struct in_ifaddr *ia, *maybe_ia = 0;
539: struct sockaddr_dl *sdl;
540: struct sockaddr sa;
541: struct in_addr isaddr, itaddr, myaddr;
542: int op, rif_len;
543:
544: if (m->m_len < sizeof(struct ether_arp) &&
545: (m = m_pullup(m, sizeof(struct ether_arp))) == NULL) {
546: log(LOG_ERR, "in_arp: runt packet -- m_pullup
failed\n");
547: return;
548: }
549:
550: ea = mtod(m, struct ether_arp *);
551: op = ntohs(ea->arp_op);
552: (void)memcpy(&isaddr, ea->arp_spa, sizeof (isaddr));
553: (void)memcpy(&itaddr, ea->arp_tpa, sizeof (itaddr));
554: for (ia = in_ifaddrhead.tqh_first; ia; ia =
ia->ia_link.tqe_next) {
555: /*
556: * For a bridge, we want to check the address
irrespective
557: * of the receive interface. (This will change slightly
558: * when we have clusters of interfaces).
559: */
560: #ifdef BRIDGE
561: #define BRIDGE_TEST (do_bridge)
562: #else
563: #define BRIDGE_TEST (0) /* cc will optimise the test away */
564: #endif
565: if ((BRIDGE_TEST) || (ia->ia_ifp == &ac->ac_if)) {
566: maybe_ia = ia;
567: if ((itaddr.s_addr == ia->ia_addr.sin_addr.s_addr)
||
568: (isaddr.s_addr == ia->ia_addr.sin_addr.s_addr))
{
569: break;
570: }
571: }
572: }
573: if (maybe_ia == 0) {
574: m_freem(m);
575: return;
576: }
577: myaddr = ia ? ia->ia_addr.sin_addr :
maybe_ia->ia_addr.sin_addr; --ia,ª00
at 554 line,there was nothing in_ifaddrhead.tqh_first,
and at 577, ia became 00000000.
Here,Gary, I sincerely ask your opinion.
The trouble is there is nothing in in_ifaddrhead.tqh_first,
do you have any idea what caused this mishappening ?
I expect your any hints whatever.
Thanks in advance.
Masahiro Ariga
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss