求大神帮忙分析一下这些代码的意思 关于基础入侵探测系统

qq_40681027 2017-11-14 01:48:06
#include "sniff.h"

#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <string.h>
#include <netinet/if_ether.h>
#include <signal.h>

#include "dispatch.h"

// Application main sniffing loop
void sniff(char *interface, int verbose) {
if(signal(SIGINT, sig_handler) == SIG_ERR) printf("\nCan't catch SIGINT\n");
// Open network interface for packet capture
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *pcap_handle = pcap_open_live(interface, 4096, 1, 0, errbuf);
if (pcap_handle == NULL) {
fprintf(stderr, "Unable to open interface %s\n", errbuf);
exit(EXIT_FAILURE);
} else {
printf("SUCCESS! Opened %s for capture\n", interface);
}
//Capture packets (very ugly code) - indeed
const unsigned char *packet;
//struct pcap_pkthdr header;
thread_create();

while (1) {
// Capture a packet
struct pcap_pkthdr *header = malloc(sizeof(struct pcap_pkthdr)); //declaration and allocation of memory done here to ensure that this data is not overwritten
packet = pcap_next(pcap_handle, header);
unsigned char *copy = malloc(header->len); //declaration of new buffer, allocation of memory and copying done in order to prevent overwriting of packet data
memcpy(copy, packet, header->len); //cast things
if (packet == NULL) {
// pcap_next can return null if no packet is seen within a timeout
if (verbose) {
printf("No packet received. %s\n", pcap_geterr(pcap_handle));
}
} else {
// Optional: dump raw data to terminal
if (verbose) {
dump(copy, header->len);
}
// Dispatch packet for processing
dispatch(header, copy, verbose);
}
}
}

// Utility/Debugging method for dumping raw packet data
void dump(const unsigned char *data, int length) {
unsigned int i;
static unsigned long pcount = 0;
// Decode Packet Header
struct ether_header *eth_header = (struct ether_header *) data;
printf("\n\n === PACKET %ld HEADER ===", pcount);
printf("\nSource MAC: ");
for (i = 0; i < 6; ++i) {
printf("%02x", eth_header->ether_shost[i]);
if (i < 5) {
printf(":");
}
}
printf("\nDestination MAC: ");
for (i = 0; i < 6; ++i) {
printf("%02x", eth_header->ether_dhost[i]);
if (i < 5) {
printf(":");
}
}
printf("\nType: %hu\n", eth_header->ether_type);
printf(" === PACKET %ld DATA == \n", pcount);
// Decode Packet Data (Skipping over the header)
int data_bytes = length - ETH_HLEN;
const unsigned char *payload = data + ETH_HLEN;
const static int output_sz = 20; // Output this many bytes at a time
while (data_bytes > 0) {
int output_bytes = data_bytes < output_sz ? data_bytes : output_sz;
// Print data in raw hexadecimal form
for (i = 0; i < output_sz; ++i) {
if (i < output_bytes) {
printf("%02x ", payload[i]);
} else {
printf (" "); // Maintain padding for partial lines
}
}
printf ("| ");
// Print data in ascii form
for (i = 0; i < output_bytes; ++i) {
char byte = payload[i];
if (byte > 31 && byte < 127) {
// Byte is in printable ascii range
printf("%c", byte);
} else {
printf(".");
}
}
printf("\n");
payload += output_bytes;
data_bytes -= output_bytes;
}
pcount++;
}
以上是一个sniff方法 求解读

下面是dispatch方法 求解读
#include "dispatch.h"

#include <pcap.h>
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>

#include "analysis.h"

#define MAX_THREAD_NUM 10

pthread_mutex_t muxlock_queue = PTHREAD_MUTEX_INITIALIZER; //used to change queue by threads and 'dispatch'
struct packet_queue *queue; //queue used to store packets for thread
pthread_t threads[MAX_THREAD_NUM]; //stores threads to be used
pthread_cond_t added;

