Beispiel #1
0
void gen_ip_frag_proc(int it, TPTD_Token * token)
{
	//fprintf(stderr, "gen_ip_frag_proc\n");
	struct proc_node *i;
	u_char *data = token->data;
	//fprintf(stderr, "f**k f**k  id %d\n", it);
    struct ip *iph = (struct ip *) data;
    int need_free = 0;
    int skblen;
    void (*glibc_syslog_h_workaround)(int, int, struct ip *, void*)=
       nids_params.syslog;

	ip_fast_csum((unsigned char *) iph, iph->ip_hl);

    if (token->caplen < (int)sizeof(struct ip) || iph->ip_hl < 5 || iph->ip_v != 4 ||
	(u_short)ip_fast_csum((unsigned char *) iph, iph->ip_hl) != 0 ||
	token->caplen < ntohs(iph->ip_len) || ntohs(iph->ip_len) < iph->ip_hl << 2) {
	glibc_syslog_h_workaround(NIDS_WARN_IP, NIDS_WARN_IP_HDR, iph, 0);
		token->token_state = TOKEN_STATE_END;
   // fprintf(stderr, "break on ipfragment 1\n");
		return;
    }
   if (iph->ip_hl > 5 && ip_options_compile((unsigned char *)data)) {
	glibc_syslog_h_workaround(NIDS_WARN_IP, NIDS_WARN_IP_SRR, iph, 0);
	token->token_state = TOKEN_STATE_END;
//fprintf(stderr, "break on ipfragment 2\n");
	return;
   }

    switch (ip_defrag_stub((struct ip *) data, &iph)) {
    	case IPF_ISF:
			//fprintf(stderr, "IPF_ISF\n");
			token->token_state = TOKEN_STATE_ALIVE;
            //fprintf(stderr, "break on ipfragment 2\n");
			return;
    	case IPF_NOTF:
			need_free = 0;
			iph = (struct ip *) data;
			break;
    	case IPF_NEW:
			need_free = 1;
			break;
    	default:;
    }
    skblen = ntohs(iph->ip_len) + 16;
    if (!need_free)
		skblen += nids_params.dev_addon;
    skblen = (skblen + 15) & ~15;
    skblen += nids_params.sk_buff_size;


    if (need_free)
		free(iph);
	token->token_state = TOKEN_STATE_GOON;
	return;
}
/* Generate a checksum for an outgoing IP datagram. */
__inline__ void ip_send_check(struct iphdr *iph)
{
	iph->check = 0;
#ifndef CONFIG_CSUM_UNNECESSARY
	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
#endif
}
Beispiel #3
0
static int CUSTOM_check_IP_checksum(struct sk_buff *skb, unsigned int offset){
	__sum16 ck;
	struct iphdr *iph;
	int ok;
	skb_pull(skb, offset);
	iph = get_IP_header(skb);

	//printk(" ---> checksum: %u\n", iph->check);

	if(iph->check == 0) return -1;

	ck = iph->check;
	iph->check = 0;
	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
	if(iph->check != ck){
		//printk("\n NO CHECK %u | %u \n", iph->check, ck);
		ok = -1;
		iph->check = ck;
	}
	else{
		//printk("\n YES CHECK %u | %u \n", iph->check, ck);
		ok = 0;
	}
	skb_push(skb, offset);
	return ok;
}
Beispiel #4
0
void skb_updateChecksumIP_UDP(struct sk_buff *skb)
{
    struct udphdr *uh;
    struct iphdr *iph;
    unsigned long len;

    // retrieve IP header
    iph = ip_hdr(skb);

    // retrieve UDP header
    uh = (struct udphdr*)(skb->data+(iph->ihl<<2));

    //update IP header
    iph->check = 0;
    iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);

    // update UDP header
    len = skb->len - (iph->ihl<<2);
    skb->csum = csum_partial((char*)uh + sizeof(struct udphdr),len-sizeof(struct udphdr),0);

    //skb_checksum(skb, offset, skb->len-offset, 0);

    uh->check =0;
    uh->check = csum_tcpudp_magic(iph->saddr,iph->daddr,len,IPPROTO_UDP,
                csum_partial((char*)uh,sizeof(struct udphdr),skb->csum));


}
Beispiel #5
0
int32_t fio_icmp_gen_resp(struct fio_nic *nic, struct icmp_packet *icmp_from, struct icmp_packet *icmp_to, struct fio_rxdata *rxd, int realtime)
{
    if (TXDATA_TYPE_REALTIME != realtime)
        memcpy(icmp_to, icmp_from, rxd->size); 

    memcpy(&icmp_to->eh.ether_dhost, &rxd->smac, ETH_ALEN);
    memcpy(&icmp_to->eh.ether_shost, &nic->if_mac, ETH_ALEN);

    struct ip *ip = &icmp_to->ip;
    ip->ip_len = ntohs(rxd->size - sizeof(struct ether_header));
    ip->ip_dst.s_addr = rxd->sip;
    ip->ip_src.s_addr = rxd->dip;
    ip->ip_sum = 0;
    ip->ip_sum = ip_fast_csum((char*)ip, ip->ip_hl);

    struct icmp *icmp = &icmp_to->icmp;
    OD( "icmp_type = %x", icmp->icmp_type);
    icmp->icmp_type = ICMP_ECHOREPLY;//0
    uint8_t *ptr = (uint8_t*)&icmp->icmp_cksum;
    if (*ptr > (0xff-0x08))
	    (*(ptr+1))++;
    *ptr += 0x08;
    
    //snprintf((char*)icmp_to->padding, 100, "%s", nic->alise);
    return 0;
}
static int raw_getrawfrag(const void *p, char *to, unsigned int offset,
				unsigned int fraglen, struct sk_buff *skb)
{
	struct rawfakehdr *rfh = (struct rawfakehdr *) p;

	if (memcpy_fromiovecend(to, rfh->iov, offset, fraglen))
		return -EFAULT;

	if (!offset) {
		struct iphdr *iph = (struct iphdr *)to;
		if (!iph->saddr)
			iph->saddr = rfh->saddr;
		iph->check   = 0;
		iph->tot_len = htons(fraglen); /* This is right as you can't
						  frag RAW packets */
		/*
	 	 *	Deliberate breach of modularity to keep 
	 	 *	ip_build_xmit clean (well less messy).
		 */
		if (!iph->id)
			ip_select_ident(iph, rfh->dst, NULL);
		iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
	}
	return 0;
}
Beispiel #7
0
void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
{
	int total_len, eth_len, ip_len, udp_len;
	struct sk_buff *skb;
	struct udphdr *udph;
	struct iphdr *iph;
	struct ethhdr *eth;

	udp_len = len + sizeof(*udph);
	ip_len = eth_len = udp_len + sizeof(*iph);
	total_len = eth_len + ETH_HLEN + NET_IP_ALIGN;

	skb = find_skb(np, total_len, total_len - len);
	if (!skb)
		return;

	skb_copy_to_linear_data(skb, msg, len);
	skb->len += len;

	skb_push(skb, sizeof(*udph));
	skb_reset_transport_header(skb);
	udph = udp_hdr(skb);
	udph->source = htons(np->local_port);
	udph->dest = htons(np->remote_port);
	udph->len = htons(udp_len);
	udph->check = 0;
	udph->check = csum_tcpudp_magic(htonl(np->local_ip),
					htonl(np->remote_ip),
					udp_len, IPPROTO_UDP,
					csum_partial((unsigned char *)udph, udp_len, 0));
	if (udph->check == 0)
		udph->check = CSUM_MANGLED_0;

	skb_push(skb, sizeof(*iph));
	skb_reset_network_header(skb);
	iph = ip_hdr(skb);

	/* iph->version = 4; iph->ihl = 5; */
	put_unaligned(0x45, (unsigned char *)iph);
	iph->tos      = 0;
	put_unaligned(htons(ip_len), &(iph->tot_len));
	iph->id       = 0;
	iph->frag_off = 0;
	iph->ttl      = 64;
	iph->protocol = IPPROTO_UDP;
	iph->check    = 0;
	put_unaligned(htonl(np->local_ip), &(iph->saddr));
	put_unaligned(htonl(np->remote_ip), &(iph->daddr));
	iph->check    = ip_fast_csum((unsigned char *)iph, iph->ihl);

	eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
	skb_reset_mac_header(skb);
	skb->protocol = eth->h_proto = htons(ETH_P_IP);
	memcpy(eth->h_source, np->local_mac, 6);
	memcpy(eth->h_dest, np->remote_mac, 6);

	skb->dev = np->dev;

	netpoll_send_skb(np, skb);
}
static void lro_update_tcp_ip_header(struct net_lro_desc *lro_desc)
{
	struct iphdr *iph = lro_desc->iph;
	struct tcphdr *tcph = lro_desc->tcph;
	__be32 *p;
	__wsum tcp_hdr_csum;

	tcph->ack_seq = lro_desc->tcp_ack;
	tcph->window = lro_desc->tcp_window;

	if (lro_desc->tcp_saw_tstamp) {
		p = (__be32 *)(tcph + 1);
		*(p+2) = lro_desc->tcp_rcv_tsecr;
	}

	iph->tot_len = htons(lro_desc->ip_tot_len);

	iph->check = 0;
	iph->check = ip_fast_csum((u8 *)lro_desc->iph, iph->ihl);

	tcph->check = 0;
	tcp_hdr_csum = csum_partial((u8 *)tcph, TCP_HDR_LEN(tcph), 0);
	lro_desc->data_csum = csum_add(lro_desc->data_csum, tcp_hdr_csum);
	tcph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
					lro_desc->ip_tot_len -
					IP_HDR_LEN(iph), IPPROTO_TCP,
					lro_desc->data_csum);
}
Beispiel #9
0
void denat_packet(struct sk_buff *skb){
	struct in_device *pin_dev;
	struct iphdr *iph;
	//u32 naddr;

	iph = get_IP_header(skb);
	pin_dev = (struct in_device *) upmt_dev->ip_ptr;
	if(pin_dev == NULL){
		dmesge("denat_packet - pin_dev = NULL");
		return;
	}
	if(pin_dev->ifa_list == NULL){
		dmesge("denat_packet - pin_dev->ifa_list = NULL");
		return;
	}
	/*if(pin_dev->ifa_list->ifa_address == NULL){
		dmesg("denat_packet - error - pin_dev->ifa_list->ifa_address ---> NULL");
		return;
	}*/
	//dmesg("IP of upmt_dev: %u ---> ", pin_dev->ifa_list->ifa_address);
	//print_ip_address(pin_dev->ifa_list->ifa_address);
	iph->daddr = pin_dev->ifa_list->ifa_address;

	//naddr = get_dev_ip_address(upmt_dev, NULL, 0);
	//iph->daddr = naddr;

	iph->check = 0;
	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);

	compute_TRANSPORT_checksum(skb);
}
Beispiel #10
0
static int br_parse_ip_options(struct sk_buff *skb)
{
	struct ip_options *opt;
	struct iphdr *iph;
	struct net_device *dev = skb->dev;
	u32 len;

	iph = ip_hdr(skb);
	opt = &(IPCB(skb)->opt);

	/* Basic sanity checks */
	if (iph->ihl < 5 || iph->version != 4)
		goto inhdr_error;

	if (!pskb_may_pull(skb, iph->ihl*4))
		goto inhdr_error;

	iph = ip_hdr(skb);
	if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
		goto inhdr_error;

	len = ntohs(iph->tot_len);
	if (skb->len < len) {
		IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INTRUNCATEDPKTS);
		goto drop;
	} else if (len < (iph->ihl*4))
		goto inhdr_error;

	if (pskb_trim_rcsum(skb, len)) {
		IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS);
		goto drop;
	}

	/* Zero out the CB buffer if no options present */
	if (iph->ihl == 5) {
		memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
		return 0;
	}

	opt->optlen = iph->ihl*4 - sizeof(struct iphdr);
	if (ip_options_compile(dev_net(dev), opt, skb))
		goto inhdr_error;

	/* Check correct handling of SRR option */
	if (unlikely(opt->srr)) {
		struct in_device *in_dev = __in_dev_get_rcu(dev);
		if (in_dev && !IN_DEV_SOURCE_ROUTE(in_dev))
			goto drop;

		if (ip_options_rcv_srr(skb))
			goto drop;
	}

	return 0;

