diff --git a/Makefile b/Makefile
index a6bb9b6ec6..13be2ab569 100644
--- a/Makefile
+++ b/Makefile
@@ -732,13 +732,16 @@ SRCS += mixer.c
 SRCS += music.c
 SRCS += music_gui.c
 SRCS += namegen.c
-SRCS += network.c
-SRCS += network_client.c
-SRCS += network_data.c
-SRCS += network_gamelist.c
-SRCS += network_gui.c
-SRCS += network_server.c
-SRCS += network_udp.c
+SRCS += network/core/packet.c
+SRCS += network/core/tcp.c
+SRCS += network/core/udp.c
+SRCS += network/network.c
+SRCS += network/network_client.c
+SRCS += network/network_data.c
+SRCS += network/network_gamelist.c
+SRCS += network/network_gui.c
+SRCS += network/network_server.c
+SRCS += network/network_udp.c
 SRCS += newgrf.c
 SRCS += newgrf_cargo.c
 SRCS += newgrf_config.c
diff --git a/ai/ai.c b/ai/ai.c
index f06ba06f6c..58b97ad39c 100644
--- a/ai/ai.c
+++ b/ai/ai.c
@@ -4,7 +4,7 @@
 #include "../openttd.h"
 #include "../variables.h"
 #include "../command.h"
-#include "../network.h"
+#include "../network/network.h"
 #include "ai.h"
 #include "default/default.h"
 
diff --git a/ai/ai.h b/ai/ai.h
index aedb5b5cd1..6123970ac3 100644
--- a/ai/ai.h
+++ b/ai/ai.h
@@ -2,7 +2,7 @@
 #define AI_H
 
 #include "../functions.h"
-#include "../network.h"
+#include "../network/network.h"
 #include "../player.h"
 #include "../command.h"
 
diff --git a/command.c b/command.c
index 7c07c5d371..f99371946f 100644
--- a/command.c
+++ b/command.c
@@ -8,7 +8,7 @@
 #include "gui.h"
 #include "command.h"
 #include "player.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 #include "genworld.h"
 
diff --git a/console.c b/console.c
index 9335472165..07d2181306 100644
--- a/console.c
+++ b/console.c
@@ -13,9 +13,9 @@
 #include <stdarg.h>
 #include <string.h>
 #include "console.h"
-#include "network.h"
-#include "network_data.h"
-#include "network_server.h"
+#include "network/network.h"
+#include "network/network_data.h"
+#include "network/network_server.h"
 
 #define ICON_BUFFER 79
 #define ICON_HISTORY_SIZE 20
diff --git a/console_cmds.c b/console_cmds.c
index addc9a799a..7ec55c6b97 100644
--- a/console_cmds.c
+++ b/console_cmds.c
@@ -9,10 +9,10 @@
 #include "saveload.h"
 #include "string.h"
 #include "variables.h"
-#include "network_data.h"
-#include "network_client.h"
-#include "network_server.h"
-#include "network_udp.h"
+#include "network/network_data.h"
+#include "network/network_client.h"
+#include "network/network_server.h"
+#include "network/network_udp.h"
 #include "command.h"
 #include "settings.h"
 #include "fios.h"
@@ -22,7 +22,7 @@
 #include "screenshot.h"
 #include "genworld.h"
 #include "date.h"
-#include "network.h"
+#include "network/network.h"
 
 // ** scriptfile handling ** //
 static FILE *_script_file;
diff --git a/date.c b/date.c
index 66bade3c94..856ca45283 100644
--- a/date.c
+++ b/date.c
@@ -6,9 +6,9 @@
 #include "variables.h"
 #include "macros.h"
 #include "vehicle.h"
-#include "network.h"
-#include "network_data.h"
-#include "network_server.h"
+#include "network/network.h"
+#include "network/network_data.h"
+#include "network/network_server.h"
 #include "functions.h"
 #include "currency.h"
 
diff --git a/date.h b/date.h
index 37691d24a2..488a9dc3ad 100644
--- a/date.h
+++ b/date.h
@@ -3,6 +3,8 @@
 #ifndef DATE_H
 #define DATE_H
 
+#include "openttd.h"
+
 /**
  * 1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885. On
  *                    an overflow the new day begun and 65535 / 885 = 74.
diff --git a/economy.c b/economy.c
index 8e8d8c3b88..bcd3ac5520 100644
--- a/economy.c
+++ b/economy.c
@@ -19,10 +19,10 @@
 #include "economy.h"
 #include "industry.h"
 #include "town.h"
-#include "network.h"
+#include "network/network.h"
 #include "sound.h"
 #include "engine.h"
-#include "network_data.h"
+#include "network/network_data.h"
 #include "variables.h"
 #include "vehicle_gui.h"
 #include "ai/ai.h"
diff --git a/genworld.c b/genworld.c
index 1d802d996e..ba9fe126f5 100644
--- a/genworld.c
+++ b/genworld.c
@@ -11,7 +11,7 @@
 #include "gfx.h"
 #include "gfxinit.h"
 #include "gui.h"
-#include "network.h"
+#include "network/network.h"
 #include "debug.h"
 #include "settings.h"
 #include "heightmap.h"
diff --git a/genworld_gui.c b/genworld_gui.c
index bbd0cb31bf..83d0f4cf1a 100644
--- a/genworld_gui.c
+++ b/genworld_gui.c
@@ -19,7 +19,7 @@
 #include "settings.h"
 #include "debug.h"
 #include "genworld.h"
-#include "network.h"
+#include "network/network.h"
 #include "thread.h"
 #include "date.h"
 #include "newgrf_config.h"
diff --git a/intro_gui.c b/intro_gui.c
index 364b81f5f8..5f78e3a654 100644
--- a/intro_gui.c
+++ b/intro_gui.c
@@ -9,12 +9,12 @@
 #include "gui.h"
 #include "gfx.h"
 #include "player.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 #include "settings.h"
 #include "heightmap.h"
 #include "genworld.h"
-#include "network_gui.h"
+#include "network/network_gui.h"
 #include "newgrf.h"
 
 static const Widget _select_game_widgets[] = {
diff --git a/main_gui.c b/main_gui.c
index caebe5afa2..e2b816e754 100644
--- a/main_gui.c
+++ b/main_gui.c
@@ -23,7 +23,7 @@
 #include "vehicle.h"
 #include "console.h"
 #include "sound.h"
-#include "network.h"
+#include "network/network.h"
 #include "signs.h"
 #include "waypoint.h"
 #include "variables.h"
@@ -37,10 +37,10 @@
 #include "vehicle_gui.h"
 #include "newgrf_config.h"
 
-#include "network_data.h"
-#include "network_client.h"
-#include "network_server.h"
-#include "network_gui.h"
+#include "network/network_data.h"
+#include "network/network_client.h"
+#include "network/network_server.h"
+#include "network/network_gui.h"
 #include "industry.h"
 
 static int _rename_id = 1;
diff --git a/misc.c b/misc.c
index 7f06943ca2..fd3a74b79b 100644
--- a/misc.c
+++ b/misc.c
@@ -24,7 +24,7 @@ char _name_array[512][32];
 #ifndef MERSENNE_TWISTER
 
 #ifdef RANDOM_DEBUG
-#include "network_data.h"
+#include "network/network_data.h"
 uint32 DoRandom(int line, const char *file)
 #else // RANDOM_DEBUG
 uint32 Random(void)
diff --git a/misc_cmd.c b/misc_cmd.c
index 4293706ba0..94b6755311 100644
--- a/misc_cmd.c
+++ b/misc_cmd.c
@@ -11,7 +11,7 @@
 #include "window.h"
 #include "gui.h"
 #include "economy.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 #include "livery.h"
 
diff --git a/misc_gui.c b/misc_gui.c
index 94917cfdf6..3f84192ada 100644
--- a/misc_gui.c
+++ b/misc_gui.c
@@ -22,7 +22,7 @@
 #include "player.h"
 #include "town.h"
 #include "sound.h"
-#include "network.h"
+#include "network/network.h"
 #include "string.h"
 #include "variables.h"
 #include "vehicle.h"
diff --git a/network/core/config.h b/network/core/config.h
new file mode 100644
index 0000000000..0b80800f07
--- /dev/null
+++ b/network/core/config.h
@@ -0,0 +1,49 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_CONFIG_H
+#define NETWORK_CORE_CONFIG_H
+
+#ifdef ENABLE_NETWORK
+
+/** DNS hostname of the masterserver */
+#define NETWORK_MASTER_SERVER_HOST "master.openttd.org"
+/** Message sent to the masterserver to 'identify' this client as OpenTTD */
+#define NETWORK_MASTER_SERVER_WELCOME_MESSAGE "OpenTTDRegister"
+
+enum {
+	NETWORK_MASTER_SERVER_PORT    = 3978, ///< The default port of the master server (UDP)
+	NETWORK_DEFAULT_PORT          = 3979, ///< The default port of the game server (TCP & UDP)
+
+	SEND_MTU                      = 1460, ///< Number of bytes we can pack in a single packet
+
+	NETWORK_GAME_INFO_VERSION     =    4, ///< What version of game-info do we use?
+	NETWORK_COMPANY_INFO_VERSION  =    4, ///< What version of company info is this?
+	NETWORK_MASTER_SERVER_VERSION =    1, ///< What version of master-server-protocol do we use?
+
+	NETWORK_NAME_LENGTH           =   80, ///< The maximum length of the server name and map name, in bytes including '\0'
+	NETWORK_HOSTNAME_LENGTH       =   80, ///< The maximum length of the host name, in bytes including '\0'
+	NETWORK_REVISION_LENGTH       =   15, ///< The maximum length of the revision, in bytes including '\0'
+	NETWORK_PASSWORD_LENGTH       =   20, ///< The maximum length of the password, in bytes including '\0'
+	NETWORK_PLAYERS_LENGTH        =  200, ///< The maximum length for the list of players that controls a company, in bytes including '\0'
+	NETWORK_CLIENT_NAME_LENGTH    =   25, ///< The maximum length of a player, in bytes including '\0'
+	NETWORK_RCONCOMMAND_LENGTH    =  500, ///< The maximum length of a rconsole command, in bytes including '\0'
+
+	NETWORK_GRF_NAME_LENGTH       =   80, ///< Maximum length of the name of a GRF
+	/**
+	 * Maximum number of GRFs that can be sent.
+	 * This value is related to number of handles (files) OpenTTD can open.
+	 * This is currently 64 and about 10 are currently used when OpenTTD loads
+	 * without any NewGRFs. Therefore one can only load about 55 NewGRFs, so
+	 * this is not a limit, but rather a way to easily check whether the limit
+	 * imposed by the handle count is reached. Secondly it isn't possible to
+	 * send much more GRF IDs + MD5sums in the PACKET_UDP_SERVER_RESPONSE, due
+	 * to the limited size of UDP packets.
+	 */
+	NETWORK_MAX_GRF_COUNT         =   55,
+
+	NETWORK_NUM_LANGUAGES         =    4, ///< Number of known languages (to the network protocol) + 1 for 'any'.
+};
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_CONFIG_H */
diff --git a/network/core/game.h b/network/core/game.h
new file mode 100644
index 0000000000..71268f7d2a
--- /dev/null
+++ b/network/core/game.h
@@ -0,0 +1,47 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_GAME_H
+#define NETWORK_CORE_GAME_H
+
+#ifdef ENABLE_NETWORK
+
+/**
+ * @file game.h Information about a game that is sent between a
+ *              game server, game client and masterserver.
+ */
+
+/**
+ * This is the struct used by both client and server
+ * some fields will be empty on the client (like game_password) by default
+ * and only filled with data a player enters.
+ */
+typedef struct NetworkGameInfo {
+	byte game_info_version;                         ///< Version of the game info
+	char server_name[NETWORK_NAME_LENGTH];          ///< Server name
+	char hostname[NETWORK_HOSTNAME_LENGTH];         ///< Hostname of the server (if any)
+	char server_revision[NETWORK_REVISION_LENGTH];  ///< The version number the server is using (e.g.: 'r304' or 0.5.0)
+	bool version_compatible;                        ///< Can we connect to this server or not? (based on server_revision)
+	bool compatible;                                ///< Can we connect to this server or not? (based on server_revision _and_ grf_match
+	byte server_lang;                               ///< Language of the server (we should make a nice table for this)
+	byte use_password;                              ///< Is set to != 0 if it uses a password
+	char server_password[NETWORK_PASSWORD_LENGTH];  ///< On the server: the game password, on the client: != "" if server has password
+	byte clients_max;                               ///< Max clients allowed on server
+	byte clients_on;                                ///< Current count of clients on server
+	byte companies_max;                             ///< Max companies allowed on server
+	byte companies_on;                              ///< How many started companies do we have
+	byte spectators_max;                            ///< Max spectators allowed on server
+	byte spectators_on;                             ///< How many spectators do we have?
+	Date game_date;                                 ///< Current date
+	Date start_date;                                ///< When the game started
+	char map_name[NETWORK_NAME_LENGTH];             ///< Map which is played ["random" for a randomized map]
+	uint16 map_width;                               ///< Map width
+	uint16 map_height;                              ///< Map height
+	byte map_set;                                   ///< Graphical set
+	bool dedicated;                                 ///< Is this a dedicated server?
+	char rcon_password[NETWORK_PASSWORD_LENGTH];    ///< RCon password for the server. "" if rcon is disabled
+	struct GRFConfig *grfconfig;                    ///< List of NewGRF files used
+} NetworkGameInfo;
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_GAME_H */
diff --git a/network_core.h b/network/core/os_abstraction.h
similarity index 69%
rename from network_core.h
rename to network/core/os_abstraction.h
index cdc79c1688..c7df16a939 100644
--- a/network_core.h
+++ b/network/core/os_abstraction.h
@@ -1,40 +1,37 @@
 /* $Id$ */
 
-#ifndef NETWORK_CORE_H
-#define NETWORK_CORE_H
+#ifndef NETWORK_CORE_OS_ABSTRACTION_H
+#define NETWORK_CORE_OS_ABSTRACTION_H
 
-// Network stuff has many things that needs to be included
-//  by default. All those things are in this file.
+/**
+ * @file os_abstraction.h Network stuff has many things that needs to be
+ *                        included and/or implemented by default.
+ *                        All those things are in this file.
+ */
 
-// =============================
-// Include standard stuff per OS
+/* Include standard stuff per OS */
 
 #ifdef ENABLE_NETWORK
 
-#if defined(__APPLE__) && (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_2)
-	// OSX 10.2 don't have socklen_t defined, so we will define it here
-	typedef int socklen_t;
-#endif
-
-// Windows stuff
+/* Windows stuff */
 #if defined(WIN32) || defined(WIN64)
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <windows.h>
 
 #if !(defined(__MINGW32__) || defined(__CYGWIN__))
