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 + -
显示快捷键?