⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 support.c

📁 netflow,抓包
💻 C
字号:
/* * Copyright (c) 2001 Mark Fullmer and The Ohio State University * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *      $Id: support.c,v 1.35 2003/02/13 02:38:43 maf Exp $ */#include "ftconfig.h"#include "ftlib.h"#include <sys/types.h>#include <sys/stat.h>#include <sys/socket.h>#include <ctype.h>#include <errno.h>#include <limits.h>#include <netdb.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <syslog.h>#include <time.h>#include <fcntl.h>#if HAVE_STRINGS_H #include <strings.h>#endif#if HAVE_STRING_H  #include <string.h>#endif#if !HAVE_STRSEP  char    *strsep (char **, const char *);#endif#ifndef IN_CLASSD_NET#define IN_CLASSD_NET 0xf0000000#endif/* * lookup table for mask length to mask * *               (first 8) *  128.0.0.0 192.0.0.0 224.0.0.0 240.0.0.0 *  248.0.0.0 252.0.0.0 254.0.0.0 255.0.0.0 * */u_int32 mask_lookup[] = { 0xffffffff,     0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,     0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,     0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,     0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,     0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,     0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,     0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,     0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff };/* * function ipv4_len2mask * * returns the 32 bit network mask given a length **/u_int32 ipv4_len2mask(u_int8 len){  return mask_lookup[(len > 32) ? 0 : len];}/* * function: load_lookup * *  loads a list of , seperated numbers into an array *  ! will invert the list *  - can be used as a range operator * *  example *   1,5-10   == 1,5,6,7,8,9,10 *   !1       == all numbers in the range except for 1 */int load_lookup(char *s, int size, char *list){  char *p;  int j, k;  unsigned i, i2;  p = s;  while ((*p == ' ') || (*p == '\t')) ++p;  if (*p == '!') {    for (k = 0; k < size; ++k)      list[k] = 1;    k = 0;    ++p;  } else {    for (k = 0; k < size; ++k)      list[k] = 0;    k = 1;  }  while (*p) {    i = (unsigned)strtol(p, (char**)0L, 0);    if (i >= size) return -1;    list[i] = k;    /* skip to , or - */    while (*p && (*p != ',') && (*p != '-')) ++p;    if (*p == '-') {      ++p;      i2 = (unsigned)strtol(p, (char**)0L, 0);      if (i2 >= size) return -1;      for (j = i; j <= i2; ++j) list[j] = k;      /* skip to , or - */      while (*p && (*p != ',') && (*p != '-')) ++p;    }    /* skip past , and - */    while (*p && ((*p == ',') || (*p == '-'))) ++p;  } /* *p */  return 0;} /* load_lookup *//* * function: scan_peeri * * scan peer identifier * * scan 1.2.3.4/1.2.3.4/nn[/nnl] *      locip   remip   port  ttl * into ftpeer struct */struct ftpeeri scan_peeri(char *input){  struct ftpeeri ftpi;  char *s, *s2, *locip, *remip, *dstport, *ttl;  bzero (&ftpi, sizeof ftpi);  ftpi.dst_port = FT_PORT;  locip = remip = dstport = ttl = (char*)0L;  if (!(s = malloc(strlen(input)+1))) {    fterr_warn("malloc");    return ftpi;  }  /* keep track of original pointer to free */  s2 = s;  strcpy(s, input);  locip = s;  if (*s) {  }  for (; *s && *s != '/'; ++s);  if (*s) {    *s = 0;    remip = ++s;  }  for (; *s && *s != '/'; ++s);  if (*s) {    *s = 0;    dstport = ++s;  }  for (; *s && *s != '/'; ++s);  if (*s) {    *s = 0;    ttl = ++s;  }  if (locip)    ftpi.loc_ip = scan_ip(locip);  if (remip)    ftpi.rem_ip = scan_ip(remip);  if (dstport)    ftpi.dst_port = atoi(dstport);  if (ttl)    ftpi.ttl = atoi(ttl);  free (s2);  return ftpi;  } /* scan_peer */struct ip_prefix scan_ip_prefix(char *input){  struct ip_prefix p;  char *s, *s2;  int has_slash;  has_slash = 0;  bzero(&p, sizeof p);  for (s = input; *s; ++s)    if (*s == '/') {      has_slash = 1;      break;    }  if (!has_slash) {    p.addr = scan_ip(input);    if ((IN_CLASSA(p.addr)) && (p.addr == (p.addr & IN_CLASSA_NET)))      p.len = 8;    else if ((IN_CLASSB(p.addr)) && (p.addr == (p.addr & IN_CLASSB_NET)))      p.len = 16;    else if ((IN_CLASSC(p.addr)) && (p.addr == (p.addr & IN_CLASSC_NET)))      p.len = 24;    else if ((IN_CLASSD(p.addr)) && (p.addr == (p.addr & IN_CLASSD_NET)))      p.len = 28;    else      p.len = 32;  } else {    if (!(s = malloc(strlen(input)+1))) {      fterr_warn("malloc");      return p;    }    s2 = s;    strcpy(s, input);    for (; *s2 && *s2 != '/'; ++s2);    if (*s2) {      *s2 = 0;      ++s2;    }    p.addr = scan_ip(s);    p.len = atoi(s2);    free (s);  }  if (p.len > 32)    p.len = 32;  return p;} /* scan_ip_prefix *//* * function: scan_ip * *  IP address in string S is converted to a u_long *  (borrowed from tcpdump) * *  left shift any partial dotted quads, ie 10 is 0x0a000000 not 0x0a *  so scan_ip_prefix() works for standard prefix notation, ie 10/8 */u_long scan_ip(char *s){  struct hostent *he;  struct in_addr *ina;  u_long addr = 0;  u_int n;  int dns, shift;  char *t;  /* if there is anything ascii in here, this may be a hostname */  for (dns = 0, t = s; *t; ++t) {    if (islower((int)*t) || isupper((int)*t)) {      dns = 1;      break;    }  }  if (dns) {    if (!(he = gethostbyname(s)))      goto numeric;    if (he->h_addrtype != AF_INET)      goto numeric;    if (he->h_length != sizeof (u_int32))      goto numeric;    ina = (struct in_addr*)*he->h_addr_list;    return (ntohl(ina->s_addr));  } /* dns */  shift = 0;numeric:  while (1) {    /* n is the nibble */    n = 0;    /* nibble's are . bounded */    while (*s && (*s != '.') && (*s != ' ') && (*s != '\t'))      n = n * 10 + *s++ - '0';    /* shift in the nibble */    addr <<=8;    addr |= n & 0xff;    ++shift;    /* return on end of string */    if ((!*s) || (*s == ' ') || (*s == '\t'))      goto ndone;    /* skip the . */    ++s;  } /* forever */ndone:  for (; shift < 4; ++shift)    addr <<=8;  return addr;} /* scan_ip *//* * function: print_3float * *  format a floating point # to stdout w. 1 trailing space * */void print_3float(float f){  char s[10], *c;  sprintf(s, "%-3.3f", f);  c = s + 1;  printf("%s ", c);} /* print_3float *//* * function: print_3float2 * *  format a floating point # to stdout w. 2 trailing spaces * */void print_3float2(float f){  char s[10], *c;  sprintf(s, "%-3.3f", f);  c = s + 1;  printf("%s  ", c);} /* print_3float *//* adapted from dd */int64 scan_size(char *val){  u_int64 num, t;  char *expr;  if ((num = strtoul(val, &expr, 0)) == ULONG_MAX)    goto erange;  switch(*expr) {    case 0:      break;    case 'b':      t = num;      num *= 512;      if (t > num)        goto erange;      break;    case 'G':      t = num;      num *= 1024;      num *= 1024;      num *= 1024;      if (t > num)        goto erange;      break;    case 'K':      t = num;      num *= 1024;      if (t > num)        goto erange;      break;    case 'M':      t = num;      num *= 1024;      num *= 1024;      if (t > num)        goto erange;      break;    default:      goto erange;  }  return num;erange:   return (int64)-1;} /* scan_size */#if HAVE_SIGACTION/* * Function: mysignal() *  POSIX style signals. * *  signal() has different semantics over different versions of unix. *  this emulates signal() with sigaction() to behave like BSD. * * From Stevens Advanced Programming in the UNIX environment  * */void *mysignal(int signo, void *func){  struct sigaction act, oact;    act.sa_handler = (void*)func;  sigemptyset(&act.sa_mask);  act.sa_flags = 0;  if (signo == SIGALRM) {#ifdef  SA_INTERRUPT  act.sa_flags |= SA_INTERRUPT; /* SunOS */#endif  } else {#ifdef SA_RESTART  act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */#endif  }  if (sigaction(signo, &act, &oact) < 0)    return SIG_ERR;  return oact.sa_handler;} /* signal */#else /* SIGACTION */void *mysignal(int signo, void *func){ return signal(signo, func) };#endif /* SIGACTION */int unlink_pidfile(int pid, char *file, u_int16 port){  char *c;  int ret;  if (!(c = (char*)malloc(strlen(file)+16)))    return -1;  sprintf(c, "%s.%d", file, (int)port);  if ((ret = unlink(c)) < 0)    fterr_warn("unlink(%s)", c);  free (c);  return ret;} /* unlink_pidfile */ int write_pidfile(int pid, char *file, u_int16 port){  int fd, len;  char str[16], *c;    if (!(c = (char*)malloc(strlen(file)+16)))    return -1;  sprintf(c, "%s.%d", file, (int)port);      len = sprintf(str, "%u\n", (unsigned)pid);  if ((fd = open(c, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0 ) {    fterr_warn("open(%s)", c);    free (c);    return -1;   }  if (write(fd, str, len) != len) {    fterr_warn("write(%s)", c);    close (fd);    free (c);    return -1;  }  return close (fd);} /* write_pidfile *//* * function get_gmtoff * * return offset from GMT in seconds * * based on compute_tz() code by Michael R. Elkins */int get_gmtoff(time_t t) {  struct tm *tmp, local, gmt;  time_t t2;  int yday;  tmp = gmtime(&t);  bcopy(tmp, &gmt, sizeof gmt);  tmp = localtime(&t);  bcopy(tmp, &local, sizeof local);  /* calculate difference in seconds */  t2 = (local.tm_hour - gmt.tm_hour) * 60; /* to minutes */  t2 += (local.tm_min - gmt.tm_min); /* minutes */  t2 *= 60; /* to seconds */  /* diff day */  yday = (local.tm_yday - gmt.tm_yday);  if ((yday == -1) || (yday > 1))    t2 -= 86400; /* sub one day */  else if (yday != 0)    t2 += 86400; /* add one day */  return t2;} /* get_gmtoff *//* * function: bigsockbuf * * There is no portable way to determine the max send and receive buffers * that can be set for a socket, so guess then decrement that guess by * 2K until the call succeeds.  If n > 1MB then the decrement by .5MB * instead. * * returns size or -1 for error*/int bigsockbuf(int fd, int dir, int size){  int n, tries;  /* initial size */  n = size;  tries = 0;  while (n > 4096) {    if (setsockopt(fd, SOL_SOCKET, dir, (char*)&n, sizeof (n)) < 0) {      /* anything other than no buffers available is fatal */      if (errno != ENOBUFS) {        fterr_warn("setsockopt(size=%d)", n);        return -1;      }      /* try a smaller value */      if (n > 1024*1024) /* most systems not > 256K bytes w/o tweaking */        n -= 1024*1024;      else        n -= 2048;      ++tries;    } else {      fterr_info("setsockopt(size=%d)", n);      return n;    }  } /* while */  /* no increase in buffer size */  return 0;} /* bigsockbuf *//* * function: mkpath * * make the path to a filename. * * returns 0: ok *         -1 fail **/int mkpath(const char *path, mode_t mode){  char *c, *cs, *c2, *p, *p2;  int len, ret, done, nodir;   len = strlen(path);  c = (char*)0L;  ret = -1;  done = 0;  if (!(c = (char*)malloc(len+1))) {    fterr_warn("malloc()");    goto mkpath_out;  }  if (!(c2 = (char*)malloc(len+1))) {    fterr_warn("malloc()");    goto mkpath_out;  }  cs = c;  strcpy(c, path);  c2[0] = 0;  while (c && !done) {    /* break out pathname components in p */    if (!(p = strsep(&c, "/")))      break;    /* end of string? */    if (!c)      break;    for (done = 1, p2 = c; p2 && *p2; ++p2)      if (*p2 == '/') {        done = 0;        break;      }    /* build path */    strcat(c2, p);    nodir = 0;    if (p[0] == '.' && p[1] == 0)      nodir = 1;    if (p[0] == '.' && p[1] == '.' && p[2] == 0)      nodir = 1;    if (p[0] == 0)      nodir = 1;    if (!nodir) {      if (mkdir(c2, mode) < 0) {        if (errno != EEXIST) {          fterr_warn("mkdir(%s)", c2);          goto mkpath_out;        }      }     } /* nodir */    strcat(c2, "/");  }  ret = 0;mkpath_out:  if (cs)    free(cs);  if (c2)    free(c2);  return ret;} /* mkpath *//*     * function: udp_cksum * * calculate checksum of IP pseudo header plus UDP header * */int udp_cksum(struct ip *ip, struct udphdr *up, int len){  u_int16 *word;  int sum;    word = (u_int16*)&ip->ip_src.s_addr;  sum = *word++;  sum += *word;  word = (u_int16*)&ip->ip_dst.s_addr;  sum += *word++;  sum += *word;  sum += htons(len);  sum += IPPROTO_UDP<<8;  word = (u_short*)up;  sum += *word++;  sum += *word++;  sum += *word++;  return sum;} /* udp_cksum */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -