u_int16_t
libnet_ip_check(u_int16_t *addr, int len)
{
    int sum;

    sum = libnet_in_cksum(addr, len);
    return (LIBNET_CKSUM_CARRY(sum));
}
예제 #2
0
파일: sender6.c 프로젝트: LucasLage/netlib
/*****************************************************************************
 * static implementations
 ****************************************************************************/
static uint16_t sender6_compute_icmp_payload(uint16_t icmpsum, /*{{{*/
		uint16_t icmpid, uint16_t icmpseq)
{
	int payload;

	struct libnet_icmpv6_hdr hdrv6;
	hdrv6.icmp_type = ICMP6_ECHO;
	hdrv6.icmp_code = 0;
	hdrv6.icmp_sum = htons(icmpsum);
	hdrv6.id = htons(icmpid);
	hdrv6.seq = htons(icmpseq);
	payload = libnet_in_cksum((uint16_t *)&hdrv6, LIBNET_ICMPV6_ECHO_H);

	return (uint16_t)LIBNET_CKSUM_CARRY(payload);
} /*}}}*/
예제 #3
0
파일: net.c 프로젝트: jwilkins/libnet
/*-
- chksum = net.chksum(string, ...)

Checksum the series of strings passed in.
*/
static int lnet_chksum(lua_State *L)
{
    int interm = 0;
    u_int16_t chks = 0;

    int i;
    int top = lua_gettop(L);
    for (i = 1; i <= top; i++) {
        size_t length = 0;
        const char* src = luaL_checklstring(L, i, &length);
        interm += libnet_in_cksum((u_int16_t*)src, length);
    }

    chks = LIBNET_CKSUM_CARRY(interm);

    lua_pushlstring(L, (char *)&chks, 2);
    return 1;
}
예제 #4
0
int update_USUM(libnet_t *l, libnet_ptag_t t)
{
     int sum = 0;
     unsigned int tmp;

     if (tx.udp_sum != 0)
	return 0;

     sum += libnet_in_cksum((u_int16_t *) &tx.ip6_src, 16);
     if (tx.ip_option_s && tx.ip6_segs)
       sum += libnet_in_cksum((u_int16_t *) &tx.ip_option[tx.ip_option_s - 16], 16); // Use last IP address
     else
       sum += libnet_in_cksum((u_int16_t *) &tx.ip6_dst, 16);

     tmp = htonl(tx.udp_len);
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);
     tmp = htonl(IPPROTO_UDP);
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);

     tmp = ((htons(tx.sp) << 16) + htons(tx.dp));
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);

     tmp = htons(tx.udp_len) << 16;
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);

     if (tx.udp_payload_s)
       sum += libnet_in_cksum((u_int16_t *) tx.udp_payload, tx.udp_payload_s);

     tx.udp_sum = ntohs(LIBNET_CKSUM_CARRY(sum));

     t = libnet_build_udp(tx.sp,
			  tx.dp,
			  tx.udp_len,
			  tx.udp_sum,
			  tx.udp_payload_s ? tx.udp_payload : NULL,
			  tx.udp_payload_s,
			  l,
			  t);
     return t;
}
예제 #5
0
int update_ISUM(libnet_t *l, libnet_ptag_t t)
{
     int sum = 0;
     unsigned int tmp;

     if (tx.icmp_chksum != 0)
	return 0;

     sum += libnet_in_cksum((u_int16_t *) &tx.ip6_src, 16);
     if (tx.ip_option_s && tx.ip6_segs)
       sum += libnet_in_cksum((u_int16_t *) &tx.ip_option[tx.ip_option_s - 16], 16); // Use last IP address
     else
       sum += libnet_in_cksum((u_int16_t *) &tx.ip6_dst, 16);

     tmp = htonl(LIBNET_ICMPV6_H + tx.icmp_payload_s);
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);
     tmp = htonl(IPPROTO_ICMP6);
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);

     tmp = htonl(((tx.icmp_type << 8) + tx.icmp_code));
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);

     if (tx.icmp_payload_s)
       sum += libnet_in_cksum((u_int16_t *) tx.icmp_payload, tx.icmp_payload_s);

     tx.icmp_chksum = ntohs(LIBNET_CKSUM_CARRY(sum));

     t = libnet_build_icmpv4_echo (tx.icmp_type,
				   tx.icmp_code,
				   tx.icmp_chksum,
				   tx.icmp_ident,
				   tx.icmp_sqnr,
				   tx.icmp_payload_s ? tx.icmp_payload : NULL,
				   tx.icmp_payload_s,
				   l,
				   t);

   return t;
}
int
libnet_do_checksum(libnet_t *l, u_int8_t *buf, int protocol, int len)
{
    /* will need to update this for ipv6 at some point */
    struct libnet_ipv4_hdr *iph_p;
    struct libnet_ipv6_hdr *ip6h_p;
    int is_ipv6;
    int ip_hl;
    int sum;

    is_ipv6 = 0;    /* default to not using IPv6 */
    sum     = 0;
    iph_p   = NULL;
    ip6h_p  = NULL;

    if (len == 0)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
            "%s(): header length can't be zero\n", __func__);
        return (-1);
    }

    /*
     *  Figure out which IP version we're dealing with.  We'll assume v4
     *  and overlay a header structure to yank out the version.
     */
    iph_p = (struct libnet_ipv4_hdr *)buf;

    if (iph_p && iph_p->ip_v == 6) {
	ip6h_p = (struct libnet_ipv6_hdr *)buf;
	is_ipv6 = 1;
	ip_hl   = 40;
    } else {
        is_ipv6 = 0;
	ip_hl = iph_p->ip_hl << 2; 
    }

    /*
     *  Dug Song came up with this very cool checksuming implementation
     *  eliminating the need for explicit psuedoheader use.  Check it out.
     */
    switch (protocol)
    {
        case IPPROTO_SCTP:
        {
            struct libnet_sctp_hdr *sctph_p =
                (struct libnet_sctp_hdr *)(buf + ip_hl);
            sctph_p->checksum = 0;
            sum = libnet_sctp_cksum((u_int8_t *)sctph_p, len);
            sctph_p->checksum = sum;
            break;
        }
	    
        /*
         *  Style note: normally I don't advocate declaring variables inside
         *  blocks of control, but it makes good sense here. -- MDS
         */
        case IPPROTO_TCP:
        {
            struct libnet_tcp_hdr *tcph_p =
                (struct libnet_tcp_hdr *)(buf + ip_hl);
#if 0 
#if (STUPID_SOLARIS_CHECKSUM_BUG)
            tcph_p->th_sum = tcph_p->th_off << 2;
            return (1);
#endif /* STUPID_SOLARIS_CHECKSUM_BUG */
#endif
#if (HAVE_HPUX11)   
            if (l->injection_type != LIBNET_LINK)
            {
                /*
                 *  Similiar to the Solaris Checksum bug - but need to add
                 *  the size of the TCP payload (only for raw sockets).
                 */
                tcph_p->th_sum = (tcph_p->th_off << 2) +
                        (len - (tcph_p->th_off << 2));
                return (1); 
            }
#endif
            tcph_p->th_sum = 0;
            if (is_ipv6)
            {
                sum = libnet_in_cksum((u_int16_t *)&ip6h_p->ip_src, 32);
            }
            else
            {
                sum = libnet_in_cksum((u_int16_t *)&iph_p->ip_src, 8);
            }
            sum += ntohs(IPPROTO_TCP + len);
            sum += libnet_in_cksum((u_int16_t *)tcph_p, len);
            tcph_p->th_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_UDP:
        {
            struct libnet_udp_hdr *udph_p =
                (struct libnet_udp_hdr *)(buf + ip_hl);
            udph_p->uh_sum = 0;
            if (is_ipv6)
            {
                sum = libnet_in_cksum((u_int16_t *)&ip6h_p->ip_src, 32);
            }
            else
            {
                sum = libnet_in_cksum((u_int16_t *)&iph_p->ip_src, 8);
            }
            sum += ntohs(IPPROTO_UDP + len);
            sum += libnet_in_cksum((u_int16_t *)udph_p, len);
            udph_p->uh_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_ICMP:
        {
            struct libnet_icmpv4_hdr *icmph_p =
                (struct libnet_icmpv4_hdr *)(buf + ip_hl);

            icmph_p->icmp_sum = 0;
            if (is_ipv6)
            {
                sum = libnet_in_cksum((u_int16_t *)&ip6h_p->ip_src, 32);
                sum += ntohs(IPPROTO_ICMP6 + len);
            }
            sum += libnet_in_cksum((u_int16_t *)icmph_p, len);
            icmph_p->icmp_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_IGMP:
        {
            struct libnet_igmp_hdr *igmph_p =
                (struct libnet_igmp_hdr *)(buf + ip_hl);

            igmph_p->igmp_sum = 0;
            sum = libnet_in_cksum((u_int16_t *)igmph_p, len);
            igmph_p->igmp_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_RSVP:
        {
            struct libnet_rsvp_hdr *rsvph_p =
                (struct libnet_rsvp_hdr *)(buf + ip_hl);

            rsvph_p->checksum = 0;
            sum = libnet_in_cksum((u_int16_t *)rsvph_p, len);
            rsvph_p->checksum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_PIM:
        {
            struct libnet_pim_hdr *pim_p =
                (struct libnet_pim_hdr *)(buf + ip_hl);

            pim_p->pim_sum = 0;
	    if ((pim_p->pim_ver_type & 0x0f) == PIM_REGISTER) {
		    sum = libnet_in_cksum((u_int16_t *)pim_p, LIBNET_PIM_H);
	    } else {
		   sum = libnet_in_cksum((u_int16_t *)pim_p, len);
	    }
            pim_p->pim_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
	case IPPROTO_GRE:
	{
            /* checksum is always at the same place in GRE header
             * in the multiple RFC version of the protocol ... ouf !!!
             */
	    struct libnet_gre_hdr *greh_p = 
		(struct libnet_gre_hdr *)(buf + ip_hl);
	    u_int16_t fv = ntohs(greh_p->flags_ver);
	    if (!(fv & (GRE_CSUM|GRE_ROUTING | GRE_VERSION_0)) ||
                !(fv & (GRE_CSUM|GRE_VERSION_1)))
	    {
		snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): can't compute GRE checksum (wrong flags_ver bits: 0x%x )\n",  __func__, fv);
		return (-1);
	    }
	    sum = libnet_in_cksum((u_int16_t *)greh_p, len);
	    greh_p->gre_sum = LIBNET_CKSUM_CARRY(sum);
	    break;
	}
        case IPPROTO_OSPF:
        {
            struct libnet_ospf_hdr *oh_p =
                (struct libnet_ospf_hdr *)(buf + ip_hl);

            oh_p->ospf_sum = 0;
            sum += libnet_in_cksum((u_int16_t *)oh_p, len);
            oh_p->ospf_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_OSPF_LSA:
        {
            struct libnet_ospf_hdr *oh_p =
                (struct libnet_ospf_hdr *)(buf + ip_hl);
            struct libnet_lsa_hdr *lsa_p =
                (struct libnet_lsa_hdr *)(buf + 
                ip_hl + oh_p->ospf_len);

            lsa_p->lsa_sum = 0;
            sum += libnet_in_cksum((u_int16_t *)lsa_p, len);
            lsa_p->lsa_sum = LIBNET_CKSUM_CARRY(sum);
            break;
#if 0
            /*
             *  Reworked fletcher checksum taken from RFC 1008.
             */
            int c0, c1;
            struct libnet_lsa_hdr *lsa_p = (struct libnet_lsa_hdr *)buf;
            u_int8_t *p, *p1, *p2, *p3;

            c0 = 0;
            c1 = 0;

            lsa_p->lsa_cksum = 0;

            p = buf;
            p1 = buf;
            p3 = buf + len;             /* beginning and end of buf */

            while (p1 < p3)
            {
                p2 = p1 + LIBNET_MODX;
                if (p2 > p3)
                {
                    p2 = p3;
                }
  
                for (p = p1; p < p2; p++)
                {
                    c0 += (*p);
                    c1 += c0;
                }

                c0 %= 255;
                c1 %= 255;      /* modular 255 */
 
                p1 = p2;
            }

#if AWR_PLEASE_REWORK_THIS
            lsa_p->lsa_cksum[0] = (((len - 17) * c0 - c1) % 255);
            if (lsa_p->lsa_cksum[0] <= 0)
            {
                lsa_p->lsa_cksum[0] += 255;
            }

            lsa_p->lsa_cksum[1] = (510 - c0 - lsa_p->lsa_cksum[0]);
            if (lsa_p->lsa_cksum[1] > 255)
            {
                lsa_p->lsa_cksum[1] -= 255;
            }
#endif
            break;
#endif
        }
        case IPPROTO_IP:
        {
            iph_p->ip_sum = 0;
            sum = libnet_in_cksum((u_int16_t *)iph_p, ip_hl);
            iph_p->ip_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_VRRP:
        {
            struct libnet_vrrp_hdr *vrrph_p =
                (struct libnet_vrrp_hdr *)(buf + ip_hl);

            vrrph_p->vrrp_sum = 0;
            sum = libnet_in_cksum((u_int16_t *)vrrph_p, len);
            vrrph_p->vrrp_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case LIBNET_PROTO_CDP:
        {   /* XXX - Broken: how can we easily get the entire packet size? */
            struct libnet_cdp_hdr *cdph_p =
                (struct libnet_cdp_hdr *)buf;

            cdph_p->cdp_sum = 0;
            sum = libnet_in_cksum((u_int16_t *)cdph_p, len);
            cdph_p->cdp_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case LIBNET_PROTO_ISL:
        {
           // struct libnet_isl_hdr *islh_p =
           //     (struct libnet_isl_hdr *)buf;
            /*
             *  Need to compute 4 byte CRC for the ethernet frame and for
             *  the ISL frame itself.  Use the libnet_crc function.
             */
        }
        default:
        {
            snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): unsuported protocol %d\n", __func__, protocol);
            return (-1);
        }
    }
    return (1);
}
예제 #7
0
int update_TSUM(libnet_t *l, libnet_ptag_t t)
{
     int sum = 0;
     unsigned int tmp;

     if (tx.tcp_sum != 0)
	return 0;

     sum += libnet_in_cksum((u_int16_t *) &tx.ip6_src, 16);
     if (tx.ip_option_s && tx.ip6_segs)
       sum += libnet_in_cksum((u_int16_t *) &tx.ip_option[tx.ip_option_s - 16], 16); // Use last IP address
     else
       sum += libnet_in_cksum((u_int16_t *) &tx.ip6_dst, 16);

     tmp = htonl(tx.tcp_len);
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);
     tmp = htonl(IPPROTO_TCP);
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);

     tmp = ((htons(tx.sp) << 16) + htons(tx.dp));
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);

     tmp = htonl(tx.tcp_seq);
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);
     tmp = htonl(tx.tcp_ack);
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);

     tmp = ((ntohs(((tx.tcp_offset) << 12) + tx.tcp_control) << 16) + htons(tx.tcp_win));
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);

     tmp = htonl(tx.tcp_urg);
     sum += libnet_in_cksum((u_int16_t *) &tmp, 4);

     sum += tx.tcp_sum_part;

     if (tx.tcp_payload_s)
       sum += libnet_in_cksum((u_int16_t *) tx.tcp_payload, tx.tcp_payload_s);

     tx.tcp_sum = ntohs(LIBNET_CKSUM_CARRY(sum));

     t = libnet_build_tcp (tx.sp,
	                   tx.dp,
	                   tx.tcp_seq,
	                   tx.tcp_ack,
	                   tx.tcp_control,
	                   tx.tcp_win,
	                   tx.tcp_sum,
	                   tx.tcp_urg,
	                   tx.tcp_len,
	                   tx.tcp_payload_s ? tx.tcp_payload : NULL,
	                   tx.tcp_payload_s,
	                   l,
	                   t);

   return t;
}
예제 #8
0
int
libnet_do_checksum(u_char *buf, int protocol, int len)
{
    struct libnet_ip_hdr *iph_p;
    int ip_hl;
    int sum;

    sum = 0;
    iph_p = (struct libnet_ip_hdr *)buf;
    ip_hl = iph_p->ip_hl << 2;

    /*
     *  Dug Song came up with this very cool checksuming implementation
     *  eliminating the need for explicit psuedoheader use.  Check it out.
     */
    switch (protocol)
    {
        /*
         *  Style note: normally I don't advocate declaring variables inside
         *  blocks of control, but it makes good sense here. -- MDS
         */
        case IPPROTO_TCP:
        {
            struct libnet_tcp_hdr *tcph_p =
                (struct libnet_tcp_hdr *)(buf + ip_hl);

#if (STUPID_SOLARIS_CHECKSUM_BUG)
            tcph_p->th_sum = tcph_p->th_off << 2;
            return (1);
#endif /* STUPID_SOLARIS_CHECKSUM_BUG */

            tcph_p->th_sum = 0;
            sum = libnet_in_cksum((u_short *)&iph_p->ip_src, 8);
            sum += ntohs(IPPROTO_TCP + len);
            sum += libnet_in_cksum((u_short *)tcph_p, len);
            tcph_p->th_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_UDP:
        {
            struct libnet_udp_hdr *udph_p =
                (struct libnet_udp_hdr *)(buf + ip_hl);

            udph_p->uh_sum = 0;
            sum = libnet_in_cksum((u_short *)&iph_p->ip_src, 8);
            sum += ntohs(IPPROTO_UDP + len);
            sum += libnet_in_cksum((u_short *)udph_p, len);
            udph_p->uh_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_ICMP:
        {
            struct libnet_icmp_hdr *icmph_p =
                (struct libnet_icmp_hdr *)(buf + ip_hl);

            icmph_p->icmp_sum = 0;
            sum = libnet_in_cksum((u_short *)icmph_p, len);
            icmph_p->icmp_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_IGMP:
        {
            struct libnet_igmp_hdr *igmph_p =
                (struct libnet_igmp_hdr *)(buf + ip_hl);

            igmph_p->igmp_sum = 0;
            sum += libnet_in_cksum((u_short *)igmph_p, len);
            igmph_p->igmp_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_OSPF:
        {
            struct libnet_ospf_hdr *oh_p =
                (struct libnet_ospf_hdr *)(buf + ip_hl);

            u_char *payload = (u_char *)(buf + ip_hl + LIBNET_AUTH_H + 
                        sizeof(oh_p));
            u_char *tbuf = (u_char *)malloc(sizeof(oh_p) + sizeof(payload));
            oh_p->ospf_cksum = 0;
            sum += libnet_in_cksum((u_short *)tbuf, sizeof(tbuf));
            oh_p->ospf_cksum = LIBNET_CKSUM_CARRY(sum);
            free(tbuf);
            break;
        }
        case IPPROTO_OSPF_LSA:
        {
            /*
             *  Reworked fletcher checksum taken from RFC 1008.
             */
            int c0, c1;
            struct libnet_lsa_hdr *lsa_p = (struct libnet_lsa_hdr *)buf;
            u_char *p, *p1, *p2, *p3;

            c0 = 0;
            c1 = 0;

            lsa_p->lsa_cksum[0] = 0;
            lsa_p->lsa_cksum[1] = 0;    /* zero out checksum */

            p = buf;
            p1 = buf;
            p3 = buf + len;             /* beginning and end of buf */

            while (p1 < p3)
            {
                p2 = p1 + LIBNET_MODX;
                if (p2 > p3)
                {
                    p2 = p3;
                }
  
                for (p = p1; p < p2; p++)
                {
                    c0 += (*p);
                    c1 += c0;
                }

                c0 %= 255;
                c1 %= 255;      /* modular 255 */
 
                p1 = p2;
            }

            lsa_p->lsa_cksum[0] = (((len - 17) * c0 - c1) % 255);
            if (lsa_p->lsa_cksum[0] <= 0)
            {
                lsa_p->lsa_cksum[0] += 255;
            }

            lsa_p->lsa_cksum[1] = (510 - c0 - lsa_p->lsa_cksum[0]);
            if (lsa_p->lsa_cksum[1] > 255)
            {
                lsa_p->lsa_cksum[1] -= 255;
            }
            break;
        }
        case IPPROTO_IP:
        {
            iph_p->ip_sum = 0;
            sum = libnet_in_cksum((u_short *)iph_p, len);
            iph_p->ip_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        default:
        {
#if (__DEBUG)
            libnet_error(LN_ERR_CRITICAL, "do_checksum: UNSUPP protocol %d\n",
                    protocol);
#endif
            return (-1);
        }
    }
    return (1);
}
예제 #9
0
/*
 * We are checksumming pblock "q"
 *
 * iphdr is the pointer to it's encapsulating IP header
 * protocol describes the type of "q", expressed as an IPPROTO_ value
 * h_len is the h_len from "q"
 */
int
libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int protocol, int h_len, const uint8_t *beg, const uint8_t * end)
{
    /* will need to update this for ipv6 at some point */
    struct libnet_ipv4_hdr *iph_p = (struct libnet_ipv4_hdr *)iphdr;
    struct libnet_ipv6_hdr *ip6h_p = NULL; /* default to not using IPv6 */
    int ip_hl   = 0;
    int sum     = 0;

    /* Check for memory under/over reads/writes. */
    if(iphdr < beg || (iphdr+sizeof(*iph_p)) > end)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
            "%s(): ipv4 hdr not inside packet (where %d, size %d)\n", __func__,
	    (int)(iphdr-beg), (int)(end-beg));
        return -1;
    }

    /*
     *  Figure out which IP version we're dealing with.  We'll assume v4
     *  and overlay a header structure to yank out the version.
     */
    if (iph_p->ip_v == 6)
    {
        ip6h_p = (struct libnet_ipv6_hdr *)iph_p;
        iph_p = NULL;
        ip_hl   = 40;
        if((uint8_t*)(ip6h_p+1) > end)
        {
            snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    "%s(): ipv6 hdr not inside packet\n", __func__);
            return -1;
        }
    }
    else
    {
        ip_hl = iph_p->ip_hl << 2;
    }

    if((iphdr+ip_hl) > end)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
            "%s(): ip hdr len not inside packet\n", __func__);
        return -1;
    }

    /*
     *  Dug Song came up with this very cool checksuming implementation
     *  eliminating the need for explicit psuedoheader use.  Check it out.
     */
    switch (protocol)
    {
        case IPPROTO_TCP:
        {
            struct libnet_tcp_hdr *tcph_p =
                (struct libnet_tcp_hdr *)(iphdr + ip_hl);

	    h_len = end - (uint8_t*) tcph_p; /* ignore h_len, sum the packet we've coalesced */

            CHECK_IP_PAYLOAD_SIZE();

#if (STUPID_SOLARIS_CHECKSUM_BUG)
            tcph_p->th_sum = tcph_p->th_off << 2;
            return (1);
#endif /* STUPID_SOLARIS_CHECKSUM_BUG */
#if (HAVE_HPUX11)   
            if (l->injection_type != LIBNET_LINK)
            {
                /*
                 *  Similiar to the Solaris Checksum bug - but need to add
                 *  the size of the TCP payload (only for raw sockets).
                 */
                tcph_p->th_sum = (tcph_p->th_off << 2) +
                        (h_len - (tcph_p->th_off << 2));
                return (1); 
            }
#endif
            /* TCP checksum is over the IP pseudo header:
             * ip src
             * ip dst
             * tcp protocol (IPPROTO_TCP)
             * tcp length, including the header
             * + the TCP header (with checksum set to zero) and data
             */
            tcph_p->th_sum = 0;
            if (ip6h_p)
            {
                sum = libnet_in_cksum((uint16_t *)&ip6h_p->ip_src, 32);
            }
            else
            {
                /* 8 = src and dst */
                sum = libnet_in_cksum((uint16_t *)&iph_p->ip_src, 8);
            }
            sum += ntohs(IPPROTO_TCP + h_len);
            sum += libnet_in_cksum((uint16_t *)tcph_p, h_len);
            tcph_p->th_sum = LIBNET_CKSUM_CARRY(sum);
#if 0
            printf("tcp sum calculated: %#x/%d h_len %d\n",
                    ntohs(tcph_p->th_sum),
                    ntohs(tcph_p->th_sum),
                    h_len
                  );
#endif
            break;
        }
        case IPPROTO_UDP:
        {
            struct libnet_udp_hdr *udph_p =
                (struct libnet_udp_hdr *)(iphdr + ip_hl);

	    h_len = end - (uint8_t*) udph_p; /* ignore h_len, sum the packet we've coalesced */

            CHECK_IP_PAYLOAD_SIZE();

            udph_p->uh_sum = 0;
            if (ip6h_p)
            {
                sum = libnet_in_cksum((uint16_t *)&ip6h_p->ip_src, 32);
            }
            else
            {
                sum = libnet_in_cksum((uint16_t *)&iph_p->ip_src, 8);
            }
            sum += ntohs(IPPROTO_UDP + h_len);
            sum += libnet_in_cksum((uint16_t *)udph_p, h_len);
            udph_p->uh_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_ICMP:
        {
            struct libnet_icmpv4_hdr *icmph_p =
                (struct libnet_icmpv4_hdr *)(iphdr + ip_hl);

            h_len = end - (uint8_t*) icmph_p; /* ignore h_len, sum the packet we've coalesced */

            CHECK_IP_PAYLOAD_SIZE();

            icmph_p->icmp_sum = 0;
            /* Hm, is this valid? Is the checksum algorithm for ICMPv6 encapsulated in IPv4
             * actually defined?
             */
            if (ip6h_p)
            {
                sum = libnet_in_cksum((uint16_t *)&ip6h_p->ip_src, 32);
                sum += ntohs(IPPROTO_ICMP6 + h_len);
            }
            sum += libnet_in_cksum((uint16_t *)icmph_p, h_len);
            icmph_p->icmp_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_ICMPV6:
        {
            struct libnet_icmpv6_hdr *icmph_p =
                (struct libnet_icmpv6_hdr *)(iphdr + ip_hl);

            h_len = end - (uint8_t*) icmph_p; /* ignore h_len, sum the packet we've coalesced */

            CHECK_IP_PAYLOAD_SIZE();

            icmph_p->icmp_sum = 0;
            if (ip6h_p)
            {
                sum = libnet_in_cksum((uint16_t *)&ip6h_p->ip_src, 32);
                sum += ntohs(IPPROTO_ICMP6 + h_len);
            }
            sum += libnet_in_cksum((uint16_t *)icmph_p, h_len);
            icmph_p->icmp_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_IGMP:
        {
            struct libnet_igmp_hdr *igmph_p =
                (struct libnet_igmp_hdr *)(iphdr + ip_hl);

	    h_len = end - (uint8_t*) igmph_p; /* ignore h_len, sum the packet we've coalesced */

            CHECK_IP_PAYLOAD_SIZE();

            igmph_p->igmp_sum = 0;
            sum = libnet_in_cksum((uint16_t *)igmph_p, h_len);
            igmph_p->igmp_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
	case IPPROTO_GRE:
	{
            /* checksum is always at the same place in GRE header
             * in the multiple RFC version of the protocol ... ouf !!!
             */
	    struct libnet_gre_hdr *greh_p = 
		(struct libnet_gre_hdr *)(iphdr + ip_hl);
	    uint16_t fv = ntohs(greh_p->flags_ver);

            CHECK_IP_PAYLOAD_SIZE();

	    if (!(fv & (GRE_CSUM|GRE_ROUTING | GRE_VERSION_0)) ||
                !(fv & (GRE_CSUM|GRE_VERSION_1)))
	    {
		snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): can't compute GRE checksum (wrong flags_ver bits: 0x%x )\n",  __func__, fv);
		return (-1);
	    }
	    sum = libnet_in_cksum((uint16_t *)greh_p, h_len);
	    greh_p->gre_sum = LIBNET_CKSUM_CARRY(sum);
	    break;
	}
        case IPPROTO_OSPF:
        {
            struct libnet_ospf_hdr *oh_p =
                (struct libnet_ospf_hdr *)(iphdr + ip_hl);

            CHECK_IP_PAYLOAD_SIZE();

            oh_p->ospf_sum = 0;
            sum += libnet_in_cksum((uint16_t *)oh_p, h_len);
            oh_p->ospf_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case IPPROTO_OSPF_LSA:
        {
            struct libnet_ospf_hdr *oh_p =
                (struct libnet_ospf_hdr *)(iphdr + ip_hl);
            struct libnet_lsa_hdr *lsa_p =
                (struct libnet_lsa_hdr *)(iphdr + 
                ip_hl + oh_p->ospf_len);

            /* FIXME need additional length check, to account for ospf_len */
            lsa_p->lsa_sum = 0;
            sum += libnet_in_cksum((uint16_t *)lsa_p, h_len);
            lsa_p->lsa_sum = LIBNET_CKSUM_CARRY(sum);
            break;
#if 0
            /*
             *  Reworked fletcher checksum taken from RFC 1008.
             */
            int c0, c1;
            struct libnet_lsa_hdr *lsa_p = (struct libnet_lsa_hdr *)buf;
            uint8_t *p, *p1, *p2, *p3;

            c0 = 0;
            c1 = 0;

            lsa_p->lsa_cksum = 0;

            p = buf;
            p1 = buf;
            p3 = buf + len;             /* beginning and end of buf */

            while (p1 < p3)
            {
                p2 = p1 + LIBNET_MODX;
                if (p2 > p3)
                {
                    p2 = p3;
                }
  
                for (p = p1; p < p2; p++)
                {
                    c0 += (*p);
                    c1 += c0;
                }

                c0 %= 255;
                c1 %= 255;      /* modular 255 */
 
                p1 = p2;
            }

#if AWR_PLEASE_REWORK_THIS
            lsa_p->lsa_cksum[0] = (((len - 17) * c0 - c1) % 255);
            if (lsa_p->lsa_cksum[0] <= 0)
            {
                lsa_p->lsa_cksum[0] += 255;
            }

            lsa_p->lsa_cksum[1] = (510 - c0 - lsa_p->lsa_cksum[0]);
            if (lsa_p->lsa_cksum[1] > 255)
            {
                lsa_p->lsa_cksum[1] -= 255;
            }
#endif
            break;
#endif
        }
        case IPPROTO_IP:
        {
            if(!iph_p) {
                /* IPv6 doesn't have a checksum */
            } else {
                iph_p->ip_sum = 0;
                sum = libnet_in_cksum((uint16_t *)iph_p, ip_hl);
                iph_p->ip_sum = LIBNET_CKSUM_CARRY(sum);
            }
            break;
        }
        case IPPROTO_VRRP:
        {
            struct libnet_vrrp_hdr *vrrph_p =
                (struct libnet_vrrp_hdr *)(iphdr + ip_hl);
            CHECK_IP_PAYLOAD_SIZE();

            vrrph_p->vrrp_sum = 0;
            sum = libnet_in_cksum((uint16_t *)vrrph_p, h_len);
            vrrph_p->vrrp_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case LIBNET_PROTO_CDP:
        {   /* XXX - Broken: how can we easily get the entire packet size? */
	    /* FIXME you can't, checksumming non-IP protocols was not supported by libnet */
            struct libnet_cdp_hdr *cdph_p =
                (struct libnet_cdp_hdr *)iphdr;

            if((iphdr+h_len) > end)
            {
                snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                        "%s(): cdp payload not inside packet\n", __func__);
                return -1;
            }

            cdph_p->cdp_sum = 0;
            sum = libnet_in_cksum((uint16_t *)cdph_p, h_len);
            cdph_p->cdp_sum = LIBNET_CKSUM_CARRY(sum);
            break;
        }
        case LIBNET_PROTO_ISL:
        {
#if 0
            struct libnet_isl_hdr *islh_p =
                (struct libnet_isl_hdr *)buf;
#endif
            /*
             *  Need to compute 4 byte CRC for the ethernet frame and for
             *  the ISL frame itself.  Use the libnet_crc function.
             */
        }
        default:
        {
            snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): unsupported protocol %d\n", __func__, protocol);
            return (-1);
        }
    }
    return (1);
}
예제 #10
0
파일: 1000.cpp 프로젝트: B-Rich/fullypwnd
int main(int argc, char* argv[])
{
if ( argc<4 )
{
usage(argv[0]);
return EXIT_FAILURE;
}

int retVal;
struct addrinfo hints,*addrinfo;

ZeroMemory(&hints,sizeof(hints));

WSADATA wsaData;
if ( WSAStartup( MAKEWORD(2,2), &wsaData ) != NO_ERROR )
{
fprintf( stderr, "Error in WSAStartup():%d\n",WSAGetLastError());
return EXIT_FAILURE;
}
//
// Get MAC address of remote host (assume link local IpV6 address)
//

hints.ai_family = PF_INET6;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

retVal = getaddrinfo(argv[2],0, &hints, &addrinfo);
if ( retVal!=0 )
{
WSACleanup();
fprintf( stderr, "Error in getaddrinfo():%d\n",WSAGetLastError());
exit(EXIT_FAILURE);
}

//
// Open WinPCap adapter
//
if ( (pcap_handle = pcap_open_live (argv[1], 1514, PCAP_OPENFLAG_PROMISCUOUS, 
100, (char*)errbuf)) == NULL )
{
freeaddrinfo(addrinfo);
WSACleanup();
fprintf(stderr, "Error opening device: %s\n",argv[1]);
return EXIT_FAILURE;
}

ZeroMemory(packet,sizeof(packet));
struct sockaddr_in6 *sa = (struct sockaddr_in6 *) addrinfo->ai_addr;

// fill ethernet header
eth_hdr->ether_dhost[0] = eth_hdr->ether_shost[0] = 0;// assume address like 
00:something;
eth_hdr->ether_dhost[1] = eth_hdr->ether_shost[1] = sa->sin6_addr.u.Byte[9];
eth_hdr->ether_dhost[2] = eth_hdr->ether_shost[2] = sa->sin6_addr.u.Byte[10];
eth_hdr->ether_dhost[3] = eth_hdr->ether_shost[3] = sa->sin6_addr.u.Byte[13];
eth_hdr->ether_dhost[4] = eth_hdr->ether_shost[4] = sa->sin6_addr.u.Byte[14];
eth_hdr->ether_dhost[5] = eth_hdr->ether_shost[5] = sa->sin6_addr.u.Byte[15];
eth_hdr->ether_type = 0xdd86;


// fill IP header
// source ip == destination ip

memcpy(ip6_hdr->ip_src.__u6_addr.__u6_addr8,sa->sin6_addr.u.Byte,sizeof(sa->sin6_addr.u.Byte));

memcpy(ip6_hdr->ip_dst.__u6_addr.__u6_addr8,sa->sin6_addr.u.Byte,sizeof(sa->sin6_addr.u.Byte));
ip6_hdr->ip_hl = 255;
ip6_hdr->ip_nh = IPPROTO_TCP;
ip6_hdr->ip_len = htons (20);
ip6_hdr->ip_flags[0] = 0x06 << 4;
srand((unsigned int) time(0));
// fill tcp header
tcp_hdr->th_sport = tcp_hdr->th_dport = htons (atoi(argv[3])); // source 
port equal to destination
tcp_hdr->th_seq = rand();
tcp_hdr->th_ack = rand();
tcp_hdr->th_off = htons(5);
tcp_hdr->th_win = rand();
tcp_hdr->th_sum = 0;
tcp_hdr->th_urp = htons(10);
tcp_hdr->th_off = 5;
tcp_hdr->th_flags = 2;
// calculate tcp checksum
int chsum = libnet_in_cksum ((u_int16_t *) & ip6_hdr->ip_src, 32);
chsum += ntohs (IPPROTO_TCP + sizeof (struct libnet_tcp_hdr));
chsum += libnet_in_cksum ((u_int16_t *) tcp_hdr, sizeof (struct 
libnet_tcp_hdr));
tcp_hdr->th_sum = LIBNET_CKSUM_CARRY (chsum);
// send data to wire
retVal = pcap_sendpacket (pcap_handle, (u_char *) packet, sizeof(packet));
if ( retVal == -1 )
{
fprintf(stderr,"Error writing packet to wire!!\n");
}
//
// close adapter, free mem.. etc..
//
pcap_close(pcap_handle);
freeaddrinfo(addrinfo);
WSACleanup();
return EXIT_SUCCESS;
}
예제 #11
0
/*
  ipsec_output()

            from driver-core
*/
int
ipsec_output( void* Adapter, struct pkt_buff *pktb )
{
  PIPSEC pIpsec=&((pADAPTER)Adapter)->Ipsec_SL.Ipsec;
  struct ipsec_output_state state;
  struct ip *ip;
  int ret;
  u_char *buf;
  int out_len;

  /*printk(KERN_ERR "-----------------ipsec_output-------------------\n");*/
  DBG_ENTER(ipsec_output);
/* PMC-Viana-011-カーネルログ出力有効/無効切り替え対応 add start */ 
#ifdef BUILD_ANDROID
    TNC_LOGOUT("Call ipsec_output \n");
#endif /* BUILD_ANDROID */
/* PMC-Viana-011-カーネルログ出力有効/無効切り替え対応 add end */ 

  if( !pIpsec->init ) {
/* PMC-Viana-011-カーネルログ出力有効/無効切り替え対応 add start */ 
#ifdef BUILD_ANDROID
    TNC_LOGOUT(KERN_ERR "ipsec_core Don't initialize\n");
#else /* BUILD_ANDROID */
    printk(KERN_ERR "ipsec_core Don't initialize\n");
#endif /* BUILD_ANDROID */
/* PMC-Viana-011-カーネルログ出力有効/無効切り替え対応 add end */ 
    return(0);
  }

  ip = (struct ip *)pktb->data;


/* PMC-Viana-011-カーネルログ出力有効/無効切り替え対応 add start */ 
#ifdef BUILD_ANDROID
  TNC_LOGOUT(KERN_ERR "Call ipsec_output \n");
  TNC_LOGOUT(KERN_ERR "host: 0x%x\n",(u_int)ip->ip_dst.s_addr);
  TNC_LOGOUT(KERN_ERR "pIpsec->dst_ip: 0x%x\n",(u_int)pIpsec->dst_ip);
#endif /* BUILD_ANDROID */
/* PMC-Viana-011-カーネルログ出力有効/無効切り替え対応 add end */ 
  if( pIpsec->dst_ip != (ip->ip_dst.s_addr & pIpsec->dst_mask) ) {
/* PMC-Viana-011-カーネルログ出力有効/無効切り替え対応 add start */ 
#ifdef BUILD_ANDROID
    TNC_LOGOUT(KERN_ERR "Unknown host: IPSEC_DST=0x%x IP_DST=0x%x IPSEC_MASK=0x%x\n", (u_int)pIpsec->dst_ip, (u_int)ip->ip_dst.s_addr, (u_int)pIpsec->dst_mask);
#else /* BUILD_ANDROID */
    printk(KERN_ERR "Unknown host: IPSEC_DST=0x%x IP_DST=0x%x IPSEC_MASK=0x%x\n", (u_int)pIpsec->dst_ip, (u_int)ip->ip_dst.s_addr, (u_int)pIpsec->dst_mask);
#endif /* BUILD_ANDROID */
/* PMC-Viana-011-カーネルログ出力有効/無効切り替え対応 add end */ 
/* そのまま送信するのか?
  それともエラーとして捨てるのか?*/
    return(-1);
  }

  state.m = out_state_set( pIpsec, pktb->data, pktb->len, &state );
  if(state.m == NULL) {
	  DBGPRINT(("Faile to get mbuf at out_state_set\n"));
	  return -1;
  }

  ret = ipsec4_output( pIpsec, &state );
  if( ret < 0  ) {
    return( ret );
  }
  if( ret == 1 ) {
    buf = restore_mbuf( state.m, &out_len );
#ifdef notdef /* AH Tunnel bug -> move */
    ip = (struct ip *)buf;
    if (pIpsec->def_isr.saidx.mode == IPSEC_MODE_TUNNEL) {
      ip->ip_dst.s_addr = pIpsec->tun_dst;
      ip->ip_src.s_addr = pIpsec->tun_src;
    }
    hlen = ip->ip_hl << 2;
    ip->ip_sum = 0;
    /* make ip checksum */
    sum = libnet_in_cksum((u_short *)ip, hlen);
    ip->ip_sum = (u_short)(LIBNET_CKSUM_CARRY(sum));
#endif
	if(((UINT)out_len > pktb->buff_len) || ((UINT)(buf + out_len) > (UINT)pktb->end)) {
		DbgPrint("out_len:%d,pktb->buff_len:%d, (buf + out_len):%x,pktb->end:%x\n",
				out_len, pktb->buff_len, (UINT)(buf + out_len), (u_int)pktb->end);
		return -1;
	}
	if(pktb->head > buf) {
		DBGPRINT("pktb->head:%x,buf:%x\n", (u_int)pktb->head, (u_int)buf);
		return -1;
	}

    pktb->len = out_len;
    pktb->data = buf;
    pktb->tail = pktb->data+pktb->len;
  }
  return( ret );
}