Environment: Ubuntu 8.04
Required tools: Libnet, libpcap, and tcpdump
Install these tools: sudo apt-Get install Libnet-dev libpcap-dev tcpdump
This program failed the test under FreeBSD. Libnet transmission package, Libpcap receiving package, very convenient (especially libpcap filtering rules ).
Create a receiving thread and then send a SYN packet. If you use a single thread to send and receive data first, no data is received.
When you use Libnet and libpcap to set network devices, you must have a "real" IP address, that is, the IP address can be used to communicate with the target host, it is ppp0 on my machine (I use ADSL), but it won't work if I use eth0.
Source code
// Compile: GCC synscan. c-o synscan-lnet-lpcap-lpthread <br/> # include <stdio. h> <br/> # include <pcap. h> <br/> # include <Libnet. h> <br/> # include <pthread. h> <br/> # include <sys/types. h> <br/> # include <sys/socket. h> <br/> # include <netinet/in. h> <br/> # include <netinet/IP. h> <br/> # include <netinet/TCP. h> <br/> # include <netinet/if_ether.h> <br/> # define localport 55555 <br/> # define ethernet_len 14 <br/> # Defin E sleep_time 1 <br/> # define th_syn 0x02 <br/> # define th_ack 0x10 <br/> // on my machine, the network device must be set to ppp0; if it is null, then Libnet and libpcap will automatically find the appropriate network device <br/> # ifdef _ Guzhou <br/> # define device "ppp0" <br/> # else <br/> # define device null <br/> # endif <br/> # define recv_ippacket_size 40 <br/> static unsigned char recvbuf [recv_ippacket_size]; // receive cache <br/> # define th_flag 33 // position of TCP flag in recvbuf <br/> struct syn_prop <br/> {< Br/> uint32_t dst_ip; <br/> uint16_t dst_port; <br/>}; <br/> static struct syn_1_timeout; <br/> static uint32_t gethostip (const char * Name) <br/>{< br/> struct hostent * hostinfo = NULL; <br/> uint32_t * ADDR = NULL; <br/> hostinfo = gethostbyname (name); <br/> If (! Hostinfo) <br/> return-1; <br/> If (af_inet! = Hostinfo-> h_addrtype) <br/> return-1; <br/> ADDR = (uint32_t *) (hostinfo-> h_addr_list [0]); <br/> return * ADDR; <br/>}< br/> static uint32_t flag; // used to determine whether recvbuf is the received group <br/> static void * recv_packet (void * Arg) <br/>{< br/> flag = 0; <br/> char * Dev, errbuf [pcap_errbuf_size]; <br/> pcap_t * handle; <br/> struct bpf_program FP; <br/> bpf_u_int32 mask, net; <br/> struct pcap_pkthdr header; <br/> cons T unsigned char * packet; <br/> char filter_exp [100] = "src host"; <br/> char TMP [100] = "and SRC port ", T [10]; <br/> const struct syn_rj* SS; <br/> struct in_addr ADDR; <br/> SS = (const struct syn_1_*) ARG; <br/> If (null = SS) <br/>{< br/> fprintf (stderr, "Arg is null/N"); <br/> return NULL; <br/>}< br/> Dev = device; <br/> If (null = Dev) <br/>{< br/> Dev = pcap_lookupdev (errb UF); <br/> If (null = Dev) <br/>{< br/> fprintf (stderr, "pcap_lookupdev () Error/N "); <br/> return NULL; <br/>}< br/> printf ("pcap Network Interface: % s/n", Dev ); <br/> If (pcap_lookupnet (Dev, & net, & Mask, errbuf) =-1) <br/>{< br/> fprintf (stderr, "pcap_lookupnet () error/N "); <br/> return NULL; <br/>}< br/> handle = pcap_open_live (Dev, bufsiz, 1, 1000, errbuf ); <br/> If (null = hand Le) <br/>{< br/> fprintf (stderr, "pcap_open_live () Error/N"); <br/> return NULL; <br/>}< br/> ADDR. s_addr = SS-> dst_ip; <br/> strcat (filter_exp, inet_ntoa (ADDR); <br/> sprintf (T, "% u", SS-> dst_port ); <br/> strcat (TMP, T); <br/> strcat (filter_exp, TMP); <br/> printf ("filter: % s/n", filter_exp ); // print the filter rule <br/> If (pcap_compile (handle, & FP, filter_exp, 0, net) =-1) <br/>{< br/> fprintf (stderr, "Pcap_compiler () Error/N"); <br/> return NULL; <br/>}< br/> If (pcap_setfilter (handle, & FP) =-1) <br/>{< br/> fprintf (stderr, "pcap_setfilter () error"); <br/> return NULL; <br/>}< br/> packet = pcap_next (handle, & header); // if no group is uploaded, <br/> printf ("jacked a packet with length of [% d]/n", header. len); <br/> // Save the received group ethernet_len starting from the IP header to recvbuf <br/> int I; <br/> packet + = ethernet_len; <br /> For (I = 0; I <recv_ippacket_size; I ++) <br/> recvbuf [I] = packet [I]; <br/> flag = 1; <br/> return NULL; <br/>}< br/> static int send_syn (const struct syn_0000* SS) <br/>{< br/> uint32_t src_ip, dst_ip; <br/> uint16_t dst_port; <br/> libnet_t * l; <br/> char errbuf [libnet_errbuf_size]; <br/> pthread_t Recv; <br/> dst_ip = SS-> dst_ip; <br/> dst_port = SS-> dst_port; <br/> L = libnet_init (Libnet _ Raw4, device, errbuf); <br/> If (null = L) <br/> {<br/> fprintf (stderr, "libnet_init () error/N "); <br/> return-1; <br/>}< br/> src_ip = libnet_get_ipaddr4 (L ); <br/> If (-1 = src_ip | 0 = src_ip) <br/> {<br/> fprintf (stderr, "libent_get_ipaddr4 () error/N "); <br/> return-1; <br/>}< br/> printf (" dst ip: % s, Port: % u/N ", inet_ntoa (* (struct in_addr *) & dst_ip), dst_port); <br/> printf ("src IP: % S/n ", inet_ntoa (* (struct in_addr *) & src_ip); <br/> If (libnet_build_tcp (localport, dst_port, 0, 0, th_syn, 0, 0, 0, libnet_tcp_h, null, 0, L, 0) =-1) <br/>{< br/> fprintf (stderr, "libnet_build_tcp () error/N "); <br/> return-1; <br/>}< br/> If (libnet_build_ipv4 <br/> (libnet_ipv4_h + libnet_tcp_h, 0,242, 0, 64, ipproto_tcp, 0, src_ip, dst_ip, null, 0, L, 0) =-1) <br/>{< br/> fprintf (St Derr, "libnet_build_ipv4 () Error/N"); <br/> return-1; <br/>}< br/> If (libnet_write (L) =-1) <br/>{< br/> fprintf (stderr, "libnet_write () Error/N"); <br/> return-1; <br/>}< br/> libnet_destroy (l); <br/> return 1; <br/>}< br/> // resolution group, here I simply print the group content <br/> static void parse_packet (const unsigned char * Buf, const unsigned int Len) <br/>{< br/> int I; <br/> printf ("the buffer is:/N"); <br/> for (I = 0; I <Len; I ++) <br/> printf ("% u", Buf [I]); <br/> putchar ('/N '); <br/>}< br/> int main (INT argc, char ** argv) <br/>{< br/> pthread_t Recv; <br/> void * retval; <br/> If (3! = Argc) <br/>{< br/> fprintf (stderr, "Usage: % s dst_ip dst_port/N", argv [0]); <br/> return-1; <br/>}< br/> response. dst_ip = gethostip (argv [1]); <br/> sscanf (argv [2], "% u", & (response. dst_port); <br/> If (response. dst_ip =-1) <br/>{< br/> fprintf (stderr, "gethostip () Error/N"); <br/> return-1; <br/>}< br/> printf ("scanning... /n "); <br/> // create a receiving thread <br/> If (pthread_create (& Recv, null, recv_packet, & packages )) <br/>{< br/> fprintf (stderr, "pthread_create () Error/N"); <br/> return-1; <br/>}< br/> If (send_syn (& amp; SYN) =-1) <br/>{< br/> fprintf (stderr, "send_syn () error/N "); <br/> return-1; <br/>}< br/> pthread_join (Recv, & retval ); <br/> If (recvbuf [th_flag] & th_syn) & (recvbuf [th_flag] & th_ack) <br/> printf ("% s: % s is opend/N ", argv [1], argv [2]); <br/> else <br/> printf (" % s: % s is closed/N ", argv [1], argv [2]); <br/> If (FLAG) <br/> parse_packet (recvbuf, recv_ippacket_size ); <br/> return 0; <br/>}</P> <p>