PageRenderTime 873ms CodeModel.GetById 23ms RepoModel.GetById 2ms app.codeStats 1ms

/libnetutil/netutil.cc

https://gitlab.com/g10h4ck/nmap-gsoc2015
C++ | 4714 lines | 3284 code | 641 blank | 789 comment | 1035 complexity | 16db38ae8874902163295f841f83146e MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, Apache-2.0, LGPL-2.0, LGPL-2.1, MIT

Large files files are truncated, but you can click here to view the full file

  1. /***************************************************************************
  2. * netutil.cc *
  3. * *
  4. ***********************IMPORTANT NMAP LICENSE TERMS************************
  5. * *
  6. * The Nmap Security Scanner is (C) 1996-2015 Insecure.Com LLC. Nmap is *
  7. * also a registered trademark of Insecure.Com LLC. This program is free *
  8. * software; you may redistribute and/or modify it under the terms of the *
  9. * GNU General Public License as published by the Free Software *
  10. * Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE CLARIFICATIONS *
  11. * AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your right to use, *
  12. * modify, and redistribute this software under certain conditions. If *
  13. * you wish to embed Nmap technology into proprietary software, we sell *
  14. * alternative licenses (contact sales@nmap.com). Dozens of software *
  15. * vendors already license Nmap technology such as host discovery, port *
  16. * scanning, OS detection, version detection, and the Nmap Scripting *
  17. * Engine. *
  18. * *
  19. * Note that the GPL places important restrictions on "derivative works", *
  20. * yet it does not provide a detailed definition of that term. To avoid *
  21. * misunderstandings, we interpret that term as broadly as copyright law *
  22. * allows. For example, we consider an application to constitute a *
  23. * derivative work for the purpose of this license if it does any of the *
  24. * following with any software or content covered by this license *
  25. * ("Covered Software"): *
  26. * *
  27. * o Integrates source code from Covered Software. *
  28. * *
  29. * o Reads or includes copyrighted data files, such as Nmap's nmap-os-db *
  30. * or nmap-service-probes. *
  31. * *
  32. * o Is designed specifically to execute Covered Software and parse the *
  33. * results (as opposed to typical shell or execution-menu apps, which will *
  34. * execute anything you tell them to). *
  35. * *
  36. * o Includes Covered Software in a proprietary executable installer. The *
  37. * installers produced by InstallShield are an example of this. Including *
  38. * Nmap with other software in compressed or archival form does not *
  39. * trigger this provision, provided appropriate open source decompression *
  40. * or de-archiving software is widely available for no charge. For the *
  41. * purposes of this license, an installer is considered to include Covered *
  42. * Software even if it actually retrieves a copy of Covered Software from *
  43. * another source during runtime (such as by downloading it from the *
  44. * Internet). *
  45. * *
  46. * o Links (statically or dynamically) to a library which does any of the *
  47. * above. *
  48. * *
  49. * o Executes a helper program, module, or script to do any of the above. *
  50. * *
  51. * This list is not exclusive, but is meant to clarify our interpretation *
  52. * of derived works with some common examples. Other people may interpret *
  53. * the plain GPL differently, so we consider this a special exception to *
  54. * the GPL that we apply to Covered Software. Works which meet any of *
  55. * these conditions must conform to all of the terms of this license, *
  56. * particularly including the GPL Section 3 requirements of providing *
  57. * source code and allowing free redistribution of the work as a whole. *
  58. * *
  59. * As another special exception to the GPL terms, Insecure.Com LLC grants *
  60. * permission to link the code of this program with any version of the *
  61. * OpenSSL library which is distributed under a license identical to that *
  62. * listed in the included docs/licenses/OpenSSL.txt file, and distribute *
  63. * linked combinations including the two. *
  64. * *
  65. * Any redistribution of Covered Software, including any derived works, *
  66. * must obey and carry forward all of the terms of this license, including *
  67. * obeying all GPL rules and restrictions. For example, source code of *
  68. * the whole work must be provided and free redistribution must be *
  69. * allowed. All GPL references to "this License", are to be treated as *
  70. * including the terms and conditions of this license text as well. *
  71. * *
  72. * Because this license imposes special exceptions to the GPL, Covered *
  73. * Work may not be combined (even as part of a larger work) with plain GPL *
  74. * software. The terms, conditions, and exceptions of this license must *
  75. * be included as well. This license is incompatible with some other open *
  76. * source licenses as well. In some cases we can relicense portions of *
  77. * Nmap or grant special permissions to use it in other open source *
  78. * software. Please contact fyodor@nmap.org with any such requests. *
  79. * Similarly, we don't incorporate incompatible open source software into *
  80. * Covered Software without special permission from the copyright holders. *
  81. * *
  82. * If you have any questions about the licensing restrictions on using *
  83. * Nmap in other works, are happy to help. As mentioned above, we also *
  84. * offer alternative license to integrate Nmap into proprietary *
  85. * applications and appliances. These contracts have been sold to dozens *
  86. * of software vendors, and generally include a perpetual license as well *
  87. * as providing for priority support and updates. They also fund the *
  88. * continued development of Nmap. Please email sales@nmap.com for further *
  89. * information. *
  90. * *
  91. * If you have received a written license agreement or contract for *
  92. * Covered Software stating terms other than these, you may choose to use *
  93. * and redistribute Covered Software under those terms instead of these. *
  94. * *
  95. * Source is provided to this software because we believe users have a *
  96. * right to know exactly what a program is going to do before they run it. *
  97. * This also allows you to audit the software for security holes. *
  98. * *
  99. * Source code also allows you to port Nmap to new platforms, fix bugs, *
  100. * and add new features. You are highly encouraged to send your changes *
  101. * to the dev@nmap.org mailing list for possible incorporation into the *
  102. * main distribution. By sending these changes to Fyodor or one of the *
  103. * Insecure.Org development mailing lists, or checking them into the Nmap *
  104. * source code repository, it is understood (unless you specify otherwise) *
  105. * that you are offering the Nmap Project (Insecure.Com LLC) the *
  106. * unlimited, non-exclusive right to reuse, modify, and relicense the *
  107. * code. Nmap will always be available Open Source, but this is important *
  108. * because the inability to relicense code has caused devastating problems *
  109. * for other Free Software projects (such as KDE and NASM). We also *
  110. * occasionally relicense the code to third parties as discussed above. *
  111. * If you wish to specify special license conditions of your *
  112. * contributions, just say so when you send them. *
  113. * *
  114. * This program is distributed in the hope that it will be useful, but *
  115. * WITHOUT ANY WARRANTY; without even the implied warranty of *
  116. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Nmap *
  117. * license file for more details (it's in a COPYING file included with *
  118. * Nmap, and also available from https://svn.nmap.org/nmap/COPYING) *
  119. * *
  120. ***************************************************************************/
  121. /* Since OS X 10.7, we must declare whether we expect RFC 2292 or RFC 3542
  122. behavior from <netinet6/in6.h>. */
  123. #define __APPLE_USE_RFC_3542
  124. #if HAVE_CONFIG_H
  125. #include "../nmap_config.h"
  126. #endif
  127. #include "nbase.h"
  128. #ifdef WIN32
  129. #include "mswin32/winclude.h"
  130. #include "pcap-int.h"
  131. #else
  132. #include <sys/ioctl.h>
  133. #endif
  134. #include <assert.h>
  135. #include <errno.h>
  136. #include <sys/types.h>
  137. #if HAVE_SYS_SOCKET_H
  138. #include <sys/socket.h>
  139. #endif
  140. #if HAVE_SYS_SOCKIO_H
  141. #include <sys/sockio.h> /* SIOCGIFCONF for Solaris */
  142. #endif
  143. /* Define CMSG_* symbols for Solaris 9 and earlier. See
  144. http://wiki.opencsw.org/porting-faq#toc10. */
  145. #if defined(__sun) || defined(__sun__)
  146. # ifndef CMSG_ALIGN
  147. # ifdef __sun__
  148. # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
  149. # else
  150. /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
  151. # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & ~(sizeof (long) - 1))
  152. # endif
  153. # endif
  154. # ifndef CMSG_SPACE
  155. # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + CMSG_ALIGN (len))
  156. # endif
  157. # ifndef CMSG_LEN
  158. # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
  159. # endif
  160. #endif /* Solaris */
  161. #if HAVE_NETINET_IN_H
  162. #include <netinet/in.h>
  163. #endif
  164. #ifdef HAVE_LINUX_RTNETLINK_H
  165. #include <linux/rtnetlink.h>
  166. #endif
  167. #ifndef NETINET_IN_SYSTM_H /* This guarding is needed for at least some versions of OpenBSD */
  168. #include <netinet/in_systm.h>
  169. #define NETINET_IN_SYSTM_H
  170. #endif
  171. #include "netutil.h"
  172. #if HAVE_NET_IF_H
  173. #ifndef NET_IF_H /* This guarding is needed for at least some versions of OpenBSD */
  174. #include <net/if.h>
  175. #define NET_IF_H
  176. #endif
  177. #endif
  178. #ifndef NETINET_IP_H /* This guarding is needed for at least some versions of OpenBSD */
  179. #include <netinet/ip.h>
  180. #define NETINET_IP_H
  181. #endif
  182. #include <net/if_arp.h>
  183. #if HAVE_SYS_RESOURCE_H
  184. #include <sys/resource.h>
  185. #endif
  186. #define NBASE_MAX_ERR_STR_LEN 1024 /* Max length of an error message */
  187. /** Print fatal error messages to stderr and then exits. A newline
  188. character is printed automatically after the supplied text.
  189. * @warning This function does not return because it calls exit() */
  190. void netutil_fatal(const char *str, ...){
  191. va_list list;
  192. char errstr[NBASE_MAX_ERR_STR_LEN];
  193. memset(errstr,0, NBASE_MAX_ERR_STR_LEN);
  194. va_start(list, str);
  195. fflush(stdout);
  196. /* Print error msg to strerr */
  197. vfprintf(stderr, str, list);
  198. fprintf(stderr,"\n");
  199. va_end(list);
  200. exit(EXIT_FAILURE);
  201. } /* End of fatal() */
  202. /** Print error messages to stderr and then return. A newline
  203. character is printed automatically after the supplied text.*/
  204. int netutil_error(const char *str, ...){
  205. va_list list;
  206. char errstr[NBASE_MAX_ERR_STR_LEN];
  207. memset(errstr,0, NBASE_MAX_ERR_STR_LEN);
  208. va_start(list, str);
  209. fflush(stdout);
  210. /* Print error msg to strerr */
  211. vfprintf(stderr, str, list);
  212. fprintf(stderr,"\n");
  213. va_end(list);
  214. return 0;
  215. } /* End of error() */
  216. /* This function converts zero-terminated 'txt' string to binary 'data'.
  217. It is used to parse user input for ip options. Some examples of possible input
  218. strings and results:
  219. '\x01*2\xA2' -> [0x01,0x01,0xA2] // with 'x' number is parsed in hex
  220. '\01\01\255' -> [0x01,0x01,0xFF] // without 'x' its in decimal
  221. '\x01\x00*2' -> [0x01,0x00,0x00] // '*' is copying char
  222. 'R' -> Record Route with 9 slots
  223. 'S 192.168.0.1 172.16.0.1' -> Strict Route with 2 slots
  224. 'L 192.168.0.1 172.16.0.1' -> Loose Route with 2 slots
  225. 'T' -> Record Timestamp with 9 slots
  226. 'U' -> Record Timestamp and Ip Address with 4 slots
  227. On success, the function returns the length of the final binary
  228. options stored in "data". In case of error, OP_FAILURE is returned
  229. and the "errstr" buffer is filled with an error message
  230. (unless it's NULL). Note that the returned error message does NOT
  231. contain a newline character at the end. */
  232. int parse_ip_options(const char *txt, u8 *data, int datalen, int* firsthopoff, int* lasthopoff, char *errstr, size_t errstrlen){
  233. enum{
  234. NONE = 0,
  235. SLASH = 1,
  236. MUL = 2,
  237. RR = 3,
  238. TIME = 4,
  239. } s = NONE;
  240. char *n, lc;
  241. const char *c = txt;
  242. u8 *d = data;
  243. int i,j;
  244. int base = 10;
  245. u8 *dataend = &data[datalen];
  246. u8 *len = NULL;
  247. char buf[32];
  248. memset(data, 0, datalen);
  249. int sourcerouting = 0;
  250. long strtolbyte = 0; // used to check strtol() return boundaries
  251. for(;*c;c++){
  252. switch(s){
  253. case SLASH:
  254. // parse \x00 string
  255. if(*c == 'x'){// just ignore this char
  256. base = 16;
  257. break;
  258. }
  259. if(isxdigit(*c)){
  260. strtolbyte = strtol(c, &n, base);
  261. if((strtolbyte < 0) || (strtolbyte > 255)){
  262. if(errstr) Snprintf(errstr, errstrlen, "invalid ipv4 address format");
  263. return OP_FAILURE;
  264. }
  265. *d++ = (u8) strtolbyte;
  266. c = n-1;
  267. }else{
  268. if(errstr) Snprintf(errstr, errstrlen, "not a digit after '\\'");
  269. return OP_FAILURE;
  270. }
  271. s = NONE;
  272. break;
  273. case MUL:
  274. if(d==data){
  275. if(errstr) Snprintf(errstr, errstrlen, "nothing before '*' char");
  276. return OP_FAILURE;
  277. }
  278. i = strtol(c, &n, 10);
  279. if(i<2){
  280. if(errstr) Snprintf(errstr, errstrlen, "bad number after '*'");
  281. return OP_FAILURE;
  282. }
  283. c = n-1; // move current txt pointer
  284. lc = *(d-1); // last char, we'll copy this
  285. for(j=1; j<i; j++){
  286. *d++ = lc;
  287. if(d == dataend) // check for overflow
  288. goto after;
  289. }
  290. s = NONE;
  291. break;
  292. case RR:
  293. if(*c==' ' || *c==',')
  294. break;
  295. n = buf;
  296. while((*c=='.' || (*c>='0' && *c<='9')) && n-buf <= ((int)sizeof(buf)-1))
  297. *n++ = *c++;
  298. *n = '\0'; c--;
  299. if(d+4>=dataend){
  300. if(errstr) Snprintf(errstr, errstrlen, "Buffer too small. Or input data too big :)");
  301. return OP_FAILURE;
  302. }
  303. i = inet_pton(AF_INET, buf, d);
  304. if(i<1){
  305. if(errstr) Snprintf(errstr, errstrlen, "Not a valid ipv4 address '%s'",buf);
  306. return OP_FAILURE;
  307. }
  308. // remember offset of first hop
  309. if(sourcerouting && !*firsthopoff)
  310. *firsthopoff = d - data;
  311. d+=4;
  312. if(*len<37)
  313. *len += 4;
  314. break;
  315. case TIME:
  316. if(errstr) Snprintf(errstr, errstrlen, "No more arguments allowed!");
  317. return OP_FAILURE;
  318. default:
  319. switch(*c){
  320. case '\\':s = SLASH;base=10;break;
  321. case '*':s = MUL;break;
  322. case 'R':
  323. case 'S':
  324. case 'L':
  325. if(d != data){
  326. if(errstr) Snprintf(errstr, errstrlen, "This option can't be used in that way");
  327. return OP_FAILURE;
  328. }
  329. *d++ = '\x01';//NOP
  330. switch(*c){
  331. case 'R':*d++ = 7;break;
  332. case 'S':*d++ = 137; sourcerouting=1; break;
  333. case 'L':*d++ = 131; sourcerouting=1; break;
  334. }
  335. len = d;
  336. *d++ = (*c=='R')? 39 : 3; // length: 3+4*9 bytes
  337. *d++ = 4; //pointer
  338. s = RR;
  339. break;
  340. case 'T':
  341. case 'U':
  342. if(d != data){
  343. if(errstr) Snprintf(errstr, errstrlen, "This option can't be used in that way");
  344. return OP_FAILURE;
  345. }
  346. *d++ = 68; // option type
  347. len = d;
  348. *d++ = (*c=='U') ? 36 : 40; // length: 3+4*9 bytes or 4+4*9 bytes
  349. *d++ = 5; // pointer
  350. *d++ = (*c=='U') ? 1 : 0; // flag: address and Time fields
  351. s = TIME;
  352. break;
  353. default://*d++ = *c;
  354. if(errstr) Snprintf(errstr, errstrlen, "Bad character in ip option '%c'",*c);
  355. return OP_FAILURE;
  356. }
  357. }
  358. if(d == dataend)
  359. break;
  360. assert(d<dataend);
  361. }
  362. if(sourcerouting){
  363. if(*len<37){
  364. *len+=4;
  365. *lasthopoff = d - data;
  366. *d++ = 0;*d++ = 0;*d++ = 0;*d++ = 0;
  367. }else{
  368. if(errstr) Snprintf(errstr, errstrlen, "When using source routing you must leave at least one slot for target's ip.");
  369. return OP_FAILURE;
  370. }
  371. }
  372. if(s == RR)
  373. return(*len+1); // because we inject NOP before
  374. if(s == TIME)
  375. return(*len);
  376. after:
  377. return(d - data);
  378. }
  379. /* Internal helper for resolve and resolve_numeric. addl_flags is ored into
  380. hints.ai_flags, so you can add AI_NUMERICHOST. */
  381. static int resolve_internal(const char *hostname, unsigned short port,
  382. struct sockaddr_storage *ss, size_t *sslen, int af, int addl_flags) {
  383. struct addrinfo hints;
  384. struct addrinfo *result;
  385. char portbuf[16];
  386. int rc;
  387. assert(hostname);
  388. assert(ss);
  389. assert(sslen);
  390. memset(&hints, 0, sizeof(hints));
  391. hints.ai_family = af;
  392. hints.ai_socktype = SOCK_DGRAM;
  393. hints.ai_flags |= addl_flags;
  394. /* Make the port number a string to give to getaddrinfo. */
  395. rc = Snprintf(portbuf, sizeof(portbuf), "%hu", port);
  396. assert(rc >= 0 && (size_t) rc < sizeof(portbuf));
  397. rc = getaddrinfo(hostname, portbuf, &hints, &result);
  398. if (rc != 0)
  399. return rc;
  400. if (result == NULL)
  401. return EAI_NONAME;
  402. assert(result->ai_addrlen > 0 && result->ai_addrlen <= (int) sizeof(struct sockaddr_storage));
  403. *sslen = result->ai_addrlen;
  404. memcpy(ss, result->ai_addr, *sslen);
  405. freeaddrinfo(result);
  406. return 0;
  407. }
  408. /* Resolves the given hostname or IP address with getaddrinfo, and stores the
  409. first result (if any) in *ss and *sslen. The value of port will be set in the
  410. appropriate place in *ss; set to 0 if you don't care. af may be AF_UNSPEC, in
  411. which case getaddrinfo may return e.g. both IPv4 and IPv6 results; which one
  412. is first depends on the system configuration. Returns 0 on success, or a
  413. getaddrinfo return code (suitable for passing to gai_strerror) on failure.
  414. *ss and *sslen are always defined when this function returns 0. */
  415. int resolve(const char *hostname, unsigned short port,
  416. struct sockaddr_storage *ss, size_t *sslen, int af) {
  417. return resolve_internal(hostname, port, ss, sslen, af, 0);
  418. }
  419. /* As resolve, but do not do DNS resolution of hostnames; the first argument
  420. must be the string representation of a numeric IP address. */
  421. int resolve_numeric(const char *ip, unsigned short port,
  422. struct sockaddr_storage *ss, size_t *sslen, int af) {
  423. return resolve_internal(ip, port, ss, sslen, af, AI_NUMERICHOST);
  424. }
  425. /*
  426. * Returns 1 if this is a reserved IP address, where "reserved" means
  427. * either a private address, non-routable address, or even a non-reserved
  428. * but unassigned address which has an extremely high probability of being
  429. * black-holed.
  430. *
  431. * We try to optimize speed when ordering the tests. This optimization
  432. * assumes that all byte values are equally likely in the input.
  433. *
  434. * Check
  435. * <http://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.txt>
  436. * for the most recent assigments and
  437. * <http://www.cymru.com/Documents/bogon-bn-nonagg.txt> for bogon
  438. * netblocks.
  439. */
  440. int ip_is_reserved(struct in_addr *ip)
  441. {
  442. char *ipc = (char *) &(ip->s_addr);
  443. unsigned char i1 = ipc[0], i2 = ipc[1], i3 = ipc[2]; /* i4 not currently used - , i4 = ipc[3]; */
  444. /* do all the /7's and /8's with a big switch statement, hopefully the
  445. * compiler will be able to optimize this a little better using a jump table
  446. * or what have you
  447. */
  448. switch (i1)
  449. {
  450. case 0: /* 000/8 is IANA reserved */
  451. case 6: /* USA Army ISC */
  452. case 7: /* used for BGP protocol */
  453. case 10: /* the infamous 10.0.0.0/8 */
  454. case 55: /* misc. U.S.A. Armed forces */
  455. case 127: /* 127/8 is reserved for loopback */
  456. return 1;
  457. default:
  458. break;
  459. }
  460. /* 172.16.0.0/12 is reserved for private nets by RFC1819 */
  461. if (i1 == 172 && i2 >= 16 && i2 <= 31)
  462. return 1;
  463. /* 192.0.2.0/24 is reserved for documentation and examples (RFC5737) */
  464. /* 192.88.99.0/24 is used as 6to4 Relay anycast prefix by RFC3068 */
  465. /* 192.168.0.0/16 is reserved for private nets by RFC1819 */
  466. if (i1 == 192) {
  467. if (i2 == 0 && i3 == 2)
  468. return 1;
  469. if (i2 == 88 && i3 == 99)
  470. return 1;
  471. if (i2 == 168)
  472. return 1;
  473. }
  474. /* 198.18.0.0/15 is used for benchmark tests by RFC2544 */
  475. /* 198.51.100.0/24 is reserved for documentation (RFC5737) */
  476. if (i1 == 198) {
  477. if (i2 == 18 || i2 == 19)
  478. return 1;
  479. if (i2 == 51 && i3 == 100)
  480. return 1;
  481. }
  482. /* 169.254.0.0/16 is reserved for DHCP clients seeking addresses */
  483. if (i1 == 169 && i2 == 254)
  484. return 1;
  485. /* 203.0.113.0/24 is reserved for documentation (RFC5737) */
  486. if (i1 == 203 && i2 == 0 && i3 == 113)
  487. return 1;
  488. /* 224-239/8 is all multicast stuff */
  489. /* 240-255/8 is IANA reserved */
  490. if (i1 >= 224)
  491. return 1;
  492. return 0;
  493. }
  494. /* A trivial functon that maintains a cache of IP to MAC Address
  495. entries. If the command is MACCACHE_GET, this func looks for the
  496. IPv4 address in ss and fills in the 'mac' parameter and returns
  497. true if it is found. Otherwise (not found), the function returns
  498. false. If the command is MACCACHE_SET, the function adds an entry
  499. with the given ip (ss) and mac address. An existing entry for the
  500. IP ss will be overwritten with the new MAC address. true is always
  501. returned for the set command. */
  502. #define MACCACHE_GET 1
  503. #define MACCACHE_SET 2
  504. static int do_mac_cache(int command, const struct sockaddr_storage *ss, u8 *mac) {
  505. struct MacCache {
  506. struct sockaddr_storage ip;
  507. u8 mac[6];
  508. };
  509. static struct MacCache *Cache = NULL;
  510. static int MacCapacity = 0;
  511. static int MacCacheSz = 0;
  512. int i;
  513. if (command == MACCACHE_GET) {
  514. for (i = 0; i < MacCacheSz; i++) {
  515. if (sockaddr_storage_cmp(&Cache[i].ip, ss) == 0) {
  516. memcpy(mac, Cache[i].mac, 6);
  517. return 1;
  518. }
  519. }
  520. return 0;
  521. }
  522. assert(command == MACCACHE_SET);
  523. if (MacCacheSz == MacCapacity) {
  524. if (MacCapacity == 0)
  525. MacCapacity = 32;
  526. else
  527. MacCapacity <<= 2;
  528. Cache = (struct MacCache *) safe_realloc(Cache, MacCapacity * sizeof(struct MacCache));
  529. }
  530. /* Ensure that it isn't already there ... */
  531. for (i = 0; i < MacCacheSz; i++) {
  532. if (sockaddr_storage_cmp(&Cache[i].ip, ss) == 0) {
  533. memcpy(Cache[i].mac, mac, 6);
  534. return 1;
  535. }
  536. }
  537. /* Add it to the end of the list */
  538. memcpy(&Cache[i].ip, ss, sizeof(struct sockaddr_storage));
  539. memcpy(Cache[i].mac, mac, 6);
  540. MacCacheSz++;
  541. return 1;
  542. }
  543. /* A couple of trivial functions that maintain a cache of IP to MAC
  544. * Address entries. Function mac_cache_get() looks for the IPv4 address
  545. * in ss and fills in the 'mac' parameter and returns true if it is
  546. * found. Otherwise (not found), the function returns false.
  547. * Function mac_cache_set() adds an entry with the given ip (ss) and
  548. * mac address. An existing entry for the IP ss will be overwritten
  549. * with the new MAC address. mac_cache_set() always returns true.
  550. * WARNING: The caller must ensure that the supplied "ss" is of family
  551. * AF_INET. Otherwise the function will return 0 and there would be
  552. * no way for the caller to tell tell the difference between an error
  553. * or a cache miss.*/
  554. int mac_cache_get(const struct sockaddr_storage *ss, u8 *mac){
  555. return do_mac_cache(MACCACHE_GET, ss, mac);
  556. }
  557. int mac_cache_set(const struct sockaddr_storage *ss, u8 *mac){
  558. return do_mac_cache(MACCACHE_SET, ss, mac);
  559. }
  560. /* Standard BSD internet checksum routine. Uses libdnet helper functions. */
  561. unsigned short in_cksum(u16 *ptr,int nbytes) {
  562. int sum;
  563. sum = ip_cksum_add(ptr, nbytes, 0);
  564. return ip_cksum_carry(sum);
  565. return 0;
  566. }
  567. /* Return true iff this Next Header type is an extension header we must skip to
  568. get to the upper-layer header. Types for which neither this function nor
  569. ipv6_is_upperlayer return true are unknown and could be either. */
  570. static int ipv6_is_extension_header(u8 type)
  571. {
  572. switch (type) {
  573. case IP_PROTO_HOPOPTS:
  574. case IP_PROTO_DSTOPTS:
  575. case IP_PROTO_ROUTING:
  576. case IP_PROTO_FRAGMENT:
  577. /*
  578. case IP_PROTO_ESP:
  579. case IP_PROTO_AH:
  580. */
  581. return 1;
  582. default:
  583. return 0;
  584. }
  585. }
  586. /* Return true iff this Next Header type is a known upper-layer protocol, one
  587. that isn't followed by any more headers. Types for which neither this
  588. function nor ipv6_is_upperlayer return true are unknown and could be
  589. either. */
  590. static int ipv6_is_upperlayer(u8 type)
  591. {
  592. switch (type) {
  593. case IP_PROTO_NONE:
  594. case IP_PROTO_TCP:
  595. case IP_PROTO_UDP:
  596. case IP_PROTO_ICMP:
  597. case IP_PROTO_ICMPV6:
  598. case IP_PROTO_SCTP:
  599. return 1;
  600. default:
  601. return 0;
  602. }
  603. }
  604. /* upperlayer_only controls whether we require a known upper-layer protocol at
  605. the end of the chain, or return the last readable header even if it is not an
  606. upper-layer protocol (may even be another extension header). */
  607. static const void *ipv6_get_data_primitive(const struct ip6_hdr *ip6,
  608. unsigned int *len, u8 *nxt, bool upperlayer_only)
  609. {
  610. const unsigned char *p, *end;
  611. if (*len < sizeof(*ip6))
  612. return NULL;
  613. p = (unsigned char *) ip6;
  614. end = p + *len;
  615. *nxt = ip6->ip6_nxt;
  616. p += sizeof(*ip6);
  617. while (p < end && ipv6_is_extension_header(*nxt)) {
  618. if (p + 2 > end)
  619. return NULL;
  620. *nxt = *p;
  621. p += (*(p + 1) + 1) * 8;
  622. }
  623. *len = end - p;
  624. if (upperlayer_only && !ipv6_is_upperlayer(*nxt))
  625. return NULL;
  626. return (char *) p;
  627. }
  628. static const void *ip_get_data_primitive(const void *packet, unsigned int *len,
  629. struct abstract_ip_hdr *hdr, bool upperlayer_only) {
  630. const struct ip *ip;
  631. ip = (struct ip *) packet;
  632. if (*len >= 20 && ip->ip_v == 4) {
  633. struct sockaddr_in *sin;
  634. hdr->version = 4;
  635. sin = (struct sockaddr_in *) &hdr->src;
  636. memset(&hdr->src, 0, sizeof(hdr->src));
  637. sin->sin_family = AF_INET;
  638. sin->sin_addr.s_addr = ip->ip_src.s_addr;
  639. sin = (struct sockaddr_in *) &hdr->dst;
  640. memset(&hdr->dst, 0, sizeof(hdr->dst));
  641. sin->sin_family = AF_INET;
  642. sin->sin_addr.s_addr = ip->ip_dst.s_addr;
  643. hdr->proto = ip->ip_p;
  644. hdr->ttl = ip->ip_ttl;
  645. hdr->ipid = ntohs(ip->ip_id);
  646. return ipv4_get_data(ip, len);
  647. } else if (*len >= 40 && ip->ip_v == 6) {
  648. const struct ip6_hdr *ip6 = (struct ip6_hdr *) ip;
  649. struct sockaddr_in6 *sin6;
  650. hdr->version = 6;
  651. sin6 = (struct sockaddr_in6 *) &hdr->src;
  652. memset(&hdr->src, 0, sizeof(hdr->src));
  653. sin6->sin6_family = AF_INET6;
  654. memcpy(&sin6->sin6_addr, &ip6->ip6_src, IP6_ADDR_LEN);
  655. sin6 = (struct sockaddr_in6 *) &hdr->dst;
  656. memset(&hdr->dst, 0, sizeof(hdr->dst));
  657. sin6->sin6_family = AF_INET6;
  658. memcpy(&sin6->sin6_addr, &ip6->ip6_dst, IP6_ADDR_LEN);
  659. hdr->ttl = ip6->ip6_hlim;
  660. hdr->ipid = ntohl(ip6->ip6_flow & IP6_FLOWLABEL_MASK);
  661. return ipv6_get_data_primitive(ip6, len, &hdr->proto, upperlayer_only);
  662. }
  663. return NULL;
  664. }
  665. /* Find the beginning of the data payload in the IP packet beginning at packet.
  666. Returns the beginning of the payload, updates *len to be the length of the
  667. payload, and fills in hdr if successful. Otherwise returns NULL and *hdr is
  668. undefined. */
  669. const void *ip_get_data(const void *packet, unsigned int *len,
  670. struct abstract_ip_hdr *hdr) {
  671. return ip_get_data_primitive(packet, len, hdr, true);
  672. }
  673. /* As ip_get_data, except that it doesn't insist that the payload be a known
  674. upper-layer protocol. This can matter in IPv6 where the last element of a nh
  675. chain may be a protocol we don't know about. */
  676. const void *ip_get_data_any(const void *packet, unsigned int *len,
  677. struct abstract_ip_hdr *hdr) {
  678. return ip_get_data_primitive(packet, len, hdr, false);
  679. }
  680. /* Get the upper-layer protocol from an IPv4 packet. */
  681. const void *ipv4_get_data(const struct ip *ip, unsigned int *len)
  682. {
  683. unsigned int header_len;
  684. if (*len < 20)
  685. return NULL;
  686. header_len = ip->ip_hl * 4;
  687. if (header_len < sizeof(*ip))
  688. return NULL;
  689. if (header_len > *len)
  690. return NULL;
  691. *len -= header_len;
  692. return (char *) ip + header_len;
  693. }
  694. /* Get the upper-layer protocol from an IPv6 packet. This skips over known
  695. extension headers. The length of the upper-layer payload is stored in *len.
  696. The protocol is stored in *nxt. Returns NULL in case of error. */
  697. const void *ipv6_get_data(const struct ip6_hdr *ip6, unsigned int *len, u8 *nxt)
  698. {
  699. return ipv6_get_data_primitive(ip6, len, nxt, true);
  700. }
  701. /* Get the protocol payload from an IPv6 packet. This skips over known extension
  702. headers. It differs from ipv6_get_data in that it will return a result even
  703. if the final header is not a known upper-layer protocol. */
  704. const void *ipv6_get_data_any(const struct ip6_hdr *ip6, unsigned int *len, u8 *nxt)
  705. {
  706. return ipv6_get_data_primitive(ip6, len, nxt, false);
  707. }
  708. const void *icmp_get_data(const struct icmp_hdr *icmp, unsigned int *len)
  709. {
  710. unsigned int header_len;
  711. if (icmp->icmp_type == ICMP_TIMEXCEED || icmp->icmp_type == ICMP_UNREACH)
  712. header_len = 8;
  713. else
  714. netutil_fatal("%s passed ICMP packet with unhandled type %d", __func__, icmp->icmp_type);
  715. if (header_len > *len)
  716. return NULL;
  717. *len -= header_len;
  718. return (char *) icmp + header_len;
  719. }
  720. const void *icmpv6_get_data(const struct icmpv6_hdr *icmpv6, unsigned int *len)
  721. {
  722. unsigned int header_len;
  723. if (icmpv6->icmpv6_type == ICMPV6_TIMEXCEED || icmpv6->icmpv6_type == ICMPV6_UNREACH)
  724. header_len = 8;
  725. else
  726. netutil_fatal("%s passed ICMPv6 packet with unhandled type %d", __func__, icmpv6->icmpv6_type);
  727. if (header_len > *len)
  728. return NULL;
  729. *len -= header_len;
  730. return (char *) icmpv6 + header_len;
  731. }
  732. /* Calculate the Internet checksum of some given data concatentated with the
  733. IPv4 pseudo-header. See RFC 1071 and TCP/IP Illustrated sections 3.2, 11.3,
  734. and 17.3. */
  735. unsigned short ipv4_pseudoheader_cksum(const struct in_addr *src,
  736. const struct in_addr *dst, u8 proto, u16 len, const void *hstart) {
  737. struct pseudo {
  738. struct in_addr src;
  739. struct in_addr dst;
  740. u8 zero;
  741. u8 proto;
  742. u16 length;
  743. } hdr;
  744. int sum;
  745. hdr.src = *src;
  746. hdr.dst = *dst;
  747. hdr.zero = 0;
  748. hdr.proto = proto;
  749. hdr.length = htons(len);
  750. /* Get the ones'-complement sum of the pseudo-header. */
  751. sum = ip_cksum_add(&hdr, sizeof(hdr), 0);
  752. /* Add it to the sum of the packet. */
  753. sum = ip_cksum_add(hstart, len, sum);
  754. /* Fold in the carry, take the complement, and return. */
  755. sum = ip_cksum_carry(sum);
  756. /* RFC 768: "If the computed checksum is zero, it is transmitted as all
  757. * ones (the equivalent in one's complement arithmetic). An all zero
  758. * transmitted checksum value means that the transmitter generated no
  759. * checksum" */
  760. if (proto == IP_PROTO_UDP && sum == 0)
  761. sum = 0xFFFF;
  762. return sum;
  763. }
  764. /* Calculate the Internet checksum of some given data concatenated with the
  765. IPv6 pseudo-header. See RFC 2460 section 8.1. */
  766. u16 ipv6_pseudoheader_cksum(const struct in6_addr *src,
  767. const struct in6_addr *dst, u8 nxt, u32 len, const void *hstart) {
  768. struct {
  769. struct in6_addr src;
  770. struct in6_addr dst;
  771. u32 length;
  772. u8 z0, z1, z2;
  773. u8 nxt;
  774. } hdr;
  775. int sum;
  776. hdr.src = *src;
  777. hdr.dst = *dst;
  778. hdr.z0 = hdr.z1 = hdr.z2 = 0;
  779. hdr.length = htonl(len);
  780. hdr.nxt = nxt;
  781. sum = ip_cksum_add(&hdr, sizeof(hdr), 0);
  782. sum = ip_cksum_add(hstart, len, sum);
  783. sum = ip_cksum_carry(sum);
  784. /* RFC 2460: "Unlike IPv4, when UDP packets are originated by an IPv6 node,
  785. the UDP checksum is not optional. That is, whenever originating a UDP
  786. packet, an IPv6 node must compute a UDP checksum over the packet and the
  787. pseudo-header, and, if that computation yields a result of zero, it must be
  788. changed to hex FFFF for placement in the UDP header." */
  789. if (nxt == IP_PROTO_UDP && sum == 0)
  790. sum = 0xFFFF;
  791. return sum;
  792. }
  793. void sethdrinclude(int sd) {
  794. #ifdef IP_HDRINCL
  795. int one = 1;
  796. setsockopt(sd, IPPROTO_IP, IP_HDRINCL, (const char *) &one, sizeof(one));
  797. #endif
  798. }
  799. void set_ipoptions(int sd, void *opts, size_t optslen) {
  800. #ifdef IP_OPTIONS
  801. if (sd == -1)
  802. return;
  803. setsockopt(sd, IPPROTO_IP, IP_OPTIONS, (const char *) opts, optslen);
  804. #endif
  805. }
  806. void set_ttl(int sd, int ttl) {
  807. #ifdef IP_TTL
  808. if (sd == -1)
  809. return;
  810. setsockopt(sd, IPPROTO_IP, IP_TTL, (const char *) &ttl, sizeof ttl);
  811. #endif
  812. }
  813. /* Other than WIN32, what these systems have in common is that they use BPF for
  814. packet capture. (Solaris 10 and earlier used DLPI and had valid selectable
  815. fds.) */
  816. #if defined(WIN32) || defined(MACOSX) || (defined(FREEBSD) && (__FreeBSD_version < 500000) || defined(SOLARIS_BPF_PCAP_CAPTURE))
  817. /* Returns whether the system supports pcap_get_selectable_fd() properly */
  818. int pcap_selectable_fd_valid() {
  819. return 0;
  820. }
  821. /* Call this instead of pcap_get_selectable_fd directly (or your code
  822. won't compile on Windows). On systems which don't seem to support
  823. the pcap_get_selectable_fd() function properly, returns -1,
  824. otherwise simply calls pcap_selectable_fd and returns the
  825. results. If you just want to test whether the function is supported,
  826. use pcap_selectable_fd_valid() instead. */
  827. int my_pcap_get_selectable_fd(pcap_t *p) {
  828. return -1;
  829. }
  830. #else
  831. int pcap_selectable_fd_valid() {
  832. return 1;
  833. }
  834. int my_pcap_get_selectable_fd(pcap_t *p) {
  835. return pcap_get_selectable_fd(p);
  836. }
  837. #endif
  838. /* Are we guaranteed to be able to read exactly one frame for each time the pcap
  839. fd is selectable? If not, it's possible for the fd to become selectable, then
  840. for pcap_dispatch to buffer two or more frames, and return only the first one
  841. Because select doesn't know about pcap's buffer, the fd does not become
  842. selectable again, even though another pcap_next would succeed. On these
  843. platforms, we must do a non-blocking read from the fd before doing a select
  844. on the fd.
  845. It is guaranteed that if pcap_selectable_fd_valid() is false, then so is the
  846. return value of this function. */
  847. int pcap_selectable_fd_one_to_one() {
  848. #ifdef SOLARIS
  849. return 0;
  850. #endif
  851. return pcap_selectable_fd_valid();
  852. }
  853. /* returns -1 if we can't use select() on the pcap device, 0 for timeout, and
  854. * >0 for success. If select() fails we bail out because it couldn't work with
  855. * the file descriptor we got from my_pcap_get_selectable_fd()
  856. */
  857. int pcap_select(pcap_t *p, struct timeval *timeout) {
  858. int fd, ret;
  859. fd_set rfds;
  860. if ((fd = my_pcap_get_selectable_fd(p)) == -1)
  861. return -1;
  862. FD_ZERO(&rfds);
  863. FD_SET(fd, &rfds);
  864. do {
  865. errno = 0;
  866. ret = select(fd + 1, &rfds, NULL, NULL, timeout);
  867. if (ret == -1) {
  868. if (errno == EINTR)
  869. netutil_error("%s: %s", __func__, strerror(errno));
  870. else
  871. netutil_fatal("Your system does not support select()ing on pcap devices (%s). PLEASE REPORT THIS ALONG WITH DETAILED SYSTEM INFORMATION TO THE nmap-dev MAILING LIST!", strerror(errno));
  872. }
  873. } while (ret == -1);
  874. return ret;
  875. }
  876. int pcap_select(pcap_t *p, long usecs) {
  877. struct timeval tv;
  878. tv.tv_sec = usecs / 1000000;
  879. tv.tv_usec = usecs % 1000000;
  880. return pcap_select(p, &tv);
  881. }
  882. /* These two are for eth_open_cached() and eth_close_cached() */
  883. static char etht_cache_device_name[64];
  884. static eth_t *etht_cache_device = NULL;
  885. /* A simple function that caches the eth_t from dnet for one device,
  886. to avoid opening, closing, and re-opening it thousands of tims. If
  887. you give a different device, this function will close the first
  888. one. Thus this should never be used by programs that need to deal
  889. with multiple devices at once. In addition, you MUST NEVER
  890. eth_close() A DEVICE OBTAINED FROM THIS FUNCTION. Instead, you can
  891. call eth_close_cached() to close whichever device (if any) is
  892. cached. Returns NULL if it fails to open the device. */
  893. eth_t *eth_open_cached(const char *device) {
  894. if (!device)
  895. netutil_fatal("%s() called with NULL device name!", __func__);
  896. if (!*device)
  897. netutil_fatal("%s() called with empty device name!", __func__);
  898. if (strcmp(device, etht_cache_device_name) == 0) {
  899. /* Yay, we have it cached. */
  900. return etht_cache_device;
  901. }
  902. if (*etht_cache_device_name) {
  903. eth_close(etht_cache_device);
  904. etht_cache_device_name[0] = '\0';
  905. etht_cache_device = NULL;
  906. }
  907. etht_cache_device = eth_open(device);
  908. if (etht_cache_device)
  909. Strncpy(etht_cache_device_name, device,
  910. sizeof(etht_cache_device_name));
  911. return etht_cache_device;
  912. }
  913. /* See the description for eth_open_cached */
  914. void eth_close_cached() {
  915. if (etht_cache_device) {
  916. eth_close(etht_cache_device);
  917. etht_cache_device = NULL;
  918. etht_cache_device_name[0] = '\0';
  919. }
  920. return;
  921. }
  922. /* Takes a protocol number like IPPROTO_TCP, IPPROTO_UDP, IPPROTO_IP,
  923. * etc, and returns an ASCII representation (or the string "unknown" if
  924. * it doesn't recognize the number). If uppercase is non zero, the
  925. * returned value will be in uppercase letters, otherwise it'll be
  926. * in lowercase */
  927. const char *proto2ascii_case(u8 proto, int uppercase) {
  928. switch (proto) {
  929. case IPPROTO_TCP:
  930. return uppercase ? "TCP" : "tcp";
  931. break;
  932. case IPPROTO_UDP:
  933. return uppercase ? "UDP" : "udp";
  934. break;
  935. case IPPROTO_SCTP:
  936. return uppercase ? "SCTP" : "sctp";
  937. break;
  938. case IPPROTO_IP:
  939. return uppercase ? "IP" : "ip";
  940. break;
  941. #ifdef IPPROTO_ICMP
  942. case IPPROTO_ICMP:
  943. return uppercase ? "ICMP" : "icmp";
  944. break;
  945. #endif
  946. #ifdef IPPROTO_IPV6
  947. case IPPROTO_IPV6:
  948. return uppercase ? "IPv6" : "ipv6";
  949. break;
  950. #endif
  951. #ifdef IPPROTO_ICMPV6
  952. case IPPROTO_ICMPV6:
  953. return uppercase ? "ICMPv6" : "icmpv6";
  954. break;
  955. #endif
  956. #ifdef IPPROTO_GRE
  957. case IPPROTO_GRE: // Generic Routing Encapsulation
  958. return uppercase ? "GRE" : "gre";
  959. break;
  960. #endif
  961. #ifdef IPPROTO_ESP
  962. case IPPROTO_ESP: // Encapsulating Security Payload (IPSec)
  963. return uppercase ? "IPSec/ESP" : "ipsec/esp";
  964. break;
  965. #endif
  966. #ifdef IPPROTO_AH
  967. case IPPROTO_AH: // Authentication Header (IPSec)
  968. return uppercase ? "IPSec/AH" : "ipsec/ah";
  969. break;
  970. #endif
  971. default:
  972. return uppercase ? "UNKNOWN" : "unknown";
  973. }
  974. return NULL; // Unreached
  975. }
  976. const char *proto2ascii_lowercase(u8 proto) {
  977. return proto2ascii_case(proto, 0);
  978. }
  979. const char *proto2ascii_uppercase(u8 proto) {
  980. return proto2ascii_case(proto, 1);
  981. }
  982. /* Get an ASCII information about a tcp option which is pointed by
  983. optp, with a length of len. The result is stored in the result
  984. buffer. The result may look like "<mss 1452,sackOK,timestamp
  985. 45848914 0,nop,wscale 7>" */
  986. void tcppacketoptinfo(u8 *optp, int len, char *result, int bufsize) {
  987. assert(optp);
  988. assert(result);
  989. char *p, ch;
  990. u8 *q;
  991. int opcode;
  992. u16 tmpshort;
  993. u32 tmpword1, tmpword2;
  994. unsigned int i=0;
  995. p = result;
  996. *p = '\0';
  997. q = optp;
  998. ch = '<';
  999. while (len > 0 && bufsize > 2) {
  1000. Snprintf(p, bufsize, "%c", ch);
  1001. bufsize--;
  1002. p++;
  1003. opcode = *q++;
  1004. if (!opcode) { /* End of List */
  1005. Snprintf(p, bufsize, "eol");
  1006. bufsize -= strlen(p);
  1007. p += strlen(p);
  1008. len--;
  1009. } else if (opcode == 1) { /* No Op */
  1010. Snprintf(p, bufsize, "nop");
  1011. bufsize -= strlen(p);
  1012. p += strlen(p);
  1013. len--;
  1014. } else if (opcode == 2) { /* MSS */
  1015. if (len < 4)
  1016. break; /* MSS has 4 bytes */
  1017. q++;
  1018. memcpy(&tmpshort, q, 2);
  1019. Snprintf(p, bufsize, "mss %hu", (unsigned short) ntohs(tmpshort));
  1020. bufsize -= strlen(p);
  1021. p += strlen(p);
  1022. q += 2;
  1023. len -= 4;
  1024. } else if (opcode == 3) { /* Window Scale */
  1025. if (len < 3)
  1026. break; /* Window Scale option has 3 bytes */
  1027. q++;
  1028. Snprintf(p, bufsize, "wscale %u", *q);
  1029. bufsize -= strlen(p);
  1030. p += strlen(p);
  1031. q++;
  1032. len -= 3;
  1033. } else if (opcode == 4) { /* SACK permitted */
  1034. if (len < 2)
  1035. break; /* SACK permitted option has 2 bytes */
  1036. Snprintf(p, bufsize, "sackOK");
  1037. bufsize -= strlen(p);
  1038. p += strlen(p);
  1039. q++;
  1040. len -= 2;
  1041. } else if (opcode == 5) { /* SACK */
  1042. unsigned sackoptlen = *q;
  1043. if ((unsigned) len < sackoptlen)
  1044. break;
  1045. /* This would break parsing, so it's best to just give up */
  1046. if (sackoptlen < 2)
  1047. break;
  1048. q++;
  1049. if ((sackoptlen - 2) == 0 || ((sackoptlen - 2) % 8 != 0)) {
  1050. Snprintf(p, bufsize, "malformed sack");
  1051. bufsize -= strlen(p);
  1052. p += strlen(p);
  1053. } else {
  1054. Snprintf(p, bufsize, "sack %d ", (sackoptlen - 2) / 8);
  1055. bufsize -= strlen(p);
  1056. p += strlen(p);
  1057. for (i = 0; i < sackoptlen - 2; i += 8) {
  1058. memcpy(&tmpword1, q + i, 4);
  1059. memcpy(&tmpword2, q + i + 4, 4);
  1060. Snprintf(p, bufsize, "{%u:%u}", tmpword1, tmpword2);
  1061. bufsize -= strlen(p);
  1062. p += strlen(p);
  1063. }
  1064. }
  1065. q += sackoptlen - 2;
  1066. len -= sackoptlen;
  1067. } else if (opcode == 8) { /* Timestamp */
  1068. if (len < 10)
  1069. break; /* Timestamp option has 10 bytes */
  1070. q++;
  1071. memcpy(&tmpword1, q, 4);
  1072. memcpy(&tmpword2, q + 4, 4);
  1073. Snprintf(p, bufsize, "timestamp %lu %lu", (unsigned long) ntohl(tmpword1),
  1074. (unsigned long) ntohl(tmpword2));
  1075. bufsize -= strlen(p);
  1076. p += strlen(p);
  1077. q += 8;
  1078. len -= 10;
  1079. }
  1080. ch = ',';
  1081. }
  1082. if (len > 0) {
  1083. *result = '\0';
  1084. return;
  1085. }
  1086. Snprintf(p, bufsize, ">");
  1087. }
  1088. /* A trivial function used with qsort to sort the routes by netmask and metric */
  1089. static int routecmp(const void *a, const void *b) {
  1090. struct sys_route *r1 = (struct sys_route *) a;
  1091. struct sys_route *r2 = (struct sys_route *) b;
  1092. if (r1->dest.ss_family < r2->dest.ss_family)
  1093. return -1;
  1094. else if (r1->dest.ss_family > r2->dest.ss_family)
  1095. return 1;
  1096. if (r1->netmask_bits < r2->netmask_bits)
  1097. return 1;
  1098. else if (r1->netmask_bits > r2->netmask_bits)
  1099. return -1;
  1100. if (r1->metric < r2->metric)
  1101. return -1;
  1102. else if (r1->metric > r2->metric)
  1103. return 1;
  1104. /* Compare addresses of equal elements to make the sort stable, as suggested
  1105. by the Glibc manual. */
  1106. if (a < b)
  1107. return -1;
  1108. else if (a > b)
  1109. return 1;
  1110. else
  1111. return 0;
  1112. }
  1113. /* Convert an address to a string and back again. The first parsing step
  1114. eliminates magical OS-specific syntax, for example on OS X, fe80:4::X:X:X:X
  1115. becomes "fe80::X:X:X:X" (the "4" in this case is another way of writing the
  1116. zone ID, like "%en0"; i.e., in this case en0 is interface number 4). This
  1117. must be done before e.g. comparing addresses by netmask. */
  1118. static int canonicalize_address(const struct sockaddr_storage *ss,
  1119. struct sockaddr_storage *output) {
  1120. char canonical_ip_string[NI_MAXHOST];
  1121. struct addrinfo hints;
  1122. struct addrinfo *ai;
  1123. int rc;
  1124. /* Convert address to string. */
  1125. rc = getnameinfo((struct sockaddr *) ss, sizeof(*ss),
  1126. canonical_ip_string, sizeof(canonical_ip_string), NULL, 0, NI_NUMERICHOST);
  1127. if (rc != 0) {
  1128. /* Don't care. */
  1129. *output = *ss;
  1130. return 0;
  1131. }
  1132. memset(&hints, 0, sizeof(hints));
  1133. hints.ai_family = ss->ss_family;
  1134. hints.ai_socktype = SOCK_DGRAM;
  1135. hints.ai_flags |= AI_NUMERICHOST;
  1136. rc = getaddrinfo(canonical_ip_string, NULL, &hints, &ai);
  1137. if (rc != 0 || ai == NULL)
  1138. return -1;
  1139. assert(ai->ai_addrlen > 0 && ai->ai_addrlen <= (int) sizeof(*output));
  1140. memcpy(output, ai->ai_addr, ai->ai_addrlen);
  1141. freeaddrinfo(ai);
  1142. return 0;
  1143. }
  1144. static int collect_dnet_interfaces(const struct intf_entry *entry, void *arg) {
  1145. struct dnet_collector_route_nfo *dcrn = (struct dnet_collector_route_nfo *) arg;
  1146. bool primary_done;
  1147. unsigned int num_aliases_done;
  1148. struct sockaddr_storage tmpss;
  1149. int rc;
  1150. primary_done = false;
  1151. num_aliases_done = 0;
  1152. while (!primary_done || num_aliases_done < entry->intf_alias_num) {
  1153. /* Make sure we have room for the new route */
  1154. if (dcrn->numifaces >= dcrn->capacity) {
  1155. dcrn->capacity <<= 2;
  1156. dcrn->ifaces = (struct interface_info *) safe_realloc(dcrn->ifaces,
  1157. dcrn->capacity * sizeof(struct interface_info));
  1158. }
  1159. /* The first time through the loop we add the primary interface record.
  1160. After that we add the aliases one at a time. */
  1161. if (!primary_done) {
  1162. if ( (addr_ntos(&entry->intf_addr, (struct sockaddr *) &tmpss) == -1)
  1163. #ifdef AF_LINK
  1164. || (tmpss.ss_family == AF_LINK)
  1165. #endif
  1166. ) {
  1167. dcrn->ifaces[dcrn->numifaces].addr.ss_family = 0;
  1168. } else {
  1169. rc = canonicalize_address(&tmpss, &dcrn->ifaces[dcrn->numifaces].addr);
  1170. assert(rc == 0);
  1171. }
  1172. dcrn->ifaces[dcrn->numifaces].netmask_bits = entry->intf_addr.addr_bits;
  1173. primary_done = true;
  1174. } else if (num_aliases_done < entry->intf_alias_num) {
  1175. if ( (addr_ntos(&entry->intf_alias_addrs[num_aliases_done], (struct sockaddr *) &tmpss) == -1)
  1176. #ifdef AF_LINK
  1177. || (tmpss.ss_family == AF_LINK)
  1178. #endif
  1179. ) {
  1180. dcrn->ifaces[dcrn->numifaces].addr.ss_family = 0;
  1181. } else {
  1182. rc = canonicalize_address(&tmpss, &dcrn->ifaces[dcrn->numifaces].addr);
  1183. assert(rc == 0);
  1184. }
  1185. dcrn->ifaces[dcrn->numifaces].netmask_bits = entry->intf_alias_addrs[num_aliases_done].addr_bits;
  1186. num_aliases_done++;
  1187. }
  1188. /* OK, address/netmask found. Let's get the name */
  1189. Strncpy(dcrn->ifaces[dcrn->numifaces].devname, entry->intf_name,
  1190. sizeof(dcrn->ifaces[dcrn->numifaces].devname));
  1191. Strncpy(dcrn->ifaces[dcrn->numifaces].devfullname, entry->intf_name,
  1192. sizeof(dcrn->ifaces[dcrn->numifaces].devfullname));
  1193. /* Interface type */
  1194. if (entry->intf_type == INTF_TYPE_ETH && (entry->intf_flags & INTF_FLAG_NOARP) == 0) {
  1195. dcrn->ifaces[dcrn->numifaces].device_type = devt_ethernet;
  1196. /* Collect the MAC address since this is ethernet */
  1197. memcpy(dcrn->ifaces[dcrn->numifaces].mac, &entry->intf_link_addr.addr_eth.data, 6);
  1198. } else if (entry->intf_type == INTF_TYPE_LOOPBACK) {
  1199. dcrn->ifaces[dcrn->numifaces].device_type = devt_loopback;
  1200. } else if (entry->intf_type == INTF_TYPE_TUN) {
  1201. dcrn->ifaces[dcrn->numifaces].device_type = devt_p2p;
  1202. } else {
  1203. dcrn->ifaces[dcrn->numifaces].device_type = devt_other;
  1204. }
  1205. dcrn->ifaces[dcrn->numifaces].ifindex = entry->intf_index;
  1206. dcrn->ifaces[dcrn->numifaces].mtu = entry->intf_mtu;
  1207. /* Is the interface up and running? */
  1208. dcrn->ifaces[dcrn->numifaces].device_up = (entry->intf_flags & INTF_FLAG_UP) ? true : false;
  1209. /* For the rest of the information, we must open the interface directly ... */
  1210. dcrn->numifaces++;
  1211. }
  1212. return 0;
  1213. }
  1214. /* Get a list of interfaces using dnet and intf_loop. */
  1215. static struct interface_info *getinterfaces_dnet(int *howmany, char *errstr, size_t errstrlen) {
  1216. struct dnet_collector_route_nfo dcrn;
  1217. intf_t *it;
  1218. dcrn.routes = NULL;
  1219. dcrn.numroutes = 0;
  1220. dcrn.numifaces = 0;
  1221. assert(howmany);
  1222. /* Initialize the interface array. */
  1223. dcrn.capacity = 16;
  1224. dcrn.ifaces = (struct interface_info *) safe_zalloc(sizeof(struct interface_info) * dcrn.capacity);
  1225. it = intf_open();
  1226. if (!it){
  1227. if(errstr) Snprintf(errstr, errstrlen, "%s: intf_open() failed", __func__);
  1228. *howmany=-1;
  1229. return NULL;
  1230. }
  1231. if (intf_loop(it, collect_dnet_interfaces, &dcrn) != 0){
  1232. if(errstr) Snprintf(errstr, errstrlen, "%s: intf_loop() failed", __func__);
  1233. *howmany=-1;
  1234. return NULL;
  1235. }
  1236. intf_close(it);
  1237. *howmany = dcrn.numifaces;
  1238. return dcrn.ifaces;
  1239. }
  1240. /* Returns an allocated array of struct interface_info representing the
  1241. available interfaces. The number of interfaces is returned in *howmany. This
  1242. function just does caching of results; the real work is done in
  1243. getinterfaces_dnet().
  1244. On error, NULL is returned, howmany is set to -1 and the supplied
  1245. error buffer "errstr", if not NULL, will contain an error message. */
  1246. struct interface_info *getinterfaces(int *howmany, char *errstr, size_t errstrlen) {
  1247. static int initialized = 0;
  1248. static struct interface_info *mydevs;
  1249. static int numifaces = 0;
  1250. if (!initialized) {
  1251. mydevs = getinterfaces_dnet(&numifaces, errstr, errstrlen);
  1252. initialized = 1;
  1253. }
  1254. /* These will propagate any error produced in getinterfaces_xxxx() to
  1255. * the caller. */
  1256. if (howmany)
  1257. *howmany = numifaces;
  1258. return mydevs;
  1259. }
  1260. /* The 'dev' passed in must be at least 32 bytes long. Returns 0 on success. */
  1261. int ipaddr2devname(char *dev, const struct sockaddr_storage *addr) {
  1262. struct interface_info *ifaces;
  1263. int numifaces;
  1264. int i;
  1265. ifaces = getinterfaces(&numifaces, NULL, 0);
  1266. if (ifaces == NULL)
  1267. return -1;
  1268. for (i = 0; i < numifaces; i++) {
  1269. if (sockaddr_storage_cmp(&ifaces[i].addr, addr) == 0) {
  1270. Strncpy(dev, ifaces[i].devname, 32);
  1271. return 0;
  1272. }
  1273. }
  1274. return -1;
  1275. }
  1276. int devname2ipaddr(char *dev, struct sockaddr_storage *addr) {
  1277. struct interface_info *mydevs;
  1278. int numdevs;
  1279. int i;
  1280. mydevs = getinterfaces(&numdevs, NULL, 0);
  1281. if (!mydevs)
  1282. return -1;
  1283. for (i = 0; i < numdevs; i++) {
  1284. if (!strcmp(dev, mydevs[i].devfullname)) {
  1285. *addr = mydevs[i].addr;
  1286. return 0;
  1287. }
  1288. }
  1289. return -1;
  1290. }
  1291. /* Looks for an interface with the given name (iname) and address
  1292. family type, and returns the corresponding interface_info if found.
  1293. Will accept a match of dev…

Large files files are truncated, but you can click here to view the full file