void * thread_code(void *arg) {
//struct thread_args *args = (struct thread_args *) arg; //stores the thread's number (when passed by thread_createh)
struct packet_queue_elem *tmp;
//set cancel state enabled so that signal can terminate all threads
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

while(1) {
if(queue->head == NULL) {
pthread_cond_wait(&added, &muxlock_queue); //wait for signal from dispatch saying that a packet has been added to the queue
}

//at this point, the queue is already locked
//set cancel state disabled so that if thread is processing on termination, will wait until it is done before canceling
//the reason for this is the need to free the memory allocated to the packet queue element extracted by the current thread
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
tmp = queue->head; //retrieve the oldest packet in queue
if(tmp == NULL) { //just a sanity check - should never be the case...
queue->tail = NULL;
} else if(tmp->next == NULL) {
//the extracted packet queue element was the last one in the queue (head and tail must now not point to anything)
queue->head = NULL;
queue->tail = NULL;
} else {
//there are elements still in the queue. set head to the next element for the following thread to extract
queue->head = queue->head->next;
}
pthread_mutex_unlock(&muxlock_queue); //unlock so that other thread can use the queue

//if there was actual packet in queue - another sanity check
if(tmp != NULL) {
analyse(tmp->header, tmp->packet, tmp->verbose);
//free((unsigned char *) tmp->packet);
free(tmp); //must free memory allocated in 'dispatch'

}
//set cancel state back to enabled so that termination cancels thread
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
}
}

void thread_create() {
//initializing queue that will store packets for threads to process
queue = malloc(sizeof(struct packet_queue));
queue->head = NULL;
queue->tail = NULL;
unsigned int i;
for (i = 0; i < MAX_THREAD_NUM; i++) {
//struct thread_args *args = malloc(sizeof(struct thread_args));
//args->threadnum = i;
pthread_create(&threads[i], NULL, &thread_code, NULL);
}
}


void sig_handler(int signo) {
//Ctrl + C signal
if(signo == SIGINT) {
unsigned int i;
for (i = 0; i < MAX_THREAD_NUM; ++i) {
while(!pthread_cancel(threads[i])); //terminate regardless of current activity. if the state is disabled, the cancel request is queued and the command returns 0
}

//free memory used by all packet structures in queue - allocated during execution
while(queue->head != NULL) {
if(queue->head->next == NULL) {
free((unsigned char *) queue->head->packet); //memory was allocated for the packet data each time a queue element was created - need to free this memory
free(queue->head); //memory is allocated for these packet elements - need to free this memory
break;
} else {
struct packet_queue_elem *tmp = queue->head;
queue->head = queue->head->next;
free((unsigned char *) tmp->packet); //memory was allocated for the packet data each time a queue element was created - need to free this memory
free(tmp); //memory is allocated for these packet elements - need to free this memory
}
}
free(queue); //memory was allocated for this structure upon creation - need to free
pthread_mutex_destroy(&muxlock_queue); //no longer required because no threads will be using queue and 'dispatch' will not add anymore elemnts

report(); //method in 'analyse' used to output data collected during run
exit(signo);
}
}

void dispatch(struct pcap_pkthdr *header, const unsigned char *packet, int verbose) {
// TODO: Your part 2 code here
// This method should handle dispatching of work to threads. At present
// it is a simple passthrough as this skeleton is single-threaded.

//create temporary structure before locking queue to prevent excessive wait time for anything else trying to use queue
struct packet_queue_elem *tmp = malloc(sizeof(struct packet_queue_elem)); //the new packet to be queued
tmp->next = NULL; //this will be tail so the next element must be set to NULL
tmp->header = header;
tmp->packet = packet;
tmp->verbose = verbose;

while(pthread_mutex_trylock(&muxlock_queue)); //wait until the mutex is unlocked

if(queue->head == NULL) {
//queue is empty so the only element will be the new one, also head and tail at the same time
queue->head = tmp;
queue->tail = tmp;
pthread_cond_signal(&added); //signal threads that a packet has been added
} else {
//there are elements in queue, add to tail, then this will be the new tail
queue->tail->next = tmp;
queue->tail = queue->tail->next;
pthread_cond_signal(&added); //signal threads that a packet has been added
}
pthread_mutex_unlock(&muxlock_queue); //unlock so that threads can use queue
}
...全文
246 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复

15,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