1. 把網卡置於混雜模式。
2. 捕獲數據包。
3. 分析數據包。
注:下面的源代碼取至Chad Renfro的 < < Basic Packet-Sniffer Construction from the Ground Up> > 一文中
/************************Tcp_sniff_2.c********************/
1.#include
2.#include
3.#include
4.#include
5.#include
6.#include
7.#include
8.#include
9.#include "headers.h "
#define INTERFACE "eth0 "
/*Prototype area*/
10.int Open_Raw_Socket(void);
11.int Set_Promisc(char *interface, int sock);
12.int main() {
13.int sock, bytes_recieved, fromlen;
14.char buffer[65535];
15.struct sockaddr_in from;
16.struct ip *ip;
17.struct tcp *tcp;
18.sock = Open_Raw_Socket();
19. Set_Promisc(INTERFACE, sock);
20. while(1)
22. {
23. fromlen = sizeof from;
24. bytes_recieved = recvfrom(sock, buffer, sizeof buffer, 0, (struct sockaddr *)&from, &fromlen);
25. printf( "\nBytes received ::: %5d\n ",bytes_recieved);
26. printf( "Source address ::: %s\n ",inet_ntoa(from.sin_addr));
27. ip = (struct ip *)buffer;
/*See if this is a TCP packet*/
28. if(ip-> ip_protocol == 6) {
29. printf( "IP header length ::: %d\n ",ip-> ip_length);
30. printf( "Protocol ::: %d\n ",ip-> ip_protocol);
31. tcp = (struct tcp *)(buffer + (4*ip-> ip_length));
32. printf( "Source port ::: %d\n ",ntohs(tcp-> tcp_source_port));
33. printf( "Dest port ::: %d\n ",ntohs(tcp-> tcp_dest_port));
34. }
35. }
36.}
37.int Open_Raw_Socket() {
38. int sock;
39. if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {
/*Then the socket was not created properly and must die*/
40. perror( "The raw socket was not created ");
41. exit(0);
42. };
43. return(sock);
44. }
45.int Set_Promisc(char *interface, int sock ) {
46. struct ifreq ifr;
47. strncpy(ifr.ifr_name, interface,strnlen(interface)+1);
48. if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) {
/*Could not retrieve flags for the interface*/
49. perror( "Could not retrive flags for the interface ");
50. exit(0);
51. }
52. printf( "The interface is ::: %s\n ", interface);
53. perror( "Retrieved flags from interface successfully ");
54. ifr.ifr_flags |= IFF_PROMISC;
55. if (ioctl (sock, SIOCSIFFLAGS, &ifr) == -1 ) {
/*Could not set the flags on the interface */
56. perror( "Could not set the PROMISC flag: ");
57. exit(0);
58. }
59. printf( "Setting interface ::: %s ::: to promisc ", interface);
60. return(0);
61. }
/***********************EOF**********************************/
上面這段程序中有很詳細的注解,不過我想還是有必要說一說,首先第10行--int Open_Raw_Socket(void); 是我們的自定義函數,具體內容如下:
37.int Open_Raw_Socket() {
38. int sock;
39. if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {
/*Then the socket was not created properly and must die*/
40. perror( "The raw socket was not created ");
41. exit(0);
42. };
43. return(sock);
44. }
第39行 if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {
這裡我們調用了socket函數,使創建了了一個原始套接口,使之收到TCP/IP信息包。
接下來第11行-int Set_Promisc(char *interface, int sock),這也是我們的自定義函數,目的是把網卡置於混雜模式,具體內容如下:
45.int Set_Promisc(char *interface, int sock ) {
46. struct ifreq ifr;
47. strncpy(ifr.ifr_name, interface,strnlen(interface)+1);
48. if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) {
/*Could not retrieve flags for the interface*/
49. perror( "Could not retrive flags for the interface ");
50. exit(0);
51. }
52. printf( "The interface is ::: %s\n ", interface);
53. perror( "Retrieved flags from interface successfully ");
54. ifr.ifr_flags |= IFF_PROMISC;
55. if (ioctl (sock, SIOCSIFFLAGS, &ifr) == -1 ) {
/*Could not set the flags on the interface */
56. perror( "Could not set the PROMISC flag: ");
57. exit(0);
58. }
59. printf( "Setting interface ::: %s ::: to promisc ", interface);
60. return(0);
61. }
首先 struct ifreq ifr; 定一了一個ifrreg的結構ifr,接下來 strncpy(ifr.ifr_name, interface,strnlen(interface)+1);,就是把我們網絡設備的名字填充到ifr結構中,在這裡 #define INTERFACE "eth0 " ,讓我們再往下看,ioctl(sock, SIOCGIFFLAGS, &ifr),SIOCGIFFLAGS請求表示需要獲取接口標志,現在到了第54行,在我們成功的獲取接口標志後把他設置成混雜模式,ifr.ifr_flags |= IFF_PROMISC;ioctl (sock, SIOCSIFFLAGS, &ifr)。OK,現在我們所說的第一步已經完成--------把網卡置於混雜模式。
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2013-11/92548p2.htm