inhdr_error:
	IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INHDRERRORS);
drop:
	return -1;
}
Beispiel #11
0
static int ib_get_header_version(const union rdma_network_hdr *hdr)
{
	const struct iphdr *ip4h = (struct iphdr *)&hdr->roce4grh;
	struct iphdr ip4h_checked;
	const struct ipv6hdr *ip6h = (struct ipv6hdr *)&hdr->ibgrh;

	/* If it's IPv6, the version must be 6, otherwise, the first
	 * 20 bytes (before the IPv4 header) are garbled.
	 */
	if (ip6h->version != 6)
		return (ip4h->version == 4) ? 4 : 0;
	/* version may be 6 or 4 because the first 20 bytes could be garbled */

	/* RoCE v2 requires no options, thus header length
	 * must be 5 words
	 */
	if (ip4h->ihl != 5)
		return 6;

	/* Verify checksum.
	 * We can't write on scattered buffers so we need to copy to
	 * temp buffer.
	 */
	memcpy(&ip4h_checked, ip4h, sizeof(ip4h_checked));
	ip4h_checked.check = 0;
	ip4h_checked.check = ip_fast_csum((u8 *)&ip4h_checked, 5);
	/* if IPv4 header checksum is OK, believe it */
	if (ip4h->check == ip4h_checked.check)
		return 4;
	return 6;
}
Beispiel #12
0
static int vnet_start_xmit(struct sk_buff *skb, struct net_device *net)
{
	struct pdp_info *dev = (struct pdp_info *)net->ml_priv;

#ifdef USE_LOOPBACK_PING
	int ret;
	struct sk_buff *skb2;
	struct icmphdr *icmph;
	struct iphdr *iph;
#endif

   DPRINTK(2, "BEGIN\n");

#ifdef USE_LOOPBACK_PING
	dev->vn_dev.stats.tx_bytes += skb->len;
	dev->vn_dev.stats.tx_packets++;

	skb2 = alloc_skb(skb->len, GFP_ATOMIC);
	if (skb2 == NULL) {
		DPRINTK(1, "alloc_skb() failed\n");
		dev_kfree_skb_any(skb);
		return -ENOMEM;
	}

	memcpy(skb2->data, skb->data, skb->len);
	skb_put(skb2, skb->len);
	dev_kfree_skb_any(skb);

	icmph = (struct icmphdr *)(skb2->data + sizeof(struct iphdr));
	iph = (struct iphdr *)skb2->data;

	icmph->type = __constant_htons(ICMP_ECHOREPLY);

	ret = iph->daddr;
	iph->daddr = iph->saddr;
	iph->saddr = ret;
	iph->check = 0;
	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);

	skb2->dev = net;
	skb2->protocol = __constant_htons(ETH_P_IP);

	netif_rx(skb2);

	dev->vn_dev.stats.rx_packets++;
	dev->vn_dev.stats.rx_bytes += skb->len;
