/*
* I'm rubber, you're glue.
* Whatever you say bounces off me and sticks to you.
*/
#include <u.h>
#include <libc.h>
#include <ip.h>
#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);
}
|