-	// Windows has some different names for some types..
+	/* Windows has some different names for some types */
 	typedef SSIZE_T ssize_t;
 	typedef int socklen_t;
 #endif
 
 #define GET_LAST_ERROR() WSAGetLastError()
 #define EWOULDBLOCK WSAEWOULDBLOCK
-// Windows has some different names for some types..
+/* Windows has some different names for some types */
 typedef unsigned long in_addr_t;
-#endif // WIN32
+#endif /* WIN32 */
 
-// UNIX stuff
+/* UNIX stuff */
 #if defined(UNIX)
 #	define SOCKET int
 #	define INVALID_SOCKET -1
@@ -45,10 +42,10 @@ typedef unsigned long in_addr_t;
 #	endif
 #		define GET_LAST_ERROR() (errno)
 #	endif
-// Need this for FIONREAD on solaris
+/* Need this for FIONREAD on solaris */
 #	define BSD_COMP
 
-// Includes needed for UNIX-like systems
+/* Includes needed for UNIX-like systems */
 #	include <unistd.h>
 #	include <sys/ioctl.h>
 #	if defined(__BEOS__) && defined(BEOS_NET_SERVER)
@@ -63,12 +60,12 @@ typedef unsigned long in_addr_t;
 #		include <netinet/tcp.h>
 #		include <arpa/inet.h>
 #		include <net/if.h>
-// According to glibc/NEWS, <ifaddrs.h> appeared in glibc-2.3.
+/* According to glibc/NEWS, <ifaddrs.h> appeared in glibc-2.3. */
 #		if !defined(__sgi__) && !defined(SUNOS) && !defined(__MORPHOS__) && !defined(__BEOS__) && !defined(__INNOTEK_LIBC__) \
 		   && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__)
-// If for any reason ifaddrs.h does not exist on your system, comment out
-//   the following two lines and an alternative way will be used to fetch
-//   the list of IPs from the system.
+/* If for any reason ifaddrs.h does not exist on your system, comment out
+ *   the following two lines and an alternative way will be used to fetch
+ *   the list of IPs from the system. */
 #			include <ifaddrs.h>
 #			define HAVE_GETIFADDRS
 #		endif
@@ -76,10 +73,10 @@ typedef unsigned long in_addr_t;
 #			define INADDR_NONE 0xffffffff
 #		endif
 #		if defined(__BEOS__) && !defined(BEOS_NET_SERVER)
-			// needed on Zeta
+			/* needed on Zeta */
 #			include <sys/sockio.h>
 #		endif
-#	endif // BEOS_NET_SERVER
+#	endif /* BEOS_NET_SERVER */
 
 #	if !defined(__BEOS__) && defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1)
 		typedef uint32_t in_addr_t;
@@ -94,7 +91,7 @@ typedef unsigned long in_addr_t;
 	typedef int socklen_t;
 #endif
 
-// OS/2 stuff
+/* OS/2 stuff */
 #if defined(__OS2__)
 #	define SOCKET int
 #	define INVALID_SOCKET -1
@@ -102,7 +99,7 @@ typedef unsigned long in_addr_t;
 #	define closesocket close
 #	define GET_LAST_ERROR() (sock_errno())
 
-// Includes needed for OS/2 systems
+/* Includes needed for OS/2 systems */
 #	include <types.h>
 #	include <unistd.h>
 #	include <sys/ioctl.h>
@@ -121,21 +118,21 @@ typedef int socklen_t;
 #if !defined(__INNOTEK_LIBC__)
 typedef unsigned long in_addr_t;
 #endif /* __INNOTEK_LIBC__ */
-#endif // OS/2
+#endif /* OS/2 */
 
-// MorphOS and Amiga stuff
+/* MorphOS and Amiga stuff */
 #if defined(__MORPHOS__) || defined(__AMIGA__)
 #	include <exec/types.h>
-#	include <proto/exec.h>		// required for Open/CloseLibrary()
+#	include <proto/exec.h>   // required for Open/CloseLibrary()
 #	if defined(__MORPHOS__)
-#		include <sys/filio.h> 	// FIO* defines
-#		include <sys/sockio.h>  // SIO* defines
+#		include <sys/filio.h>  // FIO* defines
+#		include <sys/sockio.h> // SIO* defines
 #		include <netinet/in.h>
-#	else // __AMIGA__
+#	else /* __AMIGA__ */
 #		include	<proto/socket.h>
 #	endif
 
-// Make the names compatible
+/* Make the names compatible */
 #	define closesocket(s) CloseSocket(s)
 #	define GET_LAST_ERROR() Errno()
 #	define ioctlsocket(s,request,status) IoctlSocket((LONG)s,(ULONG)request,(char*)status)
@@ -146,7 +143,7 @@ typedef unsigned long in_addr_t;
 	extern struct Library *SocketBase;
 
 #	ifdef __AMIGA__
-	// for usleep() implementation
+	/* for usleep() implementation */
 	extern struct Device      *TimerBase;
 	extern struct MsgPort     *TimerPort;
 	extern struct timerequest *TimerRequest;
@@ -155,30 +152,30 @@ typedef unsigned long in_addr_t;
 
 static inline bool SetNonBlocking(int d)
 {
-	#ifdef WIN32
+#ifdef WIN32
 	u_long nonblocking = 1;
-	#else
+#else
 	int nonblocking = 1;
-	#endif
-	#if defined(__BEOS__) && defined(BEOS_NET_SERVER)
+#endif
+#if defined(__BEOS__) && defined(BEOS_NET_SERVER)
 	return setsockopt(d, SOL_SOCKET, SO_NONBLOCK, &nonblocking, sizeof(nonblocking)) == 0;
-	#else
+#else
 	return ioctlsocket(d, FIONBIO, &nonblocking) == 0;
-	#endif
+#endif
 }
 
 static inline bool SetNoDelay(int d)
 {
-	// XXX should this be done at all?
-	#if !defined(BEOS_NET_SERVER) // not implemented on BeOS net_server
+	/* XXX should this be done at all? */
+#if !defined(BEOS_NET_SERVER) // not implemented on BeOS net_server
 	int b = 1;
-	// The (const char*) cast is needed for windows
+	/* The (const char*) cast is needed for windows */
 	return setsockopt(d, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)) == 0;
-	#else
+#else
 	return true;
-	#endif
+#endif
 }
 
 #endif /* ENABLE_NETWORK */
 