#else
   if (vnet_start_xmit_flag != 0) {
       return NETDEV_TX_BUSY;
   }
	vnet_start_xmit_flag = 1; 
	workqueue_data = (unsigned long)skb;
	PREPARE_WORK(&dev->vn_dev.xmit_task,vnet_defer_xmit);
	schedule_work(&dev->vn_dev.xmit_task);
	netif_stop_queue(net);
#endif

   DPRINTK(2, "END\n");
	return NETDEV_TX_OK;
}
Beispiel #13
0
static void flush_session(struct mlx4_en_priv *priv,
			  struct mlx4_en_ipfrag *session,
			  u16 more)
{
	struct sk_buff *skb = session->fragments;
	struct iphdr *iph = ip_hdr(skb);
	struct net_device *dev = skb->dev;

	/* Update IP length and checksum */
	iph->tot_len = htons(session->total_len);
	iph->frag_off = htons(more | (session->offset >> 3));
	iph->check = 0;
	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);

	if (session->vlan) {
		if (priv->mdev->profile.use_napi)
			vlan_hwaccel_receive_skb(skb, priv->vlgrp,
						 be16_to_cpu(session->sl_vid));
		else
			vlan_hwaccel_rx(skb, priv->vlgrp,
					be16_to_cpu(session->sl_vid));
	} else {
		if (priv->mdev->profile.use_napi)
			netif_receive_skb(skb);
		else
			netif_rx(skb);
	}
	dev->last_rx = jiffies;
	session->fragments = NULL;
	session->last = NULL;
}
u16 bpf_checksum(const u8 *buf, u32 len)
{
	/* if 'buf' points to BPF program stack, bpf_check()
	 * verified that 'len' bytes of it are valid
	 * len/4 rounds the length down, so that memory is safe to access
	 */
	return ip_fast_csum(buf, len/4);
}
Beispiel #15
0
/*----------------------------------------------------------------------------*/
inline int 
ProcessInIPv4Packet(mtcp_manager_t mtcp, struct pkt_ctx *pctx)
{
	bool release = false;
	int ret;
	struct mon_listener *walk;
	/* check and process IPv4 packets */
	struct iphdr* iph =
		(struct iphdr *)((char *)pctx->p.ethh + sizeof(struct ethhdr));
	int ip_len = ntohs(iph->tot_len);

	/* drop the packet shorter than ip header */
	if (ip_len < sizeof(struct iphdr)) {
		ret = ERROR;
		goto __return;
	}

	if (ip_fast_csum(iph, iph->ihl)) {
		ret = ERROR;
		goto __return;
	}

	if (iph->version != IPVERSION ) {
		release = true;
		ret = FALSE;
		goto __return;
	}

	FillInPacketIPContext(pctx, iph, ip_len);

	switch (iph->protocol) {
		case IPPROTO_TCP:
			return ProcessInTCPPacket(mtcp, pctx);
		case IPPROTO_ICMP:
			if (ProcessICMPPacket(mtcp, pctx))
				return TRUE;
		default:
			/* forward other protocols without any processing */
			if (!mtcp->num_msp || !pctx->forward)
				release = true;
			else
				ForwardIPPacket(mtcp, pctx);
			
			ret = FALSE;
			goto __return;
	}

__return:
	/* callback for monitor raw socket */
	TAILQ_FOREACH(walk, &mtcp->monitors, link)
		if (walk->socket->socktype == MOS_SOCK_MONITOR_RAW)
			HandleCallback(mtcp, MOS_NULL, walk->socket, MOS_SIDE_BOTH,
				       pctx, MOS_ON_PKT_IN);
	if (release && mtcp->iom->release_pkt)
		mtcp->iom->release_pkt(mtcp->ctx, pctx->in_ifidx,
				       (unsigned char *)pctx->p.ethh, pctx->p.eth_len);
	return ret;
}
Beispiel #16
0
static void construct_rxpack(struct sk_buff *skb, struct net_device *dev)
{ 
	unsigned char *type;
	struct iphdr *ih;
	__be32 *saddr, *daddr, tmp;
	unsigned char	tmp_dev_addr[ETH_ALEN];
	struct ethhdr *ethhdr;
	
	struct sk_buff *rx_skb;
		
    /* 
     *  Read and save the data from hardware 
     *  Switch the source/destination of the MAC address 
     */
	ethhdr = (struct ethhdr *)skb->data;
	memcpy(tmp_dev_addr, ethhdr->h_dest, ETH_ALEN);
	memcpy(ethhdr->h_dest, ethhdr->h_source, ETH_ALEN);
	memcpy(ethhdr->h_source, tmp_dev_addr, ETH_ALEN);

    /* 
     *  Switch the source/destination of the IP address 
     */
	ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
	saddr = &ih->saddr;
	daddr = &ih->daddr;

	tmp = *saddr;
	*saddr = *daddr;
	*daddr = tmp;
	
	//((u8 *)saddr)[2] ^= 1; /* change the third octet (class C) */
	//((u8 *)daddr)[2] ^= 1;
	type = skb->data + sizeof(struct ethhdr) + sizeof(struct iphdr);
	//printk("tx package type = %02x\n", *type);

    /* 
     *  Modify the type, 0x8 means ping
     */
	*type = 0; /* 0 means reply */
	
	ih->check = 0;		   /* and rebuild the checksum (ip needs it) */
	ih->check = ip_fast_csum((unsigned char *)ih,ih->ihl);
	
    /* Construct a sk_buff structure */
    rx_skb = dev_alloc_skb(skb->len + 2);
	skb_reserve(rx_skb, 2); /* align IP on 16B boundary */	
	memcpy(skb_put(rx_skb, skb->len), skb->data, skb->len);

	/* Write metadata, and then pass to the receive level */
	rx_skb->dev = dev;
	rx_skb->protocol = eth_type_trans(rx_skb, dev);
	rx_skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
	dev->stats.rx_packets++;
	dev->stats.rx_bytes += skb->len;

	/* Submit sk_buff */
	netif_rx(rx_skb);
}
Beispiel #17
0
/*----------------------------------------------------------------------------*/
void
DumpIPPacketToFile(FILE *fout, const struct iphdr *iph, int len)
{
	struct udphdr *udph;
	struct tcphdr *tcph;
	uint8_t *t;

	udph = (struct udphdr *)((uint32_t *)iph + iph->ihl);
	tcph = (struct tcphdr *)((uint32_t *)iph + iph->ihl);

	t = (uint8_t *)&iph->saddr;
	fprintf(fout, "%u.%u.%u.%u", t[0], t[1], t[2], t[3]);
	if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP)
		fprintf(fout, "(%d)", ntohs(udph->source));

	fprintf(fout, " -> ");

	t = (uint8_t *)&iph->daddr;
	fprintf(fout, "%u.%u.%u.%u", t[0], t[1], t[2], t[3]);
	if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP)
		fprintf(fout, "(%d)", ntohs(udph->dest));

	fprintf(fout, " IP_ID=%d", ntohs(iph->id));
	fprintf(fout, " TTL=%d ", iph->ttl);

	if (ip_fast_csum(iph, iph->ihl)) {
		fprintf(fout, "(bad checksum) ");
	}

	switch (iph->protocol) {
	case IPPROTO_TCP:
		fprintf(fout, "TCP ");
		
		if (tcph->syn)
			fprintf(fout, "S ");
		if (tcph->fin)
			fprintf(fout, "F ");
		if (tcph->ack)
			fprintf(fout, "A ");
		if (tcph->rst)
			fprintf(fout, "R ");

		fprintf(fout, "seq %u ", ntohl(tcph->seq));
		if (tcph->ack)
			fprintf(fout, "ack %u ", ntohl(tcph->ack_seq));
		fprintf(fout, "WDW=%u ", ntohs(tcph->window));
		break;
	case IPPROTO_UDP:
		fprintf(fout, "UDP ");
		break;
	default:
		fprintf(fout, "protocol %d ", iph->protocol);
		goto done;
	}
