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); }
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; }