210 likes | 1.6k Views
IP GLOBAL Software Organization. IP is the central switch point in the protocol software. It accepts datagrams from the network interface software as well as outgoing datagrams that higher -level protocols generate. Concentrate on gateway and treat hosts as a special case. Software Design.
E N D
IP GLOBAL Software Organization • IP is the central switch point in the protocol software. • It accepts datagrams from the network interface software as well as outgoing datagrams that higher -level protocols generate. • Concentrate on gateway and treat hosts as a special case. • Software Design - Uniform input queue and uniform routing: handle IP datagram uniformly regardless whether they are from the network or generated by local machine. without regard to the datagram’s source - Independent IP process. (independent to H/W and O.S.) - Local host interface: pseudo network interface.
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
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.
/* 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 */ }
Structure of IP Process • Basic algorithm: • Many other details - repeatedly calls ipgetp to select a datagram. - calls a procedure to compute the next hop address. - deposits the datagram on a queue associated with the destination network interface. - verify datagram checksum is correct. - generate ICMP destination unreachable if routing table does not contain a route to the specified destination. - ICMP redirect - directed broadcast
/* 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 (IP_CLASSE(pip->ip_dst)) { not in class A, B, C, continue;} if (ifnum != NI_LOCAL) { //if the IP packet comes from outside if (cksum((WORD *)pip, IP_HLEN(pip))) { checksum error continue; } ipnet2h(pip); //big endian to little endian } prt = rtget(pip->ip_dst, (ifnum == NI_LOCAL)); // search routing table if (prt == NULL) { if (gateway) { iph2net(pip); //little endian to big endian icmp(ICT_DESTUR, ICC_NETUR,pip->ip_src, pep, 0); } else {freebuf(pep);} continue; }
nonlocal = ifnum != NI_LOCAL && prt->rt_ifnum != NI_LOCAL; //come from outside if (!gateway && nonlocal) { // and DA != My-IP IpInAddrErrors++; freebuf(pep); rtfree(prt); continue; } if (nonlocal) IpForwDatagrams++; /* fill in src IP, if we're the sender */ if (ifnum == NI_LOCAL) { if (pip->ip_src == ip_anyaddr) if (prt->rt_ifnum == NI_LOCAL) pip->ip_src = pip->ip_dst; else pip->ip_src = nif[prt->rt_ifnum].ni_ip; } else if (--(pip->ip_ttl) == 0 && prt->rt_ifnum != NI_LOCAL) { icmp(ICT_TIMEX, ICC_TIMEX, pip->ip_src, pep, 0); continue; } ipdbc(ifnum, pep, prt); /* handle directed broadcasts */ ipredirect(pep, ifnum, prt); /* do redirect, if needed */ if (prt->rt_metric != 0) ipputp(prt->rt_ifnum, prt->rt_gw, pep); //send to gateway else ipputp(prt->rt_ifnum, pip->ip_dst, pep); //send to host rtfree(prt); } //while loop }
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; }
Handling Directed Broadcast • Directed broadcast includes both gateways and hosts on the destination network, even if one of those gateways is responsible for forwarding the datagram onto the network. • Recognizing a Broadcast address: - make a copy of datagram to local machine. - broadcast datagram on the specified network. - Three types of broadcast addresses - local network broadcast address - directed network broadcast address - subnet broadcast address
/* ipdbc.c - ipdbc */ void ipdbc(unsigned ifnum, struct ep *pep, struct route *prt) { struct ip *pip = (struct ip *)pep->ep_data; struct ep *pep2; struct route *prt2; int len; if (prt->rt_ifnum != NI_LOCAL) return; /* not ours */ if (!isbrc(pip->ip_dst)) return; /* not broadcast */ prt2 = rtget(pip->ip_dst, RTF_LOCAL); if (prt2 == NULL) //不是要broadcast到我這個domain return; if (prt2->rt_ifnum == ifnum) { /* not directed */ rtfree(prt2); //進來和出去是同一個nif return; } /* directed broadcast; make a copy */ /* len = ether header + IP packet */ len = EP_HLEN + pip->ip_len; if (len > EP_MAXLEN) pep2 = (struct ep *)getbuf(Net.lrgpool); else //memory有分為large與small兩種 pep2 = (struct ep *)getbuf(Net.netpool); memcpy(pep2, pep, len);
/* isbrc.c - isbrc */ /*---------------------------------------------------------- * isbrc - Is "dest" a broadcast address? *---------------------------------------------------------- */ Bool isbrc(IPaddr dest) { int inum; /* all 0's and all 1's are broadcast */ if (dest == ip_anyaddr || dest == ip_maskall) return TRUE; /* check real broadcast address and BSD-style for net & subnet */ for (inum=0; inum < Net.nif; ++inum) if (dest == nif[inum].ni_brc || dest == nif[inum].ni_nbrc || dest == nif[inum].ni_subnet || dest == nif[inum].ni_net) return TRUE; return FALSE; }
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
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.
/* 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); }
Timer Process • A timing mechanism is needed for maintenance of network data structures, including IP routing table, fragment reassembly table, ARP cache timeouts, TCP retransmission timer, connection timer, etc. • slowtimer: