📄 snap_interp.c
字号:
__FILE__,__LINE__,(p->pc - p->code_min),opname, \ (int)f1,(int)((f1 - (int)f1) * 1000000), \ (int)lit,(int)((lit - (int)lit) * 1000000), \ (int)result,(int)((result - (int)result) * 1000000)); \ SET_TAG(*top,INTV); \ SET_INT(*top,result); \ p->pc++; \ break; \}#define EQOP(res,opname) { \ value_t *top1 = p->sp - 1; \ value_t *top2 = p->sp - 2; \ int result; \ \ DYNCHECK(top2 >= p->stack_min); \ result = (res == eq_value(top1,top2,p)); \ if (result == -1) \ return -1; \ d_printf(10,"%s:%d: pc=%d: %s: (%s)\n", \ __FILE__,__LINE__,(p->pc - p->code_min),opname, \ (result ? "equal" : "not equal")); \ SET_TAG(*top2,INTV); \ SET_INT(*top2,result); \ p->sp--; \ p->pc++; \ break; \}#ifndef SMALL_INSTRS#define EQOPI(res,opname) { \ value_t *top = p->sp - 1; \ int result; \ \ DYNCHECK(top >= p->stack_min); \ result = (res == eq_value(top,&p->pc->arg,p)); \ d_printf(125,"%s:%d: pc=%d: %s: (%s)\n", \ __FILE__,__LINE__,(p->pc - p->code_min),opname, \ (result ? "equal" : "not equal")); \ SET_TAG(*top,INTV); \ SET_INT(*top,result); \ p->pc++; \ break; \}#endif/************************************************************************/static int eq_value(value_t *v1, value_t *v2, packet_t *p) { int result; TAG_T tag1 = GET_TAG(*v1); switch(tag1) {#ifdef SMALL_VALUES case INTV: case TUPLEV: case EXCV: case STRV: default: result = (*v1 == *v2); break;#else case EXCV: case INTV: default: result = (GET_INT(*v1) == GET_INT(*v2)) && (tag1 == GET_TAG(*v2)); break; case TUPLEV: case STRV: result = (GET_OFFS(*v1) == GET_OFFS(*v2)) && (tag1 == GET_TAG(*v2)); break;#endif case ADDRV: { uint32 addr1, addr2; if (tag1 == GET_TAG(*v2)) { GET_ADDR(addr1,p->heap_min,*v1); GET_ADDR(addr2,p->heap_min,*v2); result = (addr1 == addr2); } else result = 0; break; } case FLOATV: { float32 f1, f2; if (tag1 == GET_TAG(*v2)) { GET_FLOAT(f1,p->heap_min,*v1); GET_FLOAT(f2,p->heap_min,*v2); result = (f1 == f2); } else result = 0; break; } } return result;}/* assumes packet is well-formed on entry; returns -1 on failure */#ifdef __KERNEL__int snap_interp_packet(struct sk_buff *skb) {#elseint snap_interp_packet(packet_t *p) {#endif#ifdef __KERNEL__ struct iphdr *iph = skb->nh.iph; packet_t pack; packet_t *p = &pack;#endif int done;#ifdef __KERNEL__ /* set up packet struct */ p->hdr = (header_t *)((void *)iph + (iph->ihl << 2)); p->rb = iph->ttl; p->code_min = (instr_t *)((void *)p->hdr + sizeof(header_t)); p->pc = p->code_min + ntohs(p->hdr->entry_point); p->code_max = (instr_t *)((void *)p->code_min + ntohs(p->hdr->code_sizeb)); p->handler = p->code_max; /* default handler */ p->heap_min = (void *)p->code_max; p->h_alloc_ptr = NULL; p->heap_max = p->heap_min + ntohs(p->hdr->heap_sizeb); p->stack_min = (value_t *)p->heap_max; p->sp = (value_t *)((void *)p->stack_min + ntohs(p->hdr->stack_sizeb)); p->stack_max = (value_t *)skb->end; p->h_alloc_heap_max = skb->end; p->resized = 0; /* haven't grown it yet */ p->is_contiguous = 1; p->skb = skb;#else p->rb = p->iph->ttl;#endif print_anti_timer(1,"interp_packet"); done = 0; assert(p->pc >= p->code_min); d_printf(40,"%s:%d: packet src: %d.%d.%d.%d, dst: %d.%d.%d.%d\n", __FILE__,__LINE__,NIPQUAD(p->hdr->saddr),NIPQUAD(p->hdr->daddr)); d_printf(40,"%s:%d: interp_packet: %d instrs, %d stack vals, ep=%d, rb=%d\n", __FILE__,__LINE__,p->code_max - p->code_min, p->sp - p->stack_min, ntohs(p->hdr->entry_point), p->iph->ttl); d_printf(50,"%s:%d: hdr=0x%08x cmin=0x%08x pc=0x%08x cmax=0x%08x\n", __FILE__,__LINE__, (__u32)p->hdr, (__u32)p->code_min, (__u32)p->pc, (__u32)p->code_max); d_printf(50,"%s:%d: hmin=0x%08x hmax=0x%08x\n",__FILE__,__LINE__, (__u32)p->heap_min, (__u32)p->heap_max); d_printf(50,"%s:%d: smin=0x%08x sp=0x%08x smax=0x%08x\n", __FILE__,__LINE__, (__u32)p->stack_min, (__u32)p->sp, (__u32)p->stack_max);#ifdef __KERNEL__ d_printf(100,"%s:%d: skb->head=0x%08x skb->data=0x%08x skb->tail=0x%08x skb->end=0x%08x\n", __FILE__,__LINE__, (__u32)skb->head, (__u32)skb->data, (__u32)skb->tail, (__u32)skb->end);#endif /* decrement resource bound on arrival */ { if (p->rb <= 1) { /* out of resource bound after decrement */ d_printf(1,"%s:%d: out of RB, dropping packet\n",__FILE__,__LINE__);#ifdef __KERNEL__ return -ICMP_TIME_EXCEEDED;#else return -1;#endif } p->rb--; } while(!done) { /* if we exactly fall off the end of the code, we can assume an implicit EXIT instruction */ if (p->pc == p->code_max) { done = 1; break; } DYNCHECK(p->pc < p->code_max); switch(GET_OP(*p->pc)) { case EXIT: d_printf(10,"%s:%d: pc=%d: EXIT\n",__FILE__,__LINE__, (p->pc - p->code_min)); done = 1; break;#ifndef SMALL_INSTRS case PUSH: d_printf(100,"%s:%d: interp: PUSH\n",__FILE__,__LINE__); ENSURE_STACK_ROOM(p,iph); DYNCHECK(p->sp < p->stack_max); COPY_VAL(*p->sp,p->pc->arg); p->sp++; p->pc++; break;#else#ifndef NDEBUG#define PUSHOP(t,opname,fmt,arg...) { \ ENSURE_STACK_ROOM(p,iph); \ DYNCHECK(p->sp < p->stack_max); \ COPY_LIT(*p->sp,t,*p->pc); \ d_printf(10,"%s:%d: pc=%d: %s " fmt "\n", \ __FILE__,__LINE__,(p->pc - p->code_min), \ opname,##arg); \ p->sp++; \ p->pc++; \ break; \}#define PUSHWJDB(t,opname,val,fmt,arg...) { \ ENSURE_STACK_ROOM(p,iph); \ DYNCHECK(p->sp < p->stack_max); \ COPY_LIT(*p->sp,t,val); \ d_printf(10,"%s:%d: pc=%d: %s " fmt "\n", \ __FILE__,__LINE__,(p->pc - p->code_min), \ opname,##arg); \ p->sp++; \ p->pc++; \ break; \}#else /* NDEBUG */#define PUSHOP(t,opname,fmt,arg...) { \ ENSURE_STACK_ROOM(p,iph); \ DYNCHECK(p->sp < p->stack_max); \ COPY_LIT(*p->sp,t,*p->pc); \ p->sp++; \ p->pc++; \ break; \}#endif /* NDEBUG */ case PINT: PUSHOP(INTV,"PINT","%d",GET_LIT_VAL(*p->pc)); case PADDR: PUSHOP(ADDRV,"PADDR","%u.%u.%u.%u", NIPQUAD(GET_ADDR_VAL(p->heap_min,*p->pc))); case PTUP: PUSHOP(TUPLEV,"PTUP","offs[%d]",GET_OFFS(*p->pc)); case PEXC: PUSHOP(EXCV,"PEXC","exc(%d)",GET_LIT_VAL(*p->pc)); case PSTR: PUSHOP(STRV,"PSTR","\"%s\"", GET_STR_VAL(p->heap_min,*p->pc)); case PFLT: PUSHOP(FLOATV,"PFLT","%d.%06d", (int)GET_FLT_VAL(p->heap_min,*p->pc), (int)((GET_FLT_VAL(p->heap_min,*p->pc) - (int)GET_FLT_VAL(p->heap_min,*p->pc)) * 1000000));#endif case POP: d_printf(10,"%s:%d: pc=%d: POP\n",__FILE__,__LINE__, (p->pc - p->code_min)); DYNCHECK(p->sp > p->stack_min); p->sp--; p->pc++; break; case POPI: { int n; value_t *newsp; GET_LIT(n,INTV,*p->pc); DYNCHECK(n >= 0); d_printf(10,"%s:%d: pc=%d: POPI %d\n", __FILE__,__LINE__,(p->pc - p->code_min),n); newsp = p->sp - n; DYNCHECK(newsp >= p->stack_min); p->sp = newsp; p->pc++; break; } case PULL: { int n; value_t *src; d_printf(100,"%s:%d: interp: PULL\n",__FILE__,__LINE__); ENSURE_STACK_ROOM(p,iph); GET_LIT(n,INTV,*p->pc); DYNCHECK(n >= 0); src = p->sp - (n + 1); DYNCHECK(src >= p->stack_min); DYNCHECK(p->sp < p->stack_max); COPY_VAL(*p->sp,*src);#ifdef CONFIG_IP_SNAP_DEBUG d_printf(10,"%s:%d: pc=%d: PULL %d = ", __FILE__,__LINE__,(p->pc - p->code_min),n); if (sysctl_snap_debug_level == -1 || 10 <= sysctl_snap_debug_level) { printk_value(p,p->sp); printk("\n"); }#if 0#define PULL_D_PRINTF(fmt,arg...) \ { d_printf(10,"%s:%d: pc=%d: PULL %d = " fmt "\n", \ __FILE__,__LINE__,(p->pc - p->code_min),n, \ ##arg); \ break; \ } switch(GET_TAG(*p->sp)) { case INTV: PULL_D_PRINTF("%d",GET_INT(*p->sp)); case ADDRV: PULL_D_PRINTF("%d.%d.%d.%d", NIPQUAD(GET_ADDR_VAL(p->heap_min,*p->sp))); case STRV: PULL_D_PRINTF("\"%s\"",GET_STR_VAL(p->heap_min,*p->sp)); case EXCV: PULL_D_PRINTF("exc(%d)",GET_LIT_VAL(*p->sp)); case TUPLEV: PULL_D_PRINTF("offs[%d]",GET_OFFS(*p->sp)); case FLOATV: PULL_D_PRINTF("%d.%06d", (int)GET_FLT_VAL(p->heap_min,*p->sp), (int)((GET_FLT_VAL(p->heap_min,*p->sp) - (int)GET_FLT_VAL(p->heap_min,*p->sp)) * 1000000)); }#undef PULL_D_PRINTF#endif /* if 0 */#endif /* CONFIG_IP_SNAP_DEBUG */ p->sp++; p->pc++; break; } case PULLSTACK:{ int n; value_t *src; ENSURE_STACK_ROOM(p,iph); GET_LIT(n,INTV,*(p->sp -1)); DYNCHECK(n >= 0); src = p->sp - (n + 1); DYNCHECK(src >= p->stack_min); DYNCHECK(p->sp < p->stack_max); COPY_VAL(*(p->sp-1),*src); d_printf(100,"%s:%d: interp: PULLSTACK (from element %d)\n",__FILE__,__LINE__, n); p->pc++; break; } case STORE: { int n; value_t *src; value_t *dst; d_printf(100,"%s:%d: interp: STORE\n",__FILE__,__LINE__); GET_LIT(n,INTV,*p->pc); DYNCHECK(n >= 0); src = p->sp - 1; dst = p->sp - (n + 1); DYNCHECK(src >= p->stack_min); /* also effectively checks that the stack is non-empty */ COPY_VAL(*dst,*src);#ifdef CONFIG_IP_SNAP_DEBUG#define STORE_D_PRINTF(fmt,arg...) \ { d_printf(10,"%s:%d: pc=%d: STORE s[%d] := " fmt "\n", \ __FILE__,__LINE__,(p->pc - p->code_min),n, \ ##arg); \ break; \ } switch(GET_TAG(*src)) { case INTV: STORE_D_PRINTF("%d",GET_INT(*src)); case ADDRV: STORE_D_PRINTF("%d.%d.%d.%d", NIPQUAD(GET_ADDR_VAL(p->heap_min,*src))); case STRV: STORE_D_PRINTF("\"%s\"",GET_STR_VAL(p->heap_min,*src)); case EXCV: STORE_D_PRINTF("exc(%d)",GET_LIT_VAL(*src)); case TUPLEV: STORE_D_PRINTF("offs[%d]",GET_OFFS(*src)); case FLOATV: STORE_D_PRINTF("%d.%06d", (int)GET_FLT_VAL(p->heap_min,*src), (int)((GET_FLT_VAL(p->heap_min,*src) - (int)GET_FLT_VAL(p->heap_min,*src)) * 1000000)); }#undef STORE_D_PRINTF#endif /* CONFIG_IP_SNAP_DEBUG */ p->sp--; p->pc++; break; } case JI: { int jump; GET_LIT(jump,INTV,*p->pc); DYNCHECK(jump > 0); d_printf(10,"%s:%d: pc=%d: JI %d\n",__FILE__,__LINE__, (p->pc - p->code_min), jump); p->pc = p->pc + jump; break; } case PAJ: { value_t *top = p->sp - 1; int jump; int lit; DYNCHECK(top >= p->stack_min); GET_LIT(lit,INTV,*p->pc); DYNCHECK_TAG(*top,INTV); jump = GET_INT(*top); DYNCHECK(jump + lit > 0); d_printf(10,"%s:%d: pc=%d: PAJ %d + [%d] = %d\n",__FILE__,__LINE__, (p->pc - p->code_min),lit,jump,lit+jump); p->sp--; /* pop */ p->pc = p->pc + jump + lit; break; } case TPAJ: { value_t *top1 = p->sp - 1; value_t *top2 = p->sp - 2; int jump = 1; int lit; DYNCHECK(top2 >= p->stack_min); DYNCHECK_TAG(*top1,INTV); if (GET_INT(*top1) == 0) { GET_LIT(lit,INTV,*p->pc); DYNCHECK_TAG(*top2,INTV); jump = GET_INT(*top2); DYNCHECK(jump + lit > 0); d_printf(10,"%s:%d: pc=%d: TPAJ %d: top=0, branch %d+[%d]=%d\n", __FILE__,__LINE__,(p->pc - p->code_min), lit,lit,jump,jump + lit); jump += lit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -