예제 #1
0
파일: ipv4.c 프로젝트: 5kg/kvmtool
int uip_tx_do_ipv4(struct uip_tx_arg *arg)
{
	struct uip_ip *ip;

	ip = (struct uip_ip *)(arg->eth);

	if (uip_ip_hdrlen(ip) != 20) {
		pr_warning("IP header length is not 20 bytes");
		return -1;
	}

	switch (ip->proto) {
	case UIP_IP_P_ICMP:
		uip_tx_do_ipv4_icmp(arg);
		break;
	case UIP_IP_P_TCP:
		uip_tx_do_ipv4_tcp(arg);
		break;
	case UIP_IP_P_UDP:
		uip_tx_do_ipv4_udp(arg);
		break;
	default:
		break;
	}

	return 0;
}
예제 #2
0
파일: udp.c 프로젝트: 5kg/kvmtool
int uip_udp_make_pkg(struct uip_info *info, struct uip_udp_socket *sk, struct uip_buf *buf, u8* payload, int payload_len)
{
	struct uip_eth *eth2;
	struct uip_udp *udp2;
	struct uip_ip *ip2;

	/*
	 * Cook a ethernet frame
	 */
	udp2		= (struct uip_udp *)(buf->eth);
	eth2		= (struct uip_eth *)buf->eth;
	ip2		= (struct uip_ip *)(buf->eth);

	eth2->src	= info->host_mac;
	eth2->dst	= info->guest_mac;
	eth2->type	= htons(UIP_ETH_P_IP);

	ip2->vhl	= UIP_IP_VER_4 | UIP_IP_HDR_LEN;
	ip2->tos	= 0;
	ip2->id		= 0;
	ip2->flgfrag	= 0;
	ip2->ttl	= UIP_IP_TTL;
	ip2->proto	= UIP_IP_P_UDP;
	ip2->csum	= 0;

	ip2->sip	= sk->dip;
	ip2->dip	= sk->sip;
	udp2->sport	= sk->dport;
	udp2->dport	= sk->sport;

	udp2->len	= htons(payload_len + uip_udp_hdrlen(udp2));
	udp2->csum	= 0;

	if (payload)
		memcpy(udp2->payload, payload, payload_len);

	ip2->len	= udp2->len + htons(uip_ip_hdrlen(ip2));
	ip2->csum	= uip_csum_ip(ip2);
	udp2->csum	= uip_csum_udp(udp2);

	/*
	 * virtio_net_hdr
	 */
	buf->vnet_len	= info->vnet_hdr_len;
	memset(buf->vnet, 0, buf->vnet_len);

	buf->eth_len	= ntohs(ip2->len) + uip_eth_hdrlen(&ip2->eth);

	return 0;
}
예제 #3
0
static int uip_tcp_payload_send(struct uip_tcp_socket *sk, u8 flag, u16 payload_len)
{
	struct uip_info *info;
	struct uip_eth *eth2;
	struct uip_tcp *tcp2;
	struct uip_buf *buf;
	struct uip_ip *ip2;

	info		= sk->info;

	/*
	 * Get free buffer to send data to guest
	 */
	buf		= uip_buf_get_free(info);

	/*
	 * Cook a ethernet frame
	 */
	tcp2		= (struct uip_tcp *)buf->eth;
	eth2		= (struct uip_eth *)buf->eth;
	ip2		= (struct uip_ip *)buf->eth;

	eth2->src	= info->host_mac;
	eth2->dst	= info->guest_mac;
	eth2->type	= htons(UIP_ETH_P_IP);

	ip2->vhl	= UIP_IP_VER_4 | UIP_IP_HDR_LEN;
	ip2->tos	= 0;
	ip2->id		= 0;
	ip2->flgfrag	= 0;
	ip2->ttl	= UIP_IP_TTL;
	ip2->proto	= UIP_IP_P_TCP;
	ip2->csum	= 0;
	ip2->sip	= sk->dip;
	ip2->dip	= sk->sip;

	tcp2->sport	= sk->dport;
	tcp2->dport	= sk->sport;
	tcp2->seq	= htonl(sk->seq_server);
	tcp2->ack	= htonl(sk->ack_server);
	/*
	 * Diable TCP options, tcp hdr len equals 20 bytes
	 */
	tcp2->off	= UIP_TCP_HDR_LEN;
	tcp2->flg	= flag;
	tcp2->win	= htons(UIP_TCP_WIN_SIZE);
	tcp2->csum	= 0;
	tcp2->urgent	= 0;

	if (payload_len > 0)
		memcpy(uip_tcp_payload(tcp2), sk->payload, payload_len);

	ip2->len	= htons(uip_tcp_hdrlen(tcp2) + payload_len + uip_ip_hdrlen(ip2));
	ip2->csum	= uip_csum_ip(ip2);
	tcp2->csum	= uip_csum_tcp(tcp2);

	/*
	 * virtio_net_hdr
	 */
	buf->vnet_len	= sizeof(struct virtio_net_hdr);
	memset(buf->vnet, 0, buf->vnet_len);

	buf->eth_len	= ntohs(ip2->len) + uip_eth_hdrlen(&ip2->eth);

	/*
	 * Increase server seq
	 */
	sk->seq_server  += payload_len;

	/*
	 * Send data received from socket to guest
	 */
	uip_buf_set_used(info, buf);

	return 0;
}