Ejemplo n.º 1
0
status_t
ipv6_send_routed_data(net_protocol* _protocol, struct net_route* route,
	net_buffer* buffer)
{
	if (route == NULL)
		return B_BAD_VALUE;

	ipv6_protocol* protocol = (ipv6_protocol*)_protocol;
	net_interface* interface = route->interface_address->interface;
	uint8 protocolNumber;
	if (protocol != NULL && protocol->socket != NULL)
		protocolNumber = protocol->socket->protocol;
	else
		protocolNumber = buffer->protocol;

	TRACE_SK(protocol, "SendRoutedData(%p, %p [%ld bytes])", route, buffer,
		buffer->size);

	sockaddr_in6& source = *(sockaddr_in6*)buffer->source;
	sockaddr_in6& destination = *(sockaddr_in6*)buffer->destination;

	buffer->flags &= ~(MSG_BCAST | MSG_MCAST);

	if (IN6_IS_ADDR_UNSPECIFIED(&destination.sin6_addr))
		return EDESTADDRREQ;

	if (IN6_IS_ADDR_MULTICAST(&destination.sin6_addr))
		buffer->flags |= MSG_MCAST;

	uint16 dataLength = buffer->size;

	// Add IPv6 header

	NetBufferPrepend<ip6_hdr> header(buffer);
	if (header.Status() != B_OK)
		return header.Status();

	if (buffer->size > 0xffff)
		return EMSGSIZE;

	uint32 flowinfo = 0;
		// TODO: fill in the flow id from somewhere
	if (protocol) {
		// fill in traffic class
		flowinfo |= htonl(protocol->service_type << 20);
	}
	// set lower 28 bits
	header->ip6_flow = htonl(flowinfo) & IPV6_FLOWINFO_MASK;
	// set upper 4 bits
	header->ip6_vfc |= IPV6_VERSION;
	header->ip6_plen = htons(dataLength);
	header->ip6_nxt = protocolNumber;
	header->ip6_hlim = ip6_select_hoplimit(protocol, buffer);
	memcpy(&header->ip6_src, &source.sin6_addr, sizeof(in6_addr));
	memcpy(&header->ip6_dst, &destination.sin6_addr, sizeof(in6_addr));

	header.Sync();

	// write the checksum for ICMPv6 sockets
	if (protocolNumber == IPPROTO_ICMPV6
		&& dataLength >= sizeof(struct icmp6_hdr)) {
		NetBufferField<uint16, sizeof(ip6_hdr)
			+ offsetof(icmp6_hdr, icmp6_cksum)>
			icmpChecksum(buffer);
		// first make sure the existing checksum is zero
		*icmpChecksum = 0;
		icmpChecksum.Sync();

		uint16 checksum = gBufferModule->checksum(buffer, sizeof(ip6_hdr),
			buffer->size - sizeof(ip6_hdr), false);
		checksum = ipv6_checksum(&header->ip6_src,
			&header->ip6_dst, dataLength, protocolNumber,
			checksum);
		*icmpChecksum = checksum;
	}

	char addrbuf[INET6_ADDRSTRLEN];
	ip6_sprintf(&destination.sin6_addr, addrbuf);
	TRACE_SK(protocol, "  SendRoutedData(): destination: %s", addrbuf);

	uint32 mtu = route->mtu ? route->mtu : interface->mtu;
	if (buffer->size > mtu) {
		// we need to fragment the packet
		return send_fragments(protocol, route, buffer, mtu);
	}

	return sDatalinkModule->send_routed_data(route, buffer);
}
Ejemplo n.º 2
0
u_char *modify_packet(u_char *pkt_ptr,int pkt_type, int len,uint8_t* ether_src, uint8_t* ether_dst)
{   
	//printf("inside modify packet\n");
    u_char *timeExceedePacket =(char *)malloc(sizeof(char)*(70));
    memset(timeExceedePacket,0,70); 
    customIcmp *myicmp= (struct customIcmp *)malloc(sizeof(struct customIcmp));
    memset(myicmp,0,36);
    struct ether_header *eth_hdr = (struct ether_header *)pkt_ptr;     //Pointer to ethernet
    struct ip *ip_hdr = (struct ip *)(pkt_ptr + ETHERNET_HEADER_LEN); //point to an IP header structure

    int i = 0;
	for(i=0;i<6;i++){
        eth_hdr->ether_shost[i] = ether_src[i];
        eth_hdr->ether_dhost[i] = ether_dst[i];
	}
    if(pkt_type==1){
        //change the src ip and dst ipaddr
        struct in_addr inp;
        inp=ip_hdr->ip_src;
        ip_hdr->ip_src=ip_hdr->ip_dst;
        ip_hdr->ip_dst=inp;
        printf("Changing icmp Header\n");
        struct icmphdr *icmp_hdr = (struct icmphdr *)(pkt_ptr+14+20);
        icmp_hdr->type=0;
        icmp_hdr->code=0;
        icmp_hdr->checksum=0; 
        unsigned short csumicmp= htons(icmpChecksum((unsigned short *)icmp_hdr,len));
        icmp_hdr->checksum=htons(csumicmp);
    }
    if(pkt_type==2){
        //change the src ip and dst ipaddr
        memcpy(timeExceedePacket,(char*)eth_hdr,14);
        memcpy(myicmp->data,ip_hdr,28);
        struct in_addr inp;
        inp=ip_hdr->ip_src;
	ARP_table *tmp_arp_table = arp_head;
        while(tmp_arp_table){
			if((tmp_arp_table->interface_mac_addr[0] == ether_src[0]) && (tmp_arp_table->interface_mac_addr[1] == ether_src[1]) && (tmp_arp_table->interface_mac_addr[2] == ether_src[2]) && (tmp_arp_table->interface_mac_addr[3] == ether_src[3]) && (tmp_arp_table->interface_mac_addr[4] == ether_src[4]) && (tmp_arp_table->interface_mac_addr[5] == ether_src[5]) ){
				ip_hdr->ip_src = tmp_arp_table->interface_ip;
				break;
			}
		}
        ip_hdr->ip_dst=inp;
        ip_hdr->ip_p=1;
        ip_hdr->ip_len=htons(56);
        printf("Changing icmp Header for type 2\n");
        myicmp->type=11;  
        myicmp->code=0;
        myicmp->checksum=0; 
        unsigned short csumicmp= htons(icmpChecksum((unsigned short *)myicmp,36));
        myicmp->checksum=htons(csumicmp);
        memcpy(timeExceedePacket+14+20,(char *)myicmp,36); //copy whole new icmp
    }
    if(pkt_type==3){
        memcpy(timeExceedePacket,(char*)eth_hdr,14);
        memcpy(myicmp->data,ip_hdr,28);
        struct in_addr inp;
        inp=ip_hdr->ip_src;
	ARP_table *tmp_arp_table = arp_head;
        while(tmp_arp_table){
			if((tmp_arp_table->interface_mac_addr[0] == ether_src[0]) && (tmp_arp_table->interface_mac_addr[1] == ether_src[1]) && (tmp_arp_table->interface_mac_addr[2] == ether_src[2]) && (tmp_arp_table->interface_mac_addr[3] == ether_src[3]) && (tmp_arp_table->interface_mac_addr[4] == ether_src[4]) && (tmp_arp_table->interface_mac_addr[5] == ether_src[5]) ){
				ip_hdr->ip_src = tmp_arp_table->interface_ip;
				break;
			}
		}
        ip_hdr->ip_dst=inp;
        ip_hdr->ip_p=1;
        ip_hdr->ip_len=htons(56);
        printf("Changing icmp Header for type 3\n");
        myicmp->type=3;  
        myicmp->code=1;
        myicmp->checksum=0; 
        unsigned short csumicmp= htons(icmpChecksum((unsigned short *)myicmp,36));
        myicmp->checksum=htons(csumicmp);
        memcpy(timeExceedePacket+14+20,(char *)myicmp,36); //copy whole new icmp
    }
     if(pkt_type==4){
        memcpy(timeExceedePacket,(char*)eth_hdr,14);
        memcpy(myicmp->data,ip_hdr,28);
        struct in_addr inp;
        inp=ip_hdr->ip_src;
		ip_hdr->ip_src = ip_hdr->ip_dst; 
        ip_hdr->ip_dst=inp;
        ip_hdr->ip_p=1;
        ip_hdr->ip_len=htons(56);
        printf("Changing icmp Header for type 4\n");
        myicmp->type=3;  
        myicmp->code=3;
        myicmp->checksum=0; 
        unsigned short csumicmp= htons(icmpChecksum((unsigned short *)myicmp,36));
        myicmp->checksum=htons(csumicmp);
        memcpy(timeExceedePacket+14+20,(char *)myicmp,36); //copy whole new icmp
    }

	//Change the ttl and checksum
    ip_hdr->ip_ttl-=1;
    if(ip_hdr->ip_ttl==0){
        ip_hdr->ip_ttl=64;
    }
    ip_hdr->ip_sum = (htons)(ip_checksum(ip_hdr));
    if(pkt_type == 2  || pkt_type == 3 || pkt_type == 4){
        memcpy(timeExceedePacket+14,ip_hdr,20);
        return timeExceedePacket;
    }
    //printf("end of modify packet\n");
    return pkt_ptr;
}