Fixed implementation of ChRoot
[tpg/acess2.git] / Modules / IPStack / link.c
1 /*
2  * Acess2 IP Stack
3  * - Link/Media Layer Interface
4  */
5 #include "ipstack.h"
6 #include "link.h"
7
8 // === CONSTANTS ===
9 #define MAX_PACKET_SIZE 2048
10
11 // === GLOBALS ===
12  int    giRegisteredTypes = 0;
13 struct {
14         Uint16  Type;
15         tPacketCallback Callback;
16 }       *gaRegisteredTypes;
17
18 // === CODE ===
19 /**
20  * \fn void Link_RegisterType(Uint16 Type, tPacketCallback Callback)
21  * \brief Registers a callback for a specific packet type
22  */
23 void Link_RegisterType(Uint16 Type, tPacketCallback Callback)
24 {
25          int    i;
26         void    *tmp;
27         for( i = giRegisteredTypes; i -- ; )
28         {
29                 if(gaRegisteredTypes[i].Type == Type) {
30                         Warning("[NET  ] Attempt to register 0x%x twice", Type);
31                         return ;
32                 }
33                 // Ooh! Free slot!
34                 if(gaRegisteredTypes[i].Callback == NULL)       break;
35         }
36         
37         if(i + 1 == 0)
38         {
39                 tmp = realloc(gaRegisteredTypes, (giRegisteredTypes+1)*sizeof(*gaRegisteredTypes));
40                 if(!tmp)        Panic("[NET  ] Out of heap space!");
41                 i = giRegisteredTypes;
42                 giRegisteredTypes ++;
43                 gaRegisteredTypes = tmp;
44         }
45         
46         gaRegisteredTypes[i].Callback = Callback;
47         gaRegisteredTypes[i].Type = Type;
48 }
49
50 /**
51  * \fn void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, int Length, void *Buffer)
52  * \brief Formats and sends a packet on the specified interface
53  */
54 void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, int Length, void *Buffer)
55 {
56          int    bufSize = sizeof(tEthernetHeader) + Length;
57         Uint8   buf[bufSize];
58         tEthernetHeader *hdr = (void*)buf;
59         
60         hdr->Dest = To;
61         hdr->Src = Adapter->MacAddr;
62         hdr->Type = htons(Type);
63         
64         memcpy(hdr->Data, Buffer, Length);
65         
66         VFS_Write(Adapter->DeviceFD, bufSize, buf);
67 }
68
69 /**
70  * \fn void Link_WatchDevice(tAdapter *Adapter)
71  * \brief Spawns a worker thread to watch the specified adapter
72  */
73 void Link_WatchDevice(tAdapter *Adapter)
74 {
75          int    tid = Proc_SpawnWorker();       // Create a new worker thread
76         
77         if(tid < 0) {
78                 Panic("[NET  ] Unable to create watcher thread for '%s'", Adapter->Device);
79         }
80         
81         if(tid > 0) {
82                 Log("[NET  ] Watching '%s' using tid %i", Adapter->Device, tid);
83                 return ;
84         }
85         
86         // Child Thread
87         while(Adapter->DeviceFD != -1)
88         {
89                 Uint8   buf[MAX_PACKET_SIZE];
90                 tEthernetHeader *hdr = (void*)buf;
91                  int    ret, i;
92                 
93                 // Wait for a packet
94                 ret = VFS_Read(Adapter->DeviceFD, MAX_PACKET_SIZE, buf);
95                 if(ret == -1)   break;
96                 
97                 if(ret <= sizeof(tEthernetHeader)) {
98                         Log("[NET  ] Recieved an undersized packet");
99                         continue;
100                 }
101                 
102                 // Check if there is a registered callback for this packet type
103                 for( i = giRegisteredTypes; i--; )
104                 {
105                         if(gaRegisteredTypes[i].Type == hdr->Type)      continue;
106                 }
107                 // No? Ignore it
108                 if( i + 1 == 0 )        continue;
109                 
110                 // Call the callback
111                 gaRegisteredTypes[i].Callback(
112                         Adapter,
113                         hdr->Src,
114                         ret - sizeof(tEthernetHeader),
115                         hdr->Data
116                         );
117         }
118 }

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