/*------------------------------------------------------------------------ * netstart - initialize net *------------------------------------------------------------------------ */ int netstart(int userpid) { char str[128]; char *str1 = "sleeping 30 secs to get routes..."; char *str2 = "\ndone.\n"; unsigned long now; int i; if (clkruns == FALSE) panic("net: no clock"); /* initialize ports */ for (i=0 ; i<UPPS ; i++) upqs[i].up_valid = FALSE; udpmutex = screate(1); arpinit(); ipfinit(); /* init the IP frag queue */ /* these need a command to set/clear them. FIX ME!!! */ gateway = 1; IpForwarding = 1; /* == 2 if not a gateway */ IfNumber = Net.nif - 1; /* bsdbrc = 1; */ /* uncomment to use 0's broadcast */ if (gateway) { IPaddr gw; initgate(); gw = dot2ip(DEFRTR); rtadd(RT_DEFAULT, RT_DEFAULT, gw, RTM_INF-1, 1, RT_INF); } else inithost(); rtadd(RT_LOOPBACK, ip_maskall, RT_LOOPBACK, 0, NI_LOCAL, RT_INF); for (i=0; i<Net.nif; ++i) { nif[i].ni_ipinq = newq(NI_INQSZ, QF_NOWAIT); nif[i].ni_hwtype = AR_HARDWARE; /* for ARP */ /* no OTHER's for now */ if (i < 2) nif[i].ni_state = NIS_UP; } /* * wait()'s synchronize to insure initialization is done * before proceeding. */ resume(create(slowtimer, STSTK, STPRI, STNAM, STARGC)); wait(Net.sema); resume(create(ipproc, IPSTK, IPPRI, IPNAM, IPARGC)); wait(Net.sema); resume(create(tcptimer, TMSTK, TMPRI, TMNAM, TMARGC)); wait(Net.sema); resume(create(tcpinp, TCPISTK, TCPIPRI, TCPINAM, TCPIARGC)); wait(Net.sema); resume(create(tcpout, TCPOSTK, TCPOPRI, TCPONAM, TCPOARGC)); wait(Net.sema); if (!gateway) { write(CONSOLE, str1, strlen(str1)); sleep(30); write(CONSOLE, str2, strlen(str2)); } /* get addrs & names */ for (i=0; i<Net.nif; ++i) { IPaddr junk; char junk2[64]; if (i == NI_LOCAL) continue; if (nif[i].ni_state != NIS_UP) continue; junk = getiaddr(i); sprintf(str, "if%d IP %s ha %02x:%02x:%02x:%02x:%02x:%02x ", i, ip2dot(junk2, nif[i].ni_ip), nif[i].ni_hwa.ha_addr[0]&0xff, nif[i].ni_hwa.ha_addr[1]&0xff, nif[i].ni_hwa.ha_addr[2]&0xff, nif[i].ni_hwa.ha_addr[3]&0xff, nif[i].ni_hwa.ha_addr[4]&0xff, nif[i].ni_hwa.ha_addr[5]&0xff); write(CONSOLE, str, strlen(str)); sprintf(str, "br %02x:%02x:%02x:%02x:%02x:%02x\n", nif[i].ni_hwb.ha_addr[0]&0xff, nif[i].ni_hwb.ha_addr[1]&0xff, nif[i].ni_hwb.ha_addr[2]&0xff, nif[i].ni_hwb.ha_addr[3]&0xff, nif[i].ni_hwb.ha_addr[4]&0xff, nif[i].ni_hwb.ha_addr[5]&0xff); write(CONSOLE, str, strlen(str)); icmp(ICT_MASKRQ, 0, nif[i].ni_brc, 0, 0); recvtim(30); /* wait for an answer */ getiname(i, junk2); } getutim(&now); #ifdef MULTICAST hginit(); #endif /* MULTICAST */ #ifdef RIP resume(create(rip, RIPISTK, RIPPRI, RIPNAM, RIPARGC)); #endif /* RIP */ #ifdef OSPF resume(create(ospf, OSPFSTK, OSPFPRI, OSPFNAM, 0)); #endif /* OSPF */ #ifdef SNMP resume(create(snmpd, SNMPSTK, SNMPPRI, SNMPDNAM, 0)); #endif /* SNMP */ rwho(); resume(create(FINGERD, FNGDSTK, FNGDPRI, FNGDNAM, FNGDARGC)); resume(create(ECHOD, ECHOSTK, ECHOPRI, ECHODNAM, 0)); resume(create(udpecho, 1000, 50, "udpecho", 0)); resume(userpid); }
/*------------------------------------------------------------------------ * ip2name - return DNS name for a host given its IP address *------------------------------------------------------------------------ */ char * ip2name(IPaddr ip, char *nam) { char tmpstr[20]; /* temporary string buffer */ char *buf; /* buffer to hold domain query */ int dg, i; register char *p; register struct dn_mesg *dnptr; dnptr = (struct dn_mesg *) (buf = (char *) getmem(DN_MLEN)); *nam = NULLCH; dnptr->dn_id = 0; dnptr->dn_opparm = hs2net(DN_RD); dnptr->dn_qcount = hs2net(1); dnptr->dn_acount = dnptr->dn_ncount = dnptr->dn_dcount = 0; p = dnptr->dn_qaaa; /* Fill in question with ip[3].ip[2].ip[1].ip[0].in-addr.arpa */ for (i=3 ; i >= 0 ; i--) { sprintf(tmpstr, "%u", ((char *)&ip)[i] & LOWBYTE); dn_cat(p, tmpstr); } dn_cat(p, "in-addr"); dn_cat(p, "arpa"); *p++ = NULLCH; /* terminate name */ /* Add query type and query class fields to name */ ( (struct dn_qsuf *)p )->dn_type = hs2net(DN_QTPR); ( (struct dn_qsuf *)p )->dn_clas = hs2net(DN_QCIN); p += sizeof(struct dn_qsuf); /* Send query */ dg = open(UDP, NSERVER, ANYLPORT); control(dg, DG_SETMODE, DG_DMODE | DG_TMODE); if (write (dg, buf, p - buf) == SYSERR) panic("ip2name write(%d) failed\n", dg); i = read(dg, buf, DN_MLEN); if (i == SYSERR) panic("ip2name read(%d) failed\n", dg); if (i == TIMEOUT) { close(dg); return ip2dot(nam, ip); } close(dg); if (net2hs(dnptr->dn_opparm) & DN_RESP || net2hs(dnptr->dn_acount) <= 0) { freemem(buf, DN_MLEN); return ip2dot(nam, ip); } /* In answer, skip name and remainder of resource record header */ while (*p != NULLCH) if (*p & DN_CMPRS) /* compressed section of name */ *++p = NULLCH; else p += *p + 1; p += DN_RLEN + 1; /* Copy name to user */ *nam = NULLCH; while (*p != NULLCH) { if (*p & DN_CMPRS) p = buf + (net2hs(*(int *)p) & DN_CPTR); else { strncat(nam, p+1, *p); strcat(nam, "."); p += *p + 1; } } if (strlen(nam)) /* remove trailing dot */ nam[strlen(nam) - 1] = NULLCH; else ip2dot(nam, ip); freemem(buf, DN_MLEN); return nam; }
/*------------------------------------------------------------------------ * x_snmp - SNMP shell that does MIB object name completion *------------------------------------------------------------------------ */ int x_snmp(int stdin, int stdout, int stderr, int nargs, char *args[]) { int ch; char snmpservstr[BUFSIZE]; struct tty *ttyp; int ct, i, mode; IPaddr destmach; if (nargs != 2) { snusage(stdout); return OK; } args++; nargs--; sninit(); if ((destmach = name2ip(*args)) == (IPaddr)SYSERR) { fprintf(stdout,"snmp: couldn't resolve name %s\n", *args); return OK; } ip2dot(snmpservstr, destmach); sprintf(snmpservstr + strlen(snmpservstr), ":%d", SNMPPORT); ttyp = &ttytab[stdin]; ct = 0; mode = M_CHARIN; next_completion = num_completions = 0; control(stdin, TTC_MODER); /* put stdin into raw mode */ write(stdout, PROMPT, strlen(PROMPT)); /* print the prompt */ while (TRUE) { if ((ch = getc(stdin)) == EOF) { write(stdout, EXITSTR, strlen(EXITSTR)); putc(stdout, '\n'); control(stdin, TTC_MODEC); return OK; } if (ch == SYSERR) { return SYSERR; } if (ch == COMPLETE) { if (mode == M_CHARIN) { mode = M_COMPL; /* find beginning of word */ for (i=ct-1; i >= 0 && buf[i] != ' '; i--) /* empty */; s2clen = ct - ++i; strncpy(str2compl, buf + i, s2clen); find_completions(); } if (num_completions == 0) { putc(stdout, BELL); mode = M_CHARIN; } else print_completion(&ct, stdout); continue; } if (ch == KILLWORD && mode == M_COMPL) { /* kill word in compl. mode goes back to original string to complete. */ eraseword(&ct, stdout); strncpy(buf + ct, str2compl, s2clen); write(stdout, buf + ct, s2clen); ct += s2clen; mode = M_CHARIN; next_completion = num_completions = 0; continue; } if (mode == M_COMPL) { /* && ch != KILLWORD */ mode = M_CHARIN; str2compl[(s2clen = 0)] = '\0'; num_completions = next_completion = 0; } if (ch == KILLWORD) { /* && mode != M_COMPL */ eraseword(&ct, stdout); continue; } if ((ch == ttyp->tty_tchars.tc_kill)) { eraseall(ct, stdout); ct = 0; continue; } if ((ch == ttyp->tty_tchars.tc_erase)) { if (ct > 0) erase1(--ct, stdout); continue; } if ((ch == '\r') || (ch == '\n')) { echoch(ch, stdout); buf[ct] = '\0'; if (strequ(buf, EXITSTR)) { control(stdin, TTC_MODEC); return OK; } sendquery(stdout, snmpservstr); for (i = 0; i < BUFSIZE; i++) buf[i] = '\0'; write(stdout, PROMPT, strlen(PROMPT)); ct = 0; continue; } /* all non-special characters */ if (ct == BUFSIZE - 1) putc(stdout, BELL); else { echoch(ch, stdout); buf[ct++] = ch; } } return OK; }