#include "net_sys.h" #include "inet.h" #include "icmp.h" #include "ipv4.h" uint32_t icmp_generic(struct netdev *dev, uint32_t ip, uint8_t type, uint8_t* pos,uint8_t *end) { pos-=4; //we need 32 bytes struct icmp_v4 *icmp=pos; icmp->type=type; icmp->code=0; icmp->csum=0; icmp->csum=checksum(icmp,end-pos); return ipv4_generic(dev,ip,IPV4_P_ICMP,pos,end); } uint32_t icmp_ping(struct netdev *dev, uint32_t ip, uint16_t* pos,uint32_t *end) { // payload for(int i=0;i<64;i++) { pos--; *pos=0xbeef; } // id and sequence number pos-=2; // we need 32 bytes struct icmp_v4_echo *ping=pos; ping->id=htons(0xabcd); // some random number ping->seq=htons(0); // we just send one single ping with id 1 for now return icmp_generic(dev,ip,ICMP_ECHO_REQUEST,pos,end); } bool icmp_reply(struct netdev *dev,struct eth_hdr *hdr) { unsigned char tmp[6]; memcpy(tmp,hdr->dmac,6); memcpy(hdr->dmac,hdr->smac,6); memcpy(hdr->smac,tmp,6); struct ipv4_hdr *ipv4=hdr->payload; uint32_t tmp2; tmp2=ipv4->saddr; ipv4->saddr=ipv4->daddr; ipv4->daddr=tmp2; uint32_t daddr; // destination ip address struct icmp_v4 *data=(uint32_t *)ipv4+ipv4->ihl; data->type=ICMP_ECHO_REPLY; data->csum=0; ipv4->csum=0; data->csum=(checksum(data,ntohs(ipv4->len)-ipv4->ihl*4)); ipv4->csum=(checksum(ipv4,ntohs(ipv4->len))); dev->transmit(hdr,ntohs(ipv4->len)+14); // 14bytes for link2 return true; } bool icmp_incoming(struct netdev *dev,struct eth_hdr *hdr) { struct ipv4_hdr *ipv4=hdr->payload; struct icmp_v4 *data=(uint32_t *)ipv4+ipv4->ihl; // klog ("icmp type=%d",data->type); // klog ("icmp code=%d",data->code); // klog ("icmp csum=0x%04x",ntohs(data->csum)); data->csum=0; // klog("expected checksum = 0x%04X",checksum(data,ntohs(ipv4->len)-ipv4->ihl*4)); if(data->type==ICMP_ECHO_REQUEST) // echo request { struct icmp_v4_echo *echo=data->data; //klog ("received echo request id=%d, seq=%d, data=%d ",ntohs(echo->id),ntohs(echo->seq),echo->data); icmp_reply(dev,hdr); /// TODO watchout that this is the memory managed by the network card we are dealing with!!. fix this later. } return true; }