-#endif /* NETWORK_CORE_H */
+#endif /* NETWORK_CORE_OS_ABSTRACTION_H */
diff --git a/network/core/packet.c b/network/core/packet.c
new file mode 100644
index 0000000000..957bd2ad6a
--- /dev/null
+++ b/network/core/packet.c
@@ -0,0 +1,216 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../../stdafx.h"
+#include "../../macros.h"
+#include "../../string.h"
+
+#include "os_abstraction.h"
+#include "config.h"
+#include "packet.h"
+
+/**
+ * @file packet.h Basic functions to create, fill and read packets.
+ */
+
+
+/* Do not want to include functions.h and all required headers */
+extern void NORETURN CDECL error(const char *str, ...);
+
+
+/**
+ * Create a packet for sending
+ * @param type the of packet
+ * @return the newly created packet
+ */
+Packet *NetworkSend_Init(PacketType type)
+{
+	Packet *packet = malloc(sizeof(Packet));
+	/* An error is inplace here, because it simply means we ran out of memory. */
+	if (packet == NULL) error("Failed to allocate Packet");
+
+	/* Skip the size so we can write that in before sending the packet */
+	packet->size = sizeof(packet->size);
+	packet->buffer[packet->size++] = type;
+	packet->pos = 0;
+
+	return packet;
+}
+
+/**
+ * Writes the packet size from the raw packet from packet->size
+ * @param packet the packet to write the size of
+ */
+void NetworkSend_FillPacketSize(Packet *packet)
+{
+	packet->buffer[0] = GB(packet->size, 0, 8);
+	packet->buffer[1] = GB(packet->size, 8, 8);
+}
+
+/**
+ * The next couple of functions make sure we can send
+ *  uint8, uint16, uint32 and uint64 endian-safe
+ *  over the network. The least significant bytes are
+ *  sent first.
+ *
+ *  So 0x01234567 would be sent as 67 45 23 01.
+ */
+
+void NetworkSend_uint8(Packet *packet, uint8 data)
+{
+	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
+	packet->buffer[packet->size++] = data;
+}
+
+void NetworkSend_uint16(Packet *packet, uint16 data)
+{
+	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
+	packet->buffer[packet->size++] = GB(data, 0, 8);
+	packet->buffer[packet->size++] = GB(data, 8, 8);
+}
+
+void NetworkSend_uint32(Packet *packet, uint32 data)
+{
+	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
+	packet->buffer[packet->size++] = GB(data,  0, 8);
+	packet->buffer[packet->size++] = GB(data,  8, 8);
+	packet->buffer[packet->size++] = GB(data, 16, 8);
+	packet->buffer[packet->size++] = GB(data, 24, 8);
+}
+
+void NetworkSend_uint64(Packet *packet, uint64 data)
+{
+	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
+	packet->buffer[packet->size++] = GB(data,  0, 8);
+	packet->buffer[packet->size++] = GB(data,  8, 8);
+	packet->buffer[packet->size++] = GB(data, 16, 8);
+	packet->buffer[packet->size++] = GB(data, 24, 8);
+	packet->buffer[packet->size++] = GB(data, 32, 8);
+	packet->buffer[packet->size++] = GB(data, 40, 8);
+	packet->buffer[packet->size++] = GB(data, 48, 8);
+	packet->buffer[packet->size++] = GB(data, 56, 8);
+}
+
+/**
+ *  Sends a string over the network. It sends out
+ *  the string + '\0'. No size-byte or something.
+ */
+void NetworkSend_string(Packet *packet, const char* data)
+{
+	assert(data != NULL);
+	assert(packet->size < sizeof(packet->buffer) - strlen(data) - 1);
+	while ((packet->buffer[packet->size++] = *data++) != '\0') {}
+}
+
+
+/**
+ * Receiving commands
+ * Again, the next couple of functions are endian-safe
+ *  see the comment before NetworkSend_uint8 for more info.
+ */
+
+
+extern uint CloseConnection(NetworkClientState *cs);
+
+/** Is it safe to read from the packet, i.e. didn't we run over the buffer ? */
+static inline bool CanReadFromPacket(NetworkClientState *cs, Packet *packet, uint bytes_to_read)
+{
+	/* Don't allow reading from a closed socket */
+	if (HasClientQuit(cs)) return false;
+
+	/* Check if variable is within packet-size */
+	if (packet->pos + bytes_to_read > packet->size) {
+		CloseConnection(cs);
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * Reads the packet size from the raw packet and stores it in the packet->size
+ * @param packet the packet to read the size of
+ */
+void NetworkRecv_ReadPacketSize(Packet *packet)
+{
+	packet->size  = (uint16)packet->buffer[0];
+	packet->size += (uint16)packet->buffer[1] << 8;
+}
+
+uint8 NetworkRecv_uint8(NetworkClientState *cs, Packet *packet)
+{
+	uint8 n;
+
+	if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0;
+
+	n = packet->buffer[packet->pos++];
+	return n;
+}
+
+uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet)
+{
+	uint16 n;
+
+	if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0;
+
+	n  = (uint16)packet->buffer[packet->pos++];
+	n += (uint16)packet->buffer[packet->pos++] << 8;
+	return n;
+}
+
+uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet)
+{
+	uint32 n;
+
+	if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0;
+
+	n  = (uint32)packet->buffer[packet->pos++];
+	n += (uint32)packet->buffer[packet->pos++] << 8;
+	n += (uint32)packet->buffer[packet->pos++] << 16;
+	n += (uint32)packet->buffer[packet->pos++] << 24;
+	return n;
+}
+
+uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet)
+{
+	uint64 n;
+
+	if (!CanReadFromPacket(cs, packet, sizeof(n))) return 0;
+
+	n  = (uint64)packet->buffer[packet->pos++];
+	n += (uint64)packet->buffer[packet->pos++] << 8;
+	n += (uint64)packet->buffer[packet->pos++] << 16;
+	n += (uint64)packet->buffer[packet->pos++] << 24;
+	n += (uint64)packet->buffer[packet->pos++] << 32;
+	n += (uint64)packet->buffer[packet->pos++] << 40;
+	n += (uint64)packet->buffer[packet->pos++] << 48;
+	n += (uint64)packet->buffer[packet->pos++] << 56;
+	return n;
+}
+
+/** Reads a string till it finds a '\0' in the stream */
+void NetworkRecv_string(NetworkClientState *cs, Packet *p, char *buffer, size_t size)
+{
+	PacketSize pos;
+	char *bufp = buffer;
+
+	/* Don't allow reading from a closed socket */
+	if (HasClientQuit(cs)) return;
+
+	pos = p->pos;
+	while (--size > 0 && pos < p->size && (*buffer++ = p->buffer[pos++]) != '\0') {}
+
+	if (size == 0 || pos == p->size) {
+		*buffer = '\0';
+		/* If size was sooner to zero then the string in the stream
+		 *  skip till the \0, so than packet can be read out correctly for the rest */
+		while (pos < p->size && p->buffer[pos] != '\0') pos++;
+		pos++;
+	}
+	p->pos = pos;
+
+	str_validate(bufp);
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/network/core/packet.h b/network/core/packet.h
new file mode 100644
index 0000000000..2510c69a7f
--- /dev/null
+++ b/network/core/packet.h
@@ -0,0 +1,67 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_PACKET_H
+#define NETWORK_CORE_PACKET_H
+
+#ifdef ENABLE_NETWORK
+
+/**
+ * @file packet.h Basic functions to create, fill and read packets.
+ */
+
+typedef struct NetworkClientState NetworkClientState;
+
+/**
+ * Queries the network client state struct to determine whether
+ * the client has quit. It indirectly also queries whether the
+ * packet is corrupt as the connection will be closed if it is
+ * reading beyond the boundary of the received packet.
+ * @param cs the state to query
+ * @param true if the connection should be considered dropped
+ */
+bool HasClientQuit(NetworkClientState *cs);
+
+typedef uint16 PacketSize; ///< Size of the whole packet.
+typedef uint8  PacketType; ///< Identifier for the packet
+
+/**
+ * Internal entity of a packet. As everything is sent as a packet,
+ * all network communication will need to call the functions that
+ * populate the packet.
+ * Every packet can be at most SEND_MTU bytes. Overflowing this
+ * limit will give an assertion when sending (i.e. writing) the
+ * packet. Reading past the size of the packet when receiving
+ * will return all 0 values and "" in case of the string.
+ */
+typedef struct Packet {
+	/** The next packet. Used for queueing packets before sending. */
+	struct Packet *next;
+	/** The size of the whole packet for received packets. For packets
+	 * that will be sent, the value is filled in just before the
+	 * actual transmission. */
+	PacketSize size;
+	/** The current read/write position in the packet */
+	PacketSize pos;
+	/** The buffer of this packet */
+	byte buffer[SEND_MTU];
+} Packet;
+
+
+Packet *NetworkSend_Init(PacketType type);
+void NetworkSend_FillPacketSize(Packet *packet);
+void NetworkSend_uint8 (Packet *packet, uint8 data);
+void NetworkSend_uint16(Packet *packet, uint16 data);
+void NetworkSend_uint32(Packet *packet, uint32 data);
+void NetworkSend_uint64(Packet *packet, uint64 data);
+void NetworkSend_string(Packet *packet, const char* data);
+
+void NetworkRecv_ReadPacketSize(Packet *packet);
+uint8  NetworkRecv_uint8 (NetworkClientState *cs, Packet *packet);
+uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet);
+uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet);
+uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet);
+void   NetworkRecv_string(NetworkClientState *cs, Packet *packet, char* buffer, size_t size);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_PACKET_H */
diff --git a/network/core/tcp.c b/network/core/tcp.c
new file mode 100644
index 0000000000..493a97dfff
--- /dev/null
+++ b/network/core/tcp.c
@@ -0,0 +1,227 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../../stdafx.h"
+#include "../../debug.h"
+#include "../../openttd.h"
+#include "../../variables.h"
+#include "../../table/strings.h"
+#include "../../functions.h"
+
+#include "os_abstraction.h"
+#include "config.h"
+#include "packet.h"
+#include "../network_data.h"
+#include "tcp.h"
+
+/**
+ * @file tcp.c Basic functions to receive and send TCP packets.
+ */
+
+/**
+ * Functions to help NetworkRecv_Packet/NetworkSend_Packet a bit
+ *  A socket can make errors. When that happens this handles what to do.
+ * For clients: close connection and drop back to main-menu
+ * For servers: close connection and that is it
+ * @param cs the client to close the connection of
+ * @return the new status
+ */
+NetworkRecvStatus CloseConnection(NetworkClientState *cs)
+{
+	NetworkCloseClient(cs);
+
+	/* Clients drop back to the main menu */
+	if (!_network_server && _networking) {
+		_switch_mode = SM_MENU;
+		_networking = false;
+		_switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
+
+		return NETWORK_RECV_STATUS_CONN_LOST;
+	}
+
+	return NETWORK_RECV_STATUS_OKAY;
+}
+
+/**
+ * Whether the client has quit or not (used in packet.c)
+ * @param cs the client to check
+ * @return true if the client has quit
+ */
+bool HasClientQuit(NetworkClientState *cs)
+{
+	return cs->has_quit;
+}
+
+/**
+ * This function puts the packet in the send-queue and it is send as
+ * soon as possible. This is the next tick, or maybe one tick later
+ * if the OS-network-buffer is full)
+ * @param packet the packet to send
+ * @param cs     the client to send to
+ */
+void NetworkSend_Packet(Packet *packet, NetworkClientState *cs)
+{
+	Packet *p;
+	assert(packet != NULL);
+
+	packet->pos = 0;
+	packet->next = NULL;
+
+	NetworkSend_FillPacketSize(packet);
+
+	/* Locate last packet buffered for the client */
+	p = cs->packet_queue;
+	if (p == NULL) {
+		/* No packets yet */
+		cs->packet_queue = packet;
+	} else {
+		/* Skip to the last packet */
+		while (p->next != NULL) p = p->next;
+		p->next = packet;
+	}
+}
+
+/**
+ * Sends all the buffered packets out for this client. It stops when:
+ *   1) all packets are send (queue is empty)
+ *   2) the OS reports back that it can not send any more
+ *      data right now (full network-buffer, it happens ;))
+ *   3) sending took too long
+ * @param cs the client to send the packets for
+ */
+bool NetworkSend_Packets(NetworkClientState *cs)
+{
+	ssize_t res;
+	Packet *p;
+
+	/* We can not write to this socket!! */
+	if (!cs->writable) return false;
+	if (cs->socket == INVALID_SOCKET) return false;
+
+	p = cs->packet_queue;
+	while (p != NULL) {
+		res = send(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
+		if (res == -1) {
+			int err = GET_LAST_ERROR();
+			if (err != EWOULDBLOCK) {
+				/* Something went wrong.. close client! */
+				DEBUG(net, 0, "send failed with error %d", err);
+				CloseConnection(cs);
+				return false;
+			}
+			return true;
+		}
+		if (res == 0) {
+			/* Client/server has left us :( */
+			CloseConnection(cs);
+			return false;
+		}
+
+		p->pos += res;
+
+		/* Is this packet sent? */
+		if (p->pos == p->size) {
+			/* Go to the next packet */
+			cs->packet_queue = p->next;
+			free(p);
+			p = cs->packet_queue;
+		} else {
+			return true;
+		}
+	}
+
+	return true;
+}
+
+/**
+ * Receives a packet for the given client
+ * @param cs     the client to (try to) receive a packet for
+ * @param status the variable to store the status into
+ * @return the received packet (or NULL when it didn't receive one)
+ */
+Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status)
+{
+	ssize_t res;
+	Packet *p;
+
+	*status = NETWORK_RECV_STATUS_OKAY;
+
+	if (cs->socket == INVALID_SOCKET) return NULL;
+
+	if (cs->packet_recv == NULL) {
+		cs->packet_recv = malloc(sizeof(Packet));
+		if (cs->packet_recv == NULL) error("Failed to allocate packet");
+		/* Set pos to zero! */
+		cs->packet_recv->pos = 0;
+		cs->packet_recv->size = 0; // Can be ommited, just for safety reasons
+	}
+
+	p = cs->packet_recv;
+
+	/* Read packet size */
+	if (p->pos < sizeof(PacketSize)) {
+		while (p->pos < sizeof(PacketSize)) {
+			/* Read the size of the packet */
+			res = recv(cs->socket, p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0);
+			if (res == -1) {
+				int err = GET_LAST_ERROR();
+				if (err != EWOULDBLOCK) {
+					/* Something went wrong... (104 is connection reset by peer) */
+					if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
+					*status = CloseConnection(cs);
+					return NULL;
+				}
+				/* Connection would block, so stop for now */
+				return NULL;
+			}
+			if (res == 0) {
+				/* Client/server has left */
+				*status = CloseConnection(cs);
+				return NULL;
+			}
+			p->pos += res;
+		}
+
+		NetworkRecv_ReadPacketSize(p);
+
+		if (p->size > SEND_MTU) {
+			*status = CloseConnection(cs);
+			return NULL;
+		}
+	}
+
+	/* Read rest of packet */
+	while (p->pos < p->size) {
+		res = recv(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
+		if (res == -1) {
+			int err = GET_LAST_ERROR();
+			if (err != EWOULDBLOCK) {
+				/* Something went wrong... (104 is connection reset by peer) */
+				if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
+				*status = CloseConnection(cs);
+				return NULL;
+			}
+			/* Connection would block */
+			return NULL;
+		}
+		if (res == 0) {
+			/* Client/server has left */
+			*status = CloseConnection(cs);
+			return NULL;
+		}
+
+		p->pos += res;
+	}
+
+	/* We have a complete packet, return it! */
+	p->pos = 2;
+	p->next = NULL; // Should not be needed, but who knows...
+
+	/* Prepare for receiving a new packet */
+	cs->packet_recv = NULL;
+
+	return p;
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/network/core/tcp.h b/network/core/tcp.h
new file mode 100644
index 0000000000..e3c3073531
--- /dev/null
+++ b/network/core/tcp.h
@@ -0,0 +1,60 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_TCP_H
+#define NETWORK_CORE_TCP_H
+
+#ifdef ENABLE_NETWORK
+
+/**
+ * @file tcp.h Basic functions to receive and send TCP packets.
+ */
+
+/**
+ * Enum with all types of UDP packets.
+ * The order of the first 4 packets MUST not be changed, as
+ * it protects old clients from joining newer servers
+ * (because SERVER_ERROR is the respond to a wrong revision)
+ */
+enum {
+	PACKET_SERVER_FULL,
+	PACKET_SERVER_BANNED,
+	PACKET_CLIENT_JOIN,
+	PACKET_SERVER_ERROR,
+	PACKET_CLIENT_COMPANY_INFO,
+	PACKET_SERVER_COMPANY_INFO,
+	PACKET_SERVER_CLIENT_INFO,
+	PACKET_SERVER_NEED_PASSWORD,
+	PACKET_CLIENT_PASSWORD,
+	PACKET_SERVER_WELCOME,
+	PACKET_CLIENT_GETMAP,
+	PACKET_SERVER_WAIT,
+	PACKET_SERVER_MAP,
+	PACKET_CLIENT_MAP_OK,
+	PACKET_SERVER_JOIN,
+	PACKET_SERVER_FRAME,
+	PACKET_SERVER_SYNC,
+	PACKET_CLIENT_ACK,
+	PACKET_CLIENT_COMMAND,
+	PACKET_SERVER_COMMAND,
+	PACKET_CLIENT_CHAT,
+	PACKET_SERVER_CHAT,
+	PACKET_CLIENT_SET_PASSWORD,
+	PACKET_CLIENT_SET_NAME,
+	PACKET_CLIENT_QUIT,
+	PACKET_CLIENT_ERROR,
+	PACKET_SERVER_QUIT,
+	PACKET_SERVER_ERROR_QUIT,
+	PACKET_SERVER_SHUTDOWN,
+	PACKET_SERVER_NEWGAME,
+	PACKET_SERVER_RCON,
+	PACKET_CLIENT_RCON,
+	PACKET_END                   ///< Must ALWAYS be on the end of this list!! (period)
+};
+
+void NetworkSend_Packet(Packet *packet, NetworkClientState *cs);
+Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status);
+bool NetworkSend_Packets(NetworkClientState *cs);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_TCP_H */
diff --git a/network/core/udp.c b/network/core/udp.c
new file mode 100644
index 0000000000..badd9a532e
--- /dev/null
+++ b/network/core/udp.c
@@ -0,0 +1,277 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../../stdafx.h"
+#include "../../date.h"
+#include "../../debug.h"
+#include "../../macros.h"
+#include "../../newgrf_config.h"
+
+#include "os_abstraction.h"
+#include "config.h"
+#include "game.h"
+#include "packet.h"
+#include "udp.h"
+
+/**
+ * @file udp.c Basic functions to receive and send UDP packets.
+ */
+
+/**
+ * Send a packet over UDP
+ * @param udp  the socket to send over
+ * @param p    the packet to send
+ * @param recv the receiver (target) of the packet
+ */
+void NetworkSendUDP_Packet(SOCKET udp, Packet *p, struct sockaddr_in *recv)
+{
+	int res;
+
+	NetworkSend_FillPacketSize(p);
+
+	/* Send the buffer */
+	res = sendto(udp, p->buffer, p->size, 0, (struct sockaddr *)recv, sizeof(*recv));
+
+	/* Check for any errors, but ignore it otherwise */
+	if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR());
+}
+
+/**
+ * Start listening on the given host and port.
+ * @param udp       the place where the (references to the) UDP are stored
+ * @param host      the host (ip) to listen on
+ * @param port      the port to listen on
+ * @param broadcast whether to allow broadcast sending/receiving
+ * @return true if the listening succeeded
+ */
+bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast)
+{
+	struct sockaddr_in sin;
+
+	/* Make sure socket is closed */
+	closesocket(*udp);
+
+	*udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	if (*udp == INVALID_SOCKET) {
+		DEBUG(net, 0, "[udp] failed to start UDP listener");
+		return false;
+	}
+
+	/* set nonblocking mode for socket */
+	{
+		unsigned long blocking = 1;
+#ifndef BEOS_NET_SERVER
+		ioctlsocket(*udp, FIONBIO, &blocking);
+#else
+		setsockopt(*udp, SOL_SOCKET, SO_NONBLOCK, &blocking, NULL);
+#endif
+	}
+
+	sin.sin_family = AF_INET;
+	/* Listen on all IPs */
+	sin.sin_addr.s_addr = host;
+	sin.sin_port = htons(port);
+
+	if (bind(*udp, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
+		DEBUG(net, 0, "[udp] bind failed on %s:%i", inet_ntoa(*(struct in_addr *)&host), port);
+		return false;
+	}
+
+	if (broadcast) {
+		/* Enable broadcast */
+		unsigned long val = 1;
+#ifndef BEOS_NET_SERVER // will work around this, some day; maybe.
+		setsockopt(*udp, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val));
+#endif
+	}
+
+	DEBUG(net, 1, "[udp] listening on port %s:%d", inet_ntoa(*(struct in_addr *)&host), port);
+
+	return true;
+}
+
+/**
+ * Receive a packet at UDP level
+ * @param udp the socket to receive the packet on
+ */
+void NetworkUDPReceive(SOCKET udp)
+{
+	struct sockaddr_in client_addr;
+	socklen_t client_len;
+	int nbytes;
+	Packet p;
+	int packet_len;
+
+	packet_len = sizeof(p.buffer);
+	client_len = sizeof(client_addr);
+
+	/* Try to receive anything */
+	nbytes = recvfrom(udp, p.buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len);
+
+	/* We got some bytes for the base header of the packet.
+	 * Assume we received the whole packet. */
+	if (nbytes > 2) {
+		NetworkRecv_ReadPacketSize(&p);
+
+		/* Put the position on the right place */
+		p.pos = 2;
+		p.next = NULL;
+
+		/* Handle the packet */
+		NetworkHandleUDPPacket(&p, &client_addr);
+	}
+}
+
+
+/**
+ * Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet
+ * @param p the packet to write the data to
+ * @param c the configuration to write the GRF ID and MD5 checksum from
+ */
+void NetworkSend_GRFIdentifier(Packet *p, const GRFConfig *c)
+{
+	uint j;
+	NetworkSend_uint32(p, c->grfid);
+	for (j = 0; j < sizeof(c->md5sum); j++) {
+		NetworkSend_uint8 (p, c->md5sum[j]);
+	}
+}
+
+/**
+ * Deserializes the GRFIdentifier (GRF ID and MD5 checksum) from the packet
+ * @param cs the client state (for closing connect on out-of-bounds reading etc)
+ * @param p  the packet to read the data from
+ * @param c  the configuration to write the GRF ID and MD5 checksum to
+ */
+void NetworkRecv_GRFIdentifier(NetworkClientState *cs, Packet *p, GRFConfig *c)
+{
+	uint j;
+	c->grfid = NetworkRecv_uint32(cs, p);
+	for (j = 0; j < sizeof(c->md5sum); j++) {
+		c->md5sum[j] = NetworkRecv_uint8(cs, p);
+	}
+}
+
+
+/**
+ * Serializes the NetworkGameInfo struct to the packet
+ * @param p    the packet to write the data to
+ * @param info the NetworkGameInfo struct to serialize
+ */
+void NetworkSend_NetworkGameInfo(Packet *p, const NetworkGameInfo *info)
+{
+	NetworkSend_uint8 (p, NETWORK_GAME_INFO_VERSION);
+
+	/*
+	 *              Please observe the order.
+	 * The parts must be read in the same order as they are sent!
+	 */
+
+
+	/* NETWORK_GAME_INFO_VERSION = 4 */
+	{
+		/* Only send the GRF Identification (GRF_ID and MD5 checksum) of
+		 * the GRFs that are needed, i.e. the ones that the server has
+		 * selected in the NewGRF GUI and not the ones that are used due
+		 * to the fact that they are in [newgrf-static] in openttd.cfg */
+		const GRFConfig *c;
+		uint count = 0;
+
+		/* Count number of GRFs to send information about */
+		for (c = info->grfconfig; c != NULL; c = c->next) {
+			if (!HASBIT(c->flags, GCF_STATIC)) count++;
+		}
+		NetworkSend_uint8 (p, count); // Send number of GRFs
+
+		/* Send actual GRF Identifications */
+		for (c = info->grfconfig; c != NULL; c = c->next) {
+			if (!HASBIT(c->flags, GCF_STATIC)) NetworkSend_GRFIdentifier(p, c);
+		}
+	}
+
+	/* NETWORK_GAME_INFO_VERSION = 3 */
+	NetworkSend_uint32(p, info->game_date);
+	NetworkSend_uint32(p, info->start_date);
+
+	/* NETWORK_GAME_INFO_VERSION = 2 */
+	NetworkSend_uint8 (p, info->companies_max);
+	NetworkSend_uint8 (p, info->companies_on);
+	NetworkSend_uint8 (p, info->spectators_max);
+
+	/* NETWORK_GAME_INFO_VERSION = 1 */
+	NetworkSend_string(p, info->server_name);
+	NetworkSend_string(p, info->server_revision);
+	NetworkSend_uint8 (p, info->server_lang);
+	NetworkSend_uint8 (p, info->use_password);
+	NetworkSend_uint8 (p, info->clients_max);
+	NetworkSend_uint8 (p, info->clients_on);
+	NetworkSend_uint8 (p, info->spectators_on);
+	NetworkSend_string(p, info->map_name);
+	NetworkSend_uint16(p, info->map_width);
+	NetworkSend_uint16(p, info->map_height);
+	NetworkSend_uint8 (p, info->map_set);
+	NetworkSend_uint8 (p, info->dedicated);
+}
+
+/**
+ * Deserializes the NetworkGameInfo struct from the packet
+ * @param cs   the client state (for closing connect on out-of-bounds reading etc)
+ * @param p    the packet to read the data from
+ * @param info the NetworkGameInfo to deserialize into
+ */
+void NetworkRecv_NetworkGameInfo(NetworkClientState *cs, Packet *p, NetworkGameInfo *info)
+{
+	info->game_info_version = NetworkRecv_uint8(cs, p);
+
+	/*
+	 *              Please observe the order.
+	 * The parts must be read in the same order as they are sent!
+	 */
+
+	switch (info->game_info_version) {
+		case 4: {
+			GRFConfig *c, **dst = &info->grfconfig;
+			uint i;
+			uint num_grfs = NetworkRecv_uint8(cs, p);
+
+			for (i = 0; i < num_grfs; i++) {
+				c = calloc(1, sizeof(*c));
+				NetworkRecv_GRFIdentifier(cs, p, c);
+				HandleIncomingNetworkGameInfoGRFConfig(c);
+
+				/* Append GRFConfig to the list */
+				*dst = c;
+				dst = &c->next;
+			}
+		} /* Fallthrough */
+		case 3:
+			info->game_date      = NetworkRecv_uint32(cs, p);
+			info->start_date     = NetworkRecv_uint32(cs, p);
+			/* Fallthrough */
+		case 2:
+			info->companies_max  = NetworkRecv_uint8 (cs, p);
+			info->companies_on   = NetworkRecv_uint8 (cs, p);
+			info->spectators_max = NetworkRecv_uint8 (cs, p);
+			/* Fallthrough */
+		case 1:
+			NetworkRecv_string(cs, p, info->server_name,     sizeof(info->server_name));
+			NetworkRecv_string(cs, p, info->server_revision, sizeof(info->server_revision));
+			info->server_lang    = NetworkRecv_uint8 (cs, p);
+			info->use_password   = NetworkRecv_uint8 (cs, p);
+			info->clients_max    = NetworkRecv_uint8 (cs, p);
+			info->clients_on     = NetworkRecv_uint8 (cs, p);
+			info->spectators_on  = NetworkRecv_uint8 (cs, p);
+			if (info->game_info_version < 3) { // 16 bits dates got scrapped and are read earlier
+				info->game_date    = NetworkRecv_uint16(cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR;
+				info->start_date   = NetworkRecv_uint16(cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR;
+			}
+			NetworkRecv_string(cs, p, info->map_name, sizeof(info->map_name));
+			info->map_width      = NetworkRecv_uint16(cs, p);
+			info->map_height     = NetworkRecv_uint16(cs, p);
+			info->map_set        = NetworkRecv_uint8 (cs, p);
+			info->dedicated      = NetworkRecv_uint8 (cs, p);
+	}
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/network/core/udp.h b/network/core/udp.h
new file mode 100644
index 0000000000..3221e664f6
--- /dev/null
+++ b/network/core/udp.h
@@ -0,0 +1,62 @@
+/* $Id$ */
+
+#ifndef NETWORK_CORE_UDP_H
+#define NETWORK_CORE_UDP_H
+
+#ifdef ENABLE_NETWORK
+
+/**
+ * @file udp.h Basic functions to receive and send UDP packets.
+ */
+
+///** Sending/receiving of UDP packets **////
+
+void NetworkSendUDP_Packet(SOCKET udp, Packet *p, struct sockaddr_in *recv);
+bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast);
+void NetworkUDPReceive(SOCKET udp);
+
+/**
+ * Function that is called for every received UDP packet.
+ * @param packet      the received packet
+ * @param client_addr the address of the sender of the packet
+ */
+void NetworkHandleUDPPacket(Packet *p, struct sockaddr_in *client_addr);
+
+
+///** Sending/receiving of (large) chuncks of UDP packets **////
+
+
+/** Enum with all types of UDP packets. The order MUST not be changed **/
+enum {
+	PACKET_UDP_CLIENT_FIND_SERVER,   ///< Queries a game server for game information
+	PACKET_UDP_SERVER_RESPONSE,      ///< Reply of the game server with game information
+	PACKET_UDP_CLIENT_DETAIL_INFO,   ///< Queries a game server about details of the game, such as companies
+	PACKET_UDP_SERVER_DETAIL_INFO,   ///< Reply of the game server about details of the game, such as companies
+	PACKET_UDP_SERVER_REGISTER,      ///< Packet to register itself to the master server
+	PACKET_UDP_MASTER_ACK_REGISTER,  ///< Packet indicating registration has succedeed
+	PACKET_UDP_CLIENT_GET_LIST,      ///< Request for serverlist from master server
+	PACKET_UDP_MASTER_RESPONSE_LIST, ///< Response from master server with server ip's + port's
+	PACKET_UDP_SERVER_UNREGISTER,    ///< Request to be removed from the server-list
+	PACKET_UDP_CLIENT_GET_NEWGRFS,   ///< Requests the name for a list of GRFs (GRF_ID and MD5)
+	PACKET_UDP_SERVER_NEWGRFS,       ///< Sends the list of NewGRF's requested.
+	PACKET_UDP_END                   ///< Must ALWAYS be on the end of this list!! (period)
+};
+
+void NetworkSend_GRFIdentifier(Packet *p, const GRFConfig *c);
+void NetworkSend_NetworkGameInfo(Packet *p, const NetworkGameInfo *info);
+
+void NetworkRecv_GRFIdentifier(NetworkClientState *cs, Packet *p, GRFConfig *c);
+void NetworkRecv_NetworkGameInfo(NetworkClientState *cs, Packet *p, NetworkGameInfo *info);
+
+/**
+ * Function that is called for every GRFConfig that is read when receiving
+ * a NetworkGameInfo. Only grfid and md5sum are set, the rest is zero. This
+ * function must set all appropriate fields. This GRF is later appended to
+ * the grfconfig list of the NetworkGameInfo.
+ * @param config the GRF to handle
+ */
+void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config);
+
+#endif /* ENABLE_NETWORK */
+
+#endif /* NETWORK_CORE_UDP_H */
diff --git a/network.c b/network/network.c
similarity index 98%
rename from network.c
rename to network/network.c
index 8b5b9ceef8..83f7eedcd7 100644
--- a/network.c
+++ b/network/network.c
@@ -1,6 +1,6 @@
 /* $Id$ */
 
-#include "stdafx.h"
+#include "../stdafx.h"
 #include "network_data.h"
 
 #if defined(WITH_REV)
@@ -15,24 +15,27 @@
 
 #ifdef ENABLE_NETWORK
 
-#include "openttd.h"
-#include "debug.h"
-#include "functions.h"
-#include "string.h"
-#include "strings.h"
-#include "map.h"
-#include "command.h"
-#include "variables.h"
-#include "date.h"
-#include "table/strings.h"
+#include "../openttd.h"
+#include "../debug.h"
+#include "../functions.h"
+#include "../string.h"
+#include "../strings.h"
+#include "../map.h"
+#include "../command.h"
+#include "../variables.h"
+#include "../date.h"
+#include "../newgrf_config.h"
+#include "../table/strings.h"
 #include "network_client.h"
 #include "network_server.h"
 #include "network_udp.h"
 #include "network_gamelist.h"
+#include "core/udp.h"
+#include "core/tcp.h"
 #include "network_gui.h"
-#include "console.h" /* IConsoleCmdExec */
+#include "../console.h" /* IConsoleCmdExec */
 #include <stdarg.h> /* va_list */
-#include "md5.h"
+#include "../md5.h"
 
 #ifdef __MORPHOS__
 // the library base is required here
diff --git a/network.h b/network/network.h
similarity index 68%
rename from network.h
rename to network/network.h
index 5453658e42..779fe393ec 100644
--- a/network.h
+++ b/network/network.h
@@ -7,7 +7,9 @@
 
 #ifdef ENABLE_NETWORK
 
-#include "player.h"
+#include "../player.h"
+#include "core/config.h"
+#include "core/game.h"
 
 // If this line is enable, every frame will have a sync test
 //  this is not needed in normal games. Normal is like 1 sync in 100
@@ -31,13 +33,6 @@
 // Do not change this next line. It should _ALWAYS_ be MAX_CLIENTS + 1
 #define MAX_CLIENT_INFO (MAX_CLIENTS + 1)
 
-/* Stuff for the master-server */
-#define NETWORK_MASTER_SERVER_PORT 3978
-#define NETWORK_MASTER_SERVER_HOST "master.openttd.org"
-#define NETWORK_MASTER_SERVER_WELCOME_MESSAGE "OpenTTDRegister"
-
-#define NETWORK_DEFAULT_PORT 3979
-
 #define MAX_INTERFACES 9
 
 
@@ -45,60 +40,6 @@
 #define NETWORK_VEHICLE_TYPES 5
 #define NETWORK_STATION_TYPES 5
 
-enum {
-	NETWORK_NAME_LENGTH        =  80,
-	NETWORK_HOSTNAME_LENGTH    =  80,
-	NETWORK_REVISION_LENGTH    =  15,
-	NETWORK_PASSWORD_LENGTH    =  20,
-	NETWORK_PLAYERS_LENGTH     = 200,
-	NETWORK_CLIENT_NAME_LENGTH =  25,
-	NETWORK_RCONCOMMAND_LENGTH = 500,
-
-	NETWORK_GRF_NAME_LENGTH    =  80, ///< Maximum length of the name of a GRF
-	/* Maximum number of GRFs that can be sent.
-	 * This value is related to number of handles (files) OpenTTD can open.
-	 * This is currently 64 and about 10 are currently used when OpenTTD loads
-	 * without any NewGRFs. Therefore one can only load about 55 NewGRFs, so
-	 * this is not a limit, but rather a way to easily check whether the limit
-	 * imposed by the handle count is reached. Secondly it isn't possible to
-	 * send much more GRF IDs + MD5sums in the PACKET_UDP_SERVER_RESPONSE, due
-	 * to the limited size of UDP packets. */
-	NETWORK_MAX_GRF_COUNT      =  55,
-
-	NETWORK_NUM_LANGUAGES      =   4,
-};
-
-// This is the struct used by both client and server
-//  some fields will be empty on the client (like game_password) by default
-//  and only filled with data a player enters.
-typedef struct NetworkGameInfo {
-	char server_name[NETWORK_NAME_LENGTH];          // Server name
-	char hostname[NETWORK_HOSTNAME_LENGTH];         // Hostname of the server (if any)
-	char server_revision[NETWORK_REVISION_LENGTH];  // The SVN version number the server is using (e.g.: 'r304')
-	                                                //  It even shows a SVN version in release-version, so
-	                                                //  it is easy to compare if a server is of the correct version
-	bool version_compatible;                        // Can we connect to this server or not? (based on server_revision)
-	bool compatible;                                // Can we connect to this server or not? (based on server_revision _and_ grf_match
-	byte server_lang;                               // Language of the server (we should make a nice table for this)
-	byte use_password;                              // Is set to != 0 if it uses a password
-	char server_password[NETWORK_PASSWORD_LENGTH];  // On the server: the game password, on the client: != "" if server has password
-	byte clients_max;                               // Max clients allowed on server
-	byte clients_on;                                // Current count of clients on server
-	byte companies_max;                             // Max companies allowed on server
-	byte companies_on;                              // How many started companies do we have (XXX - disabled for server atm, use ActivePlayerCount())
-	byte spectators_max;                            // Max spectators allowed on server
-	byte spectators_on;                             // How many spectators do we have? (XXX - disabled for server atm, use NetworkSpectatorCount())
-	Date game_date;                                 // Current date
-	Date start_date;                                // When the game started
-	char map_name[NETWORK_NAME_LENGTH];             // Map which is played ["random" for a randomized map]
-	uint16 map_width;                               // Map width
-	uint16 map_height;                              // Map height
-	byte map_set;                                   // Graphical set
-	bool dedicated;                                 // Is this a dedicated server?
-	char rcon_password[NETWORK_PASSWORD_LENGTH];    // RCon password for the server. "" if rcon is disabled
-	struct GRFConfig *grfconfig;                    // List of NewGRF files required
-} NetworkGameInfo;
-
 typedef struct NetworkPlayerInfo {
 	char company_name[NETWORK_NAME_LENGTH];         // Company name
 	char password[NETWORK_PASSWORD_LENGTH];         // The password for the player
diff --git a/network_client.c b/network/network_client.c
similarity index 98%
rename from network_client.c
rename to network/network_client.c
index 39a12c28c9..ce2a71ac19 100644
--- a/network_client.c
+++ b/network/network_client.c
@@ -2,23 +2,24 @@
 
 #ifdef ENABLE_NETWORK
 
-#include "stdafx.h"
-#include "debug.h"
-#include "string.h"
-#include "strings.h"
+#include "../stdafx.h"
+#include "../debug.h"
+#include "../string.h"
+#include "../strings.h"
 #include "network_data.h"
-#include "date.h"
-#include "table/strings.h"
-#include "functions.h"
+#include "core/tcp.h"
+#include "../date.h"
+#include "../table/strings.h"
+#include "../functions.h"
 #include "network_client.h"
 #include "network_gamelist.h"
 #include "network_gui.h"
-#include "saveload.h"
-#include "command.h"
-#include "window.h"
-#include "console.h"
-#include "variables.h"
-#include "ai/ai.h"
+#include "../saveload.h"
+#include "../command.h"
+#include "../window.h"
+#include "../console.h"
+#include "../variables.h"
+#include "../ai/ai.h"
 
 
 // This file handles all the client-commands
diff --git a/network_client.h b/network/network_client.h
similarity index 100%
rename from network_client.h
rename to network/network_client.h
diff --git a/network/network_data.c b/network/network_data.c
new file mode 100644
index 0000000000..9e5e6424d3
--- /dev/null
+++ b/network/network_data.c
@@ -0,0 +1,106 @@
+/* $Id$ */
+
+#ifdef ENABLE_NETWORK
+
+#include "../stdafx.h"
+#include "../debug.h"
+#include "network_data.h"
+#include "../string.h"
+#include "network_client.h"
+#include "../command.h"
+#include "../callback_table.h"
+
+// Add a command to the local command queue
+void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *cp)
+{
+	CommandPacket* new_cp = malloc(sizeof(*new_cp));
+
+	*new_cp = *cp;
+
+	if (cs->command_queue == NULL) {
+		cs->command_queue = new_cp;
+	} else {
+		CommandPacket *c = cs->command_queue;
+		while (c->next != NULL) c = c->next;
+		c->next = new_cp;
+	}
+}
+
+// Prepare a DoCommand to be send over the network
+void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback)
+{
+	CommandPacket *c = malloc(sizeof(CommandPacket));
+	byte temp_callback;
+
+	c->player = _local_player;
+	c->next = NULL;
+	c->tile = tile;
+	c->p1 = p1;
+	c->p2 = p2;
+	c->cmd = cmd;
+	c->callback = 0;
+
+	temp_callback = 0;
+
+	while (temp_callback < _callback_table_count && _callback_table[temp_callback] != callback)
+		temp_callback++;
+	if (temp_callback == _callback_table_count) {
+		DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", callback);
+		temp_callback = 0; /* _callback_table[0] == NULL */
+	}
+
+	if (_network_server) {
+		// We are the server, so set the command to be executed next possible frame
+		c->frame = _frame_counter_max + 1;
+	} else {
+		c->frame = 0; // The client can't tell which frame, so just make it 0
+	}
+
+	ttd_strlcpy(c->text, (_cmd_text != NULL) ? _cmd_text : "", lengthof(c->text));
+
+	if (_network_server) {
+		// If we are the server, we queue the command in our 'special' queue.
+		//   In theory, we could execute the command right away, but then the
+		//   client on the server can do everything 1 tick faster than others.
+		//   So to keep the game fair, we delay the command with 1 tick
+		//   which gives about the same speed as most clients.
+		NetworkClientState *cs;
+
+		// And we queue it for delivery to the clients
+		FOR_ALL_CLIENTS(cs) {
+			if (cs->status > STATUS_AUTH) NetworkAddCommandQueue(cs, c);
+		}
+
+		// Only the server gets the callback, because clients should not get them
+		c->callback = temp_callback;
+		if (_local_command_queue == NULL) {
+			_local_command_queue = c;
+		} else {
+			// Find last packet
+			CommandPacket *cp = _local_command_queue;
+			while (cp->next != NULL) cp = cp->next;
+			cp->next = c;
+		}
+
+		return;
+	}
+
+	// Clients send their command to the server and forget all about the packet
+	c->callback = temp_callback;
+	SEND_COMMAND(PACKET_CLIENT_COMMAND)(c);
+}
+
+// Execute a DoCommand we received from the network
+void NetworkExecuteCommand(CommandPacket *cp)
+{
+	_current_player = cp->player;
+	_cmd_text = cp->text;
+	/* cp->callback is unsigned. so we don't need to do lower bounds checking. */
+	if (cp->callback > _callback_table_count) {
+		DEBUG(net, 0, "Received out-of-bounds callback (%d)", cp->callback);
+		cp->callback = 0;
+	}
+	DoCommandP(cp->tile, cp->p1, cp->p2, _callback_table[cp->callback], cp->cmd | CMD_NETWORK_COMMAND);
+}
+
+#endif /* ENABLE_NETWORK */
diff --git a/network_data.h b/network/network_data.h
similarity index 69%
rename from network_data.h
rename to network/network_data.h
index 16263c7762..3e42e00cf1 100644
--- a/network_data.h
+++ b/network/network_data.h
@@ -3,36 +3,21 @@
 #ifndef NETWORK_DATA_H
 #define NETWORK_DATA_H
 