done:
	fprintf(fout, "len=%d\n", len);
}
Beispiel #18
0
s32 dp_bfd_echo_packet_rebound(struct sk_buff *skb)
{
    u32 l2_len;
    u32 data_off = (u32)((skb->nh.raw - skb->data) + skb->nh.iph->ihl*4);
    u32 udp_data_len;
    struct sk_buff    *skb_new;
    struct ethhdr     *eth;
	struct iphdr      *iph;
	struct udphdr     *udph; 
    struct udphdr _hdr, *hdr;
    
    skb_new = alloc_skb(1500, GFP_ATOMIC);
    if(NULL == skb_new)
    {
        return ERROR_FAIL;
    }
    skb_new->in_if = skb->out_if;
	skb_new->out_if = skb->in_if;
	skb_new->forward_flag = 0;
    skb_new->dev = skb->dev;

	l2_len = (u32)((u8*)skb->nh.iph - (u8*)skb->mac.raw);
	eth = (struct ethhdr*)skb_put(skb_new, l2_len);
	memcpy(eth, skb->mac.raw, l2_len);                
	skb_new->mac.raw = (u8 *)eth;
	memcpy(eth->h_dest, eth_hdr(skb)->h_source, ETH_ALEN);
	memcpy(eth->h_source, eth_hdr(skb)->h_dest, ETH_ALEN);
	eth->h_proto = 0x0800;   

	iph = (struct iphdr*)skb_put(skb_new, sizeof(struct iphdr));
    memcpy(iph, skb->nh.iph, sizeof(struct iphdr));
    skb_new->nh.iph = iph;
	iph->daddr = skb_get_src_ip(skb);
	iph->saddr = skb_get_dst_ip(skb);
    iph->id = skb->nh.iph->id;

	udph = (struct udphdr*)skb_put(skb_new, sizeof(struct udphdr));
    hdr = skb_header_pointer(skb, (s32)data_off, sizeof(_hdr), &_hdr);
    memcpy(udph, hdr, sizeof(struct udphdr));
	skb_new->h.uh = udph;
	udph->dest = hdr->source;
	udph->source = hdr->dest;
    udp_data_len = hdr->len - sizeof(struct udphdr);
	skb_put(skb_new, udp_data_len);
	memcpy((u8 *)udph + sizeof(struct udphdr), (u8 *)hdr + sizeof(struct udphdr), udp_data_len);
    
	udph->check = 0;
	udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, (u16)(sizeof(struct udphdr) + udp_data_len), IPPROTO_UDP, 
	                              csum_partial((u8*)udph, (int)(sizeof(struct udphdr)+udp_data_len), 0));

	iph->check = 0;
	iph->check = ip_fast_csum((u8*)iph, iph->ihl);

    skb_xmit_for_bfd(skb_new ,skb->dev->ifindex);
    
	return ERROR_SUCCESS;
}
Beispiel #19
0
void inat_packet(struct sk_buff *skb, const struct tun_param *tp){
	struct iphdr *iph;
	iph = get_IP_header(skb);
	iph->saddr = tp->in.local;

	iph->check = 0;
	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);

	compute_TRANSPORT_checksum(skb);
}
Beispiel #20
0
/**
 * Netfilter is nice enough to defragment the packet for us and store
 * details about the fragments in skb->data_len and skb_shinfo(skb)->frag_list
 * All the fragments are there, we just have to add them all up by 
 * traversing the frag_list linked list.
 *
 **/ 
