1 / 26

3.3 Ethernet Definitions

/* ether.h */ #define EPT_LOOP 0x0060 /* type: Loopback */ #define EPT_ECHO 0x0200 /* type: Echo */ #define EPT_PUP 0x0400 /* type: Xerox PUP */ #define EPT_IP 0x0800 /* type: Internet Protocol */ #define EPT_ARP 0x0806 /* type: ARP */

jolie
Télécharger la présentation

3.3 Ethernet Definitions

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. /* ether.h */ #define EPT_LOOP 0x0060 /* type: Loopback */ #define EPT_ECHO 0x0200 /* type: Echo */ #define EPT_PUP 0x0400 /* type: Xerox PUP */ #define EPT_IP 0x0800 /* type: Internet Protocol */ #define EPT_ARP 0x0806 /* type: ARP */ #define EPT_RARP 0x8035 /* type: Reverse ARP */ struct eh { /* ethernet header */ Eaddr eh_dst; /* destination host address */ Eaddr eh_src; /* source host address */ unsigned short eh_type;/* Ethernet packet type (see below) */ }; struct ep { /* complete structure of Ethernet packet*/ struct eh ep_eh; /* the ethernet header */ char ep_data[EP_DLEN]; /* data in the packet */ }; #define ep_dst ep_eh.eh_dst #define ep_src ep_eh.eh_src #define ep_type ep_eh.eh_type 3.3 Ethernet Definitions

  2. Demultiplexing Incoming Packets /* ni_in.c - ni_in */ int ni_in(struct netif *pni, struct ep *pep, unsigned len) { switch (pep->ep_type) { case EPT_ARP: rv = arp_in(pni, pep); break; case EPT_RARP: rv = rarp_in(pni, pep); break; case EPT_IP: rv = ip_in(pni, pep); break; default: pni->ni_iunkproto++; freebuf(pep); rv = OK; } return rv; }

  3. Address Discovery and Binding (ARP) ARP binds high-level IP addresses to low-level physical addresses. Address binding software forms a boundary between higher layers of protocol software, which use IP addresses, and lower layers of device driver software, which use hardware addresses. ARP is considered residing in the network interface layer. UDP TCP IP IGMP ICMP ARP Network Interface RARP

  4. Network Byte Order - Big Endian: lowest memory address holds high-order byte of the integer -Little Endian: lowest memory address contains low-order byte of the integer - Internet standard byte order: integers are sent most significant byte first (Big Endian style). (p.69, Vol.1) 0x128c n n n+1 n+1 0x12 0x8c 0x8c 0x12 Little endian Big endian

  5. ARP Packet Format H/W Type Protocol Type HLen. PLen. ARP Operation Sender Hardware Address Sender Protocol Address Target Hardware Address Target Protocol Address /* arp.h - SHA, SPA, THA, TPA */ #define AR_HARDWARE 1 /* Ethernet hardware type code */ /* Definitions of codes used in operation field of ARP packet */ #define AR_REQUEST 1 /* ARP request to resolve address*/ #define AR_REPLY 2 /* reply to a resolve request */ #define RA_REQUEST 3 /* reverse ARP request (RARP packets)*/ #define RA_REPLY 4 /* reply to a reverse request (RARP ")*/ struct arp { u_short ar_hwtype; /* hardware type */ u_short ar_prtype; /* protocol type */ u_char ar_hwlen; /* hardware address length */ u_char ar_prlen; /* protocol address length */ u_short ar_op; /* ARP operation (see list above)*/ u_char ar_addrs[1];/* sender and target hw & proto addrs*/ /* char ar_sha[???]; - sender's physical hardware address*/ /* char ar_spa[???]; - sender's protocol address (IP addr.)*/ /* char ar_tha[???]; - target's physical hardware address*/ /* char ar_tpa[???]; - target's protocol address (IP) */ }; #define SHA(p) (&p->ar_addrs[0]) #define SPA(p) (&p->ar_addrs[p->ar_hwlen]) #define THA(p) (&p->ar_addrs[p->ar_hwlen + p->ar_prlen]) #define TPA(p) (&p->ar_addrs[(p->ar_hwlen*2) + p->ar_prlen])

  6. ARP Cache Table struct arpentry { /* format of entry in ARP cache*/ short ae_state;/* state of this entry (see below)*/ int ae_queue; /* queue of packets for this address*/ int ae_attempts;/* number of retries so far */ int ae_ttl; /* time to live */ u_char ae_hwa[MAXHWALEN]; /* Hardware address*/ u_char ae_pra[MAXPRALEN]; /* Protocol address */ }; #define AS_FREE 0 /* Entry is unused (initial value)*/ #define AS_PENDING 1 /* Entry is used but incomplete*/ #define AS_RESOLVED 2 /* Entry has been resolved*/ /* ARP variables */ extern struct arpentry arptable[ARP_TSIZE]; /* ARP function declarations */

  7. ARP Input Processing arp_in( ) { translate the big endian to little endian; pae=arpfind(using SA-IP); if(arp-table have the entry of the SA-IP of incoming ARP data} {update entry; update entry timer;} if (ARP.target IP =! My IP) freebuf(pep); return(ok); if(pae ==0) arpadd( ); if(pae->state == AS_PENDING) {pae->state = AS_RESOLVED; arpqsend(); } if(receive an ARP Request) { to form a ARP Reply packet; send an ARP Reply; } } #if BYTE_ORDER == LITTLE_ENDIAN #define hs2net(x) (unsigned) ((((x)>>8) &0xff) | (((x) & 0xff)<<8)) #define net2hs(x) hs2net(x) #define hl2net(x) (((((x)& 0xff)<<24) | ((x)>>24) & 0xff) | \ (((x) & 0xff0000)>>8) | (((x) & 0xff00)<<8)) #define net2hl(x) hl2net(x) #endif #if BYTE_ORDER == BIG_ENDIAN #define hs2net(x) (x) #define net2hs(x) (x) #define hl2net(x) (x) #define net2hl(x) (x) #endif

  8. /* arpfind.c - arpfind */ #include <conf.h> #include <kernel.h> #include <network.h> /*------------------------------------------------------------------------ * arpfind - find an ARP entry given a protocol address and interface *------------------------------------------------------------------------ */ struct arpentry * arpfind(u_char *pra, u_short prtype, struct netif *pni) { struct arpentry *pae; int i; for (i=0; i<ARP_TSIZE; ++i) { pae = &arptable[i]; if (pae->ae_state == AS_FREE) continue; if (pae->ae_prtype == prtype && pae->ae_pni == pni && BLKEQU(pae->ae_pra, pra, pae->ae_prlen)) return pae; } return 0; }

  9. /* arpsend.c - arpsend */ int arpsend(struct arpentry *pae) { struct netif *pni = pae->ae_pni; struct ep *pep; struct arp *parp; int arplen; pep = (struct ep *) getbuf(Net.netpool); if ((int)pep == SYSERR) return SYSERR; memcpy(pep->ep_dst, pni->ni_hwb.ha_addr, pae->ae_hwlen); pep->ep_type = EPT_ARP; pep->ep_order = EPO_NET; parp = (struct arp *) pep->ep_data; parp->ar_hwtype = hs2net(pae->ae_hwtype); parp->ar_prtype = hs2net(pae->ae_prtype); parp->ar_hwlen = pae->ae_hwlen; parp->ar_prlen = pae->ae_prlen; parp->ar_op = hs2net(AR_REQUEST); memcpy(SHA(parp), pni->ni_hwa.ha_addr, pae->ae_hwlen); memcpy(SPA(parp), &pni->ni_ip, pae->ae_prlen); memset(THA(parp), 0, pae->ae_hwlen); memcpy(TPA(parp), pae->ae_pra, pae->ae_prlen); arplen = ARP_HLEN + 2*(parp->ar_hwlen + parp->ar_prlen); write(pni->ni_dev, pep, EP_HLEN+arplen); return OK; }

  10. /* arpadd.c - arpadd */ struct arpentry *arpalloc(void); /*------------------------------------------------------------------------ * arpadd - Add a RESOLVED entry to the ARP cache * N.B. Assumes interrupts disabled *------------------------------------------------------------------------ */ struct arpentry * arpadd(struct netif *pni, struct arp *parp) { struct arpentry *pae; pae = arpalloc(); pae->ae_hwtype = parp->ar_hwtype; pae->ae_prtype = parp->ar_prtype; pae->ae_hwlen = parp->ar_hwlen; pae->ae_prlen = parp->ar_prlen; pae->ae_pni = pni; pae->ae_queue = EMPTY; memcpy(pae->ae_hwa, SHA(parp), parp->ar_hwlen); memcpy(pae->ae_pra, SPA(parp), parp->ar_prlen); pae->ae_ttl = ARP_TIMEOUT; pae->ae_state = AS_RESOLVED; return pae; }

  11. /* arpqsend.c - arpqsend */ int netwrite(struct netif *, struct ep *, unsigned); /*------------------------------------------------------------------------ * arpqsend - write packets queued waiting for an ARP resolution *------------------------------------------------------------------------ */ void arpqsend(struct arpentry *pae) { struct ep *pep; struct netif *pni; if (pae->ae_queue == EMPTY) return; pni = pae->ae_pni; while (pep = (struct ep *)deq(pae->ae_queue)) netwrite(pni, pep, pep->ep_len); freeq(pae->ae_queue); pae->ae_queue = EMPTY; }

  12. ARP Output Processing netwrite( ) { if (DA_IP is broadcast) { DA_MAC = NIC’s H/W broadcast address ; write ( ); return ok; } pae = arpfind(); if (pae && AS_RESOLVED) { DA_MAC = ARP_entry’s_H/W address; return write( ); } if (pae == 0) { arpalloc ( ); arpsend ( ); } enq(pae->ae_queue, pep, 0) return OK; }

  13. Interface for Net 1 Interface for Net N IP GLOBAL Software Organization Datagrams sent to IP from local host Message queue IP Process Queues for packets sent to IP …. Interface for local host

  14. Policy for Selecting Incoming Datagrams • The IP code that choose a datagram to route implements an important policy: it decides the relative priorities of the datagram sources. • Local vs. network in priority assignment. • Round-robin is fair. /* implemented using static type */ • ipgetp /* message queue is used for process synchronization, not as a FIFO */ • When all input queues are empty, the IP process blocks in a call to procedure ipgetp.

  15. /* ipgetp.c - ipgetp */ static int ifnext = NI_LOCAL; /*------------------------------------------------------------------------ * ipgetp -- choose next IP input queue and extract a packet *----------------------------------------------------------------------*/ struct ep * ipgetp(int *pifnum) { struct ep *pep; int i; recvclr(); /* make sure no old messages are waiting */ while (TRUE) { for (i=0; i < Net.nif; ++i, ++ifnext) { if (ifnext >= Net.nif) ifnext = 0; if (nif[ifnext].ni_state == NIS_DOWN) continue; if (pep = NIGET(ifnext)) { *pifnum = ifnext; return pep; } } ifnext = receive(); } /* can't reach here */ }

  16. /* ipproc.c - ipproc */ struct ep *ipgetp(int *); struct route *rtget(IPaddr, Bool); PROCESS ipproc(void) { struct ep *pep; struct ip *pip; struct route *prt; Bool nonlocal; int ifnum; while (TRUE) { pep = ipgetp(&ifnum); //ifnum and pep are return values pip = (struct ip *)pep->ep_data; // change the structure if ((pip->ip_verlen>>4) != IP_VERSION) { not ipv4, continue} if (cksum((WORD *)pip, IP_HLEN(pip))) { checksum error continue; } ipnet2h(pip); //big endian to little endian ipputp(prt->rt_ifnum, pip->ip_dst, pep); }

  17. Checksum Computation /* cksum.c - cksum */ unsigned short cksum(buf, nwords) unsigned short *buf; int nwords; { unsigned long sum; for (sum=0; nwords>0; nwords--) sum += *buf++; sum = (sum >> 16) + (sum & 0xffff); /* add in carry */ sum += (sum >> 16); /* maybe one more */ return (unsigned short)~sum; }

  18. Byte Ordering • Before sending a datagram, the host must convert all integers from the local machine byte order to standard network byte order; upon receiving a datagram, the host must convert integers from standard network byte order to the local machine byte order • To optimize processing time, store all IP addresses in network byte order. • typedef unsigned long Ipaddr; #if BYTE_ORDER == LITTLE_ENDIAN IPaddr ip_loopback =0x0100007f; #else /* BYTE-ORDER */ IPaddr ip_loopback = 0x7f000001; #endif

  19. Sending a Datagram to IP for local host • ipsend : given a locally generated datagram and an IP destination address, ipsend fills in the IP header and enqueues the datagram on the local host interface, where IP process will extract and send it. • ip_in: sending incoming IP datagram from network to IP process.

  20. /* ipsend.c - ipsend */ static ipackid = 1; int ipsend(IPaddr faddr, struct ep *pep, unsigned datalen, u_char proto, u_char ptos, u_char ttl) { struct ip *pip = (struct ip *) pep->ep_data; pep->ep_type = EPT_IP; pep->ep_order |= EPO_IP|EPO_NET; pip->ip_verlen = (IP_VERSION<<4) | IP_MINHLEN; pip->ip_tos = ptos; pip->ip_len = datalen+IP_HLEN(pip); pip->ip_id = ipackid++; pip->ip_fragoff = 0; pip->ip_ttl = ttl; pip->ip_proto = proto; pip->ip_dst = faddr; if (pip->ip_proto != IPT_ICMP) pip->ip_src = ip_anyaddr; if (enq(nif[NI_LOCAL].ni_ipinq, pep, 0) < 0) { freebuf(pep); IpOutDiscards++; } send(ippid, NI_LOCAL); }

  21. /* ICMP packet format (following the IP header) */ struct icmp { /* ICMP packet */ char ic_type; /* type of message (ICT_* above)*/ char ic_code; /* code (ICC_* above) */ short ic_cksum; /* checksum of ICMP header+data*/ union { struct { int ic1_id:16; /* echo type, a message id */ int ic1_seq:16;/* echo type, a seq. number*/ } ic1; IPaddr ic2_gw; /* for redirect, gateway*/ struct { char ic3_ptr;/* pointer, for ICT_PARAMP*/ char ic3_pad[IC_PADLEN]; } ic3; int ic4_mbz; /* must be zero */ } icu; char ic_data[1]; /* data area of ICMP message*/ };

  22. /* format 1 */ #define ic_id icu.ic1.ic1_id #define ic_seq icu.ic1.ic1_seq /* format 2 */ #define ic_gw icu.ic2_gw /* format 3 */ #define ic_ptr icu.ic3.ic3_ptr #define ic_pad icu.ic3.ic3_pad /* format 4 */ #define ic_mbz icu.ic4_mbz

  23. 8.4 handling Incoming ICMP messages • When receive an ICMP message, Net-Interface => IP => icmp_in /*------------------------------------------------------- *icmp_in - handle ICMP packet coming in from the network *------------------------------------------------------*/ int icmp_in(struct netif *pni, struct ep *pep) { struct ip *pip; struct icmp *pic; int i, len; pip = (struct ip *)pep->ep_data; pic = (struct icmp *) pip->ip_data; len = pip->ip_len - IP_HLEN(pip); if (cksum((WORD *)pic, len)) { IcmpInErrors++; freebuf(pep); return SYSERR; } IcmpInMsgs++;

  24. switch(pic->ic_type) { case ICT_ECHORQ: IcmpInEchos++; return icmp(ICT_ECHORP, 0, pip->ip_src, pep, 0); case ICT_MASKRQ: IcmpInAddrMasks++; if (!gateway) { freebuf(pep); return OK; } pic->ic_type = (char) ICT_MASKRP; *(IPaddr *)pic->ic_data = netmask(pip->ip_dst); break;

  25. case ICT_MASKRP: IcmpInAddrMaskReps++; for (i=0; i<Net.nif; ++i) if (nif[i].ni_ip == pip->ip_dst) break; if (i != Net.nif) { setmask(i, *(IPaddr *)pic->ic_data); send(pic->ic_id, ICT_MASKRP); } freebuf(pep); return OK; case ICT_ECHORP: IcmpInEchoReps++; if (send(pic->ic_id, (int)pep) != OK) freebuf(pep); return OK; case ICT_REDIRECT: IcmpInRedirects++; icredirect(pep); return OK;

  26. case ICT_DESTUR: IcmpInDestUnreachs++; freebuf(pep); return OK; case ICT_SRCQ: IcmpInSrcQuenchs++; freebuf(pep); return OK; case ICT_TIMEX: IcmpInTimeExcds++; freebuf(pep); return OK; case ICT_PARAMP: IcmpInParmProbs++; freebuf(pep); return OK; case ICT_TIMERQ: IcmpInTimestamps++; freebuf(pep); return OK; case ICT_TIMERP: IcmpInTimestampReps++; freebuf(pep); return OK; default: IcmpInErrors++; freebuf(pep); return OK; }

More Related