char nullstring[] = "";
-/* Code */
+int use_dns = 1;
+/* Code */
#ifdef CorruptCheck
#define TOT_SLACK 2
#define HEAD_SLACK 1
void *statmalloc(size_t size)
{
- void *p;
- size_t mallocsize;
- mem+= size;
- mallocsize = size + TOT_SLACK * sizeof(dword);
-
- p = malloc(mallocsize);
- if (!p) {
- fprintf(stderr,"malloc() of %u bytes failed: %s\n", (unsigned int)size, strerror(errno));
- exit(-1);
- }
- *((dword *)p) = (dword)size;
+ void *p;
+ size_t mallocsize;
+
+ mem+= size;
+ mallocsize = size + TOT_SLACK * sizeof(dword);
+
+ p = malloc(mallocsize);
+ if (!p) {
+ fprintf(stderr,"malloc() of %u bytes failed: %s\n", (unsigned int)size, strerror(errno));
+ exit(-1);
+ }
+ *((dword *)p) = (dword)size;
#ifdef CorruptCheck
- *(byte *)((char *)p + size + sizeof(dword) + sizeof(byte) * 0) = 0xde;
- *(byte *)((char *)p + size + sizeof(dword) + sizeof(byte) * 1) = 0xad;
- *(byte *)((char *)p + size + sizeof(dword) + sizeof(byte) * 2) = 0xbe;
- *(byte *)((char *)p + size + sizeof(dword) + sizeof(byte) * 3) = 0xef;
+ *(byte *)((char *)p + size + sizeof(dword) + sizeof(byte) * 0) = 0xde;
+ *(byte *)((char *)p + size + sizeof(dword) + sizeof(byte) * 1) = 0xad;
+ *(byte *)((char *)p + size + sizeof(dword) + sizeof(byte) * 2) = 0xbe;
+ *(byte *)((char *)p + size + sizeof(dword) + sizeof(byte) * 3) = 0xef;
#endif
- p = (void *)((dword *)p + HEAD_SLACK);
+ p = (void *)((dword *)p + HEAD_SLACK);
#ifdef WipeMallocs
- memset(p,0xf0,size);
+ memset(p,0xf0,size);
#endif
- return p;
+ return p;
}
+
void statfree(void *p)
{
- if (p) {
- if (*((dword *)p - HEAD_SLACK) == 0) {
- fprintf(stderr,"ERROR: Attempt to free pointer twice.\n");
- *(int*)0=0;
- exit(-1);
- } else {
- if (*((dword *)p - HEAD_SLACK) > 8192) {
- fprintf(stderr,"ERROR: Corrupted free() buffer. (header)\n");
- *(int*)0=0;
- exit(-1);
- }
+ if (p) {
+ if (*((dword *)p - HEAD_SLACK) == 0) {
+ fprintf(stderr,"ERROR: Attempt to free pointer twice.\n");
+ *(int*)0=0;
+ exit(-1);
+ } else {
+ if (*((dword *)p - HEAD_SLACK) > 8192) {
+ fprintf (stderr,"ERROR: Corrupted free() buffer. (header)\n");
+ *(int*)0=0;
+ exit(-1);
+ }
#ifdef CorruptCheck
- if ((*(byte *)((char *)p + (*((dword *)p - 1)) + sizeof(byte) * 0) != 0xde) ||
- (*(byte *)((char *)p + (*((dword *)p - 1)) + sizeof(byte) * 1) != 0xad) ||
- (*(byte *)((char *)p + (*((dword *)p - 1)) + sizeof(byte) * 2) != 0xbe) ||
- (*(byte *)((char *)p + (*((dword *)p - 1)) + sizeof(byte) * 3) != 0xef)) {
- fprintf(stderr,"ERROR: Corrupted free() buffer. (footer)\n");
- *(int*)0=0;
- exit(-1);
- }
+ if ((*(byte *)((char *)p + (*((dword *)p - 1)) + sizeof(byte) * 0) != 0xde) ||
+ (*(byte *)((char *)p + (*((dword *)p - 1)) + sizeof(byte) * 1) != 0xad) ||
+ (*(byte *)((char *)p + (*((dword *)p - 1)) + sizeof(byte) * 2) != 0xbe) ||
+ (*(byte *)((char *)p + (*((dword *)p - 1)) + sizeof(byte) * 3) != 0xef)) {
+ fprintf(stderr,"ERROR: Corrupted free() buffer. (footer)\n");
+ *(int*)0=0;
+ exit(-1);
+ }
#endif
- mem-= *((dword *)p - HEAD_SLACK);
+ mem-= *((dword *)p - HEAD_SLACK);
#ifdef WipeFrees
- memset(p,0xfe,*((dword *)p - HEAD_SLACK));
- *((dword *)p - 1) = 0;
+ memset(p,0xfe,*((dword *)p - HEAD_SLACK));
+ *((dword *)p - 1) = 0;
#endif
- free((dword *)p - HEAD_SLACK);
- }
- }
+ free((dword *)p - HEAD_SLACK);
+ }
+ }
}
+
char *strtdiff(char *d,long signeddiff)
{
- dword diff;
- dword seconds,minutes,hours;
- long days;
- if ((diff = labs(signeddiff))) {
- seconds = diff % 60; diff/= 60;
- minutes = diff % 60; diff/= 60;
- hours = diff % 24;
- days = signeddiff / (60 * 60 * 24);
- if (days)
- sprintf(d,"%lid",days);
- else
- *d = '\0';
- if (hours)
- sprintf(d + strlen(d),"%luh",hours);
- if (minutes)
- sprintf(d + strlen(d),"%lum",minutes);
- if (seconds)
- sprintf(d + strlen(d),"%lus",seconds);
- } else
- sprintf(d,"0s");
- return d;
+ dword diff;
+ dword seconds,minutes,hours;
+ long days;
+
+ if ((diff = labs(signeddiff))) {
+ seconds = diff % 60; diff/= 60;
+ minutes = diff % 60; diff/= 60;
+ hours = diff % 24;
+ days = signeddiff / (60 * 60 * 24);
+ if (days)
+ sprintf(d,"%lid",days);
+ else
+ *d = '\0';
+ if (hours)
+ sprintf(d + strlen(d),"%luh",hours);
+ if (minutes)
+ sprintf(d + strlen(d),"%lum",minutes);
+ if (seconds)
+ sprintf(d + strlen(d),"%lus",seconds);
+ } else
+ sprintf(d,"0s");
+ return d;
}
+
int issetfd(fd_set *set,int fd)
{
- return (int)((FD_ISSET(fd,set)) && 1);
+ return (int)((FD_ISSET(fd,set)) && 1);
}
+
void setfd(fd_set *set,int fd)
{
- FD_SET(fd,set);
+ FD_SET(fd,set);
}
+
void clearfd(fd_set *set,int fd)
{
- FD_CLR(fd,set);
+ FD_CLR(fd,set);
}
+
void clearset(fd_set *set)
{
- FD_ZERO(set);
+ FD_ZERO(set);
}
+
char *strlongip(ip_t ip)
{
- struct in_addr a;
- a.s_addr = htonl(ip);
- return inet_ntoa(a);
+ struct in_addr a;
+ a.s_addr = htonl(ip);
+ return inet_ntoa(a);
}
+
ip_t longipstr(char *s)
{
- return inet_addr(s);
+ return inet_addr(s);
}
+
int dns_forward(char *name)
{
- struct hostent *host;
- if ((host = gethostbyname(name)))
- return *(int *)host->h_addr;
- else
- return 0;
+ struct hostent *host;
+
+ if ((host = gethostbyname(name)))
+ return *(int *)host->h_addr;
+ else
+ return 0;
}
+
int dns_waitfd(void)
{
- return resfd;
+ return resfd;
}
+
void dns_open(void)
{
- int option,i;
+ int option,i;
- res_init();
- if (!_res.nscount) {
- fprintf(stderr,"No nameservers defined.\n");
- exit(-1);
- }
- _res.options|= RES_RECURSE | RES_DEFNAMES | RES_DNSRCH;
- for (i = 0;i < _res.nscount;i++)
- _res.nsaddr_list[i].sin_family = AF_INET;
- resfd = socket(AF_INET, SOCK_DGRAM, 0);
- if (resfd == -1) {
- fprintf(stderr,"Unable to allocate socket for nameserver communication: %s\n",
- strerror(errno));
- exit(-1);
- }
- option = 1;
- if (setsockopt(resfd,SOL_SOCKET,SO_BROADCAST,(char *)&option,sizeof(option))) {
- fprintf(stderr,"Unable to setsockopt() on nameserver communication socket: %s\n",
- strerror(errno));
- exit(-1);
- }
- localhost = longipstr("127.0.0.1");
- aseed = time(NULL) ^ (time(NULL) << 3) ^ (dword)getpid();
- for (i = 0;i < BashSize;i++) {
- idbash[i] = NULL;
- hostbash[i] = NULL;
- }
+ res_init();
+ if (!_res.nscount) {
+ fprintf(stderr,"No nameservers defined.\n");
+ exit(-1);
+ }
+ _res.options|= RES_RECURSE | RES_DEFNAMES | RES_DNSRCH;
+ for (i = 0;i < _res.nscount;i++)
+ _res.nsaddr_list[i].sin_family = AF_INET;
+ resfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (resfd == -1) {
+ fprintf(stderr,"Unable to allocate socket for nameserver communication: %s\n",
+ strerror(errno));
+ exit(-1);
+ }
+ option = 1;
+ if (setsockopt(resfd,SOL_SOCKET,SO_BROADCAST,(char *)&option,sizeof(option))) {
+ fprintf(stderr,"Unable to setsockopt() on nameserver communication socket: %s\n",
+ strerror(errno));
+ exit(-1);
+ }
+ localhost = longipstr("127.0.0.1");
+ aseed = time(NULL) ^ (time(NULL) << 3) ^ (dword)getpid();
+ for (i = 0;i < BashSize;i++) {
+ idbash[i] = NULL;
+ hostbash[i] = NULL;
+ }
}
+
struct resolve *allocresolve(void)
{
- struct resolve *rp;
- rp = (struct resolve *)statmalloc(sizeof(struct resolve));
- if (!rp) {
- fprintf(stderr,"statmalloc() failed: %s\n",strerror(errno));
- exit(-1);
- }
- memset(rp,0, sizeof(struct resolve));
- return rp;
+ struct resolve *rp;
+
+ rp = (struct resolve *)statmalloc(sizeof(struct resolve));
+ if (!rp) {
+ fprintf(stderr,"statmalloc() failed: %s\n",strerror(errno));
+ exit(-1);
+ }
+ memset(rp,0, sizeof(struct resolve));
+ return rp;
}
+
dword getidbash(word id)
{
- return (dword)BashModulo(id);
+ return (dword)BashModulo(id);
}
+
dword getipbash(ip_t ip)
{
- return (dword)BashModulo(ip);
+ return (dword)BashModulo(ip);
}
+
dword gethostbash(char *host)
{
- dword bashvalue = 0;
- for (;*host;host++) {
- bashvalue^= *host;
- bashvalue+= (*host >> 1) + (bashvalue >> 1);
- }
- return BashModulo(bashvalue);
+ dword bashvalue = 0;
+
+ for (;*host;host++) {
+ bashvalue^= *host;
+ bashvalue+= (*host >> 1) + (bashvalue >> 1);
+ }
+ return BashModulo(bashvalue);
}
+
void linkresolveid(struct resolve *addrp)
{
- struct resolve *rp;
- dword bashnum;
- bashnum = getidbash(addrp->id);
- rp = idbash[bashnum];
- if (rp) {
- while ((rp->nextid) && (addrp->id > rp->nextid->id))
- rp = rp->nextid;
- while ((rp->previousid) && (addrp->id < rp->previousid->id))
- rp = rp->previousid;
- if (rp->id < addrp->id) {
- addrp->previousid = rp;
- addrp->nextid = rp->nextid;
- if (rp->nextid)
- rp->nextid->previousid = addrp;
- rp->nextid = addrp;
- } else {
- addrp->previousid = rp->previousid;
- addrp->nextid = rp;
- if (rp->previousid)
- rp->previousid->nextid = addrp;
- rp->previousid = addrp;
- }
- } else
- addrp->nextid = addrp->previousid = NULL;
- idbash[bashnum] = addrp;
+ struct resolve *rp;
+ dword bashnum;
+
+ bashnum = getidbash(addrp->id);
+ rp = idbash[bashnum];
+ if (rp) {
+ while ((rp->nextid) && (addrp->id > rp->nextid->id))
+ rp = rp->nextid;
+ while ((rp->previousid) && (addrp->id < rp->previousid->id))
+ rp = rp->previousid;
+ if (rp->id < addrp->id) {
+ addrp->previousid = rp;
+ addrp->nextid = rp->nextid;
+ if (rp->nextid)
+ rp->nextid->previousid = addrp;
+ rp->nextid = addrp;
+ } else {
+ addrp->previousid = rp->previousid;
+ addrp->nextid = rp;
+ if (rp->previousid)
+ rp->previousid->nextid = addrp;
+ rp->previousid = addrp;
+ }
+ } else
+ addrp->nextid = addrp->previousid = NULL;
+ idbash[bashnum] = addrp;
}
+
void unlinkresolveid(struct resolve *rp)
{
- dword bashnum;
- bashnum = getidbash(rp->id);
- if (idbash[bashnum] == rp)
- idbash[bashnum] = (rp->previousid)? rp->previousid : rp->nextid;
- if (rp->nextid)
- rp->nextid->previousid = rp->previousid;
- if (rp->previousid)
- rp->previousid->nextid = rp->nextid;
+ dword bashnum;
+
+ bashnum = getidbash(rp->id);
+ if (idbash[bashnum] == rp)
+ idbash[bashnum] = (rp->previousid)? rp->previousid : rp->nextid;
+ if (rp->nextid)
+ rp->nextid->previousid = rp->previousid;
+ if (rp->previousid)
+ rp->previousid->nextid = rp->nextid;
}
+
void linkresolvehost(struct resolve *addrp)
{
- struct resolve *rp;
- dword bashnum;
- bashnum = gethostbash(addrp->hostname);
- rp = hostbash[bashnum];
- if (rp) {
- while ((rp->nexthost) && (strcasecmp(addrp->hostname,rp->nexthost->hostname) < 0))
- rp = rp->nexthost;
- while ((rp->previoushost) && (strcasecmp(addrp->hostname,rp->previoushost->hostname) > 0))
- rp = rp->previoushost;
- if (strcasecmp(addrp->hostname,rp->hostname) < 0) {
- addrp->previoushost = rp;
- addrp->nexthost = rp->nexthost;
- if (rp->nexthost)
- rp->nexthost->previoushost = addrp;
- rp->nexthost = addrp;
- } else {
- addrp->previoushost = rp->previoushost;
- addrp->nexthost = rp;
- if (rp->previoushost)
- rp->previoushost->nexthost = addrp;
- rp->previoushost = addrp;
- }
- } else
- addrp->nexthost = addrp->previoushost = NULL;
- hostbash[bashnum] = addrp;
+ struct resolve *rp;
+ dword bashnum;
+
+ bashnum = gethostbash(addrp->hostname);
+ rp = hostbash[bashnum];
+ if (rp) {
+ while ((rp->nexthost) && (strcasecmp(addrp->hostname,rp->nexthost->hostname) < 0))
+ rp = rp->nexthost;
+ while ((rp->previoushost) && (strcasecmp(addrp->hostname,rp->previoushost->hostname) > 0))
+ rp = rp->previoushost;
+ if (strcasecmp(addrp->hostname,rp->hostname) < 0) {
+ addrp->previoushost = rp;
+ addrp->nexthost = rp->nexthost;
+ if (rp->nexthost)
+ rp->nexthost->previoushost = addrp;
+ rp->nexthost = addrp;
+ } else {
+ addrp->previoushost = rp->previoushost;
+ addrp->nexthost = rp;
+ if (rp->previoushost)
+ rp->previoushost->nexthost = addrp;
+ rp->previoushost = addrp;
+ }
+ } else
+ addrp->nexthost = addrp->previoushost = NULL;
+ hostbash[bashnum] = addrp;
}
+
void unlinkresolvehost(struct resolve *rp)
{
- dword bashnum;
- bashnum = gethostbash(rp->hostname);
- if (hostbash[bashnum] == rp)
- hostbash[bashnum] = (rp->previoushost)? rp->previoushost : rp->nexthost;
- if (rp->nexthost)
- rp->nexthost->previoushost = rp->previoushost;
- if (rp->previoushost)
- rp->previoushost->nexthost = rp->nexthost;
- statfree(rp->hostname);
+ dword bashnum;
+
+ bashnum = gethostbash(rp->hostname);
+ if (hostbash[bashnum] == rp)
+ hostbash[bashnum] = (rp->previoushost)? rp->previoushost : rp->nexthost;
+ if (rp->nexthost)
+ rp->nexthost->previoushost = rp->previoushost;
+ if (rp->previoushost)
+ rp->previoushost->nexthost = rp->nexthost;
+ statfree(rp->hostname);
}
+
void linkresolveip(struct resolve *addrp)
{
- struct resolve *rp;
- dword bashnum;
- bashnum = getipbash(addrp->ip);
- rp = ipbash[bashnum];
- if (rp) {
- while ((rp->nextip) && (addrp->ip > rp->nextip->ip))
- rp = rp->nextip;
- while ((rp->previousip) && (addrp->ip < rp->previousip->ip))
- rp = rp->previousip;
- if (rp->ip < addrp->ip) {
- addrp->previousip = rp;
- addrp->nextip = rp->nextip;
- if (rp->nextip)
- rp->nextip->previousip = addrp;
- rp->nextip = addrp;
- } else {
- addrp->previousip = rp->previousip;
- addrp->nextip = rp;
- if (rp->previousip)
- rp->previousip->nextip = addrp;
- rp->previousip = addrp;
- }
- } else
- addrp->nextip = addrp->previousip = NULL;
- ipbash[bashnum] = addrp;
+ struct resolve *rp;
+ dword bashnum;
+
+ bashnum = getipbash(addrp->ip);
+ rp = ipbash[bashnum];
+ if (rp) {
+ while ((rp->nextip) && (addrp->ip > rp->nextip->ip))
+ rp = rp->nextip;
+ while ((rp->previousip) && (addrp->ip < rp->previousip->ip))
+ rp = rp->previousip;
+ if (rp->ip < addrp->ip) {
+ addrp->previousip = rp;
+ addrp->nextip = rp->nextip;
+ if (rp->nextip)
+ rp->nextip->previousip = addrp;
+ rp->nextip = addrp;
+ } else {
+ addrp->previousip = rp->previousip;
+ addrp->nextip = rp;
+ if (rp->previousip)
+ rp->previousip->nextip = addrp;
+ rp->previousip = addrp;
+ }
+ } else
+ addrp->nextip = addrp->previousip = NULL;
+ ipbash[bashnum] = addrp;
}
+
void unlinkresolveip(struct resolve *rp)
{
- dword bashnum;
- bashnum = getipbash(rp->ip);
- if (ipbash[bashnum] == rp)
- ipbash[bashnum] = (rp->previousip)? rp->previousip : rp->nextip;
- if (rp->nextip)
- rp->nextip->previousip = rp->previousip;
- if (rp->previousip)
- rp->previousip->nextip = rp->nextip;
+ dword bashnum;
+
+ bashnum = getipbash(rp->ip);
+ if (ipbash[bashnum] == rp)
+ ipbash[bashnum] = (rp->previousip)? rp->previousip : rp->nextip;
+ if (rp->nextip)
+ rp->nextip->previousip = rp->previousip;
+ if (rp->previousip)
+ rp->previousip->nextip = rp->nextip;
}
+
void linkresolve(struct resolve *rp)
{
- struct resolve *irp;
- if (expireresolves) {
- irp = expireresolves;
- while ((irp->next) && (rp->expiretime >= irp->expiretime)) irp = irp->next;
- if (rp->expiretime >= irp->expiretime) {
- rp->next = NULL;
- rp->previous = irp;
- irp->next = rp;
- lastresolve = rp;
- } else {
- rp->previous = irp->previous;
- rp->next = irp;
- if (irp->previous)
- irp->previous->next = rp;
- else
- expireresolves = rp;
- irp->previous = rp;
- }
- } else {
+ struct resolve *irp;
+
+ if (expireresolves) {
+ irp = expireresolves;
+ while ((irp->next) && (rp->expiretime >= irp->expiretime)) irp = irp->next;
+ if (rp->expiretime >= irp->expiretime) {
rp->next = NULL;
- rp->previous = NULL;
- expireresolves = lastresolve = rp;
- }
- resolvecount++;
+ rp->previous = irp;
+ irp->next = rp;
+ lastresolve = rp;
+ } else {
+ rp->previous = irp->previous;
+ rp->next = irp;
+ if (irp->previous)
+ irp->previous->next = rp;
+ else
+ expireresolves = rp;
+ irp->previous = rp;
+ }
+ } else {
+ rp->next = NULL;
+ rp->previous = NULL;
+ expireresolves = lastresolve = rp;
+ }
+ resolvecount++;
}
+
void lastlinkresolve(struct resolve *rp)
{
- struct resolve *irp;
- if (lastresolve) {
- irp = lastresolve;
- while ((irp->previous) && (rp->expiretime < irp->expiretime)) irp = irp->previous;
- while ((irp->next) && (rp->expiretime >= irp->expiretime)) irp = irp->next;
- if (rp->expiretime >= irp->expiretime) {
- rp->next = NULL;
- rp->previous = irp;
- irp->next = rp;
- lastresolve = rp;
- } else {
- rp->previous = irp->previous;
- rp->next = irp;
- if (irp->previous)
- irp->previous->next = rp;
- else
- expireresolves = rp;
- irp->previous = rp;
- }
- } else {
+ struct resolve *irp;
+
+ if (lastresolve) {
+ irp = lastresolve;
+ while ((irp->previous) && (rp->expiretime < irp->expiretime)) irp = irp->previous;
+ while ((irp->next) && (rp->expiretime >= irp->expiretime)) irp = irp->next;
+ if (rp->expiretime >= irp->expiretime) {
rp->next = NULL;
- rp->previous = NULL;
- expireresolves = lastresolve = rp;
- }
- resolvecount++;
+ rp->previous = irp;
+ irp->next = rp;
+ lastresolve = rp;
+ } else {
+ rp->previous = irp->previous;
+ rp->next = irp;
+ if (irp->previous)
+ irp->previous->next = rp;
+ else
+ expireresolves = rp;
+ irp->previous = rp;
+ }
+ } else {
+ rp->next = NULL;
+ rp->previous = NULL;
+ expireresolves = lastresolve = rp;
+ }
+ resolvecount++;
}
+
void untieresolve(struct resolve *rp)
{
- if (rp->previous)
- rp->previous->next = rp->next;
- else
- expireresolves = rp->next;
- if (rp->next)
- rp->next->previous = rp->previous;
- else
- lastresolve = rp->previous;
- resolvecount--;
+ if (rp->previous)
+ rp->previous->next = rp->next;
+ else
+ expireresolves = rp->next;
+ if (rp->next)
+ rp->next->previous = rp->previous;
+ else
+ lastresolve = rp->previous;
+ resolvecount--;
}
+
void unlinkresolve(struct resolve *rp)
{
- untieresolve(rp);
- unlinkresolveid(rp);
- unlinkresolveip(rp);
- if (rp->hostname)
- unlinkresolvehost(rp);
+ untieresolve(rp);
+ unlinkresolveid(rp);
+ unlinkresolveip(rp);
+ if (rp->hostname)
+ unlinkresolvehost(rp);
}
+
struct resolve *findid(word id)
{
- struct resolve *rp;
- int bashnum;
- bashnum = getidbash(id);
- rp = idbash[bashnum];
- if (rp) {
- while ((rp->nextid) && (id >= rp->nextid->id))
- rp = rp->nextid;
- while ((rp->previousid) && (id <= rp->previousid->id))
- rp = rp->previousid;
- if (id == rp->id) {
- idbash[bashnum] = rp;
- return rp;
- } else
- return NULL;
- }
- return rp; /* NULL */
+ struct resolve *rp;
+ int bashnum;
+
+ bashnum = getidbash(id);
+ rp = idbash[bashnum];
+ if (rp) {
+ while ((rp->nextid) && (id >= rp->nextid->id))
+ rp = rp->nextid;
+ while ((rp->previousid) && (id <= rp->previousid->id))
+ rp = rp->previousid;
+ if (id == rp->id) {
+ idbash[bashnum] = rp;
+ return rp;
+ } else
+ return NULL;
+ }
+ return rp; /* NULL */
}
+
struct resolve *findhost(char *hostname)
{
- struct resolve *rp;
- int bashnum;
- bashnum = gethostbash(hostname);
- rp = hostbash[bashnum];
- if (rp) {
- while ((rp->nexthost) && (strcasecmp(hostname,rp->nexthost->hostname) >= 0))
- rp = rp->nexthost;
- while ((rp->previoushost) && (strcasecmp(hostname,rp->nexthost->hostname) <= 0))
- rp = rp->previoushost;
- if (strcasecmp(hostname,rp->hostname))
- return NULL;
- else {
- hostbash[bashnum] = rp;
- return rp;
- }
- }
- return rp; /* NULL */
+ struct resolve *rp;
+ int bashnum;
+
+ bashnum = gethostbash(hostname);
+ rp = hostbash[bashnum];
+ if (rp) {
+ while ((rp->nexthost) && (strcasecmp(hostname,rp->nexthost->hostname) >= 0))
+ rp = rp->nexthost;
+ while ((rp->previoushost) && (strcasecmp(hostname,rp->nexthost->hostname) <= 0))
+ rp = rp->previoushost;
+ if (strcasecmp(hostname,rp->hostname))
+ return NULL;
+ else {
+ hostbash[bashnum] = rp;
+ return rp;
+ }
+ }
+ return rp; /* NULL */
}
+
struct resolve *findip(ip_t ip)
{
- struct resolve *rp;
- dword bashnum;
- bashnum = getipbash(ip);
- rp = ipbash[bashnum];
- if (rp) {
- while ((rp->nextip) && (ip >= rp->nextip->ip))
- rp = rp->nextip;
- while ((rp->previousip) && (ip <= rp->previousip->ip))
- rp = rp->previousip;
- if (ip == rp->ip) {
- ipbash[bashnum] = rp;
- return rp;
- } else
- return NULL;
- }
- return rp; /* NULL */
+ struct resolve *rp;
+ dword bashnum;
+
+ bashnum = getipbash(ip);
+ rp = ipbash[bashnum];
+ if (rp) {
+ while ((rp->nextip) && (ip >= rp->nextip->ip))
+ rp = rp->nextip;
+ while ((rp->previousip) && (ip <= rp->previousip->ip))
+ rp = rp->previousip;
+ if (ip == rp->ip) {
+ ipbash[bashnum] = rp;
+ return rp;
+ } else
+ return NULL;
+ }
+ return rp; /* NULL */
}
+
void restell(char *s)
{
- fputs(s,stderr);
- fputs("\r",stderr);
+ fputs(s,stderr);
+ fputs("\r",stderr);
}
+
void dorequest(char *s,int type,word id)
{
- packetheader *hp;
- int r,i;
- int buf[(MaxPacketsize/sizeof (int))+1];
- r = res_mkquery(QUERY,s,C_IN,type,NULL,0,NULL,(unsigned char*)buf,MaxPacketsize);
- if (r == -1) {
- restell("Resolver error: Query too large.");
- return;
- }
- hp = (packetheader *)buf;
- hp->id = id; /* htons() deliberately left out (redundant) */
- for (i = 0;i < _res.nscount;i++)
- (void)sendto(resfd,buf,r,0,(struct sockaddr *)&_res.nsaddr_list[i],
- sizeof(struct sockaddr));
+ packetheader *hp;
+ int r,i;
+ int buf[(MaxPacketsize/sizeof (int))+1];
+
+ r = res_mkquery(QUERY,s,C_IN,type,NULL,0,NULL,(unsigned char*)buf,MaxPacketsize);
+ if (r == -1) {
+ restell("Resolver error: Query too large.");
+ return;
+ }
+ hp = (packetheader *)buf;
+ hp->id = id; /* htons() deliberately left out (redundant) */
+ for (i = 0;i < _res.nscount;i++)
+ (void)sendto(resfd,buf,r,0,(struct sockaddr *)&_res.nsaddr_list[i],
+ sizeof(struct sockaddr));
}
void resendrequest(struct resolve *rp,int type)
{
- if (type == T_A) {
- dorequest(rp->hostname,type,rp->id);
- if (debug) {
- sprintf(tempstring,"Resolver: Sent reverse authentication request for \"%s\".",
- rp->hostname);
- restell(tempstring);
- }
- } else if (type == T_PTR) {
- sprintf(tempstring,"%u.%u.%u.%u.in-addr.arpa",
- ((byte *)&rp->ip)[3],
- ((byte *)&rp->ip)[2],
- ((byte *)&rp->ip)[1],
- ((byte *)&rp->ip)[0]);
- dorequest(tempstring,type,rp->id);
- if (debug) {
- sprintf(tempstring,"Resolver: Sent domain lookup request for \"%s\".",
- strlongip(rp->ip));
- restell(tempstring);
- }
- }
+ if (type == T_A) {
+ dorequest(rp->hostname,type,rp->id);
+ if (debug) {
+ sprintf(tempstring,"Resolver: Sent reverse authentication request for \"%s\".",
+ rp->hostname);
+ restell(tempstring);
+ }
+ } else if (type == T_PTR) {
+ sprintf(tempstring,"%u.%u.%u.%u.in-addr.arpa",
+ ((byte *)&rp->ip)[3],
+ ((byte *)&rp->ip)[2],
+ ((byte *)&rp->ip)[1],
+ ((byte *)&rp->ip)[0]);
+ dorequest(tempstring,type,rp->id);
+ if (debug) {
+ sprintf(tempstring,"Resolver: Sent domain lookup request for \"%s\".",
+ strlongip(rp->ip));
+ restell(tempstring);
+ }
+ }
}
void sendrequest(struct resolve *rp,int type)
{
- do {
- idseed = (((idseed + idseed) | (long)time(NULL)) + idseed - 0x54bad4a) ^ aseed;
- aseed^= idseed;
- rp->id = (word)idseed;
- } while (findid(rp->id));
- linkresolveid(rp);
- resendrequest(rp,type);
+ do {
+ idseed = (((idseed + idseed) | (long)time(NULL)) + idseed - 0x54bad4a) ^ aseed;
+ aseed^= idseed;
+ rp->id = (word)idseed;
+ } while (findid(rp->id));
+ linkresolveid(rp);
+ resendrequest(rp,type);
}
+
void failrp(struct resolve *rp)
{
- if (rp->state == STATE_FINISHED)
- return;
- rp->state = STATE_FAILED;
- untieresolve(rp);
- if (debug)
- restell("Resolver: Lookup failed.\n");
+ if (rp->state == STATE_FINISHED)
+ return;
+ rp->state = STATE_FAILED;
+ untieresolve(rp);
+ if (debug)
+ restell("Resolver: Lookup failed.\n");
}
+
void passrp(struct resolve *rp,long ttl)
{
- rp->state = STATE_FINISHED;
- rp->expiretime = sweeptime + (double)ttl;
- untieresolve(rp);
- if (debug) {
- sprintf(tempstring,"Resolver: Lookup successful: %s\n",rp->hostname);
- restell(tempstring);
- }
+ rp->state = STATE_FINISHED;
+ rp->expiretime = sweeptime + (double)ttl;
+ untieresolve(rp);
+ if (debug) {
+ sprintf(tempstring,"Resolver: Lookup successful: %s\n",rp->hostname);
+ restell(tempstring);
+ }
}
+
void parserespacket(byte *s,int l)
{
- struct resolve *rp;
- packetheader *hp;
- byte *eob;
- byte *c;
- long ttl;
- int r,usefulanswer;
- word rr,datatype,class,qdatatype,qclass;
- byte rdatalength;
- if (l < sizeof(packetheader)) {
- restell("Resolver error: Packet smaller than standard header size.");
- return;
- }
- if (l == sizeof(packetheader)) {
- restell("Resolver error: Packet has empty body.");
- return;
- }
- hp = (packetheader *)s;
- /* Convert data to host byte order */
- /* hp->id does not need to be redundantly byte-order flipped, it is only echoed by nameserver */
- rp = findid(hp->id);
- if (!rp) {
- res_unknownid++;
- return;
- }
- if ((rp->state == STATE_FINISHED) || (rp->state == STATE_FAILED))
- return;
- hp->qdcount = ntohs(hp->qdcount);
- hp->ancount = ntohs(hp->ancount);
- hp->nscount = ntohs(hp->nscount);
- hp->arcount = ntohs(hp->arcount);
- if (getheader_tc(hp)) { /* Packet truncated */
- restell("Resolver error: Nameserver packet truncated.");
- return;
- }
- if (!getheader_qr(hp)) { /* Not a reply */
- restell("Resolver error: Query packet received on nameserver communication socket.");
- return;
- }
- if (getheader_opcode(hp)) { /* Not opcode 0 (standard query) */
- restell("Resolver error: Invalid opcode in response packet.");
- return;
- }
- eob = s + l;
- c = s + HFIXEDSZ;
- switch (getheader_rcode(hp)) {
- case NOERROR:
- if (hp->ancount) {
- if (debug) {
- sprintf(tempstring,"Resolver: Received nameserver reply. (qd:%u an:%u ns:%u ar:%u)",
+ struct resolve *rp;
+ packetheader *hp;
+ byte *eob;
+ byte *c;
+ long ttl;
+ int r,usefulanswer;
+ word rr,datatype,class,qdatatype,qclass;
+ byte rdatalength;
+
+ if (l < sizeof(packetheader)) {
+ restell("Resolver error: Packet smaller than standard header size.");
+ return;
+ }
+ if (l == sizeof(packetheader)) {
+ restell("Resolver error: Packet has empty body.");
+ return;
+ }
+ hp = (packetheader *)s;
+ /* Convert data to host byte order */
+ /* hp->id does not need to be redundantly byte-order flipped, it is only echoed by nameserver */
+ rp = findid(hp->id);
+ if (!rp) {
+ res_unknownid++;
+ return;
+ }
+ if ((rp->state == STATE_FINISHED) || (rp->state == STATE_FAILED))
+ return;
+ hp->qdcount = ntohs(hp->qdcount);
+ hp->ancount = ntohs(hp->ancount);
+ hp->nscount = ntohs(hp->nscount);
+ hp->arcount = ntohs(hp->arcount);
+ if (getheader_tc(hp)) { /* Packet truncated */
+ restell("Resolver error: Nameserver packet truncated.");
+ return;
+ }
+ if (!getheader_qr(hp)) { /* Not a reply */
+ restell("Resolver error: Query packet received on nameserver communication socket.");
+ return;
+ }
+ if (getheader_opcode(hp)) { /* Not opcode 0 (standard query) */
+ restell("Resolver error: Invalid opcode in response packet.");
+ return;
+ }
+ eob = s + l;
+ c = s + HFIXEDSZ;
+ switch (getheader_rcode(hp)) {
+ case NOERROR:
+ if (hp->ancount) {
+ if (debug) {
+ sprintf(tempstring,"Resolver: Received nameserver reply. (qd:%u an:%u ns:%u ar:%u)",
hp->qdcount,hp->ancount,hp->nscount,hp->arcount);
- restell(tempstring);
- }
- if (hp->qdcount != 1) {
- restell("Resolver error: Reply does not contain one query.");
- return;
- }
- if (c > eob) {
- restell("Resolver error: Reply too short.");
- return;
- }
- switch (rp->state) { /* Construct expected query reply */
- case STATE_PTRREQ1:
- case STATE_PTRREQ2:
- case STATE_PTRREQ3:
- sprintf(stackstring,"%u.%u.%u.%u.in-addr.arpa",
- ((byte *)&rp->ip)[3],
- ((byte *)&rp->ip)[2],
- ((byte *)&rp->ip)[1],
- ((byte *)&rp->ip)[0]);
- break;
- }
- *namestring = '\0';
- r = dn_expand(s,s + l,c,namestring,MAXDNAME);
- if (r == -1) {
- restell("Resolver error: dn_expand() failed while expanding query domain.");
- return;
- }
- namestring[strlen(stackstring)] = '\0';
- if (strcasecmp(stackstring,namestring)) {
- if (debug) {
- sprintf(tempstring,"Resolver: Unknown query packet dropped. (\"%s\" does not match \"%s\")",
- stackstring,namestring);
- restell(tempstring);
- }
- return;
- }
- if (debug) {
- sprintf(tempstring,"Resolver: Queried domain name: \"%s\"",namestring);
- restell(tempstring);
- }
- c+= r;
- if (c + 4 > eob) {
- restell("Resolver error: Query resource record truncated.");
- return;
- }
- qdatatype = sucknetword(c);
- qclass = sucknetword(c);
- if (qclass != C_IN) {
- sprintf(tempstring,"Resolver error: Received unsupported query class: %u (%s)",
+ restell(tempstring);
+ }
+ if (hp->qdcount != 1) {
+ restell("Resolver error: Reply does not contain one query.");
+ return;
+ }
+ if (c > eob) {
+ restell("Resolver error: Reply too short.");
+ return;
+ }
+ switch (rp->state) { /* Construct expected query reply */
+ case STATE_PTRREQ1:
+ case STATE_PTRREQ2:
+ case STATE_PTRREQ3:
+ sprintf(stackstring,"%u.%u.%u.%u.in-addr.arpa",
+ ((byte *)&rp->ip)[3],
+ ((byte *)&rp->ip)[2],
+ ((byte *)&rp->ip)[1],
+ ((byte *)&rp->ip)[0]);
+ break;
+ }
+ *namestring = '\0';
+ r = dn_expand(s,s + l,c,namestring,MAXDNAME);
+ if (r == -1) {
+ restell("Resolver error: dn_expand() failed while expanding query domain.");
+ return;
+ }
+ namestring[strlen(stackstring)] = '\0';
+ if (strcasecmp(stackstring,namestring)) {
+ if (debug) {
+ sprintf(tempstring,"Resolver: Unknown query packet dropped. (\"%s\" does not match \"%s\")",
+ stackstring,namestring);
+ restell(tempstring);
+ }
+ return;
+ }
+ if (debug) {
+ sprintf(tempstring,"Resolver: Queried domain name: \"%s\"",namestring);
+ restell(tempstring);
+ }
+ c+= r;
+ if (c + 4 > eob) {
+ restell("Resolver error: Query resource record truncated.");
+ return;
+ }
+ qdatatype = sucknetword(c);
+ qclass = sucknetword(c);
+ if (qclass != C_IN) {
+ sprintf(tempstring,"Resolver error: Received unsupported query class: %u (%s)",
qclass,qclass < ClasstypeCount ? classtypes[qclass] :
- classtypes[ClasstypeCount]);
- restell(tempstring);
- }
- switch (qdatatype) {
- case T_PTR:
- if (!Is_PTR(rp))
- if (debug) {
- restell("Resolver warning: Ignoring response with unexpected query type \"PTR\".");
- return;
- }
- break;
- default:
- sprintf(tempstring,"Resolver error: Received unimplemented query type: %u (%s)",
- qdatatype,qdatatype < ResourcetypeCount ?
- resourcetypes[qdatatype] : resourcetypes[ResourcetypeCount]);
- restell(tempstring);
- }
- for (rr = hp->ancount + hp->nscount + hp->arcount;rr;rr--) {
- if (c > eob) {
- restell("Resolver error: Packet does not contain all specified resouce records.");
- return;
- }
- *namestring = '\0';
- r = dn_expand(s,s + l,c,namestring,MAXDNAME);
- if (r == -1) {
- restell("Resolver error: dn_expand() failed while expanding answer domain.");
- return;
- }
- namestring[strlen(stackstring)] = '\0';
- if (strcasecmp(stackstring,namestring))
- usefulanswer = 0;
- else
- usefulanswer = 1;
- if (debug) {
- sprintf(tempstring,"Resolver: answered domain query: \"%s\"",namestring);
- restell(tempstring);
- }
- c+= r;
- if (c + 10 > eob) {
- restell("Resolver error: Resource record truncated.");
- return;
- }
- datatype = sucknetword(c);
- class = sucknetword(c);
- ttl = sucknetlong(c);
- rdatalength = sucknetword(c);
- if (class != qclass) {
- sprintf(tempstring,"query class: %u (%s)",qclass,qclass < ClasstypeCount ?
- classtypes[qclass] : classtypes[ClasstypeCount]);
- restell(tempstring);
- sprintf(tempstring,"rr class: %u (%s)",class,class < ClasstypeCount ?
- classtypes[class] : classtypes[ClasstypeCount]);
- restell(tempstring);
- restell("Resolver error: Answered class does not match queried class.");
- return;
- }
- if (!rdatalength) {
- restell("Resolver error: Zero size rdata.");
- return;
- }
- if (c + rdatalength > eob) {
- restell("Resolver error: Specified rdata length exceeds packet size.");
- return;
- }
- if (datatype == qdatatype || datatype == T_CNAME) {
- if (debug) {
- sprintf(tempstring,"Resolver: TTL: %s",strtdiff(sendstring,ttl));
- restell(tempstring);
- }
- if (usefulanswer)
- switch (datatype) {
- case T_A:
- if (rdatalength != 4) {
- sprintf(tempstring,"Resolver error: Unsupported rdata format for \"A\" type. (%u bytes)",
- rdatalength);
- restell(tempstring);
- return;
- }
- if (memcmp(&rp->ip,(ip_t *)c,sizeof(ip_t))) {
- sprintf(tempstring,"Resolver: Reverse authentication failed: %s != ",
- strlongip(rp->ip));
- memcpy(&alignedip,(ip_t *)c,sizeof(ip_t));
- strcat(tempstring,strlongip(alignedip));
- restell(tempstring);
- res_hostipmismatch++;
- failrp(rp);
- } else {
- sprintf(tempstring,"Resolver: Reverse authentication complete: %s == \"%s\".",
- strlongip(rp->ip),nonull(rp->hostname));
- restell(tempstring);
- res_reversesuccess++;
- passrp(rp,ttl);
- return;
- }
- break;
- case T_PTR:
- case T_CNAME:
- *namestring = '\0';
- r = dn_expand(s,s + l,c,namestring,MAXDNAME);
- if (r == -1) {
- restell("Resolver error: dn_expand() failed while expanding domain in rdata.");
- return;
- }
- if (debug) {
- sprintf(tempstring,"Resolver: Answered domain: \"%s\"",namestring);
- restell(tempstring);
- }
- if (r > HostnameLength) {
- restell("Resolver error: Domain name too long.");
- failrp(rp);
- return;
- }
- if (datatype == T_CNAME) {
- strcpy(stackstring,namestring);
- break;
- }
- if (!rp->hostname) {
- rp->hostname = (char *)statmalloc(strlen(namestring) + 1);
- if (!rp->hostname) {
- fprintf(stderr,"statmalloc() error: %s\n",strerror(errno));
- exit(-1);
- }
- strcpy(rp->hostname,namestring);
- linkresolvehost(rp);
- passrp(rp,ttl);
- res_iplookupsuccess++;
- }
- break;
- default:
- sprintf(tempstring,"Resolver error: Received unimplemented data type: %u (%s)",
- datatype,datatype < ResourcetypeCount ?
- resourcetypes[datatype] : resourcetypes[ResourcetypeCount]);
- restell(tempstring);
- }
- } else {
- if (debug) {
- sprintf(tempstring,"Resolver: Ignoring resource type %u. (%s)",
- datatype,datatype < ResourcetypeCount ?
- resourcetypes[datatype] : resourcetypes[ResourcetypeCount]);
- restell(tempstring);
- }
- }
- c+= rdatalength;
- }
- } else
- restell("Resolver error: No error returned but no answers given.");
- break;
- case NXDOMAIN:
- if (debug)
- restell("Resolver: Host not found.");
- res_nxdomain++;
- failrp(rp);
- break;
+ classtypes[ClasstypeCount]);
+ restell(tempstring);
+ }
+ switch (qdatatype) {
+ case T_PTR:
+ if (!Is_PTR(rp))
+ if (debug) {
+ restell("Resolver warning: Ignoring response with unexpected query type \"PTR\".");
+ return;
+ }
+ break;
default:
- sprintf(tempstring,"Resolver: Received error response %u. (%s)",
- getheader_rcode(hp),getheader_rcode(hp) < ResponsecodeCount ?
- responsecodes[getheader_rcode(hp)] : responsecodes[ResponsecodeCount]);
- restell(tempstring);
- res_nserror++;
- }
+ sprintf(tempstring,"Resolver error: Received unimplemented query type: %u (%s)",
+ qdatatype,qdatatype < ResourcetypeCount ?
+ resourcetypes[qdatatype] : resourcetypes[ResourcetypeCount]);
+ restell(tempstring);
+ }
+ for (rr = hp->ancount + hp->nscount + hp->arcount;rr;rr--) {
+ if (c > eob) {
+ restell("Resolver error: Packet does not contain all specified resouce records.");
+ return;
+ }
+ *namestring = '\0';
+ r = dn_expand(s,s + l,c,namestring,MAXDNAME);
+ if (r == -1) {
+ restell("Resolver error: dn_expand() failed while expanding answer domain.");
+ return;
+ }
+ namestring[strlen(stackstring)] = '\0';
+ if (strcasecmp(stackstring,namestring))
+ usefulanswer = 0;
+ else
+ usefulanswer = 1;
+ if (debug) {
+ sprintf(tempstring,"Resolver: answered domain query: \"%s\"",namestring);
+ restell(tempstring);
+ }
+ c+= r;
+ if (c + 10 > eob) {
+ restell("Resolver error: Resource record truncated.");
+ return;
+ }
+ datatype = sucknetword(c);
+ class = sucknetword(c);
+ ttl = sucknetlong(c);
+ rdatalength = sucknetword(c);
+ if (class != qclass) {
+ sprintf(tempstring,"query class: %u (%s)",qclass,qclass < ClasstypeCount ?
+ classtypes[qclass] : classtypes[ClasstypeCount]);
+ restell(tempstring);
+ sprintf(tempstring,"rr class: %u (%s)",class,class < ClasstypeCount ?
+ classtypes[class] : classtypes[ClasstypeCount]);
+ restell(tempstring);
+ restell("Resolver error: Answered class does not match queried class.");
+ return;
+ }
+ if (!rdatalength) {
+ restell("Resolver error: Zero size rdata.");
+ return;
+ }
+ if (c + rdatalength > eob) {
+ restell("Resolver error: Specified rdata length exceeds packet size.");
+ return;
+ }
+ if (datatype == qdatatype || datatype == T_CNAME) {
+ if (debug) {
+ sprintf(tempstring,"Resolver: TTL: %s",strtdiff(sendstring,ttl));
+ restell(tempstring);
+ }
+ if (usefulanswer)
+ switch (datatype) {
+ case T_A:
+ if (rdatalength != 4) {
+ sprintf(tempstring,"Resolver error: Unsupported rdata format for \"A\" type. (%u bytes)",
+ rdatalength);
+ restell(tempstring);
+ return;
+ }
+ if (memcmp(&rp->ip,(ip_t *)c,sizeof(ip_t))) {
+ sprintf(tempstring,"Resolver: Reverse authentication failed: %s != ",
+ strlongip(rp->ip));
+ memcpy(&alignedip,(ip_t *)c,sizeof(ip_t));
+ strcat(tempstring,strlongip(alignedip));
+ restell(tempstring);
+ res_hostipmismatch++;
+ failrp(rp);
+ } else {
+ sprintf(tempstring,"Resolver: Reverse authentication complete: %s == \"%s\".",
+ strlongip(rp->ip),nonull(rp->hostname));
+ restell(tempstring);
+ res_reversesuccess++;
+ passrp(rp,ttl);
+ return;
+ }
+ break;
+ case T_PTR:
+ case T_CNAME:
+ *namestring = '\0';
+ r = dn_expand(s,s + l,c,namestring,MAXDNAME);
+ if (r == -1) {
+ restell("Resolver error: dn_expand() failed while expanding domain in rdata.");
+ return;
+ }
+ if (debug) {
+ sprintf(tempstring,"Resolver: Answered domain: \"%s\"",namestring);
+ restell(tempstring);
+ }
+ if (r > HostnameLength) {
+ restell("Resolver error: Domain name too long.");
+ failrp(rp);
+ return;
+ }
+ if (datatype == T_CNAME) {
+ strcpy(stackstring,namestring);
+ break;
+ }
+ if (!rp->hostname) {
+ rp->hostname = (char *)statmalloc(strlen(namestring) + 1);
+ if (!rp->hostname) {
+ fprintf(stderr,"statmalloc() error: %s\n",strerror(errno));
+ exit(-1);
+ }
+ strcpy(rp->hostname,namestring);
+ linkresolvehost(rp);
+ passrp(rp,ttl);
+ res_iplookupsuccess++;
+ }
+ break;
+ default:
+ sprintf(tempstring,"Resolver error: Received unimplemented data type: %u (%s)",
+ datatype,datatype < ResourcetypeCount ?
+ resourcetypes[datatype] : resourcetypes[ResourcetypeCount]);
+ restell(tempstring);
+ }
+ } else {
+ if (debug) {
+ sprintf(tempstring,"Resolver: Ignoring resource type %u. (%s)",
+ datatype,datatype < ResourcetypeCount ?
+ resourcetypes[datatype] : resourcetypes[ResourcetypeCount]);
+ restell(tempstring);
+ }
+ }
+ c+= rdatalength;
+ }
+ } else
+ restell("Resolver error: No error returned but no answers given.");
+ break;
+ case NXDOMAIN:
+ if (debug)
+ restell("Resolver: Host not found.");
+ res_nxdomain++;
+ failrp(rp);
+ break;
+ default:
+ sprintf(tempstring,"Resolver: Received error response %u. (%s)",
+ getheader_rcode(hp),getheader_rcode(hp) < ResponsecodeCount ?
+ responsecodes[getheader_rcode(hp)] : responsecodes[ResponsecodeCount]);
+ restell(tempstring);
+ res_nserror++;
+ }
}
+
void dns_ack(void)
{
- int r,i;
- r = recvfrom(resfd,(byte *)resrecvbuf,MaxPacketsize,0,(struct sockaddr *)&from,&fromlen);
- if (r > 0) {
- /* Check to see if this server is actually one we sent to */
- if (from.sin_addr.s_addr == localhost) {
- for (i = 0;i < _res.nscount;i++)
- if ((_res.nsaddr_list[i].sin_addr.s_addr == from.sin_addr.s_addr) ||
- (!_res.nsaddr_list[i].sin_addr.s_addr)) /* 0.0.0.0 replies as 127.0.0.1 */
- break;
- } else
- for (i = 0;i < _res.nscount;i++)
- if (_res.nsaddr_list[i].sin_addr.s_addr == from.sin_addr.s_addr)
- break;
- if (i == _res.nscount) {
- sprintf(tempstring,"Resolver error: Received reply from unknown source: %s",
- inet_ntoa(from.sin_addr));
- restell(tempstring);
- } else
- parserespacket((byte *)resrecvbuf,r);
- } else {
- sprintf(tempstring,"Resolver: Socket error: %s",strerror(errno));
+ int r,i;
+
+ r = recvfrom(resfd,(byte *)resrecvbuf,MaxPacketsize,0,(struct sockaddr *)&from,&fromlen);
+ if (r > 0) {
+ /* Check to see if this server is actually one we sent to */
+ if (from.sin_addr.s_addr == localhost) {
+ for (i = 0;i < _res.nscount;i++)
+ if ((_res.nsaddr_list[i].sin_addr.s_addr == from.sin_addr.s_addr) ||
+ (!_res.nsaddr_list[i].sin_addr.s_addr)) /* 0.0.0.0 replies as 127.0.0.1 */
+ break;
+ } else
+ for (i = 0;i < _res.nscount;i++)
+ if (_res.nsaddr_list[i].sin_addr.s_addr == from.sin_addr.s_addr)
+ break;
+ if (i == _res.nscount) {
+ sprintf(tempstring,"Resolver error: Received reply from unknown source: %s",
+ inet_ntoa(from.sin_addr));
restell(tempstring);
- }
+ } else
+ parserespacket((byte *)resrecvbuf,r);
+ } else {
+ sprintf(tempstring,"Resolver: Socket error: %s",strerror(errno));
+ restell(tempstring);
+ }
}
+
int istime(double x,double *sinterval)
{
if (x) {
- if (x > sweeptime) {
- if (*sinterval > x - sweeptime)
- *sinterval = x - sweeptime;
- } else
- return 1;
+ if (x > sweeptime) {
+ if (*sinterval > x - sweeptime)
+ *sinterval = x - sweeptime;
+ } else
+ return 1;
}
return 0;
}
+
void dns_events(double *sinterval)
{
- struct resolve *rp,*nextrp;
- for (rp = expireresolves;(rp) && (sweeptime >= rp->expiretime);rp = nextrp) {
- nextrp = rp->next;
- switch (rp->state) {
- case STATE_FINISHED: /* TTL has expired */
- case STATE_FAILED: /* Fake TTL has expired */
- if (debug) {
- sprintf(tempstring,"Resolver: Cache record for \"%s\" (%s) has expired. (state: %u) Marked for expire at: %g, time: %g.",
+ struct resolve *rp,*nextrp;
+
+ for (rp = expireresolves;(rp) && (sweeptime >= rp->expiretime);rp = nextrp) {
+ nextrp = rp->next;
+ switch (rp->state) {
+ case STATE_FINISHED: /* TTL has expired */
+ case STATE_FAILED: /* Fake TTL has expired */
+ if (debug) {
+ sprintf(tempstring,"Resolver: Cache record for \"%s\" (%s) has expired. (state: %u) Marked for expire at: %g, time: %g.",
nonull(rp->hostname),strlongip(rp->ip),rp->state,rp->expiretime,sweeptime);
- restell(tempstring);
- }
- unlinkresolve(rp);
- break;
- case STATE_PTRREQ1: /* First T_PTR send timed out */
- resendrequest(rp,T_PTR);
- restell("Resolver: Send #2 for \"PTR\" query...");
- rp->state++;
- rp->expiretime = sweeptime + ResRetryDelay2;
- (void)istime(rp->expiretime,sinterval);
- res_resend++;
- break;
- case STATE_PTRREQ2: /* Second T_PTR send timed out */
- resendrequest(rp,T_PTR);
- restell("Resolver: Send #3 for \"PTR\" query...");
- rp->state++;
- rp->expiretime = sweeptime + ResRetryDelay3;
- (void)istime(rp->expiretime,sinterval);
- res_resend++;
- break;
- case STATE_PTRREQ3: /* Third T_PTR timed out */
- restell("Resolver: \"PTR\" query timed out.");
- failrp(rp);
- (void)istime(rp->expiretime,sinterval);
- res_timeout++;
- break;
+ restell(tempstring);
}
- }
- if (expireresolves)
- (void)istime(expireresolves->expiretime,sinterval);
+ unlinkresolve(rp);
+ break;
+ case STATE_PTRREQ1: /* First T_PTR send timed out */
+ resendrequest(rp,T_PTR);
+ restell("Resolver: Send #2 for \"PTR\" query...");
+ rp->state++;
+ rp->expiretime = sweeptime + ResRetryDelay2;
+ (void)istime(rp->expiretime,sinterval);
+ res_resend++;
+ break;
+ case STATE_PTRREQ2: /* Second T_PTR send timed out */
+ resendrequest(rp,T_PTR);
+ restell("Resolver: Send #3 for \"PTR\" query...");
+ rp->state++;
+ rp->expiretime = sweeptime + ResRetryDelay3;
+ (void)istime(rp->expiretime,sinterval);
+ res_resend++;
+ break;
+ case STATE_PTRREQ3: /* Third T_PTR timed out */
+ restell("Resolver: \"PTR\" query timed out.");
+ failrp(rp);
+ (void)istime(rp->expiretime,sinterval);
+ res_timeout++;
+ break;
+ }
+ }
+ if (expireresolves)
+ (void)istime(expireresolves->expiretime,sinterval);
}
+
char *dns_lookup2(ip_t ip)
{
- struct resolve *rp;
- ip = htonl(ip);
- if ((rp = findip(ip))) {
- if ((rp->state == STATE_FINISHED) || (rp->state == STATE_FAILED)) {
- if ((rp->state == STATE_FINISHED) && (rp->hostname)) {
- if (debug) {
- sprintf(tempstring,"Resolver: Used cached record: %s == \"%s\".\n",
- strlongip(ip),rp->hostname);
- restell(tempstring);
- }
- return rp->hostname;
- } else {
- if (debug) {
- sprintf(tempstring,"Resolver: Used failed record: %s == ???\n",
- strlongip(ip));
- restell(tempstring);
- }
- return NULL;
- }
+ struct resolve *rp;
+
+ ip = htonl(ip);
+ if ((rp = findip(ip))) {
+ if ((rp->state == STATE_FINISHED) || (rp->state == STATE_FAILED)) {
+ if ((rp->state == STATE_FINISHED) && (rp->hostname)) {
+ if (debug) {
+ sprintf(tempstring,"Resolver: Used cached record: %s == \"%s\".\n",
+ strlongip(ip),rp->hostname);
+ restell(tempstring);
+ }
+ return rp->hostname;
+ } else {
+ if (debug) {
+ sprintf(tempstring,"Resolver: Used failed record: %s == ???\n",
+ strlongip(ip));
+ restell(tempstring);
+ }
+ return NULL;
}
- return NULL;
- }
- if (debug)
- fprintf(stderr,"Resolver: Added to new record.\n");
- rp = allocresolve();
- rp->state = STATE_PTRREQ1;
- rp->expiretime = sweeptime + ResRetryDelay1;
- rp->ip = ip;
- linkresolve(rp);
- rp->ip = ip;
- linkresolveip(rp);
- sendrequest(rp,T_PTR);
- return NULL;
+ }
+ return NULL;
+ }
+ if (debug)
+ fprintf(stderr,"Resolver: Added to new record.\n");
+ rp = allocresolve();
+ rp->state = STATE_PTRREQ1;
+ rp->expiretime = sweeptime + ResRetryDelay1;
+ rp->ip = ip;
+ linkresolve(rp);
+ rp->ip = ip;
+ linkresolveip(rp);
+ sendrequest(rp,T_PTR);
+ return NULL;
}
-int use_dns = 1;
char *dns_lookup(ip_t ip)
{
#include "net.h"
-#ifndef HAVE_SETEUID
-/* HPUX doesn't have seteuid, but setuid works fine in that case for us */
-#define seteuid setuid
-#endif
-
-int DisplayMode;
-int display_mode;
-int Interactive = 1;
-int PrintVersion = 0;
-int PrintHelp = 0;
-int MaxPing = 10;
-int ForceMaxPing = 0;
-float WaitTime = 1.0;
-char *Hostname = NULL;
-char *InterfaceAddress = NULL;
-char LocalHostname[128];
-int dns = 1;
-int packetsize = 64; /* default packet size */
-int bitpattern = 0;
-int tos = 0;
-/* begin ttl windows addByMin */
-int fstTTL = 1; /* default start at first hop */
-//int maxTTL = MaxHost-1; /* max you can go is 255 hops */
-int maxTTL = 30; /* inline with traceroute */
-/* end ttl */
-
#ifdef ENABLE_IPV6
#define DEFAULT_AF AF_UNSPEC
#else
#ifdef NO_HERROR
-#define herror(str) printf(str ": error looking up \"%s\"\n", Hostname);
+#define herror(str) fprintf(stderr, str ": error looking up \"%s\"\n", Hostname);
#endif
+
+int DisplayMode;
+int display_mode;
+int Interactive = 1;
+int PrintVersion = 0;
+int PrintHelp = 0;
+int MaxPing = 10;
+int ForceMaxPing = 0;
+float WaitTime = 1.0;
+char *Hostname = NULL;
+char *InterfaceAddress = NULL;
+char LocalHostname[128];
+int dns = 1;
+int packetsize = 64; /* default packet size */
+int bitpattern = 0;
+int tos = 0;
int af = DEFAULT_AF;
+ /* begin ttl windows addByMin */
+int fstTTL = 1; /* default start at first hop */
+//int maxTTL = MaxHost-1; /* max you can go is 255 hops */
+int maxTTL = 30; /* inline with traceroute */
+ /* end ttl window stuff. */
+
+
/* default display field(defined by key in net.h) and order */
unsigned char fld_active[2*MAXFLD] = "LS NABWV";
-char fld_index[256];
-char available_options[MAXFLD];
+char fld_index[256];
+char available_options[MAXFLD];
struct fields data_fields[MAXFLD] = {
/* key, Remark, Header, Format, Width, CallBackFunc */
- {' ', "<sp>: Space between fields", " ", " ", 1, &net_drop }, /* 0 */
- {'L', "L: Loss Ratio", "Loss%", " %4.1f%%", 6, &net_loss }, /* 1 */
- {'D', "D: Dropped Packets", "Drop", " %4d", 5, &net_drop }, /* 2 */
- {'R', "R: Received Packets", "Rcv", " %5d", 6, &net_returned}, /* 3 */
- {'S', "S: Sent Packets", "Snt", " %5d", 6, &net_xmit }, /* 4 */
- {'N', "N: Newest RTT(ms)", "Last", " %5.1f", 6, &net_last }, /* 5 */
- {'B', "B: Min/Best RTT(ms)", "Best", " %5.1f", 6, &net_best }, /* 6 */
- {'A', "A: Average RTT(ms)", "Avg", " %5.1f", 6, &net_avg }, /* 7 */
- {'W', "W: Max/Worst RTT(ms)", "Wrst", " %5.1f", 6, &net_worst }, /* 8 */
- {'V', "V: Standard Deviation", "StDev", " %5.1f", 6, &net_stdev }, /* 9 */
- {'G', "G: Geometric Mean", "Gmean", " %5.1f", 6, &net_gmean }, /* 10 */
- {'J', "J: Current Jitter", "Jttr", " %4.1f", 5, &net_jitter}, /* 11 */
- {'M', "M: Jitter Mean/Avg.", "Javg", " %4.1f", 5, &net_javg }, /* 12 */
- {'X', "X: Worst Jitter", "Jmax", " %4.1f", 5, &net_jworst}, /* 13 */
- {'I', "I: Interarrival Jitter", "Jint", " %4.1f", 5, &net_jinta }, /* 14 */
- {'\0', 0, 0, 0, 0, 0 }
+ {' ', "<sp>: Space between fields", " ", " ", 1, &net_drop },
+ {'L', "L: Loss Ratio", "Loss%", " %4.1f%%", 6, &net_loss },
+ {'D', "D: Dropped Packets", "Drop", " %4d", 5, &net_drop },
+ {'R', "R: Received Packets", "Rcv", " %5d", 6, &net_returned},
+ {'S', "S: Sent Packets", "Snt", " %5d", 6, &net_xmit },
+ {'N', "N: Newest RTT(ms)", "Last", " %5.1f", 6, &net_last },
+ {'B', "B: Min/Best RTT(ms)", "Best", " %5.1f", 6, &net_best },
+ {'A', "A: Average RTT(ms)", "Avg", " %5.1f", 6, &net_avg },
+ {'W', "W: Max/Worst RTT(ms)", "Wrst", " %5.1f", 6, &net_worst },
+ {'V', "V: Standard Deviation", "StDev", " %5.1f", 6, &net_stdev },
+ {'G', "G: Geometric Mean", "Gmean", " %5.1f", 6, &net_gmean },
+ {'J', "J: Current Jitter", "Jttr", " %4.1f", 5, &net_jitter},
+ {'M', "M: Jitter Mean/Avg.", "Javg", " %4.1f", 5, &net_javg },
+ {'X', "X: Worst Jitter", "Jmax", " %4.1f", 5, &net_jworst},
+ {'I', "I: Interarrival Jitter", "Jint", " %4.1f", 5, &net_jinta },
+ {'\0', NULL, NULL, NULL, 0, NULL}
};
}
-void parse_arg(int argc, char **argv)
+void parse_arg (int argc, char **argv)
{
int opt;
int i;
break;
case 's':
packetsize = atoi (optarg);
- if( packetsize >=0 ) {
- if ( packetsize < MINPACKET ) packetsize = MINPACKET;
- if ( packetsize > MAXPACKET ) packetsize = MAXPACKET;
+ if (packetsize >=0) {
+ if (packetsize < MINPACKET) packetsize = MINPACKET;
+ if (packetsize > MAXPACKET) packetsize = MAXPACKET;
}
break;
case 'a':
break;
case 'f':
fstTTL = atoi (optarg);
- if( fstTTL > maxTTL ) {
+ if (fstTTL > maxTTL) {
fstTTL = maxTTL;
}
- if( fstTTL < 1) { /* prevent 0 hop */
+ if (fstTTL < 1) { /* prevent 0 hop */
fstTTL = 1;
}
break;
case 'm':
maxTTL = atoi (optarg);
- if( maxTTL > (MaxHost - 1) ) {
+ if (maxTTL > (MaxHost - 1)) {
maxTTL = MaxHost-1;
}
- if( maxTTL < 1) { /* prevent 0 hop */
+ if (maxTTL < 1) { /* prevent 0 hop */
maxTTL = 1;
}
if (fstTTL > maxTTL) { /* don't know the pos of -m or -f */
exit (1);
}
for (i=0; optarg[i]; i++) {
- if(!strchr(available_options, optarg[i])) {
+ if(!strchr (available_options, optarg[i])) {
fprintf (stderr, "Unknown field identifier: %c\n", optarg[i]);
exit (1);
}
break;
case 'b':
bitpattern = atoi (optarg);
- if( bitpattern > 255 )
+ if (bitpattern > 255)
bitpattern = -1;
break;
case 'Q':
tos = atoi (optarg);
- if( tos > 255 || tos <0 ) {
+ if (tos > 255 || tos < 0) {
/* error message, should do more checking for valid values,
* details in rfc2474 */
tos = 0;
break;
}
}
-
- if(DisplayMode == DisplayReport ||
- DisplayMode == DisplayTXT ||
- DisplayMode == DisplayXML ||
- DisplayMode == DisplayRaw ||
- DisplayMode == DisplayCSV )
+
+ if (DisplayMode == DisplayReport ||
+ DisplayMode == DisplayTXT ||
+ DisplayMode == DisplayXML ||
+ DisplayMode == DisplayRaw ||
+ DisplayMode == DisplayCSV)
Interactive = 0;
- if(optind > argc - 1)
+ if (optind > argc - 1)
return;
Hostname = argv[optind++];
if (argc > optind) {
- packetsize = atoi(argv[optind]);
- if( packetsize >=0 ) {
- if ( packetsize < MINPACKET ) packetsize = MINPACKET;
- if ( packetsize > MAXPACKET ) packetsize = MAXPACKET;
+ packetsize = atoi (argv[optind]);
+ if (packetsize >=0 ) {
+ if (packetsize < MINPACKET) packetsize = MINPACKET;
+ if (packetsize > MAXPACKET) packetsize = MAXPACKET;
}
}
}
}
-int main(int argc, char **argv) {
+int main(int argc, char **argv)
+{
int traddr;
struct hostent * host = NULL;
int net_preopen_result;
net_preopen_result = net_preopen ();
/* Now drop to user permissions */
- if(setuid(getuid())) {
- printf("mtr: Unable to drop permissions.\n");
+ if (setuid(getuid())) {
+ fprintf (stderr, "mtr: Unable to drop permissions.\n");
exit(1);
}
/* Double check, just in case */
- if(geteuid() != getuid()) {
- printf("mtr: Unable to drop permissions.\n");
+ if (geteuid() != getuid()) {
+ fprintf (stderr, "mtr: Unable to drop permissions.\n");
exit(1);
}
/* reset the random seed */
- srand(getpid());
+ srand (getpid());
display_detect(&argc, &argv);
parse_mtr_options (getenv ("MTR_OPTIONS"));
- parse_arg(argc, argv);
+ parse_arg (argc, argv);
- if(PrintVersion) {
- printf("mtr " VERSION "\n");
+ if (PrintVersion) {
+ printf ("mtr " VERSION "\n");
exit(0);
}
- if(PrintHelp) {
+ if (PrintHelp) {
printf("usage: %s [-hvrctglsni] [--help] [--version] [--report]\n"
"\t\t[--report-cycles=COUNT] [--curses] [--gtk]\n"
"\t\t[--raw] [--split] [--no-dns] [--address interface]\n" /* BL */
"\t\t[--interval=SECONDS] HOSTNAME [PACKETSIZE]\n", argv[0]);
exit(0);
}
+
if (Hostname == NULL) Hostname = "localhost";
- if(gethostname(LocalHostname, sizeof(LocalHostname))) {
+ if (gethostname(LocalHostname, sizeof(LocalHostname))) {
strcpy(LocalHostname, "UNKNOWNHOST");
}
- if(net_preopen_result != 0) {
- printf("mtr: Unable to get raw socket. (Executable not suid?)\n");
+ if (net_preopen_result != 0) {
+ fprintf(stderr, "mtr: Unable to get raw socket. (Executable not suid?)\n");
exit(1);
}
-
- if (InterfaceAddress) { /* Mostly borrowed from ping(1) code */
- int i1, i2, i3, i4;
- char dummy;
- extern int sendsock; /* from net.c:118 */
- extern struct sockaddr_in sourceaddress; /* from net.c:120 */
-
- sourceaddress.sin_family = AF_INET;
- sourceaddress.sin_port = 0;
- sourceaddress.sin_addr.s_addr = 0;
-
- if(sscanf(InterfaceAddress, "%u.%u.%u.%u%c", &i1, &i2, &i3, &i4, &dummy) != 4) {
- printf("mtr: bad interface address: %s\n", InterfaceAddress);
- exit(1);
- } else {
- unsigned char *ptr;
- ptr = (unsigned char*)&sourceaddress.sin_addr;
- ptr[0] = i1;
- ptr[1] = i2;
- ptr[2] = i3;
- ptr[3] = i4;
- }
-
- if(bind(sendsock, (struct sockaddr*)&sourceaddress, sizeof(sourceaddress)) == -1) {
- perror("mtr: failed to bind to interface");
- exit(1);
- }
+
+ if (net_set_interfaceaddress (InterfaceAddress) != 0) {
+ fprintf (stderr, "mtr: Couldn't set interface addres.\n");
+ exit (1);
}
#ifdef ENABLE_IPV6
host = gethostbyname2(Hostname, af);
}
- if(host == NULL) {
+ if (host == NULL) {
herror("mtr");
exit(1);
}
- traddr = *(int *)host->h_addr;
-
- if(net_open(traddr) != 0) {
- printf("mtr: Unable to get raw socket. (Executable not suid?)\n");
- exit(1);
- }
-
switch (af) {
case AF_INET:
traddr = *(int *)host->h_addr;
- if(net_open(traddr) != 0) {
- printf("mtr: Unable to get raw socket. (Executable not suid?)\n");
+ if (net_open(traddr) != 0) {
+ fprintf(stderr, "mtr: Unable to start net module.\n");
exit(1);
}
break;
#include "display.h"
-#define MaxTransit 4
-
/* We can't rely on header files to provide this information, because
the fields have different names between, for instance, Linux and
Solaris */
uint16 sequence;
};
+
/* Structure of an IP header. */
struct IPHeader {
uint8 version;
uint32 daddr;
};
+
#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0
#define SOL_IP 0
#endif
-#define saddr_correction(addr) BSDfix ? addr : 0
-
struct nethost {
uint32 addr;
uint32 addrs[MAXPATH]; /* for multi paths byMin */
int saved_seq_offset;
};
+
struct sequence {
- int index;
- int transit;
- int saved_seq;
- struct timeval time;
+ int index;
+ int transit;
+ int saved_seq;
+ struct timeval time;
};
/* Configuration parameter: How many queries to unknown hosts do we
send? (This limits the amount of traffic generated if a host is not
- reachable) */
+ reachable) -- REW */
#define MAX_UNKNOWN_HOSTS 5
+/* There is something stupid with BSD. We now detect this automatically */
+static int BSDfix = 0;
+#define saddr_correction(addr) BSDfix ? addr : 0
+
static struct nethost host[MaxHost];
static struct sequence sequence[MaxSequence];
static struct timeval reset = { 0, 0 };
-int timestamp;
-int sendsock;
-int recvsock;
+int timestamp;
+int sendsock;
+int recvsock;
struct sockaddr_in sourceaddress;
struct sockaddr_in remoteaddress;
+/* XXX How do I code this to be IPV6 compatible??? -- REW */
+struct in_addr localaddr;
+
static int batch_at = 0;
static int numhosts = 10;
+
extern int fstTTL; /* initial hub(ttl) to ping byMin */
extern int maxTTL; /* last hub to ping byMin*/
extern int packetsize; /* packet size used by ping */
extern int tos; /* type of service set in ping packet*/
+
/* return the number of microseconds to wait before sending the next
ping */
int calc_deltatime (float waittime)
/* This doesn't work for odd sz. I don't know enough about this to say
that this is wrong. It doesn't seem to cripple mtr though. -- REW */
-int checksum(void *data, int sz) {
+int checksum(void *data, int sz)
+{
unsigned short *ch;
unsigned int sum;
sum = 0;
ch = data;
sz = sz / 2;
- while(sz--) {
+ while (sz--) {
sum += *(ch++);
}
}
-static int BSDfix = 0;
-
-int new_sequence(int index) {
+int new_sequence(int index)
+{
static int next_sequence = 0;
int seq;
seq = next_sequence++;
- if(next_sequence >= MaxSequence)
+ if (next_sequence >= MaxSequence)
next_sequence = 0;
sequence[seq].index = index;
return seq;
}
+
/* Attempt to find the host at a particular number of hops away */
void net_send_query(int index)
{
first = 0;
}
+
/* We got a return on something we sent out. Record the address and
time. */
-void net_process_ping(int seq, uint32 addr, struct timeval now) {
+void net_process_ping(int seq, uint32 addr, struct timeval now)
+{
int index;
int totusec;
int oldavg; /* usedByMin */
int oldjavg; /* usedByMin */
int i; /* usedByMin */
- if(seq < 0 || seq >= MaxSequence)
+ if (seq < 0 || seq >= MaxSequence)
return;
- if(!sequence[seq].transit)
+ if (!sequence[seq].transit)
return;
sequence[seq].transit = 0;
(now.tv_usec - sequence[seq].time.tv_usec);
/* impossible? if( totusec < 0 ) totusec = 0 */;
- if(host[index].addr == 0) {
+ if (host[index].addr == 0) {
host[index].addr = addr; // should be out of if as addr can change
display_rawhost(index, host[index].addr);
}
host[index].jitter = totusec - host[index].last;
- if( host[index].jitter < 0 ) host[index].jitter = - host[index].jitter;
+ if (host[index].jitter < 0 ) host[index].jitter = - host[index].jitter;
host[index].last = totusec;
- if(host[index].returned < 1) {
+ if (host[index].returned < 1) {
host[index].best = host[index].worst = host[index].gmean = totusec;
host[index].avg = host[index].var = 0;
* safe guard 1) best[index]>=best[index-1] if index>0
* 2) best >= average-20,000 usec (good number?)
* Min
- if( index > 0 ) {
- if(totusec < host[index].best &&
- totusec>= host[index-1].best ) host[index].best = totusec;
+ if (index > 0) {
+ if (totusec < host[index].best &&
+ totusec>= host[index-1].best) host[index].best = totusec;
} else {
- if(totusec < host[index].best ) host[index].best = totusec;
+ if(totusec < host[index].best) host[index].best = totusec;
}
*/
- if(totusec < host[index].best ) host[index].best = totusec;
- if(totusec > host[index].worst) host[index].worst = totusec;
+ if (totusec < host[index].best ) host[index].best = totusec;
+ if (totusec > host[index].worst) host[index].worst = totusec;
- if(host[index].jitter > host[index].jworst)
+ if (host[index].jitter > host[index].jworst)
host[index].jworst = host[index].jitter;
host[index].returned++;
display_rawping(index, totusec);
}
+
/* We know a packet has come in, because the main select loop has called us,
now we just need to read it, see if it is for us, and if it is a reply
to something we sent, then call net_process_ping() */
-void net_process_return() {
+void net_process_return()
+{
char packet[MAXPACKET];
struct sockaddr_in fromaddr;
int fromaddrsize;
}
}
+
int net_addr(int at) {
return ntohl(host[at].addr);
}
+
+
int net_addrs(int at, int i) {
return ntohl(host[at].addrs[i]);
}
int net_loss(int at)
{
- if((host[at].xmit - host[at].transit) == 0) return 0;
+ if ((host[at].xmit - host[at].transit) == 0)
+ return 0;
/* times extra 1000 */
return 1000*(100 - (100.0 * host[at].returned / (host[at].xmit - host[at].transit)) );
}
+
int net_drop(int at)
{
return (host[at].xmit - host[at].transit) - host[at].returned;
}
+
int net_last(int at)
{
return (host[at].last);
}
+
int net_best(int at)
{
return (host[at].best);
}
+
int net_worst(int at)
{
return (host[at].worst);
}
+
int net_avg(int at)
{
return (host[at].avg);
}
+
+
int net_gmean(int at)
{
return (host[at].gmean);
}
+
+
int net_stdev(int at)
{
if( host[at].returned > 1 ) {
return( 0 );
}
}
+
+
/* jitter stuff */
-int net_jitter(int at) { return (host[at].jitter); }
-int net_jworst(int at) { return (host[at].jworst); }
-int net_javg(int at) { return (host[at].javg); }
-int net_jinta(int at) { return (host[at].jinta); }
+int net_jitter(int at)
+{
+ return (host[at].jitter);
+}
+
+
+int net_jworst(int at)
+{
+ return (host[at].jworst);
+}
+
+
+int net_javg(int at)
+{
+ return (host[at].javg);
+}
+
+
+int net_jinta(int at)
+{
+ return (host[at].jinta);
+}
/* end jitter */
return max;
}
+
/* add by Min (wonder its named net_min;-)) because of ttl stuff */
int net_min ()
{
{
return host[at].returned;
}
+
+
int net_xmit(int at)
{
return host[at].xmit;
}
+
int net_transit(int at)
{
return host[at].transit;
}
+
int net_up(int at)
{
return host[at].up;
}
+
+struct in_addr *net_localaddr (void)
+{
+ return &localaddr;
+}
+
+
void net_end_transit()
{
int at;
}
-
int net_send_batch()
{
int n_unknown=0, i;
int trueopt = 1;
sendsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
- if(sendsock < 0)
+ if (sendsock < 0)
return -1;
#ifdef IP_HDRINCL
/* FreeBSD wants this to avoid sending out packets with protocol type RAW
to the network. */
- if(setsockopt(sendsock, SOL_IP, IP_HDRINCL, &trueopt, sizeof(trueopt)))
- {
+ if (setsockopt(sendsock, SOL_IP, IP_HDRINCL, &trueopt, sizeof(trueopt))) {
perror("setsockopt(IP_HDRINCL,1)");
return -1;
}
#endif
recvsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
- if(recvsock < 0)
+ if (recvsock < 0)
return -1;
return 0;
}
+
int net_open(int addr)
{
+ struct sockaddr_in name;
+ int len;
+
net_reset();
remoteaddress.sin_family = AF_INET;
remoteaddress.sin_addr.s_addr = addr;
+ len = sizeof (name);
+ getsockname (recvsock, (struct sockaddr *)&name, &len);
+ localaddr = name.sin_addr;
+#if 0
+ printf ("got localaddr: %x\n", *(int *)&localaddr);
+#endif
+
return 0;
}
+
void net_reopen(int addr)
{
int at;
net_send_batch();
}
+
void net_reset()
{
int at;
batch_at = fstTTL - 1; /* above replacedByMin */
numhosts = 10;
- for(at = 0; at < MaxHost; at++) {
+ for (at = 0; at < MaxHost; at++) {
host[at].xmit = 0;
host[at].transit = 0;
host[at].returned = 0;
host[at].saved_seq_offset = -SAVED_PINGS+2;
}
- for(at = 0; at < MaxSequence; at++) {
+ for (at = 0; at < MaxSequence; at++) {
sequence[at].transit = 0;
}
gettimeofday(&reset, NULL);
}
+
+int net_set_interfaceaddress (char *InterfaceAddress)
+{
+ int i1, i2, i3, i4;
+ char dummy;
+
+ if (!InterfaceAddress) return 0;
+
+ sourceaddress.sin_family = AF_INET;
+ sourceaddress.sin_port = 0;
+ sourceaddress.sin_addr.s_addr = 0;
+
+ if(sscanf(InterfaceAddress, "%u.%u.%u.%u%c", &i1, &i2, &i3, &i4, &dummy) != 4) {
+ printf("mtr: bad interface address: %s\n", InterfaceAddress);
+ exit(1);
+ }
+
+ ((unsigned char*)&sourceaddress.sin_addr)[0] = i1;
+ ((unsigned char*)&sourceaddress.sin_addr)[1] = i2;
+ ((unsigned char*)&sourceaddress.sin_addr)[2] = i3;
+ ((unsigned char*)&sourceaddress.sin_addr)[3] = i4;
+
+ if(bind(sendsock, (struct sockaddr*)&sourceaddress, sizeof(sourceaddress)) == -1) {
+ perror("mtr: failed to bind to interface");
+ exit(1);
+ }
+ return 0;
+}
+
+
+
void net_close()
{
close(sendsock);
close(recvsock);
}
+
int net_waitfd()
{
return recvsock;
return host[at].saved;
}
+
void net_save_increment()
{
int at;
}
}
+
void net_save_xmit(int at)
{
if (host[at].saved[SAVED_PINGS-1] != -2)
host[at].saved[SAVED_PINGS-1] = -1;
}
+
void net_save_return(int at, int seq, int ms)
{
int idx;