# #include "../h/param.h" #include "../h/user.h" #include "../h/pkts.h" #include "../h/net.h" #define NHOST 16 long mymach = 0x0a120800; int mygate = 5; struct gt_host hostgates[NHOST]; /* mk_net put local net hdr on packet * If packet's foreign inet host equals net * connection foreign host, have saved * best first hop local dest. in nt_rte * (unless first local hop is default * gateway); so fill local dest from * nt_rte unless nt_rte is NULL. * Otherwise use net routing routine * to decide if better route than * via default gateway. */ mk_net(ppkt, nip) register struct pkt *ppkt; register struct netino *nip; { register short ldest; if (ppkt->pk_inet.ip_dest == nip->nt_fhost.nt_lhost) { if (nip->nt_rte != NULL) ldest = nip->nt_rte; else ldest = mygate; } else { ldest = net_rte(ppkt->pk_inet.ip_dest); if (ldest == NULL) ldest = mygate; } if (ldest == NULL) return(ERR); ppkt->pk_net.v2_dest = ldest; ppkt->pk_net.v2_prot1 = MPHWPROT; ppkt->pk_net.v2_prot2 = INETPROT; ppkt->pk_net.v2_zero = 0; } ch_net(rp) register struct rcvpkt *rp; { register struct pkt *ppkt; if ((rp->rp_len < (NETHSIZ + IPHSIZ)) || (rp->rp_len > NETBYTES) ) { neterrt(ENETLEN); return(FALSE); } ppkt = &rp->rp_net; if ((ppkt->pk_net.v2_prot1 != MPHWPROT) || (ppkt->pk_net.v2_prot2 != INETPROT) ) { neterrt(ENETPROT); return(FALSE); } return(TRUE); } /* net_rte compute best first hop local dest. * Routing rules to foreign host are: * 1) If foreign host's net/subnet is same as * mymach's, send packet directly to host * 2) If foreign host is exact match w. host * in host gate table, send to gate specified * in table entry. * 3) Otherwise, send packet to default gateway. */ net_rte(fhost) long fhost; { register struct in_name *pfhost; struct in_name *pmymach; register struct gt_host *hgp, *hgpe; if (fhost == NULL) return(NULL); pfhost = &fhost; pmymach = &mymach; if ((pfhost->in_net == pmymach->in_net) && (pfhost->in_snet == pmymach->in_snet)) return(pfhost->in_host); for (hgp = &hostgates[0], hgpe = &hostgates[NHOST]; hgp < hgpe; hgp++) if (hgp->gt_fhost == fhost) return(hgp->gt_gate); return(NULL); } /* clr_hgate clear host gateway table and * recompute first hop local dest. for * all net inodes */ clr_hgate() { register struct gt_host *hgp, *hgpe; register struct netino *nip; register struct in_name *pmymach; for (hgp = &hostgates[0], hgpe = &hostgates[NHOST]; hgp < hgpe; hgp++) { hgp->gt_fhost = NULL; hgp->gt_gate = NULL; } pmymach = &mymach; for (nip = neti_que.q_head; nip != NULL; nip = nip->nt_forw) if ((nip->nt_fhost.nt_inhost.in_net == pmymach->in_net) && (nip->nt_fhost.nt_inhost.in_snet == pmymach->in_snet)) nip->nt_rte = nip->nt_fhost.nt_inhost.in_host; else nip->nt_rte = NULL; } /* add_hgate add a host and its gate to host gate table * if new entry has NULL host or gate or is same * net/subnet as this machine, return error * if no free slot try to drop host which is not * in net inode list * search net inodes for host, if match update nt_rte */ add_hgate(hgatep) register struct gt_host *hgatep; { register struct gt_host *hgp; struct gt_host *hgpe, *hgpsv; register struct netino *nip; struct in_name *pfhost, *pmymach; static int rephost = 0; if ((hgatep->gt_fhost == NULL) || (hgatep->gt_gate == NULL)) return( netu_err(EINVAL) ); pfhost = &hgatep->gt_fhost; pmymach = &mymach; if ((pfhost->in_net == pmymach->in_net) && (pfhost->in_snet == pmymach->in_snet)) return( netu_err(EINVAL) ); hgpsv = NULL; for (hgp = &hostgates[0], hgpe = &hostgates[NHOST]; hgp < hgpe; hgp++) { if (hgp->gt_fhost == hgatep->gt_fhost) { hgpsv = hgp; break; } if ( (hgp->gt_fhost == NULL) && (hgpsv == NULL) ) hgpsv = hgp; } if (hgpsv == NULL) { for (hgp = &hostgates[0], hgpe = &hostgates[NHOST]; hgp < hgpe; hgp++) { for (nip = neti_que.q_head; nip != NULL; nip = nip->nt_forw) if (nip->nt_fhost.nt_lhost == hgp->gt_fhost) break; if (nip == NULL) { hgpsv = hgp; break; } } } if (hgpsv == NULL) { hgpsv = &hostgates[rephost]; if (++rephost >= NHOST) rephost = 0; } hgpsv->gt_fhost = hgatep->gt_fhost; hgpsv->gt_gate = hgatep->gt_gate; for (nip = neti_que.q_head; nip != NULL; nip = nip->nt_forw) if (hgatep->gt_fhost == nip->nt_fhost.nt_lhost) nip->nt_rte = hgatep->gt_gate; } /* def_gate define default gateway */ def_gate(gate) int gate; { mygate = gate; } /* del_gate delete a gateway * if same as default gateway, NULL default gateway * search host gate table for hosts which use this * gate, NULL these entries * search net inodes for connections which use this * gate, NULL nt_rte (unless foreign host is on * our net/subnet - a local host can be both a * dest. host and a gateway */ del_gate(gate) register int gate; { register struct gt_host *hgp; struct gt_host *hgpe; register struct netino *nip; struct in_name *pmymach; if (gate == mygate) mygate = NULL; for (hgp = &hostgates[0], hgpe = &hostgates[NHOST]; hgp < hgpe; hgp++) if (hgp->gt_gate == gate) { hgp->gt_fhost = NULL; hgp->gt_gate = NULL; } pmymach = &mymach; for (nip = neti_que.q_head; nip != NULL; nip = nip->nt_forw) if (nip->nt_rte == gate) { if ((nip->nt_fhost.nt_inhost.in_net == pmymach->in_net) && (nip->nt_fhost.nt_inhost.in_snet == pmymach->in_snet)) nip->nt_rte = nip->nt_fhost.nt_inhost.in_host; else nip->nt_rte = NULL; } }