-#include "openttd.h"
-#include "network.h"
-#include "network_core.h"
-
 // Is the network enabled?
 #ifdef ENABLE_NETWORK
 
-#define SEND_MTU 1460
+#include "../openttd.h"
+#include "network.h"
+#include "core/os_abstraction.h"
+#include "core/config.h"
+#include "core/packet.h"
+
 #define MAX_TEXT_MSG_LEN 1024 /* long long long long sentences :-) */
 
 // The client-info-server-index is always 1
 #define NETWORK_SERVER_INDEX 1
 #define NETWORK_EMPTY_INDEX 0
 
-// What version of game-info do we use?
-#define NETWORK_GAME_INFO_VERSION 4
-// What version of company info is this?
-#define NETWORK_COMPANY_INFO_VERSION 4
-// What version of master-server-protocol do we use?
-#define NETWORK_MASTER_SERVER_VERSION 1
-
-typedef uint16 PacketSize;
-
-typedef struct Packet {
-	struct Packet *next;
-	PacketSize size;
-	PacketSize pos;
-	byte buffer[SEND_MTU];
-} Packet;
-
 typedef struct CommandPacket {
 	struct CommandPacket *next;
 	PlayerID player; /// player that is executing the command
@@ -112,7 +97,7 @@ typedef enum {
 } NetworkPasswordType;
 
 // To keep the clients all together
-typedef struct NetworkClientState {
+struct NetworkClientState { // Typedeffed in network_core/packet.h
 	SOCKET socket;
 	uint16 index;
 	uint32 last_frame;
@@ -127,47 +112,7 @@ typedef struct NetworkClientState {
 	Packet *packet_recv; // Partially received packet
 
 	CommandPacket *command_queue; // The command-queue awaiting delivery
-} NetworkClientState;
-
-// What packet types are there
-// WARNING: The first 3 packets can NEVER change order again
-//   it protects old clients from joining newer servers (because SERVER_ERROR
-//   is the respond to a wrong revision)
-typedef enum {
-	PACKET_SERVER_FULL,
-	PACKET_SERVER_BANNED,
-	PACKET_CLIENT_JOIN,
-	PACKET_SERVER_ERROR,
-	PACKET_CLIENT_COMPANY_INFO,
-	PACKET_SERVER_COMPANY_INFO,
-	PACKET_SERVER_CLIENT_INFO,
-	PACKET_SERVER_NEED_PASSWORD,
-	PACKET_CLIENT_PASSWORD,
-	PACKET_SERVER_WELCOME,
-	PACKET_CLIENT_GETMAP,
-	PACKET_SERVER_WAIT,
-	PACKET_SERVER_MAP,
-	PACKET_CLIENT_MAP_OK,
-	PACKET_SERVER_JOIN,
-	PACKET_SERVER_FRAME,
-	PACKET_SERVER_SYNC,
-	PACKET_CLIENT_ACK,
-	PACKET_CLIENT_COMMAND,
-	PACKET_SERVER_COMMAND,
-	PACKET_CLIENT_CHAT,
-	PACKET_SERVER_CHAT,
-	PACKET_CLIENT_SET_PASSWORD,
-	PACKET_CLIENT_SET_NAME,
-	PACKET_CLIENT_QUIT,
-	PACKET_CLIENT_ERROR,
-	PACKET_SERVER_QUIT,
-	PACKET_SERVER_ERROR_QUIT,
-	PACKET_SERVER_SHUTDOWN,
-	PACKET_SERVER_NEWGAME,
-	PACKET_SERVER_RCON,
-	PACKET_CLIENT_RCON,
-	PACKET_END // Should ALWAYS be on the end of this list!! (period)
-} PacketType;
+};
 
 typedef enum {
 	DESTTYPE_BROADCAST, ///< Send message/notice to all players (All)
@@ -202,22 +147,6 @@ NetworkClientState _clients[MAX_CLIENTS];
 #define FOR_ALL_CLIENTS(cs) for (cs = _clients; cs != endof(_clients) && cs->socket != INVALID_SOCKET; cs++)
 #define FOR_ALL_ACTIVE_CLIENT_INFOS(ci) for (ci = _network_client_info; ci != endof(_network_client_info); ci++) if (ci->client_index != NETWORK_EMPTY_INDEX)
 
-Packet *NetworkSend_Init(PacketType type);
-void NetworkSend_uint8(Packet *packet, uint8 data);
-void NetworkSend_uint16(Packet *packet, uint16 data);
-void NetworkSend_uint32(Packet *packet, uint32 data);
-void NetworkSend_uint64(Packet *packet, uint64 data);
-void NetworkSend_string(Packet *packet, const char* data);
-void NetworkSend_Packet(Packet *packet, NetworkClientState *cs);
-
-uint8 NetworkRecv_uint8(NetworkClientState *cs, Packet *packet);
-uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet);
-uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet);
-uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet);
-void NetworkRecv_string(NetworkClientState *cs, Packet *packet, char* buffer, size_t size);
-Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status);
-
-bool NetworkSend_Packets(NetworkClientState *cs);
 void NetworkExecuteCommand(CommandPacket *cp);
 void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *cp);
 
diff --git a/network_gamelist.c b/network/network_gamelist.c
similarity index 95%
rename from network_gamelist.c
rename to network/network_gamelist.c
index 15fd7aa573..a830073adb 100644
--- a/network_gamelist.c
+++ b/network/network_gamelist.c
@@ -2,10 +2,10 @@
 
 #ifdef ENABLE_NETWORK
 
-#include "stdafx.h"
-#include "debug.h"
+#include "../stdafx.h"
+#include "../debug.h"
 #include "network_data.h"
-#include "newgrf_config.h"
+#include "../newgrf_config.h"
 
 // This file handles the GameList
 // Also, it handles the request to a server for data about the server
diff --git a/network_gamelist.h b/network/network_gamelist.h
similarity index 100%
rename from network_gamelist.h
rename to network/network_gamelist.h
diff --git a/network_gui.c b/network/network_gui.c
similarity index 99%
rename from network_gui.c
rename to network/network_gui.c
index d0dd5df4cb..91c990bbca 100644
--- a/network_gui.c
+++ b/network/network_gui.c
@@ -1,32 +1,32 @@
 /* $Id$ */
 
 #ifdef ENABLE_NETWORK
-#include "stdafx.h"
-#include "openttd.h"
-#include "string.h"
-#include "strings.h"
-#include "table/sprites.h"
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../string.h"
+#include "../strings.h"
+#include "../table/sprites.h"
 #include "network.h"
-#include "date.h"
+#include "../date.h"
 
-#include "fios.h"
-#include "table/strings.h"
-#include "functions.h"
+#include "../fios.h"
+#include "../table/strings.h"
+#include "../functions.h"
 #include "network_data.h"
 #include "network_client.h"
 #include "network_gui.h"
 #include "network_gamelist.h"
-#include "window.h"
-#include "gui.h"
-#include "gfx.h"
-#include "command.h"
-#include "variables.h"
+#include "../window.h"
+#include "../gui.h"
+#include "../gfx.h"
+#include "../command.h"
+#include "../variables.h"
 #include "network_server.h"
 #include "network_udp.h"
-#include "settings.h"
-#include "string.h"
-#include "town.h"
-#include "newgrf.h"
+#include "../settings.h"
+#include "../string.h"
+#include "../town.h"
+#include "../newgrf.h"
 
 #define BGC 5
 #define BTC 15
diff --git a/network_gui.h b/network/network_gui.h
similarity index 100%
rename from network_gui.h
rename to network/network_gui.h
diff --git a/network_server.c b/network/network_server.c
similarity index 99%
rename from network_server.c
rename to network/network_server.c
index f1179ce2fa..2a75d15feb 100644
--- a/network_server.c
+++ b/network/network_server.c
@@ -2,25 +2,26 @@
 
 #ifdef ENABLE_NETWORK
 
-#include "stdafx.h"
-#include "openttd.h" // XXX StringID
-#include "debug.h"
-#include "string.h"
-#include "strings.h"
+#include "../stdafx.h"
+#include "../openttd.h" // XXX StringID
+#include "../debug.h"
+#include "../string.h"
+#include "../strings.h"
 #include "network_data.h"
-#include "train.h"
-#include "date.h"
-#include "table/strings.h"
-#include "functions.h"
+#include "core/tcp.h"
+#include "../train.h"
+#include "../date.h"
+#include "../table/strings.h"
+#include "../functions.h"
 #include "network_server.h"
 #include "network_udp.h"
-#include "console.h"
-#include "command.h"
-#include "saveload.h"
-#include "vehicle.h"
-#include "station.h"
-#include "variables.h"
-#include "genworld.h"
+#include "../console.h"
+#include "../command.h"
+#include "../saveload.h"
+#include "../vehicle.h"
+#include "../station.h"
+#include "../variables.h"
+#include "../genworld.h"
 
 // This file handles all the server-commands
 
diff --git a/network_server.h b/network/network_server.h
similarity index 100%
rename from network_server.h
rename to network/network_server.h
diff --git a/network_udp.c b/network/network_udp.c
similarity index 64%
rename from network_udp.c
rename to network/network_udp.c
index a2d6ed3955..aeef75e775 100644
--- a/network_udp.c
+++ b/network/network_udp.c
@@ -2,37 +2,25 @@
 
 #ifdef ENABLE_NETWORK
 
-#include "stdafx.h"
-#include "debug.h"
-#include "string.h"
+#include "../stdafx.h"
+#include "../debug.h"
+#include "../string.h"
 #include "network_data.h"
-#include "date.h"
-#include "map.h"
+#include "../date.h"
+#include "../map.h"
 #include "network_gamelist.h"
 #include "network_udp.h"
-#include "variables.h"
-#include "newgrf_config.h"
+#include "../variables.h"
+#include "../newgrf_config.h"
 
