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 
26 NetworkClient::NetworkClient(const char *networkDevice)
27 {
28  m_deviceName = networkDevice;
29 }
30 
32 {
33 }
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 
139  if (type != NetworkClient::UDP)
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 {
185  FileSystemClient fs;
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 }
NetworkClient::m_deviceName
String m_deviceName
Network device name.
Definition: NetworkClient.h:201
NetworkClient::Result
Result
Result codes.
Definition: NetworkClient.h:99
NetworkClient::Success
@ Success
Definition: NetworkClient.h:101
NetworkClient::SocketAction
SocketAction
Socket actions.
Definition: NetworkClient.h:51
NetworkClient::Connect
@ Connect
Definition: NetworkClient.h:53
NetworkClient::TimedOut
@ TimedOut
Definition: NetworkClient.h:105
StrictSingleton< FileDescriptor >::instance
static FileDescriptor * instance()
Retrieve the instance.
Definition: Singleton.h:53
NetworkClient::initialize
Result initialize()
Perform initialization.
Definition: NetworkClient.cpp:35
NetworkClient::createSocket
Result createSocket(const SocketType type, int *socket)
Create new socket.
Definition: NetworkClient.cpp:80
String::length
Size length() const
Same as count().
Definition: String.cpp:105
NetworkClient::close
Result close(const int sock)
Close the socket.
Definition: NetworkClient.cpp:239
NetworkClient::NotFound
@ NotFound
Definition: NetworkClient.h:103
NetworkClient::SocketInfo::address
IPV4::Address address
Definition: NetworkClient.h:67
FileSystemMount
Represents a mounted filesystem.
Definition: FileSystemMount.h:35
FileSystemClient::statFile
FileSystem::Result statFile(const char *path, FileSystem::FileStat *st) const
Retrieve status of a file.
Definition: FileSystemClient.cpp:186
String
Abstraction of strings.
Definition: String.h:41
FileSystemClient
FileSystemClient provides a simple interface to a FileSystemServer.
Definition: FileSystemClient.h:42
FileDescriptor::Entry::open
bool open
< Current position indicator.
Definition: FileDescriptor.h:51
FileSystem::WaitSet
Provides information about an inode.
Definition: FileSystem.h:127
FileSystem::FileStat::inode
u32 inode
< File type.
Definition: FileSystem.h:116
FileDescriptor.h
FileSystem::Success
@ Success
Definition: FileSystem.h:54
String::compareTo
virtual int compareTo(const String &str) const
Compares this String to the given String.
Definition: String.cpp:231
NetworkClient::SocketInfo::port
u16 port
Definition: NetworkClient.h:68
Log.h
NetworkClient::connectSocket
Result connectSocket(const int sock, const IPV4::Address addr, const u16 port=0)
Connect socket to address/port.
Definition: NetworkClient.cpp:115
FileDescriptor::getEntry
Entry * getEntry(const Size index)
Retrieve a file descriptor Entry.
Definition: FileDescriptor.cpp:58
FileSystemClient::writeFile
FileSystem::Result writeFile(const Size descriptor, const void *buf, Size *size) const
Write a file.
Definition: FileSystemClient.cpp:257
DEBUG
#define DEBUG(msg)
Output a debug message to standard output.
Definition: Log.h:89
NetworkClient::~NetworkClient
virtual ~NetworkClient()
Destructor.
Definition: NetworkClient.cpp:31
FileDescriptor::Entry::inode
u32 inode
Definition: FileDescriptor.h:48
FileSystemClient::closeFile
FileSystem::Result closeFile(const Size descriptor) const
Close a file.
Definition: FileSystemClient.cpp:218
FileDescriptor::Entry
Describes a single file opened by a user process.
Definition: FileDescriptor.h:46
FileSystemClient::openFile
FileSystem::Result openFile(const char *path, Size &descriptor) const
Open a file.
Definition: FileSystemClient.cpp:198
u16
unsigned short u16
Unsigned 16-bit number.
Definition: Types.h:56
Size
unsigned int Size
Any sane size indicator cannot go negative.
Definition: Types.h:128
FileSystem::Readable
@ Readable
Definition: FileSystem.h:139
FileSystemClient::getFileSystems
FileSystemMount * getFileSystems(Size &numberOfMounts) const
Get file system mounts table.
Definition: FileSystemClient.cpp:344
FileSystem::WaitSet::requested
u16 requested
< Inode number
Definition: FileSystem.h:130
IPV4::Address
u32 Address
IP-address.
Definition: IPV4.h:47
NetworkClient::SocketType
SocketType
Socket types.
Definition: NetworkClient.h:88
NetworkClient::bindSocket
Result bindSocket(const int sock, const IPV4::Address addr=0, const u16 port=0)
Bind socket to address/port.
Definition: NetworkClient.cpp:123
FileSystemClient::readFile
FileSystem::Result readFile(const Size descriptor, void *buf, Size *size) const
Read a file.
Definition: FileSystemClient.cpp:229
ARP.h
NetworkClient::IOError
@ IOError
Definition: NetworkClient.h:102
FileSystem::WaitSet::current
u16 current
< Requested status flags of the inode
Definition: FileSystem.h:131
NetworkClient::ARP
@ ARP
Definition: NetworkClient.h:90
FileSystemClient.h
FileSystem::FileStat
Contains file information.
Definition: FileSystem.h:113
ERROR
#define ERROR(msg)
Output an error message.
Definition: Log.h:61
NetworkClient::SocketInfo
Socket information.
Definition: NetworkClient.h:65
FileSystemMount::path
char path[FileSystemPath::MaximumLength]
Path of the mount.
Definition: FileSystemMount.h:38
FileSystem::Result
Result
Result code for filesystem Actions.
Definition: FileSystem.h:52
NetworkClient::NetworkClient
NetworkClient(const char *networkDevice)
Constructor.
Definition: NetworkClient.cpp:26
NetworkClient::ICMP
@ ICMP
Definition: NetworkClient.h:91
String.h
FileDescriptor::Entry::pid
ProcessID pid
< Inode number of the file
Definition: FileDescriptor.h:49
NetworkClient::writeSocketInfo
Result writeSocketInfo(const int sock, const IPV4::Address addr, const u16 port, const SocketAction action)
Set socket to new state.
Definition: NetworkClient.cpp:180
ARPSocket.h
FileSystemClient::waitFile
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.
Definition: FileSystemClient.cpp:296
NetworkClient.h
NetworkClient::waitSocket
Result waitSocket(const NetworkClient::SocketType type, const int sock, const Size msecTimeout)
Wait until the given socket has data to receive.
Definition: NetworkClient.cpp:131
FileSystem::TimedOut
@ TimedOut
Definition: FileSystem.h:64
type
u8 type
Definition: IntelACPI.h:63
FileSystem::WaitSet::inode
u32 inode
Definition: FileSystem.h:129
FileSystem::FileStat::pid
ProcessID pid
< Inode number
Definition: FileSystem.h:117
NetworkClient::UDP
@ UDP
Definition: NetworkClient.h:93
NetworkClient::NotSupported
@ NotSupported
Definition: NetworkClient.h:104
NetworkClient::SocketInfo::action
u16 action
Definition: NetworkClient.h:69
NetworkClient::Listen
@ Listen
Definition: NetworkClient.h:54