utils.cc

来自「Ubuntu packages of security software。 相」· CC 代码 · 共 1,028 行 · 第 1/3 页

CC
1,028
字号
 return;}// Send data to a socket, keep retrying until an error or the full length// is sent.  Returns -1 if there is an error, or len if the full length was sent.int Send(int sd, const void *msg, size_t len, int flags) {  int res;  unsigned int sentlen = 0;  do {    res = send(sd,(char *) msg + sentlen, len - sentlen, 0);    if (res > 0)      sentlen += res;  } while(sentlen < len && (res != -1 || socket_errno() == EINTR));  return (res < 0)? -1 : (int) len;}unsigned int gcd_n_uint(int nvals, unsigned int *val) {   unsigned int a,b,c;      if (!nvals) return 1;   a=*val;   for (nvals--;nvals;nvals--)     {       b=*++val;       if (a<b) { c=a; a=b; b=c; }       while (b) { c=a%b; a=b; b=c; }     }   return a; }/* This function takes a command and the address of an uninitialized   char ** .  It parses the command (by separating out whitespace)   into an argv[] style char **, which it sets the argv parameter to.   The function returns the number of items filled up in the array   (argc), or -1 in the case of an error.  This function allocates   memory for argv and thus it must be freed -- use argv_parse_free()   for that.  If arg_parse returns <1, then argv does not need to be freed.   The returned arrays are always terminated with a NULL pointer */int arg_parse(const char *command, char ***argv) {  char **myargv = NULL;  int argc = 0;  char mycommand[4096];  char *start, *end;  char oldend;  *argv = NULL;  if (Strncpy(mycommand, command, 4096) == -1) {          return -1;  }  myargv = (char **) safe_malloc((MAX_PARSE_ARGS + 2) * sizeof(char *));  memset(myargv, 0, (MAX_PARSE_ARGS+2) * sizeof(char *));  myargv[0] = (char *) 0x123456; /* Integrity checker */  myargv++;  start = mycommand;  while(start && *start) {    while(*start && isspace((int) *start))      start++;    if (*start == '"') {      start++;      end = strchr(start, '"');    } else if (*start == '\'') {      start++;      end = strchr(start, '\'');          } else if (!*start) {      continue;    } else {      end = start+1;      while(*end && !isspace((int) *end)) {      	end++;      }    }    if (!end) {      arg_parse_free(myargv);      return -1;    }    if (argc >= MAX_PARSE_ARGS) {      arg_parse_free(myargv);      return -1;    }    oldend = *end;    *end = '\0';    myargv[argc++] = strdup(start);    if (oldend)      start = end + 1;    else start = end;  }  myargv[argc+1] = 0;  *argv = myargv;  return argc;}/* Free an argv allocated inside arg_parse */void arg_parse_free(char **argv) {  char **current;  /* Integrity check */  argv--;  assert(argv[0] == (char *) 0x123456);  current = argv + 1;  while(*current) {    free(*current);    current++;  }  free(argv);}/* Converts an Nmap time specification string into milliseconds.  If   the string is a plain non-negative number, it is considered to   already be in milliseconds and is returned.  If it is a number   followed by 's' (for seconds), 'm' (minutes), or 'h' (hours), the   number is converted to milliseconds and returned.  If Nmap cannot   parse the string, it is returned instead. */long tval2msecs(char *tspec) {  long l;  char *endptr = NULL;  l = strtol(tspec, &endptr, 10);  if (l < 0 || !endptr) return -1;  if (*endptr == '\0') return l;  if (*endptr == 's' || *endptr == 'S') return l * 1000;  if ((*endptr == 'm' || *endptr == 'M')) {    if (*(endptr + 1) == 's' || *(endptr + 1) == 'S')       return l;    return l * 60000;  }  if (*endptr == 'h' || *endptr == 'H') return l * 3600000;  return -1;}// A simple function to form a character from 2 hex digits in ASCII formstatic unsigned char hex2char(unsigned char a, unsigned char b){  int val;  if (!isxdigit(a) || !isxdigit(b)) return 0;  a = tolower(a);  b = tolower(b);  if (isdigit(a))    val = (a - '0') << 4;  else val = (10 + (a - 'a')) << 4;  if (isdigit(b))    val += (b - '0');  else val += 10 + (b - 'a');  return (unsigned char) val;}/* Convert a string in the format of a roughly C-style string literal   (e.g. can have \r, \n, \xHH escapes, etc.) into a binary string.   This is done in-place, and the new (shorter or the same) length is   stored in newlen.  If parsing fails, NULL is returned, otherwise   str is returned. */char *cstring_unescape(char *str, unsigned int *newlen) {  char *dst = str, *src = str;  char newchar;  while(*src) {    if (*src == '\\' ) {      src++;      switch(*src) {      case '0':	newchar = '\0'; src++; break;      case 'a': // Bell (BEL)	newchar = '\a'; src++; break;	      case 'b': // Backspace (BS)	newchar = '\b'; src++; break;	      case 'f': // Formfeed (FF)	newchar = '\f'; src++; break;	      case 'n': // Linefeed/Newline (LF)	newchar = '\n'; src++; break;	      case 'r': // Carriage Return (CR)	newchar = '\r'; src++; break;	      case 't': // Horizontal Tab (TAB)	newchar = '\t'; src++; break;	      case 'v': // Vertical Tab (VT)	newchar = '\v'; src++; break;	      case 'x':	src++;	if (!*src || !*(src + 1)) return NULL;	if (!isxdigit(*src) || !isxdigit(*(src + 1))) return NULL;	newchar = hex2char(*src, *(src + 1));	src += 2;	break;      default:	if (isalnum(*src))	  return NULL; // I don't really feel like supporting octals such as \015	// Other characters I'll just copy as is	newchar = *src;	src++;	break;      }      *dst = newchar;      dst++;    } else {      if (dst != src)	*dst = *src;      dst++; src++;    }  }  *dst = '\0'; // terminated, but this string can include other \0, so use newlen  if (newlen) *newlen = dst - str;  return str;}/* This function converts zero-terminated 'txt' string to binary 'data'.   It is used to parse user input for ip options. Some examples of possible input   strings and results:   	'\x01*2\xA2'	-> [0x01,0x01,0xA2]	// with 'x' number is parsed in hex   	'\01\01\255'	-> [0x01,0x01,0xFF]	// without 'x' its in decimal   	'\x01\x00*2'	-> [0x01,0x00,0x00]	// '*' is copying char   	'R'		-> Record Route with 9 slots   	'S 192.168.0.1 172.16.0.1' -> Strict Route with 2 slots   	'L 192.168.0.1 172.16.0.1' -> Loose Route with 2 slots   	'T'		-> Record Timestamp with 9 slots   	'U'		-> Record Timestamp and Ip Address with 4 slots*/int parse_ip_options(char *txt, u8 *data, int datalen, int* firsthopoff, int* lasthopoff){  enum{    NONE  = 0,    SLASH = 1,    MUL   = 2,    RR	  = 3,    TIME  = 4,  } s = NONE;  char *n, lc;  char *c = txt;  u8 *d = data;  int i,j;  int base = 10;  u8 *dataend = &data[datalen];  u8 *len = NULL;  char buf[32];  memset(data, 0, datalen);  bool sourcerouting = false;    for(;*c;c++){    switch(s){    case SLASH:      // parse \x00 string      if(*c == 'x'){// just ignore this char      	base = 16;        break;      }      if(isxdigit(*c)){        *d++ = strtol(c, &n, base);        c=n-1;      }else        fatal("not a digit after '\\'");      s = NONE;      break;    case MUL:      if(d==data)        fatal("nothing before '*' char");      i = strtol(c, &n, 10);      if(i<2)        fatal("bad number after '*'");      c = n-1;		// move current txt pointer      lc = *(d-1);	// last char, we'll copy this      for(j=1; j<i; j++){        *d++ = lc;        if(d == dataend) // check for overflow          goto after;      }      s = NONE;      break;    case RR:      if(*c==' ' || *c==',')        break;      n = buf;      while((*c=='.' || (*c>='0' && *c<='9')) && n-buf <= ((int)sizeof(buf)-1))      	 *n++ = *c++;      *n = '\0'; c--;      if(d+4>=dataend)        fatal("Buffer too small. Or input data too big :)");      i = inet_pton(AF_INET, buf, d);      if(i<1)        fatal("Not a valid ipv4 address '%s'",buf);      // remember offset of first hop      if(sourcerouting && !*firsthopoff)        *firsthopoff = d - data;      d+=4;      if(*len<37)        *len += 4;      break;    case TIME:      fatal("No more arguments allowed!");    default:      switch(*c){      case '\\':s = SLASH;base=10;break;      case '*':s = MUL;break;      case 'R':      case 'S':      case 'L':        if(d != data)          fatal("This option can't be used in that way");        *d++ = '\x01';//NOP        switch(*c){        case 'R':*d++ = 7;break;        case 'S':*d++ = 137; sourcerouting=true; break;        case 'L':*d++ = 131; sourcerouting=true; break;        }	len = d;        *d++ = (*c=='R')? 39 : 3; // length: 3+4*9 bytes        *d++ = 4; //pointer                  s = RR;        break;      case 'T':      case 'U':        if(d != data)          fatal("This option can't be used in that way");	*d++ = 68;	// option type	len = d;        *d++ = (*c=='U') ? 36 : 40;   // length: 3+4*9 bytes or 4+4*9 bytes        *d++ = 5; // pointer        *d++ = (*c=='U') ? 1 : 0; // flag: address and Time fields        s = TIME;        break;      default://*d++ = *c;      	fatal("Bad character in ip option '%c'",*c);      }    }    if(d == dataend)      break;    assert(d<dataend);  }  if(sourcerouting){    if(*len<37){      *len+=4;      *lasthopoff = d - data;      *d++ = 0;*d++ = 0;*d++ = 0;*d++ = 0;    }else      fatal("When using source routing you must leave at least one slot for target's ip.");  }  if(s == RR)    return(*len+1); // because we inject NOP before  if(s == TIME)    return(*len);after:  return(d - data);}

⌨️ 快捷键说明

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