+
+/*
+ * Routine to convert from IMP Leader to InterNet Address.
+ *
+ * This procedure is necessary because IMPs may be assigned Class A, B, or C
+ * network numbers, but only have 8 bits in the leader to reflect the
+ * IMP "network number". The strategy is to take the network number from
+ * the ifnet structure, and blend in the host-on-imp and imp-on-net numbers
+ * from the leader.
+ *
+ * There is no support for "Logical Hosts".
+ *
+ * Class A: Net.Host.0.Imp
+ * Class B: Net.net.Host.Imp
+ * Class C: Net.net.net.(Host4|Imp4)
+ */
+imp_leader_to_addr(ap, ip, ifp)
+ struct in_addr *ap;
+ register struct imp_leader *ip;
+ struct ifnet *ifp;
+{
+ register u_long final;
+ register struct sockaddr_in *sin;
+ int imp = ntohs(ip->il_imp);
+
+ sin = (struct sockaddr_in *)(&ifp->if_addrlist->ifa_addr);
+ final = ntohl(sin->sin_addr.s_addr);
+
+ if (IN_CLASSA(final)) {
+ final &= IN_CLASSA_NET;
+ final |= (imp & 0xFF) | ((ip->il_host & 0xFF)<<16);
+ } else if (IN_CLASSB(final)) {
+ final &= IN_CLASSB_NET;
+ final |= (imp & 0xFF) | ((ip->il_host & 0xFF)<<8);
+ } else {
+ final &= IN_CLASSC_NET;
+ final |= (imp & 0x0F) | ((ip->il_host & 0x0F)<<4);
+ }
+ ap->s_addr = htonl(final);
+}
+
+/*
+ * Function to take InterNet address and fill in IMP leader fields.
+ */
+imp_addr_to_leader(imp, a)
+ register struct imp_leader *imp;
+ u_long a;
+{
+ register u_long addr = ntohl(a);
+
+ imp->il_network = 0; /* !! */
+
+ if (IN_CLASSA(addr)) {
+ imp->il_host = ((addr>>16) & 0xFF);
+ imp->il_imp = addr & 0xFF;
+ } else if (IN_CLASSB(addr)) {
+ imp->il_host = ((addr>>8) & 0xFF);
+ imp->il_imp = addr & 0xFF;
+ } else {
+ imp->il_host = ((addr>>4) & 0xF);
+ imp->il_imp = addr & 0xF;
+ }
+ imp->il_imp = htons(imp->il_imp);
+}