-//
-// This file handles all the LAN-stuff
-// Stuff like:
-//   - UDP search over the network
-//
+#include "core/udp.h"
 
-typedef enum {
-	PACKET_UDP_CLIENT_FIND_SERVER,
-	PACKET_UDP_SERVER_RESPONSE,
-	PACKET_UDP_CLIENT_DETAIL_INFO,
-	PACKET_UDP_SERVER_DETAIL_INFO,   // Is not used in OpenTTD itself, only for external querying
-	PACKET_UDP_SERVER_REGISTER,      // Packet to register itself to the master server
-	PACKET_UDP_MASTER_ACK_REGISTER,  // Packet indicating registration has succedeed
-	PACKET_UDP_CLIENT_GET_LIST,      // Request for serverlist from master server
-	PACKET_UDP_MASTER_RESPONSE_LIST, // Response from master server with server ip's + port's
-	PACKET_UDP_SERVER_UNREGISTER,    // Request to be removed from the server-list
-	PACKET_UDP_CLIENT_GET_NEWGRFS,   // Requests the name for a list of GRFs (GRF_ID and MD5)
-	PACKET_UDP_SERVER_NEWGRFS,       // Sends the list of NewGRF's requested.
-	PACKET_UDP_END
-} PacketUDPType;
+/**
+ * @file network_udp.c This file handles the UDP related communication.
+ *
+ * This is the GameServer <-> MasterServer and GameServer <-> GameClient
+ * communication before the game is being joined.
+ */
 
 enum {
 	ADVERTISE_NORMAL_INTERVAL = 30000, // interval between advertising in ticks (15 minutes)
@@ -41,38 +29,9 @@ enum {
 };
 
 #define DEF_UDP_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(Packet *p, struct sockaddr_in *client_addr)
-static void NetworkSendUDP_Packet(SOCKET udp, Packet* p, struct sockaddr_in* recv);
 
 static NetworkClientState _udp_cs;
 
-/**
- * Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet
- * @param p the packet to write the data to
- * @param c the configuration to write the GRF ID and MD5 checksum from
- */
-static void NetworkSend_GRFIdentifier(Packet *p, const GRFConfig *c)
-{
-	uint j;
-	NetworkSend_uint32(p, c->grfid);
-	for (j = 0; j < sizeof(c->md5sum); j++) {
-		NetworkSend_uint8 (p, c->md5sum[j]);
-	}
-}
-
-/**
- * Deserializes the GRFIdentifier (GRF ID and MD5 checksum) from the packet
- * @param p the packet to read the data from
- * @param c the configuration to write the GRF ID and MD5 checksum to
- */
-static void NetworkRecv_GRFIdentifier(Packet *p, GRFConfig *c)
-{
-	uint j;
-	c->grfid = NetworkRecv_uint32(&_udp_cs, p);
-	for (j = 0; j < sizeof(c->md5sum); j++) {
-		c->md5sum[j] = NetworkRecv_uint8(&_udp_cs, p);
-	}
-}
-
 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
 {
 	Packet *packet;
@@ -83,56 +42,15 @@ DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
 	packet = NetworkSend_Init(PACKET_UDP_SERVER_RESPONSE);
 
 	// Update some game_info
-	_network_game_info.game_date = _date;
-	_network_game_info.map_width = MapSizeX();
-	_network_game_info.map_height = MapSizeY();
-	_network_game_info.map_set = _opt.landscape;
+	_network_game_info.game_date     = _date;
+	_network_game_info.map_width     = MapSizeX();
+	_network_game_info.map_height    = MapSizeY();
+	_network_game_info.map_set       = _opt.landscape;
+	_network_game_info.companies_on  = ActivePlayerCount();
+	_network_game_info.spectators_on = NetworkSpectatorCount();
+	_network_game_info.grfconfig     = _grfconfig;
 
-	NetworkSend_uint8 (packet, NETWORK_GAME_INFO_VERSION);
-
-	/* NETWORK_GAME_INFO_VERSION = 4 */
-	{
-		/* Only send the GRF Identification (GRF_ID and MD5 checksum) of
-		 * the GRFs that are needed, i.e. the ones that the server has
-		 * selected in the NewGRF GUI and not the ones that are used due
-		 * to the fact that they are in [newgrf-static] in openttd.cfg */
-		const GRFConfig *c;
-		uint i = 0;
-
-		/* Count number of GRFs to send information about */
-		for (c = _grfconfig; c != NULL; c = c->next) {
-			if (!HASBIT(c->flags, GCF_STATIC)) i++;
-		}
-		NetworkSend_uint8 (packet, i); // Send number of GRFs
-
-		/* Send actual GRF Identifications */
-		for (c = _grfconfig; c != NULL; c = c->next) {
-			if (!HASBIT(c->flags, GCF_STATIC)) NetworkSend_GRFIdentifier(packet, c);
-		}
-	}
-
-	/* NETWORK_GAME_INFO_VERSION = 3 */
-	NetworkSend_uint32(packet, _network_game_info.game_date);
-	NetworkSend_uint32(packet, _network_game_info.start_date);
-
-	/* NETWORK_GAME_INFO_VERSION = 2 */
-	NetworkSend_uint8 (packet, _network_game_info.companies_max);
-	NetworkSend_uint8 (packet, ActivePlayerCount());
-	NetworkSend_uint8 (packet, _network_game_info.spectators_max);
-
-	/* NETWORK_GAME_INFO_VERSION = 1 */
-	NetworkSend_string(packet, _network_game_info.server_name);
-	NetworkSend_string(packet, _network_game_info.server_revision);
-	NetworkSend_uint8 (packet, _network_game_info.server_lang);
-	NetworkSend_uint8 (packet, _network_game_info.use_password);
-	NetworkSend_uint8 (packet, _network_game_info.clients_max);
-	NetworkSend_uint8 (packet, _network_game_info.clients_on);
-	NetworkSend_uint8 (packet, NetworkSpectatorCount());
-	NetworkSend_string(packet, _network_game_info.map_name);
-	NetworkSend_uint16(packet, _network_game_info.map_width);
-	NetworkSend_uint16(packet, _network_game_info.map_height);
-	NetworkSend_uint8 (packet, _network_game_info.map_set);
-	NetworkSend_uint8 (packet, _network_game_info.dedicated);
+	NetworkSend_NetworkGameInfo(p, &_network_game_info);
 
 	// Let the client know that we are here
 	NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
@@ -142,101 +60,40 @@ DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
 	DEBUG(net, 2, "[udp] queried from '%s'", inet_ntoa(client_addr->sin_addr));
 }
 
+void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config)
+{
+	/* Find the matching GRF file */
+	const GRFConfig *f = FindGRFConfig(config->grfid, config->md5sum);
+	if (f == NULL) {
+		/* Don't know the GRF, so mark game incompatible and the (possibly)
+		 * already resolved name for this GRF (another server has sent the
+		 * name of the GRF already */
+		config->name     = FindUnknownGRFName(config->grfid, config->md5sum, true);
+		SETBIT(config->flags, GCF_NOT_FOUND);
+	} else {
+		config->filename = f->filename;
+		config->name     = f->name;
+		config->info     = f->info;
+	}
+	SETBIT(config->flags, GCF_COPY);
+}
+
 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE)
 {
 	extern const char _openttd_revision[];
 	NetworkGameList *item;
-	byte game_info_version;
 
 	// Just a fail-safe.. should never happen
-	if (_network_udp_server)
-		return;
-
-	game_info_version = NetworkRecv_uint8(&_udp_cs, p);
-
-	if (_udp_cs.has_quit) return;
+	if (_network_udp_server || _udp_cs.has_quit) return;
 
 	DEBUG(net, 4, "[udp] server response from %s:%d", inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
 
 	// Find next item
 	item = NetworkGameListAddItem(inet_addr(inet_ntoa(client_addr->sin_addr)), ntohs(client_addr->sin_port));
 
+	NetworkRecv_NetworkGameInfo(&_udp_cs, p, &item->info);
+
 	item->info.compatible = true;
-	/* Please observer the order. In the order in which packets are sent
-	 * they are to be received */
-	switch (game_info_version) {
-		case 4: {
-			GRFConfig *c, **dst = &item->info.grfconfig;
-			const GRFConfig *f;
-			uint i;
-			uint num_grfs = NetworkRecv_uint8(&_udp_cs, p);
-
-			for (i = 0; i < num_grfs; i++) {
-				c = calloc(1, sizeof(*c));
-				NetworkRecv_GRFIdentifier(p, c);
-
-				/* Find the matching GRF file */
-				f = FindGRFConfig(c->grfid, c->md5sum);
-				if (f == NULL) {
-					/* Don't know the GRF, so mark game incompatible and the (possibly)
-					 * already resolved name for this GRF (another server has sent the
-					 * name of the GRF already */
-					item->info.compatible = false;
-					c->name     = FindUnknownGRFName(c->grfid, c->md5sum, true);
-					SETBIT(c->flags, GCF_NOT_FOUND);
-				} else {
-					c->filename = f->filename;
-					c->name     = f->name;
-					c->info     = f->info;
-				}
-				SETBIT(c->flags, GCF_COPY);
-
-				/* Append GRFConfig to the list */
-				*dst = c;
-				dst = &c->next;
-			}
-		} /* Fallthrough */
-		case 3:
-			item->info.game_date     = NetworkRecv_uint32(&_udp_cs, p);
-			item->info.start_date    = NetworkRecv_uint32(&_udp_cs, p);
-			/* Fallthrough */
-		case 2:
-			item->info.companies_max = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.companies_on = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.spectators_max = NetworkRecv_uint8(&_udp_cs, p);
-			/* Fallthrough */
-		case 1:
-			NetworkRecv_string(&_udp_cs, p, item->info.server_name, sizeof(item->info.server_name));
-			NetworkRecv_string(&_udp_cs, p, item->info.server_revision, sizeof(item->info.server_revision));
-			item->info.server_lang   = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.use_password  = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.clients_max   = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.clients_on    = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.spectators_on = NetworkRecv_uint8(&_udp_cs, p);
-			if (game_info_version < 3) { // 16 bits dates got scrapped and are read earlier
-				item->info.game_date     = NetworkRecv_uint16(&_udp_cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR;
-				item->info.start_date    = NetworkRecv_uint16(&_udp_cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR;
-			}
-			NetworkRecv_string(&_udp_cs, p, item->info.map_name, sizeof(item->info.map_name));
-			item->info.map_width     = NetworkRecv_uint16(&_udp_cs, p);
-			item->info.map_height    = NetworkRecv_uint16(&_udp_cs, p);
-			item->info.map_set       = NetworkRecv_uint8(&_udp_cs, p);
-			item->info.dedicated     = NetworkRecv_uint8(&_udp_cs, p);
-
-			if (item->info.server_lang >= NETWORK_NUM_LANGUAGES) item->info.server_lang = 0;
-			if (item->info.map_set >= NUM_LANDSCAPE ) item->info.map_set = 0;
-
-			if (item->info.hostname[0] == '\0')
-				snprintf(item->info.hostname, sizeof(item->info.hostname), "%s", inet_ntoa(client_addr->sin_addr));
-
-			/* Check if we are allowed on this server based on the revision-match */
-			item->info.version_compatible =
-				strcmp(item->info.server_revision, _openttd_revision) == 0 ||
-				strcmp(item->info.server_revision, NOREV_STRING) == 0;
-			item->info.compatible &= item->info.version_compatible; // Already contains match for GRFs
-			break;
-	}
-
 	{
 		/* Checks whether there needs to be a request for names of GRFs and makes
 		 * the request if necessary. GRFs that need to be requested are the GRFs
@@ -251,6 +108,7 @@ DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE)
 		struct sockaddr_in out_addr;
 
 		for (c = item->info.grfconfig; c != NULL; c = c->next) {
+			if (HASBIT(c->flags, GCF_NOT_FOUND)) item->info.compatible = false;
 			if (!HASBIT(c->flags, GCF_NOT_FOUND) || strcmp(c->name, UNKNOWN_GRF_NAME_PLACEHOLDER) != 0) continue;
 			in_request[in_request_count] = c;
 			in_request_count++;
@@ -274,6 +132,18 @@ DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE)
 		}
 	}
 
+	if (item->info.server_lang >= NETWORK_NUM_LANGUAGES) item->info.server_lang = 0;
+	if (item->info.map_set >= NUM_LANDSCAPE ) item->info.map_set = 0;
+
+	if (item->info.hostname[0] == '\0')
+		snprintf(item->info.hostname, sizeof(item->info.hostname), "%s", inet_ntoa(client_addr->sin_addr));
+
+	/* Check if we are allowed on this server based on the revision-match */
+	item->info.version_compatible =
+		strcmp(item->info.server_revision, _openttd_revision) == 0 ||
+		strcmp(item->info.server_revision, NOREV_STRING) == 0;
+	item->info.compatible &= item->info.version_compatible; // Already contains match for GRFs
+
 	item->online = true;
 
 	UpdateNetworkGameWindow(false);
@@ -455,7 +325,7 @@ DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS)
 		GRFConfig c;
 		const GRFConfig *f;
 
-		NetworkRecv_GRFIdentifier(p, &c);
+		NetworkRecv_GRFIdentifier(&_udp_cs, p, &c);
 
 		/* Find the matching GRF file */
 		f = FindGRFConfig(c.grfid, c.md5sum);
@@ -510,7 +380,7 @@ DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_NEWGRFS)
 		char name[NETWORK_GRF_NAME_LENGTH];
 		GRFConfig c;
 
-		NetworkRecv_GRFIdentifier(p, &c);
+		NetworkRecv_GRFIdentifier(&_udp_cs, p, &c);
 		NetworkRecv_string(&_udp_cs, p, name, sizeof(name));
 
 		/* An empty name is not possible under normal circumstances
@@ -550,7 +420,7 @@ static NetworkUDPPacket* const _network_udp_packet[] = {
 assert_compile(lengthof(_network_udp_packet) == PACKET_UDP_END);
 
 
-static void NetworkHandleUDPPacket(Packet* p, struct sockaddr_in* client_addr)
+void NetworkHandleUDPPacket(Packet *p, struct sockaddr_in *client_addr)
 {
 	byte type;
 
@@ -572,69 +442,6 @@ static void NetworkHandleUDPPacket(Packet* p, struct sockaddr_in* client_addr)
 }
 
 
-// Send a packet over UDP
-static void NetworkSendUDP_Packet(SOCKET udp, Packet* p, struct sockaddr_in* recv)
-{
-	int res;
-
-	// Put the length in the buffer
-	p->buffer[0] = p->size & 0xFF;
-	p->buffer[1] = p->size >> 8;
-
-	// Send the buffer
-	res = sendto(udp, p->buffer, p->size, 0, (struct sockaddr *)recv, sizeof(*recv));
-
-	// Check for any errors, but ignore it otherwise
-	if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR());
-}
-
-// Start UDP listener
-bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast)
-{
-	struct sockaddr_in sin;
-
-	// Make sure socket is closed
-	closesocket(*udp);
-
-	*udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-	if (*udp == INVALID_SOCKET) {
-		DEBUG(net, 0, "[udp] failed to start UDP listener");
-		return false;
-	}
-
-	// set nonblocking mode for socket
-	{
-		unsigned long blocking = 1;
-#ifndef BEOS_NET_SERVER
-		ioctlsocket(*udp, FIONBIO, &blocking);
-#else
-		setsockopt(*udp, SOL_SOCKET, SO_NONBLOCK, &blocking, NULL);
-#endif
-	}
-
-	sin.sin_family = AF_INET;
-	// Listen on all IPs
-	sin.sin_addr.s_addr = host;
-	sin.sin_port = htons(port);
-
-	if (bind(*udp, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
-		DEBUG(net, 0, "[udp] bind failed on %s:%i", inet_ntoa(*(struct in_addr *)&host), port);
-		return false;
-	}
-
-	if (broadcast) {
-		/* Enable broadcast */
-		unsigned long val = 1;
-#ifndef BEOS_NET_SERVER // will work around this, some day; maybe.
-		setsockopt(*udp, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val));
-#endif
-	}
-
-	DEBUG(net, 1, "[udp] listening on port %s:%d", inet_ntoa(*(struct in_addr *)&host), port);
-
-	return true;
-}
-
 // Close UDP connection
 void NetworkUDPClose(void)
 {
@@ -662,42 +469,6 @@ void NetworkUDPClose(void)
 	}
 }
 
-// Receive something on UDP level
-void NetworkUDPReceive(SOCKET udp)
-{
-	struct sockaddr_in client_addr;
-	socklen_t client_len;
-	int nbytes;
-	static Packet *p = NULL;
-	int packet_len;
-
-	// If p is NULL, malloc him.. this prevents unneeded mallocs
-	if (p == NULL) p = malloc(sizeof(*p));
-
-	packet_len = sizeof(p->buffer);
-	client_len = sizeof(client_addr);
-
-	// Try to receive anything
-	nbytes = recvfrom(udp, p->buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len);
-
-	// We got some bytes.. just asume we receive the whole packet
-	if (nbytes > 0) {
-		// Get the size of the buffer
-		p->size = (uint16)p->buffer[0];
-		p->size += (uint16)p->buffer[1] << 8;
-		// Put the position on the right place
-		p->pos = 2;
-		p->next = NULL;
-
-		// Handle the packet
-		NetworkHandleUDPPacket(p, &client_addr);
-
-		// Free the packet
-		free(p);
-		p = NULL;
-	}
-}
-
 // Broadcast to all ips
 static void NetworkUDPBroadCast(SOCKET udp)
 {
diff --git a/network_udp.h b/network/network_udp.h
similarity index 77%
rename from network_udp.h
rename to network/network_udp.h
index b7814d3b23..4488d19d49 100644
--- a/network_udp.h
+++ b/network/network_udp.h
@@ -6,8 +6,6 @@
 #ifdef ENABLE_NETWORK
 
 void NetworkUDPInitialize(void);
-bool NetworkUDPListen(SOCKET *udp, uint32 host, uint16 port, bool broadcast);
-void NetworkUDPReceive(SOCKET udp);
 void NetworkUDPSearchGame(void);
 void NetworkUDPQueryMasterServer(void);
 NetworkGameList *NetworkUDPQueryServer(const char* host, unsigned short port);
diff --git a/network_data.c b/network_data.c
deleted file mode 100644
index 62e95e2cd3..0000000000
--- a/network_data.c
+++ /dev/null
@@ -1,473 +0,0 @@
-/* $Id$ */
-
-#ifdef ENABLE_NETWORK
-
-#include "stdafx.h"
-#include "debug.h"
-#include "network_data.h"
-#include "functions.h"
-#include "string.h"
-#include "table/strings.h"
-#include "network_client.h"
-#include "command.h"
-#include "callback_table.h"
-#include "variables.h"
-
-// This files handles the send/receive of all packets
-
-// Create a packet for sending
-Packet *NetworkSend_Init(PacketType type)
-{
-	Packet *packet = malloc(sizeof(Packet));
-	// An error is inplace here, because it simply means we ran out of memory.
-	if (packet == NULL) error("Failed to allocate Packet");
-
-	// Skip the size so we can write that in before sending the packet
-	packet->size = sizeof(packet->size);
-	packet->buffer[packet->size++] = type;
-	packet->pos = 0;
-
-	return packet;
-}
-
-// The next couple of functions make sure we can send
-//  uint8, uint16, uint32 and uint64 endian-safe
-//  over the network. The order it uses is:
-//
-//  1 2 3 4
-//
-
-void NetworkSend_uint8(Packet *packet, uint8 data)
-{
-	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
-	packet->buffer[packet->size++] = data;
-}
-
-void NetworkSend_uint16(Packet *packet, uint16 data)
-{
-	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
-	packet->buffer[packet->size++] = GB(data, 0, 8);
-	packet->buffer[packet->size++] = GB(data, 8, 8);
-}
-
-void NetworkSend_uint32(Packet *packet, uint32 data)
-{
-	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
-	packet->buffer[packet->size++] = GB(data,  0, 8);
-	packet->buffer[packet->size++] = GB(data,  8, 8);
-	packet->buffer[packet->size++] = GB(data, 16, 8);
-	packet->buffer[packet->size++] = GB(data, 24, 8);
-}
-
-void NetworkSend_uint64(Packet *packet, uint64 data)
-{
-	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
-	packet->buffer[packet->size++] = GB(data,  0, 8);
-	packet->buffer[packet->size++] = GB(data,  8, 8);
-	packet->buffer[packet->size++] = GB(data, 16, 8);
-	packet->buffer[packet->size++] = GB(data, 24, 8);
-	packet->buffer[packet->size++] = GB(data, 32, 8);
-	packet->buffer[packet->size++] = GB(data, 40, 8);
-	packet->buffer[packet->size++] = GB(data, 48, 8);
-	packet->buffer[packet->size++] = GB(data, 56, 8);
-}
-
-// Sends a string over the network. It sends out
-//  the string + '\0'. No size-byte or something.
-void NetworkSend_string(Packet *packet, const char* data)
-{
-	assert(data != NULL);
-	assert(packet->size < sizeof(packet->buffer) - strlen(data) - 1);
-	while ((packet->buffer[packet->size++] = *data++) != '\0') {}
-}
-
-// If PacketSize changes of size, you have to change the 2 packet->size
-//   lines below matching the size of packet->size/PacketSize!
-// (line 'packet->buffer[0] = packet->size & 0xFF;'  and below)
-assert_compile(sizeof(PacketSize) == 2);
-
-// This function puts the packet in the send-queue and it is send
-//  as soon as possible
-// (that is: the next tick, or maybe one tick later if the
-//   OS-network-buffer is full)
-void NetworkSend_Packet(Packet *packet, NetworkClientState *cs)
-{
-	Packet *p;
-	assert(packet != NULL);
-
-	packet->pos = 0;
-	packet->next = NULL;
-
-	packet->buffer[0] = GB(packet->size, 0, 8);
-	packet->buffer[1] = GB(packet->size, 8, 8);
-
-	// Locate last packet buffered for the client
-	p = cs->packet_queue;
-	if (p == NULL) {
-		// No packets yet
-		cs->packet_queue = packet;
-	} else {
-		// Skip to the last packet
-		while (p->next != NULL) p = p->next;
-		p->next = packet;
-	}
-}
-
-// Functions to help NetworkRecv_Packet/NetworkSend_Packet a bit
-//  A socket can make errors. When that happens
-//  this handles what to do.
-// For clients: close connection and drop back to main-menu
-// For servers: close connection and that is it
-static NetworkRecvStatus CloseConnection(NetworkClientState *cs)
-{
-	NetworkCloseClient(cs);
-
-	// Clients drop back to the main menu
-	if (!_network_server && _networking) {
-		_switch_mode = SM_MENU;
-		_networking = false;
-		_switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
-
-		return NETWORK_RECV_STATUS_CONN_LOST;
-	}
-
-	return NETWORK_RECV_STATUS_OKAY;
-}
-
-// Sends all the buffered packets out for this client
-//  it stops when:
-//   1) all packets are send (queue is empty)
-//   2) the OS reports back that it can not send any more
-//        data right now (full network-buffer, it happens ;))
-//   3) sending took too long
-bool NetworkSend_Packets(NetworkClientState *cs)
-{
-	ssize_t res;
-	Packet *p;
-
-	// We can not write to this socket!!
-	if (!cs->writable) return false;
-	if (cs->socket == INVALID_SOCKET) return false;
-
-	p = cs->packet_queue;
-	while (p != NULL) {
-		res = send(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
-		if (res == -1) {
-			int err = GET_LAST_ERROR();
-			if (err != EWOULDBLOCK) { // Something went wrong.. close client!
-				DEBUG(net, 0, "send failed with error %d", err);
-				CloseConnection(cs);
-				return false;
-			}
-			return true;
-		}
-		if (res == 0) {
-			// Client/server has left us :(
-			CloseConnection(cs);
-			return false;
-		}
-
-		p->pos += res;
-
-		// Is this packet sent?
-		if (p->pos == p->size) {
-			// Go to the next packet
-			cs->packet_queue = p->next;
-			free(p);
-			p = cs->packet_queue;
-		} else {
-			return true;
-		}
-	}
-
-	return true;
-}
-
-
-// Receiving commands
-// Again, the next couple of functions are endian-safe
-//  see the comment around NetworkSend_uint8 for more info.
-uint8 NetworkRecv_uint8(NetworkClientState *cs, Packet *packet)
-{
-	/* Don't allow reading from a closed socket */
-	if (cs->has_quit) return 0;
-
-	/* Check if variable is within packet-size */
-	if (packet->pos + 1 > packet->size) {
-		CloseConnection(cs);
-		return 0;
-	}
-
-	return packet->buffer[packet->pos++];
-}
-
-uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet)
-{
-	uint16 n;
-
-	/* Don't allow reading from a closed socket */
-	if (cs->has_quit) return 0;
-
-	/* Check if variable is within packet-size */
-	if (packet->pos + 2 > packet->size) {
-		CloseConnection(cs);
-		return 0;
-	}
-
-	n  = (uint16)packet->buffer[packet->pos++];
-	n += (uint16)packet->buffer[packet->pos++] << 8;
-	return n;
-}
-
-uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet)
-{
-	uint32 n;
-
-	/* Don't allow reading from a closed socket */
-	if (cs->has_quit) return 0;
-
-	/* Check if variable is within packet-size */
-	if (packet->pos + 4 > packet->size) {
-		CloseConnection(cs);
-		return 0;
-	}
-
-	n  = (uint32)packet->buffer[packet->pos++];
-	n += (uint32)packet->buffer[packet->pos++] << 8;
-	n += (uint32)packet->buffer[packet->pos++] << 16;
-	n += (uint32)packet->buffer[packet->pos++] << 24;
-	return n;
-}
-
-uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet)
-{
-	uint64 n;
-
-	/* Don't allow reading from a closed socket */
-	if (cs->has_quit) return 0;
-
-	/* Check if variable is within packet-size */
-	if (packet->pos + 8 > packet->size) {
-		CloseConnection(cs);
-		return 0;
-	}
-
-	n  = (uint64)packet->buffer[packet->pos++];
-	n += (uint64)packet->buffer[packet->pos++] << 8;
-	n += (uint64)packet->buffer[packet->pos++] << 16;
-	n += (uint64)packet->buffer[packet->pos++] << 24;
-	n += (uint64)packet->buffer[packet->pos++] << 32;
-	n += (uint64)packet->buffer[packet->pos++] << 40;
-	n += (uint64)packet->buffer[packet->pos++] << 48;
-	n += (uint64)packet->buffer[packet->pos++] << 56;
-	return n;
-}
-
-// Reads a string till it finds a '\0' in the stream
-void NetworkRecv_string(NetworkClientState *cs, Packet *p, char *buffer, size_t size)
-{
-	PacketSize pos;
-	char *bufp = buffer;
-
-	/* Don't allow reading from a closed socket */
-	if (cs->has_quit) return;
-
-	pos = p->pos;
-	while (--size > 0 && pos < p->size && (*buffer++ = p->buffer[pos++]) != '\0') {}
-
-	if (size == 0 || pos == p->size) {
-		*buffer = '\0';
-		// If size was sooner to zero then the string in the stream
-		//  skip till the \0, so the packet can be read out correctly for the rest
-		while (pos < p->size && p->buffer[pos] != '\0') pos++;
-		pos++;
-	}
-	p->pos = pos;
-
-	str_validate(bufp);
-}
-
-// If PacketSize changes of size, you have to change the 2 packet->size
-//   lines below matching the size of packet->size/PacketSize!
-// (the line: 'p->size = (uint16)p->buffer[0];' and below)
-assert_compile(sizeof(PacketSize) == 2);
-
-Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status)
-{
-	ssize_t res;
-	Packet *p;
-
-	*status = NETWORK_RECV_STATUS_OKAY;
-
-	if (cs->socket == INVALID_SOCKET) return NULL;
-
-	if (cs->packet_recv == NULL) {
-		cs->packet_recv = malloc(sizeof(Packet));
-		if (cs->packet_recv == NULL) error("Failed to allocate packet");
-		// Set pos to zero!
-		cs->packet_recv->pos = 0;
-		cs->packet_recv->size = 0; // Can be ommited, just for safety reasons
-	}
-
-	p = cs->packet_recv;
-
-	// Read packet size
-	if (p->pos < sizeof(PacketSize)) {
-		while (p->pos < sizeof(PacketSize)) {
-			// Read the size of the packet
-			res = recv(cs->socket, p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0);
-			if (res == -1) {
-				int err = GET_LAST_ERROR();
-				if (err != EWOULDBLOCK) {
-					/* Something went wrong... (104 is connection reset by peer) */
-					if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
-					*status = CloseConnection(cs);
-					return NULL;
-				}
-				// Connection would block, so stop for now
-				return NULL;
-			}
-			if (res == 0) {
-				// Client/server has left
-				*status = CloseConnection(cs);
-				return NULL;
-			}
-			p->pos += res;
-		}
-
-		p->size = (uint16)p->buffer[0];
-		p->size += (uint16)p->buffer[1] << 8;
-
-		if (p->size > SEND_MTU) {
-			*status = CloseConnection(cs);
-			return NULL;
-		}
-	}
-
-	// Read rest of packet
-	while (p->pos < p->size) {
-		res = recv(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
-		if (res == -1) {
-			int err = GET_LAST_ERROR();
-			if (err != EWOULDBLOCK) {
-				/* Something went wrong... (104 is connection reset by peer) */
-				if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
-				*status = CloseConnection(cs);
-				return NULL;
-			}
-			// Connection would block
-			return NULL;
-		}
-		if (res == 0) {
-			// Client/server has left
-			*status = CloseConnection(cs);
-			return NULL;
-		}
-
-		p->pos += res;
-	}
-
-	// We have a complete packet, return it!
-	p->pos = 2;
-	p->next = NULL; // Should not be needed, but who knows...
-
-	// Prepare for receiving a new packet
-	cs->packet_recv = NULL;
-
-	return p;
-}
-
-// Add a command to the local command queue
-void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *cp)
-{
-	CommandPacket* new_cp = malloc(sizeof(*new_cp));
-
-	*new_cp = *cp;
-
-	if (cs->command_queue == NULL) {
-		cs->command_queue = new_cp;
-	} else {
-		CommandPacket *c = cs->command_queue;
-		while (c->next != NULL) c = c->next;
-		c->next = new_cp;
-	}
-}
-
-// Prepare a DoCommand to be send over the network
-void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback)
-{
-	CommandPacket *c = malloc(sizeof(CommandPacket));
-	byte temp_callback;
-
-	c->player = _local_player;
-	c->next = NULL;
-	c->tile = tile;
-	c->p1 = p1;
-	c->p2 = p2;
-	c->cmd = cmd;
-	c->callback = 0;
-
-	temp_callback = 0;
-
-	while (temp_callback < _callback_table_count && _callback_table[temp_callback] != callback)
-		temp_callback++;
-	if (temp_callback == _callback_table_count) {
-		DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", callback);
-		temp_callback = 0; /* _callback_table[0] == NULL */
-	}
-
-	if (_network_server) {
-		// We are the server, so set the command to be executed next possible frame
-		c->frame = _frame_counter_max + 1;
-	} else {
-		c->frame = 0; // The client can't tell which frame, so just make it 0
-	}
-
-	ttd_strlcpy(c->text, (_cmd_text != NULL) ? _cmd_text : "", lengthof(c->text));
-
-	if (_network_server) {
-		// If we are the server, we queue the command in our 'special' queue.
-		//   In theory, we could execute the command right away, but then the
-		//   client on the server can do everything 1 tick faster than others.
-		//   So to keep the game fair, we delay the command with 1 tick
-		//   which gives about the same speed as most clients.
-		NetworkClientState *cs;
-
-		// And we queue it for delivery to the clients
-		FOR_ALL_CLIENTS(cs) {
-			if (cs->status > STATUS_AUTH) NetworkAddCommandQueue(cs, c);
-		}
-
-		// Only the server gets the callback, because clients should not get them
-		c->callback = temp_callback;
-		if (_local_command_queue == NULL) {
-			_local_command_queue = c;
-		} else {
-			// Find last packet
-			CommandPacket *cp = _local_command_queue;
-			while (cp->next != NULL) cp = cp->next;
-			cp->next = c;
-		}
-
-		return;
-	}
-
-	// Clients send their command to the server and forget all about the packet
-	c->callback = temp_callback;
-	SEND_COMMAND(PACKET_CLIENT_COMMAND)(c);
-}
-
-// Execute a DoCommand we received from the network
-void NetworkExecuteCommand(CommandPacket *cp)
-{
-	_current_player = cp->player;
-	_cmd_text = cp->text;
-	/* cp->callback is unsigned. so we don't need to do lower bounds checking. */
-	if (cp->callback > _callback_table_count) {
-		DEBUG(net, 0, "Received out-of-bounds callback (%d)", cp->callback);
-		cp->callback = 0;
-	}
-	DoCommandP(cp->tile, cp->p1, cp->p2, _callback_table[cp->callback], cp->cmd | CMD_NETWORK_COMMAND);
-}
-
-#endif /* ENABLE_NETWORK */
diff --git a/newgrf_config.c b/newgrf_config.c
index aa15ffb773..a6ab2fae5d 100644
--- a/newgrf_config.c
+++ b/newgrf_config.c
@@ -9,7 +9,7 @@
 #include "string.h"
 #include "saveload.h"
 #include "md5.h"
