?? tcp_scan.c
字號:
else if (entry == (struct __sockaddr_rb *)-1) return -1; } } } } #undef __offset return 0;}#ifdef IPV6static int __proc_icmp6_packet(const struct icmp6_hdr *icmp6, size_t icmplen, struct sockaddr *saddr, socklen_t addrlen, struct rb_root *root){ struct __sockaddr_rb *entry; const struct ip6_hdr *ip6hdr; const struct tcphdr *tcphdr; if (icmp6->icmp6_type == ICMP6_DST_UNREACH) { if (icmplen >= sizeof (struct icmp6_hdr) + sizeof (struct ip6_hdr) + 8) { ip6hdr = (const struct ip6_hdr *)(icmp6 + 1); tcphdr = (const struct tcphdr *)(ip6hdr + 1); if (ntohs(tcphdr->th_sport) == __tcp_scanner_port && ntohl(tcphdr->th_seq) == __tcp_header_seq) { ((struct sockaddr_in6 *)saddr)->sin6_port = tcphdr->th_dport; if (!(entry = __rb_insert_sockaddr(saddr, addrlen, root))) { if (__info(saddr, addrlen, TS_UNREACH, __arg) < 0) return -1; } else if (entry == (struct __sockaddr_rb *)-1) return -1; } } } return 0;}#endifstatic int __recv_icmp_packet(int sockfd, struct rb_root *root){ /* Biggest IPv4 header, ICMP header, the returned IP header with 8 bytes TCP header. */ #define __BUFSIZE \ ((0xf << 2) + sizeof (struct icmphdr) + (0xf << 2) + 8) char buf[__BUFSIZE]; struct ip *iphdr = (struct ip *)buf;#ifdef IPV6 struct ip6_hdr *ip6hdr = (struct ip6_hdr *)buf;#endif union __sa_union un; socklen_t addrlen; ssize_t n; while (addrlen = sizeof (union __sa_union), (n = recvfrom(sockfd, buf, __BUFSIZE, 0, &un.sockaddr, &addrlen)) >= 0) { if (un.sockaddr.sa_family == AF_INET) { if (n >= sizeof (struct ip) && iphdr->ip_p == IPPROTO_ICMP && n >= (iphdr->ip_hl << 2) + sizeof (struct icmp)) { struct icmp *icmp = (struct icmp *)(buf + (iphdr->ip_hl << 2)); if (__proc_icmp_packet(icmp, n - (iphdr->ip_hl << 2), &un.sockaddr, addrlen, root) < 0) break; } }#ifdef IPV6 else if (un.sockaddr.sa_family == AF_INET6) { if (n >= sizeof (struct ip6_hdr) + sizeof (struct icmp6_hdr) && ip6hdr->ip6_nxt == IPPROTO_ICMPV6) { struct icmp6_hdr *icmp6 = (struct icmp6_hdr *)(ip6hdr + 1); if (__proc_icmp6_packet(icmp6, n - sizeof (struct ip6_hdr), &un.sockaddr, addrlen, root) < 0) break; } }#endif } #undef __BUFSIZE return n < 0 && errno == EAGAIN ? 0 : -1;}inline static int#ifdef IPV6__scan_ip_seg(const struct in_addr *address, unsigned int bits, unsigned short port, int tcpsock, int icmpsock, int tcpsock6, int icmpsock6, const struct in_addr *myaddr, struct rb_root *root)#else__scan_ip_seg(const struct in_addr *address, unsigned int bits, unsigned short port, int tcpsock, int icmpsock, const struct in_addr *myaddr, struct rb_root *root)#endif{ unsigned int hostmax = 0; unsigned int host; struct sockaddr_in sin; unsigned int bit = 1; bzero(&sin, sizeof (struct sockaddr_in)); sin.sin_family = AF_INET; for (host = 0; host < 32 - bits; host++) { hostmax |= bit; bit <<= 1; } host = ntohl(address->s_addr) & ~hostmax; hostmax |= ntohl(address->s_addr); do { sin.sin_addr.s_addr = htonl(host); if (!__rb_search_sockaddr((struct sockaddr *)&sin, sizeof (struct sockaddr_in), root)) { __tcp_syn(tcpsock, __tcp_scanner_port, port, myaddr, (struct sockaddr *)&sin, sizeof (struct sockaddr_in)); } if (__recv_tcp_packet(tcpsock, root) < 0) return -1; if (__recv_icmp_packet(icmpsock, root) < 0) return -1;#ifdef IPV6 if (tcpsock6 >= 0) { if (__recv_tcp_packet(tcpsock6, root) < 0) return -1; if (__recv_icmp_packet(icmpsock6, root) < 0) return -1; }#endif } while (host++ != hostmax); return 0;}#ifdef IPV6inline static int__scan_ip6_seg(const struct in6_addr *address, unsigned int bits, unsigned short port, int tcpsock, int icmpsock, int tcpsock6, int icmpsock6, const struct in6_addr *myaddr, struct rb_root *root){ struct in6_addr hostmax; struct in6_addr host; struct sockaddr_in6 sin6; unsigned char bit = 1; int i, j; bzero(&hostmax, sizeof (struct in6_addr)); for (i = 15; i > bits >> 3; i--) hostmax.s6_addr[i] = 0xff; for (j = 0; j < ((128 - bits) & 7); j++) { hostmax.s6_addr[i] |= bit; bit <<= 1; } for (i = 0; i < 4; i++) { host.s6_addr32[i] = address->s6_addr32[i] & ~hostmax.s6_addr32[i]; hostmax.s6_addr32[i] |= address->s6_addr32[i]; } bzero(&sin6, sizeof (struct sockaddr_in6)); sin6.sin6_family = AF_INET6; while (1) { sin6.sin6_addr = host; if (!__rb_search_sockaddr((struct sockaddr *)&sin6, sizeof (struct sockaddr_in6), root)) { __tcp_syn(tcpsock, __tcp_scanner_port, port, myaddr, (struct sockaddr *)&sin6, sizeof (struct sockaddr_in6)); } if (tcpsock >= 0) { if (__recv_tcp_packet(tcpsock, root) < 0) return -1; if (__recv_icmp_packet(icmpsock, root) < 0) return -1; } if (__recv_tcp_packet(tcpsock6, root) < 0) return -1; if (__recv_icmp_packet(icmpsock6, root) < 0) return -1; if (IN6_ARE_ADDR_EQUAL(&host, &hostmax)) break; IN6_ADDR_NEXT(&host); } return 0;}#endif#ifdef IPV6static int __wait_response(int tcpsock, int icmpsock, int tcpsock6, int icmpsock6, struct rb_root *root)#elsestatic int __wait_response(int tcpsock, int icmpsock, struct rb_root *root)#endif{ time_t start = time(NULL); fd_set all, rset; struct timeval timeout; int maxfd = -1; int n; #define __max(x, y) ((x) > (y) ? (x) : (y)) if (tcpsock >= 0) { FD_SET(tcpsock, &all); FD_SET(icmpsock, &all); maxfd = __max(tcpsock, icmpsock); }#ifdef IPV6 if (tcpsock6 >= 0) { FD_SET(tcpsock6, &all); FD_SET(icmpsock6, &all); maxfd = __max(maxfd, __max(tcpsock6, icmpsock6)); }#endif #undef __max /* Wait at least 2*MSL for all IP segments to expire. */ while ((n = (__max_seg_lifetime << 1) - (time(NULL) - start)) >= 0) { timeout.tv_sec = n + 1; timeout.tv_usec = 0; rset = all; if ((n = select(maxfd + 1, &rset, NULL, NULL, &timeout)) > 0) { if (tcpsock >= 0) { if (FD_ISSET(tcpsock, &rset)) { if (__recv_tcp_packet(tcpsock, root) < 0) return -1; } if (FD_ISSET(icmpsock, &rset)) { if (__recv_icmp_packet(icmpsock, root) < 0) return -1; } }#ifdef IPV6 if (tcpsock6 >= 0) { if (FD_ISSET(tcpsock6, &rset)) { if (__recv_tcp_packet(tcpsock6, root) < 0) return -1; } if (FD_ISSET(icmpsock6, &rset)) { if (__recv_icmp_packet(icmpsock6, root) < 0) return -1; } }#endif } else if (n == 0) break; else if (n < 0) return -1; } return 0;}int tcp_scan(const struct addrseg *scope, const unsigned short *ports, unsigned int ifindex, const char *ifname, int resetuid, scan_info_t info, void *arg){ const struct addrseg *p; const short *port; int tcpsock = -1, icmpsock = -1; struct in_addr ipaddr;#ifdef IPV6 int tcpsock6 = -1, icmpsock6 = -1; struct in6_addr ip6addr;#endif union __sa_union un; int i, ret = -1; struct rb_root root = RB_ROOT; for (p = scope; p; p = p->as_next) { switch (p->as_family) { case AF_INET: tcpsock = -2; break;#ifdef IPV6 case AF_INET6: tcpsock6 = -2; break;#endif default: errno = EAFNOSUPPORT; return -1; } } if (tcpsock == -2) { if (getifaddr(AF_INET, ifindex, ifname, &ipaddr) < 0) goto error; if ((tcpsock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) goto error; if ((icmpsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) goto error; bzero(&un.sin, sizeof (struct sockaddr_in)); un.sin.sin_family = AF_INET; un.sin.sin_addr = ipaddr; if (bind(tcpsock, &un.sockaddr, sizeof (struct sockaddr_in)) < 0) goto error; if (bind(icmpsock, &un.sockaddr, sizeof (struct sockaddr_in)) < 0) goto error; if (SET_FD_NONBLOCK(tcpsock) < 0) goto error; if (SET_FD_NONBLOCK(icmpsock) < 0) goto error; }#ifdef IPV6 if (tcpsock6 == -2) { if (getifaddr(AF_INET6, ifindex, ifname, &ip6addr) < 0) goto error; if ((tcpsock6 = socket(AF_INET6, SOCK_RAW, IPPROTO_TCP)) < 0) goto error; if ((icmpsock6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) goto error; bzero(&un.sin6, sizeof (struct sockaddr_in6)); un.sin6.sin6_family = AF_INET6; un.sin6.sin6_addr = ip6addr; if (bind(tcpsock6, &un.sockaddr, sizeof (struct sockaddr_in6)) < 0) goto error; if (bind(icmpsock6, &un.sockaddr, sizeof (struct sockaddr_in6)) < 0) goto error; if (SET_FD_NONBLOCK(tcpsock6) < 0) goto error; if (SET_FD_NONBLOCK(icmpsock6) < 0) goto error; }#endif /* We no longer need root privilege. */ if (resetuid) setuid(getuid()); /* Generate a random TCP sequance. */ srand(time(NULL)); __tcp_header_seq = rand(); __info = info; __arg = arg; for (i = 0; i < __tcp_scan_repeats; i++) { for (port = ports; *port; port++) { for (p = scope; p; p = p->as_next) { if (p->as_family == AF_INET) {#ifdef IPV6 if (__scan_ip_seg(p->as_address, p->as_bits, *port, tcpsock, icmpsock, tcpsock6, icmpsock6, &ipaddr, &root) < 0) goto error;#else if (__scan_ip_seg(p->as_address, p->as_bits, *port, tcpsock, icmpsock, &ipaddr, &root) < 0) goto error;#endif }#ifdef IPV6 else /* if (p->as_family == AF_INET6) */ { if (__scan_ip6_seg(p->as_address, p->as_bits, *port, tcpsock, icmpsock, tcpsock6, icmpsock6, &ip6addr, &root) < 0) goto error; }#endif } } }#ifdef IPV6 if (__wait_response(tcpsock, icmpsock, tcpsock6, icmpsock6, &root) >= 0) ret = 0;#else if (__wait_response(tcpsock, icmpsock, &root) >= 0) ret = 0;#endiferror: __rb_destroy_sockaddr(&root); if (tcpsock >= 0) close(tcpsock); if (icmpsock >= 0) close(icmpsock);#ifdef IPV6 if (tcpsock6 >= 0) close(tcpsock6); if (icmpsock6 >= 0) close(icmpsock6);#endif return ret;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -