Kernel/VTerm - "Fix" wrapping issue in VTerm (why was old behavior there?)
[tpg/acess2.git] / AcessNative / acesskernel_src / net.c
1 /*
2  * Acess2 Native Kernel
3  * - Acess kernel emulation on another OS using SDL and UDP
4  *
5  * net.c
6  * - Networking
7  */
8 #define DEBUG   0
9 #include <acess.h>
10 #include <vfs.h>
11 #include <fs_devfs.h>
12 #include "net_wrap.h"
13
14 // === PROTOTYPES ===
15  int    Net_Install(char **Arguments);
16 tVFS_Node       *Net_Root_FindDir(tVFS_Node *Node, const char *Name, Uint Flags);
17 tVFS_Node       *Net_IFace_FindDir(tVFS_Node *Node, const char *Name, Uint Flags);
18 tVFS_Node       *Net_Routes_FindDir(tVFS_Node *Node, const char *Name, Uint Flags);
19
20 tVFS_Node       *Net_TCPC_Open(int AddrType);
21 size_t  Net_TCPC_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags);
22 size_t  Net_TCPC_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags);
23  int    Net_TCPC_IOCtl(tVFS_Node *Node, int IOCtl, void *Arg);
24 void    Net_TCPC_Close(tVFS_Node *Node);
25
26 static size_t   _getaddrsize(int type);
27
28 // === GLOBALS ===
29 tVFS_NodeType   gNet_NT_Root = {
30         .FindDir = Net_Root_FindDir,
31 };
32 tVFS_NodeType   gNet_NT_IFace = {
33         .FindDir = Net_IFace_FindDir,
34 };
35 tVFS_NodeType   gNet_NT_Routes = {
36         .FindDir = Net_Routes_FindDir,
37 };
38 tVFS_NodeType   gNet_NT_TcpC = {
39         .Read = Net_TCPC_Read,
40         .Write = Net_TCPC_Write,
41         .IOCtl = Net_TCPC_IOCtl,
42         .Close = Net_TCPC_Close,
43 };
44
45 tDevFS_Driver   gNet_DevInfo = {
46         .Name = "ip",
47         .RootNode = {
48                 .Type = &gNet_NT_Root,
49                 .Flags = VFS_FFLAG_DIRECTORY,
50         }
51 };
52 tVFS_Node       gNet_Node_IFace4 = {
53         .Type = &gNet_NT_IFace,
54         .Flags = VFS_FFLAG_DIRECTORY,
55         .ImplInt = 4,
56 };
57 tVFS_Node       gNet_Node_Routes = {
58         .Type = &gNet_NT_Routes,
59         .Flags = VFS_FFLAG_DIRECTORY,
60 };
61
62 // === CODE ===
63 int Net_Install(char **Arguments)
64 {
65         DevFS_AddDevice(&gNet_DevInfo);
66         Net_Wrap_Init();
67         return 0;
68 }
69
70 tVFS_Node *Net_Root_FindDir(tVFS_Node *Node, const char *Name, Uint Flags)
71 {
72         if( strcmp(Name, "routes") == 0 )
73                 return &gNet_Node_Routes;
74         else if( strcmp(Name, "any4") == 0 )
75                 return &gNet_Node_IFace4;
76         else
77                 return NULL;
78 }
79
80 tVFS_Node *Net_IFace_FindDir(tVFS_Node *Node, const char *Name, Uint Flags)
81 {
82         if( strcmp(Name, "tcpc") == 0 )
83                 return Net_TCPC_Open(Node->ImplInt);
84         else
85                 return NULL;
86 }
87
88 tVFS_Node *Net_Routes_FindDir(tVFS_Node *Node, const char *Name, Uint Flags)
89 {
90         if( Name[0] == '@' ) {
91                 switch( Name[1] )
92                 {
93                 case '4':       return &gNet_Node_IFace4;
94                 default:        return NULL;
95                 }
96         }
97         else
98                 return NULL;
99 }
100
101 typedef struct
102 {
103          int    AddrType;
104         tVFS_Node       Node;
105         short   SrcPort;
106         short   DstPort;
107         void    *DestAddr;
108 } tNet_TCPC;
109
110 tVFS_Node *Net_TCPC_Open(int AddrType)
111 {
112         tNet_TCPC       *ret = calloc(sizeof(tNet_TCPC) + _getaddrsize(AddrType), 1);
113
114         ret->AddrType = AddrType;
115         ret->Node.ImplPtr = ret;
116         ret->Node.Type = &gNet_NT_TcpC;
117         ret->DestAddr = ret + 1;
118
119         return &ret->Node;
120 }
121
122 size_t Net_TCPC_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags)
123 {
124         return Net_Wrap_ReadSocket(Node->Data, Length, Buffer);
125 }
126
127 size_t Net_TCPC_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags)
128 {
129         return Net_Wrap_WriteSocket(Node->Data, Length, Buffer);
130 }
131
132 int Net_TCPC_IOCtl(tVFS_Node *Node, int IOCtl, void *Data)
133 {
134         tNet_TCPC       *tcpc = Node->ImplPtr;
135         switch(IOCtl)
136         {
137         case 4:
138                 if(!Data)
139                         return tcpc->SrcPort;
140                 if(Node->Data)  // Connection is open
141                         return -1;
142                 // TODO: Checkmem
143                 tcpc->SrcPort = *(Uint16*)Data;
144                 return tcpc->SrcPort;
145         case 5:
146                 if(!Data)       return tcpc->DstPort;
147                 if(Node->Data)  return -1;      // Connection open
148                 // TODO: Checkmem
149                 tcpc->DstPort = *(Uint16*)Data;
150                 return tcpc->DstPort;
151         case 6:
152                 if(Node->Data)  return -1;      // Connection open
153                 memcpy(tcpc->DestAddr, Data, _getaddrsize(tcpc->AddrType));
154                 return 0;
155         case 7: // Connect
156                 Node->Data = Net_Wrap_ConnectTcp(Node, tcpc->SrcPort, tcpc->DstPort,
157                         tcpc->AddrType, tcpc->DestAddr);
158                 return (Node->Data != NULL);
159         case 8:
160                 Debug("TODO: TCPC rx buffer length");
161                 return -1;
162         default:
163                 return -1;
164         }
165 }
166
167 void Net_TCPC_Close(tVFS_Node *Node)
168 {
169         tNet_TCPC *tcpc = Node->ImplPtr;
170         Node->ReferenceCount --;
171         if( Node->ReferenceCount == 0 )
172         {
173                 Net_Wrap_CloseSocket(Node->Data);
174                 free(tcpc);
175         }
176 }
177
178
179 static size_t _getaddrsize(int type)
180 {
181         switch(type)
182         {
183         case 4: return 4;
184         case 6: return 16;
185         default:        return 0;
186         }
187 }
188

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