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

📄 snap_io.c

📁 一个学习SNMP项目:tmoerlan.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: snap_io.c,v 1.2 2003/09/17 11:26:10 tmoerlan Exp $ *//*#define iphdr ip#define ihl ip_hl#define tot_len ip_len*/#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>//#include <linux/ip.h>#include "snap.h"#include "config.h"#include "myassert.h"#include "consts.h"#include "bytecode.h"#include "io.h"#include "memalloc.h"#include "packet.h"#include "timers.h"#include "d_printf.h"#include "wassert.h"struct iphdr  {#if __BYTE_ORDER == __LITTLE_ENDIAN    unsigned int ihl:4;    unsigned int version:4;#elif __BYTE_ORDER == __BIG_ENDIAN    unsigned int version:4;    unsigned int ihl:4;#else# error "Please fix <bits/endian.h>"#endif    u_int8_t tos;    u_int16_t tot_len;    u_int16_t id;    u_int16_t frag_off;    u_int8_t ttl;    u_int8_t protocol;    u_int16_t check;    u_int32_t saddr;    u_int32_t daddr;    /*The options start here. */  };static void *scan_value(value_t *v, void *fromh, void *fromhmax,			void *fromhalloc, void *fromhallocmax,			void *tohmin, void *tohalloc, void *tohmax);static void *copy_heap_obj(heap_obj *hsrc, int sizeb,			   void *tohmin, void *tohalloc, void *tohmax);static void reset_heap(packet_t *p, void *to_heap, void *to_heap_max);/* used to verify packet integrity */#define VERIFY(e)							\  if (e); 								\  else { 								\    fprintf(stderr,"%s:%d: packet check failed\n",__FILE__,__LINE__);	\    return NULL;							\  }/* checks if the given heap_obj ptr is within the heap bounds.   side-effects sizeb to contain the object's length (word-aligned) */#define IF_IN_FROM_HEAP(ho,sizeb,hmin,hmax,hmin2,hmax2)			 \if ((((void *)(ho) >= (void *)(hmin)) &&				 \     ((void *)(ho) < (void *)(hmax)) &&					 \     (((void *)(ho) +							 \       ((sizeb) = (ho)->len + sizeof(heap_obj))) <= (void *)(hmax))) ||	 \    (((void *)(ho) >= (void *)(hmin2)) &&				 \     ((void *)(ho) < (void *)(hmax2)) &&				 \     (((void *)(ho) +							 \       ((sizeb) = (ho)->len + sizeof(heap_obj))) <= (void *)(hmax2)))) { \  if (((sizeb) & 0x3) != 0) {						 \    (sizeb) = ((sizeb) & ~0x3) + 4;					 \  }#define ELSE_NOT_IN_FROM_HEAP } else#define IN_TOSPACE_HEAP(hdst,sizeb,toh,tohmax)				 \  (((void *)(hdst) >= (toh)) && (((void *)(hdst) + (sizeb)) <= (tohmax)))/* cache the packet_t struct */static packet_t phandle;/* given a buffer containing a packet, find pointers to the header,   code, stack, and heap portions */packet_t *unmarshal_packet(char *buffer, int packet_lenb, int buf_lenb) {  packet_t *p;			/* packet struct to return */  void *buf_end = buffer + buf_lenb;   void *packet_end = buffer + packet_lenb;   unsigned short int code_lenb, entry_point, stack_lenb, heap_lenb;  assert(sizeof(unsigned long int) == sizeof(unsigned int));  assert(packet_lenb <= buf_lenb);  d_printf(100,"%s:%d: unmarshal_packet, buf=0x%x, plen=%d, blen=%d\n",	   __FILE__,__LINE__,(unsigned int)buffer,packet_lenb,buf_lenb);  print_anti_timer(7,"unmarshal_packet");  p = &phandle;  p->iph = (struct iphdr *)buffer;    /* set up header */  {    struct iphdr *iph = (struct iphdr *)buffer;    p->hdr = (header_t *)((void *)iph + (iph->ihl << 2));  }  code_lenb = ntohs(p->hdr->code_sizeb);  stack_lenb = ntohs(p->hdr->stack_sizeb);  heap_lenb = ntohs(p->hdr->heap_sizeb);  entry_point = ntohs(p->hdr->entry_point);  /* set up code */  print_anti_timer(9,"unmarshal_code");  p->code_min = (instr_t *)((void *)p->hdr + sizeof(header_t));  p->code_max = (instr_t *)((void *)p->code_min + code_lenb);  p->pc = p->code_min + entry_point;  p->handler = p->code_max;	/* default exception handler quits */  VERIFY((entry_point * sizeof(instr_t)) <= code_lenb);  print_timer(9,"unmarshal_code");  /* set up heap */  print_anti_timer(11,"unmarshal_heap");  p->heap_min = (void *)p->code_max;  p->heap_max = p->heap_min + heap_lenb;  print_timer(11,"unmarshal_heap");  /* set up stack */  print_anti_timer(10,"unmarshal_stack");  p->stack_min = (value_t *)p->heap_max;  p->stack_max = (value_t *)buf_end;  p->sp = (value_t *)((void *)p->stack_min + stack_lenb);  VERIFY(((void *)(p->sp) <= packet_end));   print_timer(10,"unmarshal_stack");  /* top of buffer */  p->h_alloc_heap_max = (void *)p->stack_max;  p->is_contiguous = 1;  d_printf(150,"%s:%d: @hdr = %#x\n",	   __FILE__,__LINE__,(uint32)p->hdr);  d_printf(150,"%s:%d: @code_min = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (uint32)p->code_min,(void *)p->code_min - (void *)p->hdr);  d_printf(150,"%s:%d: @pc = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (uint32)p->pc, (void *)p->pc - (void *)p->code_min);  d_printf(150,"%s:%d: @code_max = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (uint32)p->code_max, (void *)p->code_max - (void *)p->pc);  d_printf(150,"%s:%d: @heap_min = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (uint32)p->heap_min, (void *)p->heap_min - (void *)p->code_max);  d_printf(150,"%s:%d: @heap_max = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (uint32)p->heap_max, (void *)p->heap_max - (void *)p->heap_min);  d_printf(150,"%s:%d: @stack_min = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (uint32)p->stack_min, (void *)p->stack_min - (void *)p->heap_max);  d_printf(150,"%s:%d: @sp = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (uint32)p->sp, (void *)p->sp - (void *)p->stack_min);  d_printf(150,"%s:%d: @stack_max = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (uint32)p->stack_max, (void *)p->stack_max - (void *)p->sp);  d_printf(150,"%s:%d: @h_alloc_heap_max = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (uint32)p->h_alloc_heap_max, (void *)p->h_alloc_heap_max -	   (void *)p->stack_max);  print_timer(7,"unmarshal_packet");  return(p);}/* cache a 10k output buffer */static char *io_outbuf = NULL;static int io_outbuf_sizeb = 10 * 1024;/* given a packet and the amount of stack to take, marshal up a packet   into a continuous block of bytes.  We assume that the packet_t   structure is well-formed, but don't assume anything about the   contents of the stack and the heap (there may be bogus values),   so we require some extra checks. */int marshal_packet(packet_t *p, int stack_amt, buffer_t *bufstr) {  int sizeb;			/* size in bytes of new buffer */  instr_t *codesrc;		/* code pointer in old packet */  instr_t *codedst;		/* code pointer in new packet */  value_t *stacksrc;		/* stack pointer in old packet */  value_t *stackdst;		/* stack pointer in new packet */  void *newhmin;		/* bottom of new heap */  void *newhalloc;		/* new heap allocation pointer */  void *newhscan;		/* new heap scan pointer */  void *newhmax;		/* high limit for new heap */  header_t *newhdr;		/* header for the new packet */  d_printf(150,"%s:%d: @hdr = %#x\n",	   __FILE__,__LINE__,(unsigned int)p->hdr);  d_printf(150,"%s:%d: @code_min = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (unsigned int)p->code_min,(void *)p->code_min - (void *)p->hdr);  d_printf(150,"%s:%d: @pc = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (unsigned int)p->pc, (void *)p->pc - (void *)p->code_min);  d_printf(150,"%s:%d: @code_max = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (unsigned int)p->code_max, (void *)p->code_max - (void *)p->pc);  d_printf(150,"%s:%d: @heap_min = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (unsigned int)p->heap_min, (void *)p->heap_min - (void *)p->code_max);  d_printf(150,"%s:%d: @heap_max = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (unsigned int)p->heap_max, (void *)p->heap_max - (void *)p->heap_min);  d_printf(150,"%s:%d: @stack_min = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (unsigned int)p->stack_min, (void *)p->stack_min - (void *)p->heap_max);  d_printf(150,"%s:%d: @sp = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (unsigned int)p->sp, (void *)p->sp - (void *)p->stack_min);  d_printf(150,"%s:%d: @stack_max = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (unsigned int)p->stack_max, (void *)p->stack_max - (void *)p->sp);  d_printf(150,"%s:%d: @h_alloc_heap_max = %#x, delta = %d\n",	   __FILE__,__LINE__,	   (unsigned int)p->h_alloc_heap_max, (void *)p->h_alloc_heap_max -	   (void *)p->stack_max);  print_anti_timer(8,"marshal_packet");  /* check for valid args */  assert(stack_amt >= 0);  assert(p != NULL);  assert(bufstr != NULL);  /* see if we can reuse this buffer.  We can if the entire stack is     to be transmitted and if we haven't done any further heap     allocation. */  /* XXX this optimization won't work in the kernel case yet unless this     send is resulting from a forw or a forwto (as then we won't     compute any further). Might be possible to clone the buffer,     though. */  if (((p->sp - p->stack_min) == stack_amt) &&      (p->h_alloc_heap_max == p->stack_max) &&      (p->is_contiguous)) {    d_printf(100,"%s:%d: reusing old buffer during marshalling\n",	     __FILE__,__LINE__);    p->hdr->stack_sizeb = htons(stack_amt * sizeof(value_t));    bufstr->lenb = (void *)p->sp - (void *)p->iph;    bufstr->s = (char *)p->iph;    print_timer(8,"marshal_packet");    return 0;  }  /* take a conservative size for the packet-- the actual heap may be     smaller than the space we provide */  /* XXX should be statically allocated */  d_printf(100,"%s:%d: sh:%d B,cs:%d B,ss:%d B,hs1:%d B,hs2:%d B\n",	  __FILE__,__LINE__, sizeof(header_t), 	  ((void *)(p->code_max) - (void *)(p->code_min)),	  (stack_amt * sizeof(value_t)),	  ((void *)p->heap_max - (void *)p->heap_min),	  ((void *)p->h_alloc_heap_max - (void *)p->stack_max));  sizeb =     /* IP hdr */ sizeof(struct iphdr) +    /* RA option */ 4 +    /* header */ sizeof(header_t) +    /* code   */ ((void *)(p->code_max) - (void *)(p->code_min)) +    /* stack  */ (stack_amt * sizeof(value_t)) +    /* heap1  */ ((void *)p->heap_max - (void *)p->heap_min) +    /* heap2  */ ((void *)p->h_alloc_heap_max - (void *)p->stack_max);  d_printf(100, "%s:%d: out sizeb = %d bytes\n", 	   __FILE__,__LINE__,sizeb);  if (io_outbuf == NULL) {    if (sizeb > io_outbuf_sizeb) {      io_outbuf_sizeb = sizeb;    }    memalloc(io_outbuf,char *,io_outbuf_sizeb);  } else {    if (sizeb > io_outbuf_sizeb) {      io_outbuf_sizeb = sizeb;      free(io_outbuf);      memalloc(io_outbuf,char *,io_outbuf_sizeb);    }  }  /* copy over the IP header from the current packet */  {    if (p && p->iph){    	unsigned char *where = io_outbuf;    	d_printf(250,"marshall_packet : where=%p, p->iph=%p, size of header=%u",where,p->iph, sizeof(struct iphdr));    	memcpy(where, p->iph, sizeof(struct iphdr));    	/* copy over RA option */    	memcpy(where + sizeof(struct iphdr),(void *)p->iph + sizeof(struct iphdr),4);    }    /* the following is only used by snapas (the assembler, can be found in the utils subdir) */    else{    	d_printf(250,"creating new IP header");    }  }    /* set up all the source and destination pointers */  newhdr = (header_t *)(io_outbuf + sizeof(struct iphdr) + 4 );  codesrc = p->code_min;  codedst = (instr_t *)(newhdr+1);  newhmin = newhscan = newhalloc =    (void *)codedst + ((void *)p->code_max - (void *)p->code_min);  newhmax =    (void *)newhmin +     ((void *)p->heap_max - (void *)p->heap_min) +    ((void *)p->h_alloc_heap_max - (void *)p->stack_max);  stacksrc = p->sp - stack_amt;  stackdst = (value_t *)newhmax;  /* first copy the header */  memcpy(newhdr,p->hdr,sizeof(header_t));  /* now copy code */  d_printf(150,"%s:%d: scanning code\n",__FILE__,__LINE__);  {    int sizeb = (int)((void *)p->code_max - (void *)codesrc);    instr_t *codemax = (instr_t *)((void *)codedst + sizeb);    memcpy(codedst,codesrc,sizeb);    /* scan it, forwarding pointers to moved objects */    while (codedst < codemax) {#ifdef SMALL_INSTRS      switch (GET_OP(*codedst)) {        case SVCV:        case CALLS:        case PSTR:        case EQSTR:        case NQSTR:        case PTUP:        case EQTUP:        case NQTUP:        case PADDR:        case EQADR:        case NQADR:        case PFLT:        case EQFLT:        case NQFLT:        case FGTI:        case FGEQI:        case FLEQI:        case FLTI:        case FADDI:        case FSUBI:        case FMULI:        case FDIVI:        case SNETI:        case BCASTI: {	  int hoffs;	  heap_obj *hsrc;	  int sizeb;	  GET_LIT(hoffs,BOGUSV,*codedst);	  hsrc = (heap_obj *)(p->heap_min + hoffs);	  IF_IN_FROM_HEAP(hsrc,sizeb,p->heap_min,p->heap_max,			  p->stack_max,p->h_alloc_heap_max) {	    newhalloc = copy_heap_obj(hsrc, sizeb,				      newhmin, newhalloc, newhmax);	    /* forward it */	    /* note that if copy_heap_obj doesn't copy the object	       because it is bogus (or a previous object was), then this	       will result in a bogus pointer.  This doesn't matter as	       we check against it later in both the GC and the	       interpreter. */	    SET_LIT(*codedst,BOGUSV,hsrc->flag - 4); /* subtract the extra							4 from the offset */	  } 	  /* bogus pointer, leave it XXX */	  ELSE_NOT_IN_FROM_HEAP {	    fprintf (stderr,"%s:%d: warning, pointer @%#x not in heap\n",		     __FILE__,__LINE__,(unsigned int)hsrc);	  }	  break;	}        default:	  break;      } /* end switch */#else      switch (GET_OP(*codedst)) {#ifdef ADDR_IN_HEAP        case SNETI:        case BCASTI:	/* these may contain floating point values */        case GTI:        case GEQI:        case LTI:        case LEQI:        case ADDI:        case SUBI:        case MULTI:        case DIVI:#endif        case PUSH:        case EQI:

⌨️ 快捷键说明

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