FreeNOS
NetworkClient.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015 Niek Linnenbank
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <Log.h>
19#include <String.h>
20#include <FileSystemClient.h>
21#include <FileDescriptor.h>
22#include "NetworkClient.h"
23#include "ARP.h"
24#include "ARPSocket.h"
25
26NetworkClient::NetworkClient(const char *networkDevice)
27{
28 m_deviceName = networkDevice;
29}
30
34
36{
37 const FileSystemClient filesystem;
38 Size numberOfMounts = 0;
39
40 // Get a list of mounts
41 const FileSystemMount *mounts = filesystem.getFileSystems(numberOfMounts);
42 const FileSystemMount *match = 0;
43 Size matchLen = 0;
44
45 // Find closest matching device
46 for (Size i = 0; i < numberOfMounts; i++)
47 {
48 const String mountPath(mounts[i].path);
49
50 if (mountPath.length() > 0 && mountPath.compareTo("/network/", true, 9) == 0)
51 {
52 Size len = 0;
53
54 for (Size j = 0; mounts[i].path[j+9] && m_deviceName[j]; j++, len++)
55 {
56 if (mounts[i].path[j+9] != m_deviceName[j])
57 {
58 len = 0;
59 break;
60 }
61 }
62 if (len >= matchLen)
63 {
64 match = &mounts[i];
65 matchLen = len;
66 }
67 }
68 }
69
70 if (!match)
71 {
72 ERROR("network device not found: " << *m_deviceName);
73 return IOError;
74 }
75
76 m_deviceName = match->path;
77 return Success;
78}
79
81 int *sock)
82{
83 const FileSystemClient fs;
84 String path = m_deviceName;
85
86 switch (type)
87 {
88 case ARP:
89 path << "/arp/socket";
90 break;
91
92 case ICMP:
93 path << "/icmp/factory";
94 break;
95
96 case UDP:
97 path << "/udp/factory";
98 break;
99
100 default:
101 return NotFound;
102 }
103
104 const FileSystem::Result result = fs.openFile(*path, *(Size *) sock);
105 if (result != FileSystem::Success)
106 {
107 ERROR("failed to open socket factory at " << *path <<
108 ": result = " << (int) result);
109 return IOError;
110 }
111
112 return Success;
113}
114
116 const IPV4::Address addr,
117 const u16 port)
118{
119 DEBUG("");
120 return writeSocketInfo(sock, addr, port, Connect);
121}
122
124 const IPV4::Address addr,
125 const u16 port)
126{
127 DEBUG("");
128 return writeSocketInfo(sock, addr, port, Listen);
129}
130
132 const int sock,
133 const Size msecTimeout)
134{
135 const FileSystemClient fs;
136
137 DEBUG("type = " << (int) type << " sock = " << sock);
138
140 {
141 ERROR("protocol not supported: " << (int) type);
143 }
144
145 // Get file descriptor of the socket
147 if (!fd || !fd->open)
148 {
149 ERROR("failed to get FileDescriptor for socket " << sock << ": " << (fd ? "closed" : "not found"));
151 }
152
153 // Prepare a wait set
154 FileSystem::WaitSet waitSet;
155 waitSet.inode = fd->inode;
157 waitSet.current = 0;
158
159 // Wait until the file is readable (has data)
160 const FileSystem::Result waitResult = fs.waitFile(*m_deviceName, &waitSet, 1, msecTimeout);
161 if (waitResult != FileSystem::Success)
162 {
163 if (waitResult == FileSystem::TimedOut)
164 {
165 DEBUG("operation timed out");
166 return TimedOut;
167 }
168 else
169 {
170 ERROR("failed to wait for socket " << sock << " with inode " <<
171 waitSet.inode << ": result = " << (int) waitResult);
172 return IOError;
173 }
174 }
175
176 // File is ready for reading
177 return Success;
178}
179
181 const IPV4::Address addr,
182 const u16 port,
183 const NetworkClient::SocketAction action)
184{
186 char buf[64];
187 Size sz = sizeof(buf);
188
189 DEBUG("");
190
191 // Get file descriptor of the socket
193 if (!fd || !fd->open)
194 {
196 }
197
198 // Read socket factory. The factory will create
199 // a new socket for us. We need to read the new file path
200 const FileSystem::Result readResult = fs.readFile(sock, buf, &sz);
201 if (readResult != FileSystem::Success)
202 {
203 ERROR("failed to read from socket " << sock <<
204 ": result = " << (int) readResult);
205 return IOError;
206 }
207
208 // Update the file descriptor inode and PID
210 const FileSystem::Result statResult = fs.statFile(buf, &st);
211 if (statResult != FileSystem::Success)
212 {
213 ERROR("failed to stat socket at path " << buf << ": result = " << (int) statResult);
214 return IOError;
215 }
216
217 fd->inode = st.inode;
218 fd->pid = st.pid;
219
220 // Write address+port+action info to the socket
221 SocketInfo info;
222 info.address = addr;
223 info.port = port;
224 info.action = action;
225 sz = sizeof(info);
226
227 const FileSystem::Result writeResult = fs.writeFile(sock, &info, &sz);
228 if (writeResult != FileSystem::Success)
229 {
230 ERROR("failed to write info to socket " << sock <<
231 ": result = " << (int) writeResult);
232 return IOError;
233 }
234
235 // Done
236 return Success;
237}
238
240{
241 const FileSystemClient fs;
242
243 const FileSystem::Result result = fs.closeFile(sock);
244 if (result != FileSystem::Success)
245 {
246 ERROR("failed to close socket " << sock << ": result = " << (int) result);
247 return IOError;
248 }
249
250 return Success;
251}
u8 type
Definition IntelACPI.h:0
Entry * getEntry(const Size index)
Retrieve a file descriptor Entry.
FileSystemClient provides a simple interface to a FileSystemServer.
FileSystem::Result closeFile(const Size descriptor) const
Close a file.
FileSystem::Result writeFile(const Size descriptor, const void *buf, Size *size) const
Write a file.
FileSystem::Result waitFile(const char *filesystemPath, const FileSystem::WaitSet *waitSet, const Size count, const Size msecTimeout) const
Wait for one or more files to become readable/writable.
FileSystem::Result statFile(const char *path, FileSystem::FileStat *st) const
Retrieve status of a file.
FileSystem::Result readFile(const Size descriptor, void *buf, Size *size) const
Read a file.
FileSystem::Result openFile(const char *path, Size &descriptor) const
Open a file.
FileSystemMount * getFileSystems(Size &numberOfMounts) const
Get file system mounts table.
u32 Address
IP-address.
Definition IPV4.h:47
String m_deviceName
Network device name.
Result bindSocket(const int sock, const IPV4::Address addr=0, const u16 port=0)
Bind socket to address/port.
Result close(const int sock)
Close the socket.
Result writeSocketInfo(const int sock, const IPV4::Address addr, const u16 port, const SocketAction action)
Set socket to new state.
SocketType
Socket types.
NetworkClient(const char *networkDevice)
Constructor.
virtual ~NetworkClient()
Destructor.
Result initialize()
Perform initialization.
Result waitSocket(const NetworkClient::SocketType type, const int sock, const Size msecTimeout)
Wait until the given socket has data to receive.
SocketAction
Socket actions.
Result
Result codes.
Result connectSocket(const int sock, const IPV4::Address addr, const u16 port=0)
Connect socket to address/port.
Result createSocket(const SocketType type, int *socket)
Create new socket.
static FileDescriptor * instance()
Retrieve the instance.
Definition Singleton.h:53
Abstraction of strings.
Definition String.h:42
Size length() const
Same as count().
Definition String.cpp:105
virtual int compareTo(const String &str) const
Compares this String to the given String.
Definition String.cpp:231
#define ERROR(msg)
Output an error message.
Definition Log.h:61
unsigned short u16
Unsigned 16-bit number.
Definition Types.h:56
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128
#define DEBUG(msg)
Output a debug message to standard output.
Definition Log.h:89
Result
Result code for filesystem Actions.
Definition FileSystem.h:53
Describes a single file opened by a user process.
ProcessID pid
< Inode number of the file
bool open
< Current position indicator.
Represents a mounted filesystem.
char path[FileSystemPath::MaximumLength]
Path of the mount.
Contains file information.
Definition FileSystem.h:114
ProcessID pid
< Inode number
Definition FileSystem.h:117
u32 inode
< File type.
Definition FileSystem.h:116
Provides information about an inode.
Definition FileSystem.h:128
u16 current
< Requested status flags of the inode
Definition FileSystem.h:131
u16 requested
< Inode number
Definition FileSystem.h:130
Socket information.