⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip_fragment.c

📁 libnids w32 libnids w32 libnids w32 libnids w32 libnids w32
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  This file is taken from Linux 2.0.36 kernel source.  Modified in Jun 99 by Nergal.*/#include <sys/types.h>#include <sys/time.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <netinet/tcp.h>#include <arpa/inet.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include "checksum.h"#include "ip_fragment.h"#include "tcp.h"#include "util.h"#include "nids.h"#define IP_CE		0x8000	/* Flag: "Congestion" */#define IP_DF		0x4000	/* Flag: "Don't Fragment" */#define IP_MF		0x2000	/* Flag: "More Fragments" */#define IP_OFFSET	0x1FFF	/* "Fragment Offset" part */#define IP_FRAG_TIME	(30 * 1000)	/* fragment lifetime */#define UNUSED 314159#define FREE_READ UNUSED#define FREE_WRITE UNUSED#define GFP_ATOMIC UNUSED#define NETDEBUG(x)struct sk_buff {  char *data;  int truesize;};struct timer_list {  struct timer_list *prev;  struct timer_list *next;  int expires;  void (*function)();  unsigned long data;  // struct ipq *frags;};struct hostfrags {  struct ipq *ipqueue;  int ip_frag_mem;  u_int ip;  int hash_index;  struct hostfrags *prev;  struct hostfrags *next;};/* Describe an IP fragment. */struct ipfrag {  int offset;			/* offset of fragment in IP datagram    */  int end;			/* last byte of data in datagram        */  int len;			/* length of this fragment              */  struct sk_buff *skb;		/* complete received fragment           */  unsigned char *ptr;		/* pointer into real fragment data      */  struct ipfrag *next;		/* linked list pointers                 */  struct ipfrag *prev;};/* Describe an entry in the "incomplete datagrams" queue. */struct ipq {  unsigned char *mac;		/* pointer to MAC header                */  struct ip *iph;		/* pointer to IP header                 */  int len;			/* total length of original datagram    */  short ihlen;			/* length of the IP header              */  short maclen;			/* length of the MAC header             */  struct timer_list timer;	/* when will this queue expire?         */  struct ipfrag *fragments;	/* linked list of received fragments    */  struct hostfrags *hf;  struct ipq *next;		/* linked list pointers                 */  struct ipq *prev;  // struct device *dev;	/* Device - for icmp replies */};/*  Fragment cache limits. We will commit 256K at one time. Should we  cross that limit we will prune down to 192K. This should cope with  even the most extreme cases without allowing an attacker to  measurably harm machine performance.*/#define IPFRAG_HIGH_THRESH		(256*1024)#define IPFRAG_LOW_THRESH		(192*1024)/*  This fragment handler is a bit of a heap. On the other hand it works  quite happily and handles things quite well.*/static struct hostfrags **fragtable;static struct hostfrags *this_host;static int numpack = 0;static int hash_size;static int timenow;static unsigned int time0;static struct timer_list *timer_head = 0, *timer_tail = 0;#define int_ntoa(x)	inet_ntoa(*((struct in_addr *)&x))static intjiffies(){  struct timeval tv;  if (timenow)    return timenow;  gettimeofday(&tv, 0);  timenow = (tv.tv_sec - time0) * 1000 + tv.tv_usec / 1000;    return timenow;}/* Memory Tracking Functions */static voidatomic_sub(int ile, int *co){  *co -= ile;}static voidatomic_add(int ile, int *co){  *co += ile;}static voidkfree_skb(struct sk_buff * skb, int type){  free(skb);}static voidpanic(char *str){  fprintf(stderr, "%s", str);  exit(1);}static voidadd_timer(struct timer_list * x){  if (timer_tail) {    timer_tail->next = x;    x->prev = timer_tail;    x->next = 0;    timer_tail = x;  }  else {    x->prev = 0;    x->next = 0;    timer_tail = timer_head = x;  }}static voiddel_timer(struct timer_list * x){  if (x->prev)    x->prev->next = x->next;  else    timer_head = x->next;  if (x->next)    x->next->prev = x->prev;  else    timer_tail = x->prev;}static voidfrag_kfree_skb(struct sk_buff * skb, int type){  if (this_host)    atomic_sub(skb->truesize, &this_host->ip_frag_mem);  kfree_skb(skb, type);}static voidfrag_kfree_s(void *ptr, int len){  if (this_host)    atomic_sub(len, &this_host->ip_frag_mem);  free(ptr);}static void *frag_kmalloc(int size, int dummy){  void *vp = (void *) malloc(size);  if (!vp)    return NULL;  atomic_add(size, &this_host->ip_frag_mem);    return vp;}/* Create a new fragment entry. */static struct ipfrag *ip_frag_create(int offset, int end, struct sk_buff * skb, unsigned char *ptr){  struct ipfrag *fp;    fp = (struct ipfrag *) frag_kmalloc(sizeof(struct ipfrag), GFP_ATOMIC);  if (fp == NULL) {    // NETDEBUG(printk("IP: frag_create: no memory left !\n"));    nids_params.no_mem("ip_frag_create");    return (NULL);  }  memset(fp, 0, sizeof(struct ipfrag));    /* Fill in the structure. */  fp->offset = offset;  fp->end = end;  fp->len = end - offset;  fp->skb = skb;  fp->ptr = ptr;  /* Charge for the SKB as well. */  this_host->ip_frag_mem += skb->truesize;    return (fp);}static intfrag_index(struct ip * iph){  unsigned int ip = ntohl(iph->ip_dst.s_addr);  return (ip % hash_size);}static inthostfrag_find(struct ip * iph){  int hash_index = frag_index(iph);  struct hostfrags *hf;    this_host = 0;  for (hf = fragtable[hash_index]; hf; hf = hf->next)    if (hf->ip == iph->ip_dst.s_addr) {      this_host = hf;      break;    }  if (!this_host)    return 0;  else    return 1;}static voidhostfrag_create(struct ip * iph){  struct hostfrags *hf = mknew(struct hostfrags);  int hash_index = frag_index(iph);  hf->prev = 0;  hf->next = fragtable[hash_index];  if (hf->next)    hf->next->prev = hf;  fragtable[hash_index] = hf;  hf->ip = iph->ip_dst.s_addr;  hf->ipqueue = 0;  hf->ip_frag_mem = 0;  hf->hash_index = hash_index;  this_host = hf;}static voidrmthis_host(){  int hash_index = this_host->hash_index;  if (this_host->prev) {    this_host->prev->next = this_host->next;    if (this_host->next)      this_host->next->prev = this_host->prev;  }  else {    fragtable[hash_index] = this_host->next;    if (this_host->next)      this_host->next->prev = 0;  }  free(this_host);  this_host = 0;}/*  Find the correct entry in the "incomplete datagrams" queue for this  IP datagram, and return the queue entry address if found.*/static struct ipq *ip_find(struct ip * iph){  struct ipq *qp;  struct ipq *qplast;    qplast = NULL;  for (qp = this_host->ipqueue; qp != NULL; qplast = qp, qp = qp->next) {    if (iph->ip_id == qp->iph->ip_id &&	iph->ip_src.s_addr == qp->iph->ip_src.s_addr &&	iph->ip_dst.s_addr == qp->iph->ip_dst.s_addr &&	iph->ip_p == qp->iph->ip_p) {      del_timer(&qp->timer);	/* So it doesn't vanish on us. The timer will				   be reset anyway */      return (qp);    }  }  return (NULL);}/*  Remove an entry from the "incomplete datagrams" queue, either  because we completed, reassembled and processed it, or because it  timed out.*/static voidip_free(struct ipq * qp){  struct ipfrag *fp;  struct ipfrag *xp;  /* Stop the timer for this entry. */  del_timer(&qp->timer);    /* Remove this entry from the "incomplete datagrams" queue. */  if (qp->prev == NULL) {    this_host->ipqueue = qp->next;    if (this_host->ipqueue != NULL)      this_host->ipqueue->prev = NULL;    else      rmthis_host();  }  else {    qp->prev->next = qp->next;    if (qp->next != NULL)      qp->next->prev = qp->prev;  }  /* Release all fragment data. */  fp = qp->fragments;  while (fp != NULL) {    xp = fp->next;    frag_kfree_skb(fp->skb, FREE_READ);    frag_kfree_s(fp, sizeof(struct ipfrag));    fp = xp;  }  /* Release the IP header. */  frag_kfree_s(qp->iph, 64 + 8);    /* Finally, release the queue descriptor itself. */  frag_kfree_s(qp, sizeof(struct ipq));}/* Oops- a fragment queue timed out.  Kill it and send an ICMP reply. */static voidip_expire(unsigned long arg){  struct ipq *qp;    qp = (struct ipq *) arg;  /* Nuke the fragment queue. */  ip_free(qp);}/*  Memory limiting on fragments. Evictor trashes the oldest fragment  queue until we are back under the low threshold.*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -