- //編譯: gcc synscan.c -o synscan -lnet -lpcap -lpthread
- #include <stdio.h>
- #include <pcap.h>
- #include <libnet.h>
- #include <pthread.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <netinet/tcp.h>
- #include <netinet/if_ether.h>
- #define LOCALPORT 55555
- #define ETHERNET_LEN 14
- #define SLEEP_TIME 1
- #define TH_SYN 0x02
- #define TH_ACK 0x10
- //在我的機子上,網(wǎng)絡(luò)設(shè)備必須設(shè)置為ppp0;如果為NULL,則libnet和libpcap會自動查找合適的網(wǎng)絡(luò)設(shè)備
- #ifdef __GUZHOU
- # define DEVICE "ppp0"
- #else
- # define DEVICE NULL
- #endif
- #define RECV_IPPACKET_SIZE 40
- static unsigned char recvbuf[RECV_IPPACKET_SIZE]; //接收緩存
- #define TH_FLAG 33 //TCP標(biāo)志位在recvbuf中的位置
- struct syn_scanner
- {
- uint32_t dst_ip;
- uint16_t dst_port;
- };
- static struct syn_scanner scanner;
- static uint32_t gethostip(const char *name)
- {
- struct hostent *hostinfo = NULL;
- uint32_t *addr = NULL;
- hostinfo = gethostbyname(name);
- if (!hostinfo)
- return -1;
- if (AF_INET != hostinfo->h_addrtype)
- return -1;
- addr = (uint32_t *) (hostinfo->h_addr_list[0]);
- return *addr;
- }
- static uint32_t flag; //用于判斷recvbuf是否為收到的分組
- static void *recv_packet(void *arg)
- {
- flag = 0;
- char *dev, errbuf[PCAP_ERRBUF_SIZE];
- pcap_t *handle;
- struct bpf_program fp;
- bpf_u_int32 mask, net;
- struct pcap_pkthdr header;
- const unsigned char *packet;
- char filter_exp[100] = "src host ";
- char tmp[100] = " and src port ", t[10];
- const struct syn_scanner *ss;
- struct in_addr addr;
- ss = (const struct syn_scanner *)arg;
- if (NULL == ss)
- {
- fprintf(stderr, "arg is NULL/n");
- return NULL;
- }
- dev = DEVICE;
- if (NULL == dev)
- {
- dev = pcap_lookupdev(errbuf);
- if (NULL == dev)
- {
- fprintf(stderr, "pcap_lookupdev() error/n");
- return NULL;
- }
- }
- printf("pcap Network interface: %s/n", dev);
- if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1)
- {
- fprintf(stderr, "pcap_lookupnet() error/n");
- return NULL;
- }
- handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
- if (NULL == handle)
- {
- fprintf(stderr, "pcap_open_live() error/n");
- return NULL;
- }
- addr.s_addr = ss->dst_ip;
- strcat(filter_exp, inet_ntoa(addr));
- sprintf(t, "%u", ss->dst_port);
- strcat(tmp, t);
- strcat(filter_exp, tmp);
- printf("filter: %s/n", filter_exp); //打印過濾規(guī)則
- if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1)
- {
- fprintf(stderr, "pcap_compiler() error/n");
- return NULL;
- }
- if (pcap_setfilter(handle, &fp) == -1)
- {
- fprintf(stderr, "pcap_setfilter() error");
- return NULL;
- }
- packet = pcap_next(handle, &header); //若沒有分組傳過來,則會阻塞
- printf("Jacked a packet with length of [%d]/n", header.len);
- //把收到的分組從ip頭開始的ETHERNET_LEN存到recvbuf中
- int i;
- packet += ETHERNET_LEN;
- for (i = 0; i < RECV_IPPACKET_SIZE; i++)
- recvbuf[i] = packet[i];
- flag = 1;
- return NULL;
- }
- static int send_syn(const struct syn_scanner *ss)
- {
- uint32_t src_ip, dst_ip;
- uint16_t dst_port;
- libnet_t *l;
- char errbuf[LIBNET_ERRBUF_SIZE];
- pthread_t recv;
- dst_ip = ss->dst_ip;
- dst_port = ss->dst_port;
- l = libnet_init(LIBNET_RAW4, DEVICE, errbuf);
- if (NULL == l)
- {
- fprintf(stderr, "libnet_init() error/n");
- return -1;
- }
- src_ip = libnet_get_ipaddr4(l);
- if (-1 == src_ip || 0 == src_ip)
- {
- fprintf(stderr, "libent_get_ipaddr4() error/n");
- return -1;
- }
- printf("dst ip: %s, port: %u/n", inet_ntoa(*(struct in_addr *)&dst_ip), dst_port);
- printf("src ip: %s/n", inet_ntoa(*(struct in_addr *)&src_ip));
- if (libnet_build_tcp(LOCALPORT, dst_port, 0, 0, TH_SYN, 0, 0, 0, LIBNET_TCP_H, NULL, 0, l, 0) == -1)
- {
- fprintf(stderr, "libnet_build_tcp() error/n");
- return -1;
- }
- if (libnet_build_ipv4
- (LIBNET_IPV4_H + LIBNET_TCP_H, 0, 242, 0, 64, IPPROTO_TCP, 0, src_ip, dst_ip, NULL, 0, l, 0) == -1)
- {
- fprintf(stderr, "libnet_build_ipv4() error/n");
- return -1;
- }
- if (libnet_write(l) == -1)
- {
- fprintf(stderr, "libnet_write() error/n");
- return -1;
- }
- libnet_destroy(l);
- return 1;
- }
- //解析分組,這里我簡單地打印分組的內(nèi)容
- static void parse_packet(const unsigned char *buf, const unsigned int len)
- {
- int i;
- printf("The buffer is:/n");
- for (i = 0; i < len; i++)
- printf("%u ", buf[i]);
- putchar('/n');
- }
- int main(int argc, char **argv)
- {
- pthread_t recv;
- void *retval;
- if (3 != argc)
- {
- fprintf(stderr, "Usage: %s dst_ip dst_port/n", argv[0]);
- return -1;
- }
- scanner.dst_ip = gethostip(argv[1]);
- sscanf(argv[2], "%u", &(scanner.dst_port));
- if (scanner.dst_ip == -1)
- {
- fprintf(stderr, "gethostip() error/n");
- return -1;
- }
- printf("Scanning.../n");
- //創(chuàng)建接收線程
- if (pthread_create(&recv, NULL, recv_packet, &scanner))
- {
- fprintf(stderr, "pthread_create() error/n");
- return -1;
- }
- if (send_syn(&scanner) == -1)
- {
- fprintf(stderr, "send_syn() error/n");
- return -1;
- }
- pthread_join(recv,&retval);
- if ((recvbuf[TH_FLAG] & TH_SYN) && (recvbuf[TH_FLAG] & TH_ACK))
- printf("%s: %s is opend/n", argv[1], argv[2]);
- else
- printf("%s: %s is closed/n", argv[1], argv[2]);
- if (flag)
- parse_packet(recvbuf, RECV_IPPACKET_SIZE);
- return 0;
- }
|