int scanner_error(struct scanner *s, const char *msg) { scanner_log(XKB_LOG_LEVEL_ERROR, s, msg); return ERROR_TOK; }
void scanner_warn(struct scanner *s, const char *msg) { scanner_log(XKB_LOG_LEVEL_WARNING, s, msg); }
/*半开扫描*/ static int half_scanner(int port) { char buffer[8192]; int raw_sock; struct sockaddr_in *_dest; int ret; static u_int32_t seq = 0x12345678; struct sockaddr_in dest; int sock_len; int i = 0; struct tcphdr *tcp; u_int32_t current_seq = seq; u_int32_t dst_ip; /*创建用于发送tcp包的原始套接字*/ raw_sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); if(raw_sock < 0) { perror("socket"); return -errno; } /*获取扫描地址*/ _dest = get_scan_addr(); memcpy(&dest, _dest, sizeof(dest)); //dest = *dest; dest.sin_port = htons(port); /*构造syn包*/ memcpy(&dst_ip, &dest.sin_addr, 4); ret = tcp_syn_pack((struct tcphdr*)buffer, 8192, get_local_ip(raw_sock), dst_ip, 5643, port, seq ++); if(ret < 0) { perror("tcp_syn_pack"); return ret; } //print_pack(buffer, ret); //ip_pack((struct ip*)buffer, IPPROTO_TCP, 255) /*发送*/ ret = sendto(raw_sock, buffer, ret, 0, (struct sockaddr*)&dest, sizeof(dest)); if(ret < 0) { perror("sendto"); return -errno; } /*接收对应的报文*/ sock_len = sizeof(dest); /*尝试接收20次,每次间隔100ms,所以最长延迟2s*/ for(i = 0; i < 40; i ++) { ret = recvfrom(raw_sock, buffer, 8192, MSG_DONTWAIT,(struct sockaddr*)&dest, &sock_len); if(ret < 0 && (errno != EAGAIN) && (errno != EWOULDBLOCK)) { perror("recvfrom"); close(raw_sock); return 0; } else if(ret >= sizeof(struct ip) + sizeof(struct tcphdr)) { /*定位到tcp报文*/ tcp = (struct tcphdr*)(buffer + ((struct ip*)buffer)->ip_hl * 4); /*检测是否是合格的确认报文*/ if(tcp->ack && tcp->seq && tcp->ack_seq == htonl(current_seq + 1)) { scanner_log("主机打开了端口:%10d\n", port); //fflush(stdout); close(raw_sock); return 1; } //printf("recv one %x %x %x\n", tcp->ack, tcp->syn, ntohl(tcp->ack_seq)); } usleep(10 * 1000); } //printf("The host didn't open %d\n", port); //fflush(stdout); close(raw_sock); return 0; }