/* * I'm rubber, you're glue. * Whatever you say bounces off me and sticks to you. */ #include #include #include #include "a1.h" int chatty = 0; void usage(void) { fprint(2, "usage: snmpmirror udp!*!snmp [redirect-host]\n"); exits("usage"); } char* ct(ulong t) { char *p; p = ctime(t); if(p[strlen(p)-1] == '\n') p[strlen(p)-1] = '\0'; return p; } void main(int argc, char **argv) { int nfd, fd, n; uchar buf[65536]; char ip[40]; char *addr, *remote, *a; Dir *d; Snmp s, r; fmtinstall('I', eipfmt); fmtinstall('E', eipfmt); ARGBEGIN{ default: usage(); }ARGEND addr = remote = nil; switch(argc){ case 2: remote = argv[1]; case 1: addr = argv[0]; break; default: usage(); } fd = openlisten(addr); while((n = read(fd, buf, sizeof buf)) > 0){ print("%s %I/%d -> %I/%d ", ct(time(0)), buf, nhgets(buf+16+16), buf+16, nhgets(buf+16+16+2)); if(Sparse(buf+36, n-36, &s) < 0){ print("format error\n"); continue; } Sprint(&s); if(remote) a = remote; else{ snprint(ip, sizeof ip, "%I", buf); a = ip; } if((nfd = dial(netmkaddr(a, "udp", "snmp"), 0, 0, 0)) < 0){ print("\tcannot dial '%s': %r\n", a); continue; } print("\tredirect %s\n", a); if(dosnmp(nfd, &s, &r) < 0){ print("\tsnmp failed: %r\n"); close(nfd); /* * Discard any packets that arrived while we were * sending things out -- they might be remirrored * copies of what we were sending. */ while((d = dirfstat(fd)) != nil && d->length > 0){ free(d); if(read(fd, buf, sizeof buf) <= 0) break; print("discard\n"); } free(d); continue; } close(nfd); print("%s %I/%d <- %I/%d ", ctime(time(0)), buf, nhgets(buf+16+16), buf+16, nhgets(buf+16+16+2)); Sprint(&r); n = Sunparse(&r, buf+36, sizeof(buf)-36); if(write(fd, buf, n+36) != n+36) print("\twrite failed: %r\n"); } print("exiting: %d %r\n", n); exits(nil); }