void calc_checksum(struct sk_buff *skb)
{
	struct iphdr *iph = NULL;
	struct tcphdr *th = NULL;
	struct udphdr *uh = NULL;
	uint16_t l4len = 0;
	uint16_t iph_len = 0;
	uint16_t tcpdata_len = 0;
	uint16_t tcph_len = 0;
	uint16_t tcp_len = 0;
	uint16_t l3len = 0;
	void *l4ptr = NULL;

	iph = ip_hdr(skb);
	if(!iph){ return; }

	l3len = iph->ihl << 2;

	if(iph->protocol == IPPROTO_UDP){
	   uh = (struct udphdr *)((unsigned char *)iph + (iph->ihl<<2));
	   iph_len = l3len;
	   l4ptr = uh;
	   l4len = ntohs(uh->len);

	   uh->check = 0x0000;
	}

	if(iph->protocol == IPPROTO_TCP){
	   th = (struct tcphdr *)((unsigned char *)iph + (iph->ihl<<2));
	   tcph_len    = th->doff << 2;
	   iph_len     = l3len;
	   tcpdata_len = ntohs(iph->tot_len) - iph_len - tcph_len; 
	   tcp_len     = tcph_len + tcpdata_len;
	   l4ptr       = th;
	   l4len       = tcp_len;

	   th->check = 0x0000;
	}

	if(th){
	   th->check = csum_tcpudp_magic(iph->saddr, iph->daddr, l4len, 
	   		IPPROTO_TCP,
	   		skb_checksum(skb, iph_len, l4len, 0));
	}
	
	if(uh){
	   uh->check = csum_tcpudp_magic(iph->saddr, iph->daddr, l4len, 
	   		IPPROTO_UDP,
	   		skb_checksum(skb, iph_len, l4len, 0));
	}

	iph->check = 0;
	iph->check = ip_fast_csum((void *)iph, iph->ihl);

}
Beispiel #21
0
void build_packet(char *buf, int size, uint64_t *seed)
{
    struct ethhdr *eth;
    struct iphdr *ip;
    struct udphdr *udp;

    uint32_t rand_val;

    //memset(buf, 0, size);

    /* build an ethernet header */
    eth = (struct ethhdr *)buf;

    eth->h_dest[0] = 0x00;
    eth->h_dest[1] = 0x00;
    eth->h_dest[2] = 0x00;
    eth->h_dest[3] = 0x00;
    eth->h_dest[4] = 0x00;
    eth->h_dest[5] = 0x02;

    eth->h_source[0] = 0x00;
    eth->h_source[1] = 0x00;
    eth->h_source[2] = 0x00;
    eth->h_source[3] = 0x00;
    eth->h_source[4] = 0x00;
    eth->h_source[5] = 0x01;

    eth->h_proto = HTONS(0x0800);

    /* build an IP header */
    ip = (struct iphdr *)(buf + sizeof(*eth));

    ip->version = 4;
    ip->ihl = 5;
    ip->tos = 0;
    ip->tot_len = HTONS(size - sizeof(*eth));
    ip->id = 0;
    ip->frag_off = 0;
    ip->ttl = 32;
    ip->protocol = IPPROTO_UDP;
    ip->saddr = HTONL(0x0A000001);
    ip->daddr = HTONL(myrand(seed));
    ip->check = 0;
    ip->check = ip_fast_csum(ip, ip->ihl);

    udp = (struct udphdr *)((char *)ip + sizeof(*ip));

    rand_val = myrand(seed);
    udp->source = HTONS(rand_val & 0xFFFF);
    udp->dest = HTONS((rand_val >> 16) & 0xFFFF);

    udp->len = HTONS(size - sizeof(*eth) - sizeof(*ip));
    udp->check = 0;
}
Beispiel #22
0
static bool parse_udp_packet(struct sk_buff *skb, struct iphdr **piph, struct udphdr **puh, int *pulen)
{
	int proto, len, ulen;
	struct iphdr *iph;
	struct udphdr *uh;

	proto = ntohs(eth_hdr(skb)->h_proto);
	if (proto != ETH_P_IP)
		return false;
	if (skb->pkt_type == PACKET_OTHERHOST)
		return false;
	if (skb_shared(skb))
		return false;

	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
		return false;
	iph = (struct iphdr *)skb->data;
	if (iph->ihl < 5 || iph->version != 4)
		return false;
	if (!pskb_may_pull(skb, iph->ihl * 4))
		return false;
	iph = (struct iphdr *)skb->data;
	if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
		return false;

	len = ntohs(iph->tot_len);
	if (skb->len < len || len < iph->ihl * 4)
		return false;

	/*
	* Our transport medium may have padded the buffer out.
	* Now We trim to the true length of the frame.
	*/
	if (pskb_trim_rcsum(skb, len))
		return false;

	iph = (struct iphdr *)skb->data;
	if (iph->protocol != IPPROTO_UDP)
		return false;

	len -= iph->ihl * 4;
	uh = (struct udphdr *)(((char *)iph) + iph->ihl * 4);
	ulen = ntohs(uh->len);

	if (ulen != len)
		return false;

	*piph = iph;
	*puh = uh;
	*pulen = ulen;

	return true;
}
Beispiel #23
0
/**
 * @brief this adds a IP ckecksum in the IP header of the packet
 * @param skb
 */
