Multi-user testing and bugfixing
[tpg/acess2.git] / Modules / IPStack / icmp.c
1 /*
2  * Acess2 IP Stack
3  * - ICMP Handling
4  */
5 #include "ipstack.h"
6 #include "ipv4.h"
7 #include "icmp.h"
8
9 // === CONSTANTS ===
10 #define PING_SLOTS      64
11
12 // === PROTOTYPES ===
13 void    ICMP_Initialise();
14 void    ICMP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer);
15
16 // === GLOBALS ===
17 struct {
18         tInterface      *Interface;
19          int    bArrived;
20 }       gICMP_PingSlots[PING_SLOTS];
21
22 // === CODE ===
23 /**
24  * \fn void ICMP_Initialise()
25  * \brief Initialise the ICMP Layer
26  */
27 void ICMP_Initialise()
28 {
29         IPv4_RegisterCallback(IP4PROT_ICMP, ICMP_GetPacket);
30 }
31
32 /**
33  * \fn void ICMP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer)
34  * \brief Handles a packet from the IP Layer
35  */
36 void ICMP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer)
37 {
38         tICMPHeader     *hdr = Buffer;
39         
40         Log("[ICMP ] hdr->Type = %i", hdr->Type);
41         Log("[ICMP ] hdr->Code = %i", hdr->Code);
42         Log("[ICMP ] hdr->Checksum = 0x%x", ntohs(hdr->Checksum));
43         Log("[ICMP ] hdr->ID = 0x%x", ntohs(hdr->ID));
44         Log("[ICMP ] hdr->Sequence = 0x%x", ntohs(hdr->Sequence));
45         
46         switch(hdr->Type)
47         {
48         case ICMP_ECHOREPLY:
49                 if(hdr->Code != 0) {
50                         Warning("[ICMP ] Code == %i for ICMP Echo Reply, should be 0", hdr->Code);
51                         return ;
52                 }
53                 if(hdr->ID != ~hdr->Sequence) {
54                         Warning("[ICMP ] ID and Sequence values do not match");
55                         return ;
56                 }
57                 gICMP_PingSlots[hdr->ID].bArrived = 1;
58                 break;
59         }
60         
61 }
62
63 /**
64  * \brief Sends ICMP Echo and waits for the reply
65  * \note Times out after \a Interface->TimeoutDelay has elapsed
66  */
67 int ICMP_Ping(tInterface *Interface, tIPv4 Addr)
68 {
69         //Sint64        ts;
70         char    buf[32] = "\x8\0\0\0\0\0\0\0Acess2 I"
71                       "P/TCP Stack 1.0\0";
72         tICMPHeader     *hdr = (void*)buf;
73          int    i;
74         
75         for(;;)
76         {
77                 for(i=0;i<PING_SLOTS;i++)
78                 {
79                         if(gICMP_PingSlots[i].Interface == NULL)        break;
80                 }
81                 if(gICMP_PingSlots[i].Interface == NULL)        break;
82                 Threads_Yield();
83         }
84         gICMP_PingSlots[i].Interface = Interface;
85         gICMP_PingSlots[i].bArrived = 0;
86         hdr->ID = i;
87         hdr->Sequence = ~i;
88         hdr->Checksum = htons( IPv4_Checksum(hdr, sizeof(buf)) );
89         IPv4_SendPacket(Interface, Addr, 1, i, 32, buf);
90         
91         return -1;
92 }

UCC git Repository :: git.ucc.asn.au