Download presentation
Presentation is loading. Please wait.
Published byNeil Hunt Modified over 8 years ago
1
3.3 Ethernet Definitions /* ether.h */ #defineEPT_LOOP0x0060/* type: Loopback*/ #defineEPT_ECHO0x0200/* type: Echo*/ #defineEPT_PUP0x0400/* type: Xerox PUP*/ #defineEPT_IP0x0800/* type: Internet Protocol*/ #defineEPT_ARP0x0806/* type: ARP*/ #defineEPT_RARP0x8035/* type: Reverse ARP*/ structeh {/* ethernet header*/ Eaddreh_dst;/* destination host address*/ Eaddreh_src;/* source host address*/ unsigned shorteh_type;/* Ethernet packet type (see below)*/ }; structep{/* complete structure of Ethernet packet*/ structeh ep_eh;/* the ethernet header*/ charep_data[EP_DLEN];/* data in the packet*/ }; #defineep_dstep_eh.eh_dst #defineep_srcep_eh.eh_src #defineep_typeep_eh.eh_type
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. IPIGMP ICMP Network Interface RARP ARP UDP TCP
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+1 n 0x12 0x8c 0x12 Big endian Little endian
5
ARP Packet Format H/W Type Protocol Type HLen.PLen. ARP Operation Sender Hardware Address Target Hardware Address Target Protocol Address Sender Protocol Address /* arp.h - SHA, SPA, THA, TPA */ #defineAR_HARDWARE1/* Ethernet hardware type code */ /* Definitions of codes used in operation field of ARP packet */ #defineAR_REQUEST1 /* ARP request to resolve address*/ #defineAR_REPLY2 /* reply to a resolve request*/ #defineRA_REQUEST3 /* reverse ARP request (RARP packets)*/ #defineRA_REPLY4 /* reply to a reverse request (RARP ")*/ structarp{ u_shortar_hwtype;/* hardware type*/ u_shortar_prtype;/* protocol type*/ u_charar_hwlen;/* hardware address length*/ u_charar_prlen;/* protocol address length*/ u_shortar_op;/* ARP operation (see list above)*/ u_charar_addrs[1];/* sender and target hw & proto addrs*/ /*charar_sha[???]; - sender's physical hardware address*/ /*charar_spa[???]; - sender's protocol address (IP addr.)*/ /*charar_tha[???]; - target's physical hardware address*/ /*charar_tpa[???]; - target's protocol address (IP)*/ }; #defineSHA(p)(&p->ar_addrs[0]) #defineSPA(p)(&p->ar_addrs[p->ar_hwlen]) #defineTHA(p)(&p->ar_addrs[p->ar_hwlen + p->ar_prlen]) #defineTPA(p)(&p->ar_addrs[(p->ar_hwlen*2) + p->ar_prlen])
6
ARP Cache Table structarpentry {/* format of entry in ARP cache*/ shortae_state;/* state of this entry (see below)*/ intae_queue; /* queue of packets for this address*/ intae_attempts;/* number of retries so far */ intae_ttl;/* time to live*/ u_charae_hwa[MAXHWALEN];/* Hardware address*/ u_charae_pra[MAXPRALEN];/* Protocol address */ }; #defineAS_FREE0/* Entry is unused (initial value)*/ #defineAS_PENDING1/* Entry is used but incomplete*/ #defineAS_RESOLVED2/* Entry has been resolved*/ /* ARP variables */ extern structarpentryarptable[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; } #ifBYTE_ORDER == LITTLE_ENDIAN #define hs2net(x) (unsigned) ((((x)>>8) &0xff) | (((x) & 0xff)<<8)) #definenet2hs(x) hs2net(x) #define hl2net(x)(((((x)& 0xff) >24) & 0xff) | \ (((x) & 0xff0000)>>8) | (((x) & 0xff00)<<8)) #define net2hl(x) hl2net(x) #endif #ifBYTE_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 /*------------------------------------------------------------------------ * 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; inti; 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) { structnetif*pni = pae->ae_pni; structep*pep; structarp*parp; intarplen; 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 *------------------------------------------------------------------------ */ structarpentry * arpadd(struct netif *pni, struct arp *parp) { structarpentry*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) { structep*pep; structnetif*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
IP GLOBAL Software Organization Interface for Net 1 Interface for local host Interface for Net N IP Process Message queue Queues for packets sent to IP Datagrams sent to IP from 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 */ staticintifnext = NI_LOCAL; /*------------------------------------------------------------------------ * ipgetp -- choose next IP input queue and extract a packet *----------------------------------------------------------------------*/ struct ep * ipgetp(int *pifnum) { structep*pep; inti; 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 */ structep*ipgetp(int *); structroute*rtget(IPaddr, Bool); PROCESS ipproc(void) { structep*pep; structip*pip; structroute*prt; Boolnonlocal; intifnum; 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; intnwords; { unsigned longsum; 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) { structip *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)*/ structicmp{/* ICMP packet*/ charic_type;/* type of message (ICT_* above)*/ charic_code;/* code (ICC_* above)*/ shortic_cksum;/* checksum of ICMP header+data*/ union{ struct { intic1_id:16; /* echo type, a message id*/ intic1_seq:16;/* echo type, a seq. number*/ } ic1; IPaddric2_gw;/* for redirect, gateway*/ struct { charic3_ptr;/* pointer, for ICT_PARAMP*/ charic3_pad[IC_PADLEN]; } ic3; intic4_mbz;/* must be zero*/ } icu; charic_data[1];/* data area of ICMP message*/ };
22
/* format 1 */ #define ic_idicu.ic1.ic1_id #define ic_seqicu.ic1.ic1_seq /* format 2 */ #define ic_gwicu.ic2_gw /* format 3 */ #define ic_ptricu.ic3.ic3_ptr #define ic_padicu.ic3.ic3_pad /* format 4 */ #define ic_mbzicu.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) {structip*pip; structicmp*pic; inti, 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; }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.