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

📄 checksum.c

📁 libnids w32 libnids w32 libnids w32 libnids w32 libnids w32
💻 C
字号:
#include <sys/types.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <netinet/udp.h>#if ( __i386__ || __i386 )// all asm procedures are copied from Linux 2.0.36 and 2.2.10 kernels/*  computes the checksum of a memory block at buff, length len, and  adds in "sum" (32-bit)   returns a 32-bit number suitable for feeding into itself or  csum_tcpudp_magic   this function must be called with even lengths, except for the last  fragment, which may be odd   it's best to have buff aligned on a 32-bit boundary*/u_intcsum_partial(const u_char * buff, int len, u_int sum){  __asm__ (/*		"pushl %esi	pushl %ebx	movl 20(%esp),%eax	# Function arg: u_int sum	movl 16(%esp),%ecx	# Function arg: int len        movl 12(%esp),%esi	# Function arg: u_char *buff*/"	testl $2, %%esi						\n"		"	jz 2f							\n"			"	subl $2, %%ecx						\n"		"	jae 1f							\n"			"	addl $2, %%ecx						\n"		"	jmp 4f							\n""1:	movw (%%esi), %%bx					\n""	addl $2, %%esi						\n""	addw %%bx, %%ax						\n""	adcl $0, %%eax						\n""2:								\n""	movl %%ecx, %%edx					\n""	shrl $5, %%ecx						\n""	jz 2f							\n""	testl %%esi, %%esi					\n""1:	movl (%%esi), %%ebx					\n""	adcl %%ebx, %%eax					\n""	movl 4(%%esi), %%ebx					\n""	adcl %%ebx, %%eax					\n""	movl 8(%%esi), %%ebx					\n""	adcl %%ebx, %%eax					\n""	movl 12(%%esi), %%ebx					\n""	adcl %%ebx, %%eax					\n""	movl 16(%%esi), %%ebx					\n""	adcl %%ebx, %%eax					\n""	movl 20(%%esi), %%ebx					\n""	adcl %%ebx, %%eax					\n""	movl 24(%%esi), %%ebx					\n""	adcl %%ebx, %%eax					\n""	movl 28(%%esi), %%ebx					\n""	adcl %%ebx, %%eax					\n""	lea 32(%%esi), %%esi					\n""	dec %%ecx						\n""	jne 1b							\n""	adcl $0, %%eax						\n""2:	movl %%edx, %%ecx					\n""	andl $0x1c, %%edx					\n""	je 4f							\n""	shrl $2, %%edx						\n""3:	adcl (%%esi), %%eax					\n""	lea 4(%%esi), %%esi					\n""	dec %%edx						\n""	jne 3b							\n""	adcl $0, %%eax						\n""4:	andl $3, %%ecx						\n""	jz 7f							\n""	cmpl $2, %%ecx						\n""	jb 5f							\n""	movw (%%esi),%%cx					\n""	leal 2(%%esi),%%esi					\n""	je 6f							\n""	shll $16,%%ecx						\n""5:	movb (%%esi),%%cl					\n""6:	addl %%ecx,%%eax					\n""	adcl $0, %%eax						\n""7: 								\n"       : "=a"(sum)       : "0"(sum), "c"(len), "S"(buff)       : "bx", "dx");  return (sum);}/*  This is a version of ip_compute_csum() optimized for IP headers,  which always checksum on 4 octet boundaries.   By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by Arnt  Gulbrandsen.*/inline u_short ip_fast_csum(u_char * iph, u_int ihl){  u_int sum;    __asm__ __volatile__("	    movl (%1), %0			\n""	    subl $4, %2				\n""	    jbe 2f				\n""	    addl 4(%1), %0			\n""	    adcl 8(%1), %0			\n""	    adcl 12(%1), %0			\n""1:	    adcl 16(%1), %0			\n""	    lea 4(%1), %1			\n""	    decl %2				\n""	    jne	1b				\n""	    adcl $0, %0				\n""	    movl %0, %2				\n""	    shrl $16, %0			\n""	    addw %w2, %w0			\n""	    adcl $0, %0				\n""	    notl %0				\n""2:						\n"	/*	  Since the input registers which are loaded with iph and ipl	  are modified, we must also specify them as outputs, or gcc	  will assume they contain their original values.	*/	: "=r" (sum), "=r" (iph), "=r" (ihl)	: "1" (iph), "2" (ihl));    return (sum);}/* Fold a partial checksum. */static inline u_intcsum_fold(u_int sum){  __asm__("	addl %1, %0		\n""	adcl $0xffff, %0	\n"	: "=r" (sum)	: "r" (sum << 16), "0" (sum & 0xffff0000)	  );  return ((~sum) >> 16);} /*  computes the checksum of the TCP/UDP pseudo-header  returns a 16-bit checksum, already complemented*/static inline u_shortcsum_tcpudp_magic(u_int saddr, u_int daddr, u_short len,		  u_short proto, u_int sum){  __asm__("	addl %1, %0	\n""	adcl %2, %0	\n""	adcl %3, %0	\n""	adcl $0, %0	\n"	: "=r" (sum)	: "g" (daddr), "g"(saddr), "g"((ntohs(len) << 16) + proto * 256), "0"(sum));  return (csum_fold(sum));}/*  this routine is used for miscellaneous IP-like checksums, mainly in  icmp.c*/inline u_shortip_compute_csum(u_char * buff, int len){  return (csum_fold(csum_partial(buff, len, 0)));}inline u_shortmy_tcp_check(struct tcphdr *th, int len, u_int saddr, u_int daddr){  return csum_tcpudp_magic(saddr, daddr, len, IPPROTO_TCP,			   csum_partial((char *)th, len, 0));}inline u_shortmy_udp_check(void *u, int len, u_int saddr, u_int daddr){  return csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP,			   csum_partial((char *)u, len, 0));}#else /* !i386 */struct psuedo_hdr{  u_int saddr;        u_int daddr;        u_char zero;          u_char protocol;      u_short len;        };u_shortip_check_ext(register u_short *addr, register int len, int addon){  register int nleft = len;  register u_short *w = addr;  register int sum = addon;  u_short answer = 0;  /*   *  Our algorithm is simple, using a 32 bit accumulator (sum),   *  we add sequential 16 bit words to it, and at the end, fold   *  back all the carry bits from the top 16 bits into the lower   *  16 bits.   */  while (nleft > 1)  {    sum += *w++;    nleft -= 2;  }  /* mop up an odd byte, if necessary */  if (nleft == 1) {    *(u_char *)(&answer) = *(u_char *)w;    sum += answer;  }    /* add back carry outs from top 16 bits to low 16 bits */  sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */  sum += (sum >> 16);                     /* add carry */  answer = ~sum;                          /* truncate to 16 bits */  return (answer);}u_shortip_fast_csum(u_short *addr, int len){  return ip_check_ext(addr, len << 2, 0);}u_shortip_compute_csum(u_short *addr, int len){  return ip_check_ext(addr, len, 0);}u_shortmy_tcp_check(struct tcphdr *th, int len, u_int saddr, u_int daddr){  int i, sum = 0;  struct psuedo_hdr hdr;    hdr.saddr = saddr;  hdr.daddr = daddr;  hdr.zero = 0;  hdr.protocol = IPPROTO_TCP;  hdr.len = htons(len);  for (i = 0; i < sizeof(hdr); i += 2)    sum += *(u_short *)((char *)(&hdr) + i);    return (ip_check_ext((u_short *)th, len, sum));}                     u_shortmy_udp_check(void *u, int len, u_int saddr, u_int daddr){  int i, sum = 0;  struct psuedo_hdr hdr;    hdr.saddr = saddr;  hdr.daddr = daddr;  hdr.zero = 0;  hdr.protocol = IPPROTO_UDP;  hdr.len = htons(len);  for (i = 0; i < sizeof(hdr); i += 2)    sum += *(u_short *)((char *)(&hdr) + i);    return (ip_check_ext((u_short *)u, len, sum));}                     #endif /* !i386 */

⌨️ 快捷键说明

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