static void
__adf_net_ip_cksum(struct sk_buff *skb)
{
    struct iphdr   *ih  = {0};
    struct skb_shared_info  *sh = skb_shinfo(skb);

    adf_os_assert(sh->nr_frags == 0);

    ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
    ih->check = 0;
    ih->check = ip_fast_csum((unsigned char *)ih, ih->ihl);
}
Beispiel #24
0
static void emulator_rx_packet(struct sk_buff *skb, struct net_device *dev)
{
	/* 参考LDD3 */
	unsigned char *type;
	struct iphdr *ih;
	__be32 *saddr, *daddr, tmp;
	unsigned char	tmp_dev_addr[ETH_ALEN];
	struct ethhdr *ethhdr;
	
	struct sk_buff *rx_skb;
		
	// 从硬件读出/保存数据
	/* 对调"源/目的"的mac地址 */
	ethhdr = (struct ethhdr *)skb->data;
	memcpy(tmp_dev_addr, ethhdr->h_dest, ETH_ALEN);
	memcpy(ethhdr->h_dest, ethhdr->h_source, ETH_ALEN);
	memcpy(ethhdr->h_source, tmp_dev_addr, ETH_ALEN);

	/* 对调"源/目的"的ip地址 */    
	ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
	saddr = &ih->saddr;
	daddr = &ih->daddr;

	tmp = *saddr;
	*saddr = *daddr;
	*daddr = tmp;
	
	//((u8 *)saddr)[2] ^= 1; /* change the third octet (class C) */
	//((u8 *)daddr)[2] ^= 1;
	type = skb->data + sizeof(struct ethhdr) + sizeof(struct iphdr);
	//printk("tx package type = %02x\n", *type);
	// 修改类型, 原来0x8表示ping
	*type = 0; /* 0表示reply */
	
	ih->check = 0;		   /* and rebuild the checksum (ip needs it) */
	ih->check = ip_fast_csum((unsigned char *)ih,ih->ihl);
	
	// 构造一个sk_buff
	rx_skb = dev_alloc_skb(skb->len + 2);
	skb_reserve(rx_skb, 2); /* align IP on 16B boundary */	
	memcpy(skb_put(rx_skb, skb->len), skb->data, skb->len);

	/* Write metadata, and then pass to the receive level */
	rx_skb->dev = dev;
	rx_skb->protocol = eth_type_trans(rx_skb, dev);
	rx_skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
	dev->stats.rx_packets++;
	dev->stats.rx_bytes += skb->len;

	// 提交sk_buff
	netif_rx(rx_skb);
}
Beispiel #25
0
/***
 *	rt_ip_rcv
 */
