Esempio n. 1
0
static void process_udp(char *data)
{
    struct proc_node *ipp = udp_procs;
    struct ip *iph = (struct ip *) data;
    struct udphdr *udph;
    struct tuple4 addr;
    int hlen = iph->ip_hl << 2;
    int len = ntohs(iph->ip_len);
    int ulen;
    if (len - hlen < (int)sizeof(struct udphdr))
	return;
    udph = (struct udphdr *) (data + hlen);
    ulen = ntohs(udph->UH_ULEN);
    if (len - hlen < ulen || ulen < (int)sizeof(struct udphdr))
	return;
    if (my_udp_check
	((void *) udph, ulen, iph->ip_src.s_addr,
	 iph->ip_dst.s_addr)) return;
    addr.source = ntohs(udph->UH_SPORT);
    addr.dest = ntohs(udph->UH_DPORT);
    addr.saddr = iph->ip_src.s_addr;
    addr.daddr = iph->ip_dst.s_addr;
    while (ipp) {
	ipp->item(&addr, ((char *) udph) + sizeof(struct udphdr),
		  ulen - sizeof(struct udphdr), data);
	ipp = ipp->next;
    }
}
Esempio n. 2
0
static void process_udp(char *data, struct timeval* ts)
{
    struct proc_node *ipp = udp_procs;
    struct ip *iph = (struct ip *) data;
    struct udphdr *udph;
    struct tuple4 addr;
    int hlen = iph->ip_hl << 2;
    int len = ntohs(iph->ip_len);
    int ulen;
    if (len - hlen < (int)sizeof(struct udphdr))
	return;
    udph = (struct udphdr *) (data + hlen);
    ulen = ntohs(udph->UH_ULEN);
    if (len - hlen < ulen || ulen < (int)sizeof(struct udphdr))
	return;
    /* According to RFC768 a checksum of 0 is not an error (Sebastien Raveau) */
    if (udph->uh_sum && my_udp_check
	((void *) udph, ulen, iph->ip_src.s_addr,
	 iph->ip_dst.s_addr)) return;
    addr.source = ntohs(udph->UH_SPORT);
    addr.dest = ntohs(udph->UH_DPORT);
    addr.saddr = iph->ip_src.s_addr;
    addr.daddr = iph->ip_dst.s_addr;
    while (ipp) {
	ipp->item(&addr, ((char *) udph) + sizeof(struct udphdr),
		  ulen - sizeof(struct udphdr), data);
	ipp = ipp->next;
    }
}
Esempio n. 3
0
int form_syn_response(char *data, int len)
{
	struct ethhdr *ethh;
	struct iphdr *iph;
	struct udphdr *udph;
	struct tcphdr *tcph;
	uint8_t proto_in_ip = 0;
	uint16_t checksum;
	char tmp[6];
	char *payload_ptr;
	int payload_len;

	ethh = (struct ethhdr *)data;

	// FIXME: dest address of the server/client
	memcpy(tmp, ethh->h_dest, 6);
	memcpy(ethh->h_dest, ethh->h_source, 6);
	memcpy(ethh->h_source, tmp, 6);

	/* IP layer */
	switch (ntohs(ethh->h_proto)) {
	case ETH_P_IP:
		iph = (struct iphdr *)(ethh + 1);
		proto_in_ip = iph->protocol;
		udph = (struct udphdr *)((uint32_t *)iph + iph->ihl);
		tcph = (struct tcphdr *)((uint32_t *)iph + iph->ihl);

		uint32_t tmp = iph->saddr;
		iph->saddr = iph->daddr;
		iph->daddr = tmp;

		/* Do checksum */
		iph->check = 0;
		checksum = ip_fast_csum((unsigned char *)iph, iph->ihl);
		iph->check = ~checksum;
		break;
	default:
		fprint(ERROR, "protocol %04hx  ", ntohs(ethh->h_proto));
		goto done;
	}

	/* Transport layer */
	switch (proto_in_ip) {
	case IPPROTO_TCP:
		payload_ptr = (char *)tcph + tcph->doff * 4;
		payload_len = len - (payload_ptr - data);

		/* TODO: there will be a mapping between sequence
			number of p-c and s-p connection, the sequence difference
			will be stored in the TCB, and code should be added, but not here
		*/ 
		tcph->ack_seq = htonl(ntohl(tcph->seq) + 1);
		tcph->seq = 0;
		uint16_t tmp_port = tcph->source;
		tcph->source = tcph->dest;
		tcph->dest = tmp_port;
		tcph->ack = 1;

		tcph->check = 0;
		checksum = my_tcp_check((void *)tcph, len - ((char *)tcph - data),
			iph->saddr, iph->daddr);
		tcph->check = ~checksum;
		break;
	case IPPROTO_UDP:
		fprint(ERROR, "a udp packet?\n");
		payload_ptr = (char *)udph + 8;
		payload_len = len - (payload_ptr - data);

		udph->check = 0;
		checksum = my_udp_check((void *)udph, ntohs(udph->len),
			iph->saddr, iph->daddr);
		udph->check = ~checksum;
		break;
	default:
		fprint(ERROR, "protocol %d\n", proto_in_ip);
		break;
	}

done:
	return 0;
}