-#include "network_data.h"
+#include "network/network_data.h"
 #include "newgrf.h"
 #include "newgrf_config.h"
 
diff --git a/npf.c b/npf.c
index eabce79625..97b9bf367a 100644
--- a/npf.c
+++ b/npf.c
@@ -14,7 +14,7 @@
 #include "tile.h"
 #include "depot.h"
 #include "tunnel_map.h"
-#include "network.h"
+#include "network/network.h"
 #include "water_map.h"
 
 static AyStar _npf_aystar;
diff --git a/oldloader.c b/oldloader.c
index e0579eb60a..f6a56fdd6a 100644
--- a/oldloader.c
+++ b/oldloader.c
@@ -16,7 +16,7 @@
 #include "signs.h"
 #include "debug.h"
 #include "depot.h"
-#include "network.h"
+#include "network/network.h"
 #include "ai/ai.h"
 #include "date.h"
 
diff --git a/openttd.c b/openttd.c
index 023d9588bf..3f15a944e4 100644
--- a/openttd.c
+++ b/openttd.c
@@ -41,7 +41,7 @@
 #include "airport.h"
 #include "console.h"
 #include "screenshot.h"
-#include "network.h"
+#include "network/network.h"
 #include "signs.h"
 #include "depot.h"
 #include "waypoint.h"
diff --git a/openttd.vcproj b/openttd.vcproj
index c044a60eed..a2b99aa1fc 100644
--- a/openttd.vcproj
+++ b/openttd.vcproj
@@ -292,22 +292,31 @@
 				RelativePath=".\namegen.c">
 			</File>
 			<File
-				RelativePath=".\network.c">
+				RelativePath=".\network\core\packet.c">
 			</File>
 			<File
-				RelativePath=".\network_client.c">
+				RelativePath=".\network\core\tcp.c">
 			</File>
 			<File
-				RelativePath=".\network_data.c">
+				RelativePath=".\network\core\udp.c">
 			</File>
 			<File
-				RelativePath=".\network_gamelist.c">
+				RelativePath=".\network\network.c">
 			</File>
 			<File
-				RelativePath=".\network_server.c">
+				RelativePath=".\network\network_client.c">
 			</File>
 			<File
-				RelativePath=".\network_udp.c">
+				RelativePath=".\network\network_data.c">
+			</File>
+			<File
+				RelativePath=".\network\network_gamelist.c">
+			</File>
+			<File
+				RelativePath=".\network\network_server.c">
+			</File>
+			<File
+				RelativePath=".\network\network_udp.c">
 			</File>
 			<File
 				RelativePath=".\newgrf.c">
@@ -542,22 +551,37 @@
 				RelativePath=".\music.h">
 			</File>
 			<File
-				RelativePath=".\network.h">
+				RelativePath=".\network\core\config.h">
 			</File>
 			<File
-				RelativePath=".\network_client.h">
+				RelativePath=".\network\core\game.h">
 			</File>
 			<File
-				RelativePath=".\network_core.h">
+				RelativePath=".\network\core\os_abstraction.h">
 			</File>
 			<File
-				RelativePath=".\network_data.h">
+				RelativePath=".\network\core\packet.h">
 			</File>
 			<File
-				RelativePath=".\network_gamelist.h">
+				RelativePath=".\network\core\tcp.h">
 			</File>
 			<File
-				RelativePath=".\network_gui.h">
+				RelativePath=".\network\core\udp.h">
+			</File>
+			<File
+				RelativePath=".\network\network.h">
+			</File>
+			<File
+				RelativePath=".\network\network_client.h">
+			</File>
+			<File
+				RelativePath=".\network\network_data.h">
+			</File>
+			<File
+				RelativePath=".\network\network_gamelist.h">
+			</File>
+			<File
+				RelativePath=".\network\network_gui.h">
 			</File>
 			<File
 				RelativePath=".\network_server.h">
diff --git a/openttd_vs80.vcproj b/openttd_vs80.vcproj
index 77e91ecffe..11daa722ca 100644
--- a/openttd_vs80.vcproj
+++ b/openttd_vs80.vcproj
@@ -653,27 +653,39 @@
 				>
 			</File>
 			<File
-				RelativePath=".\network.c"
+				RelativePath=".\network\core\packet.c"
 				>
 			</File>
 			<File
-				RelativePath=".\network_client.c"
+				RelativePath=".\network\core\tcp.c"
 				>
 			</File>
 			<File
-				RelativePath=".\network_data.c"
+				RelativePath=".\network\core\udp.c"
 				>
 			</File>
 			<File
-				RelativePath=".\network_gamelist.c"
+				RelativePath=".\network\network.c"
 				>
 			</File>
 			<File
-				RelativePath=".\network_server.c"
+				RelativePath=".\network\network_client.c"
 				>
 			</File>
 			<File
-				RelativePath=".\network_udp.c"
+				RelativePath=".\network\network_data.c"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_gamelist.c"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_server.c"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_udp.c"
 				>
 			</File>
 			<File
@@ -1036,35 +1048,55 @@
 				>
 			</File>
 			<File
-				RelativePath=".\network.h"
+				RelativePath=".\networe\core\config.h"
 				>
 			</File>
 			<File
-				RelativePath=".\network_client.h"
+				RelativePath=".\network\core\game.h"
 				>
 			</File>
 			<File
-				RelativePath=".\network_core.h"
+				RelativePath=".\network\core\os_abstraction.h"
 				>
 			</File>
 			<File
-				RelativePath=".\network_data.h"
+				RelativePath=".\network\core\packet.h"
 				>
 			</File>
 			<File
-				RelativePath=".\network_gamelist.h"
+				RelativePath=".\network\core\tcp.h"
 				>
 			</File>
 			<File
-				RelativePath=".\network_gui.h"
+				RelativePath=".\network\core\udp.h"
 				>
 			</File>
 			<File
-				RelativePath=".\network_server.h"
+				RelativePath=".\network\network.h"
 				>
 			</File>
 			<File
-				RelativePath=".\network_udp.h"
+				RelativePath=".\network\network_client.h"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_data.h"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_gamelist.h"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_gui.h"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_server.h"
+				>
+			</File>
+			<File
+				RelativePath=".\network\network_udp.h"
 				>
 			</File>
 			<File
diff --git a/player_gui.c b/player_gui.c
index 80eb77d3bf..c4612f5dcd 100644
--- a/player_gui.c
+++ b/player_gui.c
@@ -13,13 +13,13 @@
 #include "command.h"
 #include "vehicle.h"
 #include "economy.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 #include "train.h"
 #include "date.h"
 #include "newgrf.h"
-#include "network_data.h"
-#include "network_client.h"
+#include "network/network_data.h"
+#include "network/network_client.h"
 
 static void DoShowPlayerFinances(PlayerID player, bool show_small, bool show_stickied);
 
diff --git a/players.c b/players.c
index 38b5fa5182..4c2d1ed37e 100644
--- a/players.c
+++ b/players.c
@@ -21,7 +21,7 @@
 #include "saveload.h"
 #include "command.h"
 #include "sound.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 #include "engine.h"
 #include "ai/ai.h"
diff --git a/saveload.c b/saveload.c
index d21d452893..75396aeee8 100644
--- a/saveload.c
+++ b/saveload.c
@@ -26,7 +26,7 @@
 #include "town.h"
 #include "player.h"
 #include "saveload.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 #include <setjmp.h>
 
@@ -1042,7 +1042,6 @@ static void UninitNoComp(void)
 //********** START OF MEMORY CODE (in ram)****
 //********************************************
 
-#include "network.h"
 #include "table/strings.h"
 #include "table/sprites.h"
 #include "gfx.h"
diff --git a/settings.c b/settings.c
index af40febfad..b6d7fa895c 100644
--- a/settings.c
+++ b/settings.c
@@ -28,7 +28,7 @@
 #include "sound.h"
 #include "string.h"
 #include "variables.h"
-#include "network.h"
+#include "network/network.h"
 #include "settings.h"
 #include "command.h"
 #include "console.h"
diff --git a/settings_gui.c b/settings_gui.c
index 1c1bdcb7da..f6806f4247 100644
--- a/settings_gui.c
+++ b/settings_gui.c
@@ -15,7 +15,7 @@
 #include "engine.h"
 #include "screenshot.h"
 #include "newgrf.h"
-#include "network.h"
+#include "network/network.h"
 #include "town.h"
 #include "variables.h"
 #include "settings.h"
diff --git a/town_gui.c b/town_gui.c
index 10fef991be..f580cd3245 100644
--- a/town_gui.c
+++ b/town_gui.c
@@ -14,7 +14,7 @@
 #include "gui.h"
 #include "command.h"
 #include "player.h"
-#include "network.h"
+#include "network/network.h"
 #include "variables.h"
 
 static const Widget _town_authority_widgets[] = {
diff --git a/vehicle.c b/vehicle.c
index b6239b4aa9..c2a2175f82 100644
--- a/vehicle.c
+++ b/vehicle.c
@@ -30,7 +30,7 @@
 #include "industry_map.h"
 #include "station_map.h"
 #include "water_map.h"
-#include "network.h"
+#include "network/network.h"
 #include "yapf/yapf.h"
 #include "date.h"
 #include "newgrf_engine.h"
diff --git a/video/cocoa_v.m b/video/cocoa_v.m
index 0c4c6d9f1e..f93f86ca4b 100644
--- a/video/cocoa_v.m
+++ b/video/cocoa_v.m
@@ -54,7 +54,7 @@ extern void HideMenuBar(void);
 #include "../macros.h"
 #include "../sdl.h"
 #include "../window.h"
-#include "../network.h"
+#include "../network/network.h"
 #include "../variables.h"
 #include "../os/macosx/splash.h"
 
diff --git a/video/dedicated_v.c b/video/dedicated_v.c
index 824ca2936d..caa1c89639 100644
--- a/video/dedicated_v.c
+++ b/video/dedicated_v.c
@@ -8,7 +8,7 @@
 #include "../debug.h"
 #include "../functions.h"
 #include "../gfx.h"
-#include "../network.h"
+#include "../network/network.h"
 #include "../window.h"
 #include "../console.h"
 #include "../variables.h"
diff --git a/video/sdl_v.c b/video/sdl_v.c
index d94819dedf..e88de85a57 100644
--- a/video/sdl_v.c
+++ b/video/sdl_v.c
@@ -11,7 +11,7 @@
 #include "../macros.h"
 #include "../sdl.h"
 #include "../window.h"
-#include "../network.h"
+#include "../network/network.h"
 #include "../variables.h"
 #include "sdl_v.h"
 #include <SDL.h>
diff --git a/video/win32_v.c b/video/win32_v.c
index e9fb1ca78e..7588653f04 100644
--- a/video/win32_v.c
+++ b/video/win32_v.c
@@ -5,7 +5,7 @@
 #include "../functions.h"
 #include "../gfx.h"
 #include "../macros.h"
-#include "../network.h"
+#include "../network/network.h"
 #include "../variables.h"
 #include "../win32.h"
 #include "../window.h"