int rt_ip_rcv(struct rtskb *skb, struct rtnet_device *rtdev, struct rtpacket_type *pt)
{
	struct iphdr *iph;
	
	/* When the interface is in promisc. mode, drop all the crap
	 * that it receives, do not try to analyse it.
	 */
	if (skb->pkt_type == PACKET_OTHERHOST)
		goto drop;

	iph = skb->nh.iph;

	/*
	 *	RFC1122: 3.1.2.2 MUST silently discard any IP frame that fails the checksum.
	 *
	 *	Is the datagram acceptable?
	 *
	 *	1.	Length at least the size of an ip header
	 *	2.	Version of 4
	 *	3.	Checksums correctly. [Speed optimisation for later, skip loopback checksums]
	 *	4.	Doesn't have a bogus length
	 */
	if (iph->ihl < 5 || iph->version != 4)
		goto drop; 

	if ( ip_fast_csum((u8 *)iph, iph->ihl)!=0 ) 
		goto drop; 
		
	{
		__u32 len = ntohs(iph->tot_len); 
		if ( (skb->len<len) || (len<(iph->ihl<<2)) )
			goto drop;
	
		rtskb_trim(skb, len);
	}
	
	if (skb->dst == NULL)
		if ( rt_ip_route_input(skb, iph->daddr, iph->saddr, skb->rtdev) )
			goto drop; 

	/* ip_local_deliver */	
	if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
		skb = rt_ip_defrag(skb);
		if (!skb)
			return 0;
	}
	return rt_ip_local_deliver_finish(skb);

