summaryrefslogtreecommitdiff
path: root/net/icmp.c
blob: 54dc67b37c2c193507e460b17e6a920a9bc4623c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "inet.h"
#include "icmp.h"
#include "ipv4.h"
#include "log.h"

#include "lib/string/string.h"

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=htons(checksum(data,ipv4->len-ipv4->ihl*4));
    ipv4->csum=htons(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,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;
}