drop:
	kfree_rtskb(skb);
	return NET_RX_DROP;
}
Beispiel #26
0
static void nic_hw_xmit(struct net_device *netdev)
{
    struct nic_priv *priv = netdev_priv(netdev);
    struct iphdr *iph;
    u32 *saddr, *daddr;
    struct in_device* in_dev;
    struct in_ifaddr* if_info;

    if (priv->tx_len < sizeof(struct ethhdr) + sizeof(struct iphdr)) {
        netif_info(priv, hw, netdev, "%s(#%d), too short\n",
                   __func__, __LINE__);
        return;
    }
    dump(priv->tx_buf);
    iph = (struct iphdr *)(priv->tx_buf + sizeof(struct ethhdr));
    saddr = &iph->saddr;
    daddr = &iph->daddr;

    netif_info(priv, hw, netdev, "%s(#%d), orig, src:%pI4, dst:%pI4, len:%d\n",
                __func__, __LINE__, saddr, daddr, priv->tx_len);

    in_dev = nic_dev[(netdev == nic_dev[0] ? 1 : 0)]->ip_ptr;
    if (in_dev) {
        if_info = in_dev->ifa_list;
        for (if_info = in_dev->ifa_list; if_info; if_info=if_info->ifa_next) {
#if 0
            printk("label:%s, address=%pI4\n",
               if_info->ifa_label, &if_info->ifa_address);
#endif
            *saddr = *daddr = if_info->ifa_address;
            ((u8 *)saddr)[3]++;
            netif_info(priv, hw, netdev, "%s(#%d), new, src:%pI4, dst:%pI4\n",
                        __func__, __LINE__, saddr, daddr);
            break;
        }
        if (!if_info) {
            /* drop packet */
            netdev->stats.tx_dropped++;
            netif_info(priv, hw, netdev, "%s(#%d), drop packet\n",
                        __func__, __LINE__);
            return;
        }
    }

    iph->check = 0;         /* and rebuild the checksum (ip needs it) */
    iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);

    netdev->stats.tx_packets++;
    netdev->stats.tx_bytes += priv->tx_len;

    nic_rx(nic_dev[(netdev == nic_dev[0] ? 1 : 0)], priv->tx_len, priv->tx_buf);
}
Beispiel #27
0
static void emulate_large_send_offload(struct sk_buff *skb)
{
	struct iphdr *iph = skb->nh.iph;
	struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4));
	unsigned int doffset = (iph->ihl + th->doff) * 4;
	unsigned int mtu = skb_shinfo(skb)->tso_size + doffset;
	unsigned int offset = 0;
	u32 seq = ntohl(th->seq);
	u16 id  = ntohs(iph->id);

	while (offset + doffset < skb->len) {
		unsigned int frag_size = min(mtu, skb->len - offset) - doffset;
		struct sk_buff *nskb = alloc_skb(mtu + 32, GFP_ATOMIC);

		if (!nskb)
			break;
		skb_reserve(nskb, 32);
		nskb->mac.raw = nskb->data - 14;
		nskb->nh.raw = nskb->data;
		iph = nskb->nh.iph;
		memcpy(nskb->data, skb->nh.raw, doffset);
		if (skb_copy_bits(skb,
				  doffset + offset,
				  nskb->data + doffset,
				  frag_size))
			BUG();
		skb_put(nskb, doffset + frag_size);
		nskb->ip_summed = CHECKSUM_UNNECESSARY;
		nskb->dev = skb->dev;
		nskb->priority = skb->priority;
		nskb->protocol = skb->protocol;
		nskb->dst = dst_clone(skb->dst);
		memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
		nskb->pkt_type = skb->pkt_type;

		th = (struct tcphdr*)(nskb->nh.raw + iph->ihl*4);
		iph->tot_len = htons(frag_size + doffset);
		iph->id = htons(id);
		iph->check = 0;
		iph->check = ip_fast_csum((unsigned char *) iph, iph->ihl);
		th->seq = htonl(seq);
		if (offset + doffset + frag_size < skb->len)
			th->fin = th->psh = 0;
		netif_rx(nskb);
		offset += frag_size;
		seq += frag_size;
		id++;
	}

	dev_kfree_skb(skb);
}
Beispiel #28
0
/*----------------------------------------------------------------------------*/
uint8_t *
IPOutput(struct mtcp_manager *mtcp, tcp_stream *stream, uint16_t tcplen)
{
	struct iphdr *iph;
	int nif;
	unsigned char *haddr;

	if (stream->sndvar->nif_out >= 0) {
		nif = stream->sndvar->nif_out;
	} else {
		nif = GetOutputInterface(stream->daddr);
		stream->sndvar->nif_out = nif;
	}

	haddr = GetDestinationHWaddr(stream->daddr);
	if (!haddr) {
#if 0
		uint8_t *da = (uint8_t *)&stream->daddr;
		TRACE_INFO("[WARNING] The destination IP %u.%u.%u.%u "
				"is not in ARP table!\n",
				da[0], da[1], da[2], da[3]);
#endif
		/* if not found in the arp table, send arp request and return NULL */
		/* tcp will retry sending the packet later */
		RequestARP(mtcp, stream->daddr, stream->sndvar->nif_out, mtcp->cur_ts);
		return NULL;
	}

	iph = (struct iphdr *)EthernetOutput(mtcp, ETH_P_IP,
			stream->sndvar->nif_out, haddr, tcplen + IP_HEADER_LEN);
	if (!iph) {
		return NULL;
	}

	iph->ihl = IP_HEADER_LEN >> 2;
	iph->version = 4;
	iph->tos = 0;
	iph->tot_len = htons(IP_HEADER_LEN + tcplen);
	iph->id = htons(stream->sndvar->ip_id++);
	iph->frag_off = htons(0x4000);	// no fragmentation
	iph->ttl = 64;
	iph->protocol = IPPROTO_TCP;
	iph->saddr = stream->saddr;
	iph->daddr = stream->daddr;
	iph->check = 0;
	iph->check = ip_fast_csum(iph, iph->ihl);

	return (uint8_t *)(iph + 1);
}
Beispiel #29
0
static void gen_ip_frag_proc(u_char * data, int len)
{
    struct proc_node *i;
    struct ip *iph = (struct ip *) data;
    int need_free = 0;
    int skblen;
    void (*glibc_syslog_h_workaround)(int, int, struct ip *, void*)=
        nids_params.syslog;

    if (!nids_params.ip_filter(iph, len))
        return;

#if 0
    if (len < (int)sizeof(struct ip) || iph->ip_hl < 5 || iph->ip_v != 4 ||
            ip_fast_csum((unsigned char *) iph, iph->ip_hl) != 0 ||
            len < ntohs(iph->ip_len) || ntohs(iph->ip_len) < iph->ip_hl << 2) {
        glibc_syslog_h_workaround(NIDS_WARN_IP, NIDS_WARN_IP_HDR, iph, 0);
        return;
    }
#endif
    if (iph->ip_hl > 5 && ip_options_compile((unsigned char *)data)) {
        glibc_syslog_h_workaround(NIDS_WARN_IP, NIDS_WARN_IP_SRR, iph, 0);
        return;
    }
    switch (ip_defrag_stub((struct ip *) data, &iph)) {
    case IPF_ISF:
        return;
    case IPF_NOTF:
        need_free = 0;
        iph = (struct ip *) data;
        break;
    case IPF_NEW:
        need_free = 1;
        break;
    default:
        ;
    }
    skblen = ntohs(iph->ip_len) + 16;
    if (!need_free)
        skblen += nids_params.dev_addon;
    skblen = (skblen + 15) & ~15;
    skblen += nids_params.sk_buff_size;

    for (i = ip_procs; i; i = i->next)
        (i->item) (iph, skblen);
    if (need_free)
        free(iph);
}
int ipsec_tunnel_udp_encap(struct sk_buff *skb, uint8_t natt_type,
    uint8_t natt_head, uint16_t natt_sport, uint16_t natt_dport)
{
    struct iphdr *ipp = skb->nh.iph;
    struct udphdr *udp;
    int iphlen;

    KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
	"klips_debug:ipsec_tunnel_udp_encap: "
	"encapsuling packet into UDP (NAT-Traversal) (%d %d)\n",
	natt_type, natt_head);

    iphlen = ipp->ihl << 2;
    ipp->tot_len = htons(ntohs(ipp->tot_len) + natt_head);
    if(skb_tailroom(skb) < natt_head) {
	printk(KERN_WARNING "klips_error:ipsec_tunnel_udp_encap: "
	    "tried to skb_put %d, %d available. "
	    "This should never happen, please report.\n",
	    natt_head,
	    skb_tailroom(skb));
	return -1;
    }
    skb_put(skb, natt_head);

    udp = (struct udphdr *)((char *)ipp + iphlen);

    /* move ESP hdr after UDP hdr */
    memmove((void *)((char *)udp + natt_head),
	(void *)(udp),
	ntohs(ipp->tot_len) - iphlen - natt_head);

    /* clear UDP & Non-IKE Markers (if any) */
    memset(udp, 0, natt_head);

    /* fill UDP with usefull informations ;-) */
    udp->source = htons(natt_sport);
    udp->dest = htons(natt_dport);
    udp->len = htons(ntohs(ipp->tot_len) - iphlen);

    /* set protocol */
    ipp->protocol = IPPROTO_UDP;

    /* fix IP checksum */
    ipp->check = 0;
    ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl);

    return 0;
}