
commit
18b7ce6bc9
38 changed files with 5735 additions and 0 deletions
@ -0,0 +1,6 @@
|
||||
[submodule "zlib"] |
||||
path = zlib |
||||
url = https://github.com/madler/zlib |
||||
[submodule "enet"] |
||||
path = enet |
||||
url = https://github.com/rna88/enet |
@ -0,0 +1,27 @@
|
||||
## Irrnet |
||||
|
||||
An updated version of the (irrNetLite)[http://irrlicht.sourceforge.net/forum/viewtopic.php?f=6&t=22658] networking library compiled against recent versions of (enet)[https://github.com/lsalzman/enet] and (zlib)[https://github.com/madler/zlib]. |
||||
|
||||
## Compiling for Linux |
||||
|
||||
When cloning use the `--recurse-submodules` flag to retrieve the enet and zlib libraries needed by the project: |
||||
|
||||
`git clone --recurse-submodules https://github.com/rna88/irrnet.git` |
||||
|
||||
Then run `make` in the `source/` directory to build the library. |
||||
|
||||
## Building examples |
||||
|
||||
Navigate to `examples/` and run: |
||||
|
||||
`./linux_buildAllExamples.sh` |
||||
|
||||
or to build them with optimizations: |
||||
|
||||
`./linux_buildAllExamples.sh release` |
||||
|
||||
The compiled binaries will be found in `examples/bin/` |
||||
|
||||
|
||||
|
||||
Original code by Ahmed Hilali. |
@ -0,0 +1,28 @@
|
||||
CXX = g++
|
||||
Target := Example1
|
||||
TargetPath := ../bin/
|
||||
Sources := main.cpp
|
||||
|
||||
CXXINCS = -I../../include/
|
||||
|
||||
#ifndef NDEBUG
|
||||
CXXFLAGS_D = -g -Wall
|
||||
#else
|
||||
CXXFLAGS_R = -fexpensive-optimizations -O3
|
||||
#endif
|
||||
|
||||
LDIR =../../lib/
|
||||
LIBS = -L$(LDIR) -lirrnet
|
||||
|
||||
debug: main.cpp |
||||
$(CXX) $(CXXFLAGS_D) $(CXXINCS) -o $(Target) $(Sources) $(LIBS)
|
||||
mv $(Target) $(TargetPath)
|
||||
|
||||
release: main.cpp |
||||
$(CXX) $(CXXFLAGS_R) $(CXXINCS) -o $(Target) $(Sources) $(LIBS)
|
||||
mv $(Target) $(TargetPath)
|
||||
|
||||
clean: |
||||
rm -f *.o $(TargetPath)$(Target)
|
||||
|
||||
.PHONY: clean debug release |
@ -0,0 +1,252 @@
|
||||
/*
|
||||
Example 1: Packet Identification. |
||||
|
||||
In this example I will expain the basics of packet identification. |
||||
For a more basic introduction please refer to Tutorial.cpp first. |
||||
(Recommended) |
||||
*/ |
||||
|
||||
// Do the usual things here.
|
||||
#include <irrNet.h> |
||||
#include <iostream> |
||||
|
||||
using namespace irr; |
||||
|
||||
#pragma comment(lib, "irrNetLite.lib") |
||||
#pragma comment(lib, "ws2_32.lib") |
||||
|
||||
// Now, in this example, I will teach you the basics of packet
|
||||
// identification. What is packet identification? For instance,
|
||||
// lets say the client sends 3 floating point values to the server,
|
||||
// how will the server now if these represent a position, a rotation,
|
||||
// or something completely different? How will it even know these
|
||||
// are floating point values and not integers, or maybe a 12-byte
|
||||
// string? Obviously, we need some kind of mechanism to define this.
|
||||
// So in this example, we are going to define a few basic packet
|
||||
// types, that let us differentiate between the different kinds of
|
||||
// information coming into our client/server.
|
||||
|
||||
// I will start off by creating an enum that holds a simple id
|
||||
// for each of our packet types. (Note, you don't have to
|
||||
// explicitly set the values like I do, I am just doing that
|
||||
// for clarity.)
|
||||
enum E_PACKET_TYPE |
||||
{ |
||||
EPT_ROTATION = 1, |
||||
EPT_POWER = 2, |
||||
EPT_MESSAGE = 3 |
||||
}; |
||||
|
||||
// In this example we will create 2 different callback classes, one
|
||||
// for the clients and one for the server. We will have an imaginary
|
||||
// cannon on the server, and the clients can send messages to change
|
||||
// it's angle and power.
|
||||
|
||||
// The server callback.
|
||||
class ServerNetCallback : public net::INetCallback |
||||
{ |
||||
// We will store a pointer to the net manager.
|
||||
net::INetManager* netManager; |
||||
|
||||
// Here we will store the cannon's power and angle.
|
||||
// Remember that f32 is just a typedef for float.
|
||||
f32 cannonPower; |
||||
f32 cannonAngle; |
||||
public: |
||||
ServerNetCallback(net::INetManager* netManagerIn) : netManager(netManagerIn) {} |
||||
|
||||
|
||||
// Our handlePacket function.
|
||||
virtual void handlePacket(net::SInPacket& packet) |
||||
{ |
||||
// The packets will use a single char to store
|
||||
// the packet identifier, remember to use the
|
||||
// smallest possible datatype for storing your
|
||||
// packet identifiers. c8 is a typedef for char.
|
||||
c8 packetid; |
||||
packet >> packetid; |
||||
|
||||
// Here we will switch based on the packet id.
|
||||
switch((E_PACKET_TYPE)packetid) |
||||
{ |
||||
case EPT_ROTATION: |
||||
// We obtain the cannon angle from the packet.
|
||||
packet >> cannonAngle; |
||||
std::cout << "The cannon angle is now " << cannonAngle << std::endl; |
||||
break; |
||||
case EPT_POWER: |
||||
// Same here.
|
||||
packet >> cannonPower; |
||||
std::cout << "The cannon power is now " << cannonPower << std::endl; |
||||
break; |
||||
case EPT_MESSAGE: |
||||
// Now this is a special case (Pun intended, or is it even a pun?... nevermind),
|
||||
// The client has sent us a message as a string, so we will just print that
|
||||
// to the console.
|
||||
core::stringc message; |
||||
packet >> message; |
||||
|
||||
// We can obtain a unique "player id" from a packet identifying the client that
|
||||
// sent it. More details about the player id in a later example, for now we will
|
||||
// just print it out with the message so we know whos saying what.
|
||||
std::cout << "Client " << packet.getPlayerId() << " says: " << message.c_str(); |
||||
std::cout << std::endl; |
||||
break; |
||||
} |
||||
|
||||
// After handling a packet, we will send an updated status of the cannon to all clients.
|
||||
net::SOutPacket rotationPacket; |
||||
|
||||
// The packet id is the first thing that goes in a packet. Note that I am casting it to a char,
|
||||
// because that is what we want to store it as, to save space. Be careful to use the same types
|
||||
// when sending and receiving, don't send as a char and receive as an int, it will cause trouble.
|
||||
rotationPacket << (c8)EPT_ROTATION; |
||||
rotationPacket << cannonAngle; |
||||
|
||||
// Send the packet to all connected clients.
|
||||
netManager->sendOutPacket(rotationPacket); |
||||
|
||||
// Send a power update too.
|
||||
net::SOutPacket powerPacket; |
||||
powerPacket << (c8)EPT_POWER; |
||||
powerPacket << cannonPower; |
||||
netManager->sendOutPacket(powerPacket); |
||||
} |
||||
}; |
||||
|
||||
// The client callback.
|
||||
class ClientNetCallback : public net::INetCallback |
||||
{ |
||||
public: |
||||
// Our handlePacket function.
|
||||
virtual void handlePacket(net::SInPacket& packet) |
||||
{ |
||||
// Just like the server, we obtain the packet id and print
|
||||
// the information based on the packet we received. I hope the
|
||||
// rest of this function is self-explanatory.
|
||||
c8 packetid; |
||||
packet >> packetid; |
||||
|
||||
switch((E_PACKET_TYPE)packetid) |
||||
{ |
||||
case EPT_ROTATION: |
||||
f32 cannonAngle; |
||||
packet >> cannonAngle; |
||||
std::cout << "Server says that the cannon angle is now " << cannonAngle << std::endl; |
||||
break; |
||||
case EPT_POWER: |
||||
f32 cannonPower; |
||||
packet >> cannonPower; |
||||
std::cout << "Server says that the cannon power is now " << cannonPower << std::endl; |
||||
break; |
||||
default: |
||||
// We don't care about any other types, so we catch them here and break.
|
||||
break; |
||||
} |
||||
} |
||||
}; |
||||
|
||||
int main() |
||||
{ |
||||
// Ask the user whether they want to be the server or a client.
|
||||
std::cout << "Client (c) or Server (s)?"; |
||||
char i; |
||||
std::cin >> i; |
||||
|
||||
// If they typed 's' they are the server else they are the client.
|
||||
if(i == 's') |
||||
{ |
||||
// Create an irrNetLite server.
|
||||
net::INetManager* netManager = net::createIrrNetServer(0); |
||||
|
||||
// Pass in a server specific net callback.
|
||||
ServerNetCallback* serverCallback = new ServerNetCallback(netManager); |
||||
netManager->setNetCallback(serverCallback); |
||||
// Here we update like usual, most of the logic is in the callback.
|
||||
while(netManager->getConnectionStatus() != net::EICS_FAILED) |
||||
netManager->update(1000); |
||||
|
||||
// Delete everything.
|
||||
delete netManager; |
||||
delete serverCallback; |
||||
} |
||||
else |
||||
{ |
||||
// Create a client and pass in the client callback.
|
||||
// You may want to change the ip address to a remote one and experiment
|
||||
// with connecting to a remote host.
|
||||
ClientNetCallback* clientCallback = new ClientNetCallback(); |
||||
net::INetManager* netManager = net::createIrrNetClient(clientCallback, "127.0.0.1"); |
||||
|
||||
// Print a simple menu.
|
||||
std::cout << "Example 1. What would you like to do?" << std::endl |
||||
<< "1. Change the cannon rotation." << std::endl |
||||
<< "2. Change the cannon power." << std::endl |
||||
<< "3. Send a message." << std::endl; |
||||
|
||||
// Take the input.
|
||||
char i = 0; |
||||
std::cin >> i; |
||||
|
||||
// Switch based on input.
|
||||
switch(i) |
||||
{ |
||||
case '1': |
||||
{ |
||||
// Here we create a rotation packet and send it to the server.
|
||||
net::SOutPacket rotationPacket; |
||||
rotationPacket << (c8)EPT_ROTATION; // Remember to cast to the correct type.
|
||||
|
||||
// Ask for the rotation.
|
||||
f32 rotation; |
||||
std::cout << "Please enter a rotation: "; |
||||
std::cin >> rotation; |
||||
rotationPacket << rotation; |
||||
netManager->sendOutPacket(rotationPacket); |
||||
break; |
||||
} |
||||
case '2': |
||||
{ |
||||
// And here we create a power packet and send it to the server.
|
||||
net::SOutPacket powerPacket; |
||||
powerPacket << (c8)EPT_POWER; // Remember to cast to the correct type.
|
||||
// Ask for the power.
|
||||
f32 power; |
||||
std::cout << "Please enter the power: "; |
||||
std::cin >> power; |
||||
powerPacket << power; |
||||
netManager->sendOutPacket(powerPacket); |
||||
break; |
||||
} |
||||
case '3': |
||||
{ |
||||
// We'll also send the server a message in the form of a string.
|
||||
net::SOutPacket messagePacket; |
||||
messagePacket << (c8)EPT_MESSAGE; // Remember to cast to the correct type.
|
||||
// Ask for the message.
|
||||
char message[512] = {}; |
||||
std::cout << "Please enter a message:" << std::endl; |
||||
std::cin >> message; |
||||
messagePacket << message; |
||||
netManager->sendOutPacket(messagePacket); |
||||
break; |
||||
} |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
// Here is the update loop, we will exit if there is a connection problem.
|
||||
while(netManager->getConnectionStatus() != net::EICS_FAILED) |
||||
{ |
||||
// Here we update.
|
||||
netManager->update(1000); |
||||
} |
||||
|
||||
// Clean up.
|
||||
delete netManager; |
||||
delete clientCallback; |
||||
} |
||||
|
||||
// And we're done, return 0 and make like a banana.
|
||||
return 0; |
||||
} |
@ -0,0 +1,28 @@
|
||||
CXX = g++
|
||||
Target := Example2
|
||||
TargetPath := ../bin/
|
||||
Sources := main.cpp
|
||||
|
||||
CXXINCS = -I../../include/
|
||||
|
||||
#ifndef NDEBUG
|
||||
CXXFLAGS_D = -g -Wall
|
||||
#else
|
||||
CXXFLAGS_R = -fexpensive-optimizations -O3
|
||||
#endif
|
||||
|
||||
LDIR =../../lib/
|
||||
LIBS = -L$(LDIR) -lirrnet
|
||||
|
||||
debug: main.cpp |
||||
$(CXX) $(CXXFLAGS_D) $(CXXINCS) -o $(Target) $(Sources) $(LIBS)
|
||||
mv $(Target) $(TargetPath)
|
||||
|
||||
release: main.cpp |
||||
$(CXX) $(CXXFLAGS_R) $(CXXINCS) -o $(Target) $(Sources) $(LIBS)
|
||||
mv $(Target) $(TargetPath)
|
||||
|
||||
clean: |
||||
rm -f *.o $(TargetPath)$(Target)
|
||||
|
||||
.PHONY: clean debug release |
@ -0,0 +1,230 @@
|
||||
/*
|
||||
Example 2: Client management. |
||||
|
||||
In this example I will demonstrate client management. |
||||
For a more basic introduction please refer to Tutorial.cpp first. |
||||
(Recommended) |
||||
*/ |
||||
|
||||
// Do the usual things here.
|
||||
#include <irrNet.h> |
||||
#include <iostream> |
||||
|
||||
using namespace irr; |
||||
|
||||
#pragma comment(lib, "irrNetLite.lib") |
||||
#pragma comment(lib, "ws2_32.lib") |
||||
|
||||
// In this tutorial, I will show you how to kick/ban clients,
|
||||
// set a limit on how many clients can join a server, and
|
||||
// respond when a client connects/disconnects.
|
||||
|
||||
// Our server callback will be doing a little more than just
|
||||
// handling packets this time. We will override 2 more virtual
|
||||
// methods, onConnect and onDisconnect, that will notify us
|
||||
// with the player id of the client that has just connected or
|
||||
// disconnected. What is a player id? A player id is a unique
|
||||
// number that irrNetLite assigns to a client when they connect
|
||||
// to the server. The ids will start at 1 and grow until there
|
||||
// are no available slots left. Ids are not specific to a
|
||||
// computer or ip address, and are re-used when freed,
|
||||
// so if the client with played id 1 disconnects, and
|
||||
// a different one connects, he will take over that player id.
|
||||
// You may be thinking, "But how do I know which player is
|
||||
// connecting?" or, "How can I ban a player with a specific
|
||||
// ip address using this system?". These questions will be
|
||||
// answered in this tutorial, so pay close attention.
|
||||
class ServerNetCallback : public net::INetCallback |
||||
{ |
||||
public: |
||||
ServerNetCallback(net::INetManager* netManagerIn) : netManager(netManagerIn) {} |
||||
|
||||
// Override the "onConnect" function, don't forget to get the method
|
||||
// signature correct. Whenever a fresh client connects, their brand
|
||||
// spanking new player id will be passed to this function. A "u16"
|
||||
// is a typedef for an unsigned short, incase you were wondering.
|
||||
virtual void onConnect(const u16 playerId) |
||||
{ |
||||
// When a client connects we inform all other connected
|
||||
// clients that a client with that player id has connected.
|
||||
|
||||
// But first, lets say that we have already banned a few
|
||||
// clients from this server, and that we are keeping a list
|
||||
// of all the banned ip addresses. We can simply use
|
||||
// "getClientAddress()", to obtain the 32-bit representation
|
||||
// of the ip address and check it against the list.
|
||||
bool playerIsBanned = false; |
||||
for(int i = 0;i < banList.size();++i) |
||||
{ |
||||
if(netManager->getClientAddress(playerId) == banList[i]) |
||||
{ |
||||
playerIsBanned = true; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
// If the player is banned, send a message to all connected
|
||||
// clients that a player that is banned tried to connect
|
||||
// and then kick the naughty player.
|
||||
if(playerIsBanned) |
||||
{ |
||||
net::SOutPacket packet; |
||||
packet << "A player that is banned tried to connect, " \
|
||||
"so I kicked them."; |
||||
netManager->sendOutPacket(packet); |
||||
|
||||
// Kick the client by passing the player id.
|
||||
netManager->kickClient(playerId); |
||||
} |
||||
else // Else we tell everyone who connected.
|
||||
{ |
||||
// I am using a core::stringc here, it is very
|
||||
// similar to a std::string. You can use a std::string
|
||||
// if you want.
|
||||
net::SOutPacket packet; |
||||
core::stringc message; |
||||
message = "Client number "; |
||||
message += playerId; |
||||
message += " has just connected."; |
||||
packet << message; |
||||
netManager->sendOutPacket(packet); |
||||
}
|
||||
} |
||||
|
||||
// Similar to the onConnect function, except it happens when a
|
||||
// player disconnects. When this happens we will just report
|
||||
// which player has disconnected.
|
||||
virtual void onDisconnect(const u16 playerId) |
||||
{ |
||||
net::SOutPacket packet; |
||||
core::stringc message; |
||||
message = "Client number "; |
||||
message += playerId; |
||||
message += " has just left the building."; |
||||
packet << message; |
||||
netManager->sendOutPacket(packet); |
||||
} |
||||
|
||||
// Handle the packets, as usual.
|
||||
virtual void handlePacket(net::SInPacket& packet) |
||||
{ |
||||
// Now, we need a good reason to ban players.
|
||||
// Lets say I don't like people who talk alot,
|
||||
// so lets ban anyone who sends a greeting message
|
||||
// that is longer than 20 characters, else just
|
||||
// print the welcome message.
|
||||
core::stringc message; |
||||
packet >> message; |
||||
|
||||
// We can grab the unique player id of the player
|
||||
// that sent the packet from the packet itself.
|
||||
u16 playerId = packet.getPlayerId(); |
||||
|
||||
|
||||
if(message.size() > 20) |
||||
{ |
||||
// Kick and ban the player by adding their address to our list.
|
||||
netManager->kickClient(playerId); |
||||
u32 address = netManager->getClientAddress(playerId); |
||||
banList.push_back(address); |
||||
std::cout << "Player from " << address << " banned." << std::endl; |
||||
} |
||||
else |
||||
{ |
||||
// Print the message.
|
||||
std::cout << "Client " << playerId << " said " << message.c_str() << std::endl; |
||||
} |
||||
} |
||||
|
||||
private: |
||||
// An array of "u32", a typedef for unsigned int. This core::array is a
|
||||
// custom implementation of a dynamic array, very similar to std::vector.
|
||||
core::array<u32> banList; |
||||
|
||||
// A pointer to the INetManager.
|
||||
net::INetManager* netManager; |
||||
}; |
||||
|
||||
// The client callback.
|
||||
class ClientNetCallback : public net::INetCallback |
||||
{ |
||||
public: |
||||
// Our handlePacket function.
|
||||
virtual void handlePacket(net::SInPacket& packet) |
||||
{ |
||||
// Very simple callback, just echo what the server says.
|
||||
core::stringc message; |
||||
packet >> message; |
||||
std::cout << "Server says: " << message.c_str() << std::endl; |
||||
} |
||||
}; |
||||
|
||||
int main() |
||||
{ |
||||
// Ask the user whether they want to be the server or a client.
|
||||
std::cout << "Client (c) or Server (s)?"; |
||||
char i; |
||||
std::cin >> i; |
||||
|
||||
// If they typed 's' they are the server else they are the client.
|
||||
if(i == 's') |
||||
{ |
||||
// Create an irrNetLite server.
|
||||
net::INetManager* netManager = net::createIrrNetServer(0); |
||||
|
||||
// Pass in a server specific net callback.
|
||||
ServerNetCallback* serverCallback = new ServerNetCallback(netManager); |
||||
netManager->setNetCallback(serverCallback); |
||||
|
||||
// Here we update like usual, most of the logic is in the callback.
|
||||
while(netManager->getConnectionStatus() != net::EICS_FAILED) |
||||
netManager->update(1000); |
||||
|
||||
// Delete everything.
|
||||
delete netManager; |
||||
delete serverCallback; |
||||
} |
||||
else |
||||
{ |
||||
// Create a client and pass in the client callback.
|
||||
// You may want to change the ip address to a remote one and experiment
|
||||
// with connecting to a remote host, especially for this example as,
|
||||
// if you run all the clients from the same pc and ban one, you
|
||||
// won't be able to create anymore clients unless you restart the server.
|
||||
ClientNetCallback* clientCallback = new ClientNetCallback(); |
||||
net::INetManager* netManager = net::createIrrNetClient(clientCallback, "127.0.0.1"); |
||||
|
||||
// The clients in this example will simply send a custom greeting message
|
||||
// when they connect and then wait and poll for events.
|
||||
|
||||
// If there wasn't a problem connecting we will send a greeting message.
|
||||
if(netManager->getConnectionStatus() != net::EICS_FAILED) |
||||
{ |
||||
// Print a simple menu.
|
||||
std::cout << "Example 2. Please enter a greeting message:" << std::endl; |
||||
|
||||
// Take the input.
|
||||
std::string message; |
||||
std::cin >> message; |
||||
|
||||
// Send a packet with the message entered.
|
||||
net::SOutPacket packet; |
||||
packet << message; |
||||
netManager->sendOutPacket(packet); |
||||
} |
||||
|
||||
// Here is the update loop, we will exit if there is a connection problem.
|
||||
while(netManager->getConnectionStatus() != net::EICS_FAILED) |
||||
{ |
||||
// Here we update.
|
||||
netManager->update(1000); |
||||
} |
||||
|
||||
// Clean up.
|
||||
delete netManager; |
||||
delete clientCallback; |
||||
} |
||||
|
||||
// And we're done, return 0 and make like an egg.
|
||||
return 0; |
||||
} |
@ -0,0 +1,28 @@
|
||||
CXX = g++
|
||||
Target := Tutorial
|
||||
TargetPath := ../bin/
|
||||
Sources := main.cpp
|
||||
|
||||
CXXINCS = -I../../include/
|
||||
|
||||
#ifndef NDEBUG
|
||||
CXXFLAGS_D = -g -Wall
|
||||
#else
|
||||
CXXFLAGS_R = -fexpensive-optimizations -O3
|
||||
#endif
|
||||
|
||||
LDIR =../../lib/
|
||||
LIBS = -L$(LDIR) -lirrnet
|
||||
|
||||
debug: main.cpp |
||||
$(CXX) $(CXXFLAGS_D) $(CXXINCS) -o $(Target) $(Sources) $(LIBS)
|
||||
mv $(Target) $(TargetPath)
|
||||
|
||||
release: main.cpp |
||||
$(CXX) $(CXXFLAGS_R) $(CXXINCS) -o $(Target) $(Sources) $(LIBS)
|
||||
mv $(Target) $(TargetPath)
|
||||
|
||||
clean: |
||||
rm -f *.o $(TargetPath)$(Target)
|
||||
|
||||
.PHONY: clean debug release |
@ -0,0 +1,177 @@
|
||||
/*
|
||||
Welcome to the simple, introductory tutorial for irrNetLite. This will show you the |
||||
very basics of setting up a client and server, and sending and receiving packets. |
||||
Because irrNetLite is so easy to use, I think you will not find many actual lines of |
||||
code in this example, rather most of it is documentation. |
||||
|
||||
For much more sophisticated use of irrNetLite, I recommend taking a look in the
|
||||
examples subdirectory. |
||||
*/ |
||||
|
||||
// Include the main irrNet.h header for irrNetLite.
|
||||
#include <irrNet.h> |
||||
#include <iostream> |
||||
|
||||
// irrNetLite resides within the irr::net:: namespace, therefore,
|
||||
// we use "using namespace irr" here to simplify things.
|
||||
// Alternatively you can add "using namespace net" after
|
||||
// this so that net:: doesn't have to be used either.
|
||||
using namespace irr; |
||||
|
||||
// These pragmas are for MSVC users, they ease the linking of librarys.
|
||||
// "ws2_32.lib" is part of the Windows Platform SDK and must be linked
|
||||
// in when compiling on windows. On linux/mac machines, these pragmas
|
||||
// will simply be ignored, and the linking to irrNetLite static lib
|
||||
// should be performed by a makefile.
|
||||
#pragma comment(lib, "irrNetLite.lib") |
||||
#pragma comment(lib, "ws2_32.lib") |
||||
|
||||
// You must derive a class from INetCallback and override the
|
||||
// "handlePacket" method. When a packet is received it will be
|
||||
// passed to this function, and you may dissect it as you wish.
|
||||
// If this is the server you may retrieve the player ID using
|
||||
// packet.getPlayerId().
|
||||
class MyNetCallback : public net::INetCallback |
||||
{ |
||||
public: |
||||
virtual void handlePacket(net::SInPacket& packet) |
||||
{ |
||||
// irrNetLite encryption is very easy to use! Just pass
|
||||
// a 16-byte (128-bit) string to encryptPacket/decryptPacket
|
||||
// to encrypt/decrypt a packet respectively. Do not try to
|
||||
// decrypt an un-encrypted packet or read from an encrypted
|
||||
// packet without decrypting it first or bad things will happen!
|
||||
packet.decryptPacket("hushthisissecret"); |
||||
|
||||
// irrNetLite compression is even easier! The ZLib library is used
|
||||
// here, just call compressPacket/decompressPacket to
|
||||
// compress/decompress a packet. Again, do not try to decompress
|
||||
// an un-compressed packet or read from a compressed packet without
|
||||
// decompressing it! Another thing to keep in mind is that you should
|
||||
// decompress and decrypt in the correct order. If you compressed a file
|
||||
// and then encrypted it when it was sent, you must decrypt it first
|
||||
// before trying to decompress it, same goes for the other order.
|
||||
packet.deCompressPacket(); |
||||
|
||||
// Extracting info from a received packet is simple. You can treat
|
||||
// the packet as an input stream, the >> operator is overloaded
|
||||
// and works for most built in types. The string class in irrNetLite
|
||||
// is a custom implementation not unlike the std::string. You can
|
||||
// also send and receive strings as "char*". Note that the "char*"
|
||||
// and stringc are interchangeable, you can send a stringc and
|
||||
// receive a char*, or vice-versa.
|
||||
core::stringc str; |
||||
packet >> str; |
||||
|
||||
// Support for a simple 3-dimensional vector class is there too. Both
|
||||
// vector3df and core::stringc are borrowed from Irrlicht and included
|
||||
// here for convenience.
|
||||
core::vector3df vec; |
||||
packet >> vec; |
||||
|
||||
// Here we are obtaining the last value from the packet. f32 is just a
|
||||
// typedef for float.
|
||||
f32 height; |
||||
packet >> height; |
||||
|
||||
// Print the values to the console.
|
||||
std::cout << "Message: " << str.c_str(); |
||||
std::cout << " Position: " << vec.X << " " << vec.Y << " " << vec.Z; |
||||
std::cout << " Height: " << height << " ft"; |
||||
std::cout << std::endl; |
||||
} |
||||
}; |
||||
|
||||
// Ok, lets go from the start, int main()
|
||||
int main() |
||||
{ |
||||
// Ask the user whether they want to be the server or a client.
|
||||
std::cout << "Client (c) or Server (s)?"; |
||||
char i; |
||||
std::cin >> i; |
||||
|
||||
// If they typed 's' they are the server else they are the client.
|
||||
if(i == 's') |
||||
{ |
||||
// Create a server and pass in a new instance of our callback class. The default
|
||||
// port that clients can connect to is set to 45000.
|
||||
MyNetCallback* netCallback = new MyNetCallback(); |
||||
net::INetManager* netManager = net::createIrrNetServer(netCallback); |
||||
|
||||
// Setting verbose to true makes irrNetLite spit out debug information to the console.
|
||||
netManager->setVerbose(true); |
||||
|
||||
// While the connection is active (Not failed), we update the netManager.
|
||||
// Note that since this is a server the connection will pretty much always
|
||||
// be flagged as active, unless some error occured whilst creating the server.
|
||||
// A value of 1000 is passed to update to make it hang for a second and wait for
|
||||
// packets to arrive. (Recommended for servers, so you don't busy-loop).
|
||||
while(netManager->getConnectionStatus() != net::EICS_FAILED) |
||||
netManager->update(1000); |
||||
|
||||
// Don't forget to clean up!
|
||||
delete netManager; |
||||
delete netCallback; |
||||
} |
||||
else |
||||
{ |
||||
// Create an irrNet client, in this example we will just connect to the localhost
|
||||
// address ("127.0.0.1"), which basically means we are connecting to the same
|
||||
// computer the client is on. Note that we just pass a value of 0 as our
|
||||
// INetCallback, because the client in this example does no need to handle any
|
||||
// packets. You can safely pass a value of 0 if this is the case.
|
||||
net::INetManager* netManager = net::createIrrNetClient(0, "127.0.0.1"); |
||||
|
||||
// Enable debug messages.
|
||||
netManager->setVerbose(true); |
||||
|
||||
// Here comes the fun part, while the client is connected we update the netManager
|
||||
// and ask it to wait 1 second (1000 milliseconds) for new packets to arrive before
|
||||
// returning. Since the client in this example doesn't actually receive any packets,
|
||||
// the only purpose of the update call is to leave a 1 second interval between each
|
||||
// packet we send.
|
||||
|
||||
int i = 0; |
||||
// To send a packet, first you create an SOutPacket object.
|
||||
net::SOutPacket packet; |
||||
|
||||
while(netManager->getConnectionStatus() != net::EICS_FAILED && i < 10 ) |
||||
{ |
||||
|
||||
// To send a packet, first you create an SOutPacket object.
|
||||
//net::SOutPacket packet;
|
||||
|
||||
// Then you can use the streaming operator << to add new data to it.
|
||||
packet << "Help I am stuck on a mountain!"; |
||||
|
||||
// You can even chain the << operators like so, just like with ostream.
|
||||
packet << core::vector3df(50.0f, 30.0f, 20.0f) << 50.0f; |
||||
|
||||
// Compress the packet, not much to be said.
|
||||
packet.compressPacket(); |
||||
|
||||
// Encrypt the packet. Note that here we are just using a simple key
|
||||
// that is shared among the client and the server. In more sophisticated
|
||||
// implementations you may want to generate a random key on the server for
|
||||
// each client and send that using a shared key, then use the new key for
|
||||
// further communication. Remember that the key should be 16 characters
|
||||
// long, and obviously the client and server must share the same key.
|
||||
packet.encryptPacket("hushthisissecret"); |
||||
|
||||
// A simple call to "sendOutPacket" will send the packet to the server.
|
||||
netManager->sendOutPacket(packet); |
||||
|
||||
netManager->update(1000); |
||||
packet.clearData(); |
||||
i++; |
||||
} |
||||
|
||||
// When the connection disconnects (Or fails), the loop will terminate.
|
||||
// Remember to delete the netManager so that all the low level networking
|
||||
// stuff is cleaned up properly.
|
||||
delete netManager; |
||||
} |
||||
|
||||
// And we're done, return 0 and make like a tree.
|
||||
return 0; |
||||
} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,15 @@
|
||||
#! /bin/bash |
||||
[ -z $1 ] || TARGET=$1 |
||||
[ -z $TARGET ] && TARGET=debug |
||||
for i in Tutorial Example* ; do |
||||
echo "Building $i"; |
||||
pushd $i && make clean $TARGET; |
||||
popd; |
||||
done |
||||
|
||||
|
||||
|
||||
|
||||
#g++ Tutorial.cpp -I../irrnet -L../lib -lirrnet -o Tutorial |
||||
#g++ Example1.cpp -I../irrnet -L../lib -lirrnet -o Example1 |
||||
#g++ Example2.cpp -I../irrnet -L../lib -lirrnet -o Example2 |
@ -0,0 +1,411 @@
|
||||
// AES encryption class, based on work by Karl Malbrain, malbrain@yahoo.com,
|
||||
// original license shown here:
|
||||
|
||||
/*
|
||||
This work, including the source code, documentation |
||||
and related data, is placed into the public domain. |
||||
|
||||
The orginal author is Karl Malbrain. |
||||
|
||||
THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY |
||||
OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF |
||||
MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, |
||||
ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE |
||||
RESULTING FROM THE USE, MODIFICATION, OR |
||||
REDISTRIBUTION OF THIS SOFTWARE. |
||||
*/ |
||||
|
||||
typedef unsigned char uchar; |
||||
#include <string.h> |
||||
#include <memory.h> |
||||
|
||||
// AES only supports Nb=4
|
||||
#define Nb 4 // number of columns in the state & expanded key
|
||||
|
||||
#define Nk 4 // number of columns in a key
|
||||
#define Nr 10 // number of rounds in encryption
|
||||
|
||||
static const uchar Sbox[256] = { // forward s-box
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, |
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, |
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, |
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, |
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, |
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, |
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, |
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, |
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, |
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, |
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, |
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, |
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, |
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, |
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, |
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; |
||||
|
||||
static const uchar InvSbox[256] = { // inverse s-box
|
||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, |
||||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, |
||||
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, |
||||
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, |
||||
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, |
||||
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, |
||||
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, |
||||
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, |
||||
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, |
||||
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, |
||||
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, |
||||
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, |
||||
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, |
||||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, |
||||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, |
||||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}; |
||||
|
||||
// combined Xtimes2[Sbox[]]
|
||||
static const uchar Xtime2Sbox[256] = { |
||||
0xc6, 0xf8, 0xee, 0xf6, 0xff, 0xd6, 0xde, 0x91, 0x60, 0x02, 0xce, 0x56, 0xe7, 0xb5, 0x4d, 0xec,
|
||||
0x8f, 0x1f, 0x89, 0xfa, 0xef, 0xb2, 0x8e, 0xfb, 0x41, 0xb3, 0x5f, 0x45, 0x23, 0x53, 0xe4, 0x9b,
|
||||
0x75, 0xe1, 0x3d, 0x4c, 0x6c, 0x7e, 0xf5, 0x83, 0x68, 0x51, 0xd1, 0xf9, 0xe2, 0xab, 0x62, 0x2a,
|
||||
0x08, 0x95, 0x46, 0x9d, 0x30, 0x37, 0x0a, 0x2f, 0x0e, 0x24, 0x1b, 0xdf, 0xcd, 0x4e, 0x7f, 0xea,
|
||||
0x12, 0x1d, 0x58, 0x34, 0x36, 0xdc, 0xb4, 0x5b, 0xa4, 0x76, 0xb7, 0x7d, 0x52, 0xdd, 0x5e, 0x13,
|
||||
0xa6, 0xb9, 0x00, 0xc1, 0x40, 0xe3, 0x79, 0xb6, 0xd4, 0x8d, 0x67, 0x72, 0x94, 0x98, 0xb0, 0x85,
|
||||
0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11, 0x8a, 0xe9, 0x04, 0xfe, 0xa0, 0x78, 0x25, 0x4b,
|
||||
0xa2, 0x5d, 0x80, 0x05, 0x3f, 0x21, 0x70, 0xf1, 0x63, 0x77, 0xaf, 0x42, 0x20, 0xe5, 0xfd, 0xbf,
|
||||
0x81, 0x18, 0x26, 0xc3, 0xbe, 0x35, 0x88, 0x2e, 0x93, 0x55, 0xfc, 0x7a, 0xc8, 0xba, 0x32, 0xe6,
|
||||
0xc0, 0x19, 0x9e, 0xa3, 0x44, 0x54, 0x3b, 0x0b, 0x8c, 0xc7, 0x6b, 0x28, 0xa7, 0xbc, 0x16, 0xad,
|
||||
0xdb, 0x64, 0x74, 0x14, 0x92, 0x0c, 0x48, 0xb8, 0x9f, 0xbd, 0x43, 0xc4, 0x39, 0x31, 0xd3, 0xf2,
|
||||
0xd5, 0x8b, 0x6e, 0xda, 0x01, 0xb1, 0x9c, 0x49, 0xd8, 0xac, 0xf3, 0xcf, 0xca, 0xf4, 0x47, 0x10,
|
||||
0x6f, 0xf0, 0x4a, 0x5c, 0x38, 0x57, 0x73, 0x97, 0xcb, 0xa1, 0xe8, 0x3e, 0x96, 0x61, 0x0d, 0x0f,
|
||||
0xe0, 0x7c, 0x71, 0xcc, 0x90, 0x06, 0xf7, 0x1c, 0xc2, 0x6a, 0xae, 0x69, 0x17, 0x99, 0x3a, 0x27,
|
||||
0xd9, 0xeb, 0x2b, 0x22, 0xd2, 0xa9, 0x07, 0x33, 0x2d, 0x3c, 0x15, 0xc9, 0x87, 0xaa, 0x50, 0xa5,
|
||||
0x03, 0x59, 0x09, 0x1a, 0x65, 0xd7, 0x84, 0xd0, 0x82, 0x29, 0x5a, 0x1e, 0x7b, 0xa8, 0x6d, 0x2c
|
||||
}; |
||||
|
||||
// combined Xtimes3[Sbox[]]
|
||||
static const uchar Xtime3Sbox[256] = { |
||||
0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54, 0x50, 0x03, 0xa9, 0x7d, 0x19, 0x62, 0xe6, 0x9a,
|
||||
0x45, 0x9d, 0x40, 0x87, 0x15, 0xeb, 0xc9, 0x0b, 0xec, 0x67, 0xfd, 0xea, 0xbf, 0xf7, 0x96, 0x5b,
|
||||
0xc2, 0x1c, 0xae, 0x6a, 0x5a, 0x41, 0x02, 0x4f, 0x5c, 0xf4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3f,
|
||||
0x0c, 0x52, 0x65, 0x5e, 0x28, 0xa1, 0x0f, 0xb5, 0x09, 0x36, 0x9b, 0x3d, 0x26, 0x69, 0xcd, 0x9f,
|
||||
0x1b, 0x9e, 0x74, 0x2e, 0x2d, 0xb2, 0xee, 0xfb, 0xf6, 0x4d, 0x61, 0xce, 0x7b, 0x3e, 0x71, 0x97,
|
||||
0xf5, 0x68, 0x00, 0x2c, 0x60, 0x1f, 0xc8, 0xed, 0xbe, 0x46, 0xd9, 0x4b, 0xde, 0xd4, 0xe8, 0x4a,
|
||||
0x6b, 0x2a, 0xe5, 0x16, 0xc5, 0xd7, 0x55, 0x94, 0xcf, 0x10, 0x06, 0x81, 0xf0, 0x44, 0xba, 0xe3,
|
||||
0xf3, 0xfe, 0xc0, 0x8a, 0xad, 0xbc, 0x48, 0x04, 0xdf, 0xc1, 0x75, 0x63, 0x30, 0x1a, 0x0e, 0x6d,
|
||||
0x4c, 0x14, 0x35, 0x2f, 0xe1, 0xa2, 0xcc, 0x39, 0x57, 0xf2, 0x82, 0x47, 0xac, 0xe7, 0x2b, 0x95,
|
||||
0xa0, 0x98, 0xd1, 0x7f, 0x66, 0x7e, 0xab, 0x83, 0xca, 0x29, 0xd3, 0x3c, 0x79, 0xe2, 0x1d, 0x76,
|
||||
0x3b, 0x56, 0x4e, 0x1e, 0xdb, 0x0a, 0x6c, 0xe4, 0x5d, 0x6e, 0xef, 0xa6, 0xa8, 0xa4, 0x37, 0x8b,
|
||||
0x32, 0x43, 0x59, 0xb7, 0x8c, 0x64, 0xd2, 0xe0, 0xb4, 0xfa, 0x07, 0x25, 0xaf, 0x8e, 0xe9, 0x18,
|
||||
0xd5, 0x88, 0x6f, 0x72, 0x24, 0xf1, 0xc7, 0x51, 0x23, 0x7c, 0x9c, 0x21, 0xdd, 0xdc, 0x86, 0x85,
|
||||
0x90, 0x42, 0xc4, 0xaa, 0xd8, 0x05, 0x01, 0x12, 0xa3, 0x5f, 0xf9, 0xd0, 0x91, 0x58, 0x27, 0xb9,
|
||||
0x38, 0x13, 0xb3, 0x33, 0xbb, 0x70, 0x89, 0xa7, 0xb6, 0x22, 0x92, 0x20, 0x49, 0xff, 0x78, 0x7a,
|
||||
0x8f, 0xf8, 0x80, 0x17, 0xda, 0x31, 0xc6, 0xb8, 0xc3, 0xb0, 0x77, 0x11, 0xcb, 0xfc, 0xd6, 0x3a
|
||||
}; |
||||
|
||||
// modular multiplication tables
|
||||
// based on:
|
||||
|
||||
// Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
|
||||
// Xtime3[x] = x^Xtime2[x];
|
||||
|
||||
static const uchar Xtime2[256] = { |
||||
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
|
||||
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
|
||||
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
|
||||
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
|
||||
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
|
||||
0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
|
||||
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
|
||||
0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
|
||||
0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
|
||||
0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
|
||||
0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
|
||||
0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
|
||||
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
|
||||
0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
|
||||
0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
|
||||
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5};
|
||||
|
||||
static const uchar Xtime9[256] = { |
||||
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
|
||||
0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
|
||||
0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
|
||||
0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
|
||||
0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
|
||||
0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
|
||||
0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
|
||||
0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
|
||||
0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
|
||||
0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
|
||||
0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
|
||||
0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
|
||||
0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
|
||||
0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
|
||||
0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
|
||||
0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46}; |
||||
|
||||
static const uchar XtimeB[256] = { |
||||
0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
|
||||
0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
|
||||
0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
|
||||
0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
|
||||
0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
|
||||
0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
|
||||
0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
|
||||
0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
|
||||
0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
|
||||
0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
|
||||
0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
|
||||
0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
|
||||
0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
|
||||
0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
|
||||
0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
|
||||
0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3};
|
||||
|
||||
static const uchar XtimeD[256] = { |
||||
0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
|
||||
0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
|
||||
0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
|
||||
0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
|
||||
0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
|
||||
0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
|
||||
0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
|
||||
0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
|
||||
0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
|
||||
0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
|
||||
0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
|
||||
0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
|
||||
0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
|
||||
0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
|
||||
0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
|
||||
0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97};
|
||||
|
||||
static const uchar XtimeE[256] = { |
||||
0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
|
||||
0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
|
||||
0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
|
||||
0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
|
||||
0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
|
||||
0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
|
||||
0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
|
||||
0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
|
||||
0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
|
||||
0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
|
||||
0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
|
||||
0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
|
||||
0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
|
||||
0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
|
||||
0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
|
||||
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d};
|
||||
|
||||
// exchanges columns in each of 4 rows
|
||||
// row0 - unchanged, row1- shifted left 1,
|
||||
// row2 - shifted left 2 and row3 - shifted left 3
|
||||
static void ShiftRows (uchar *state) |
||||
{ |
||||
uchar tmp; |
||||
|
||||
// just substitute row 0
|
||||
state[0] = Sbox[state[0]], state[4] = Sbox[state[4]]; |
||||
state[8] = Sbox[state[8]], state[12] = Sbox[state[12]]; |
||||
|
||||
// rotate row 1
|
||||
tmp = Sbox[state[1]], state[1] = Sbox[state[5]]; |
||||
state[5] = Sbox[state[9]], state[9] = Sbox[state[13]], state[13] = tmp; |
||||
|
||||
// rotate row 2
|
||||
tmp = Sbox[state[2]], state[2] = Sbox[state[10]], state[10] = tmp; |
||||
tmp = Sbox[state[6]], state[6] = Sbox[state[14]], state[14] = tmp; |
||||
|
||||
// rotate row 3
|
||||
tmp = Sbox[state[15]], state[15] = Sbox[state[11]]; |
||||
state[11] = Sbox[state[7]], state[7] = Sbox[state[3]], state[3] = tmp; |
||||
} |
||||
|
||||
// restores columns in each of 4 rows
|
||||
// row0 - unchanged, row1- shifted right 1,
|
||||
// row2 - shifted right 2 and row3 - shifted right 3
|
||||
static void InvShiftRows (uchar *state) |
||||
{ |
||||
uchar tmp; |
||||
|
||||
// restore row 0
|
||||
state[0] = InvSbox[state[0]], state[4] = InvSbox[state[4]]; |
||||
state[8] = InvSbox[state[8]], state[12] = InvSbox[state[12]]; |
||||
|
||||
// restore row 1
|
||||
tmp = InvSbox[state[13]], state[13] = InvSbox[state[9]]; |
||||
state[9] = InvSbox[state[5]], state[5] = InvSbox[state[1]], state[1] = tmp; |
||||
|
||||
// restore row 2
|
||||
tmp = InvSbox[state[2]], state[2] = InvSbox[state[10]], state[10] = tmp; |
||||
tmp = InvSbox[state[6]], state[6] = InvSbox[state[14]], state[14] = tmp; |
||||
|
||||
// restore row 3
|
||||
tmp = InvSbox[state[3]], state[3] = InvSbox[state[7]]; |
||||
state[7] = InvSbox[state[11]], state[11] = InvSbox[state[15]], state[15] = tmp; |
||||
} |
||||
|
||||
// recombine and mix each row in a column
|
||||
static void MixSubColumns (uchar *state) |
||||
{ |
||||
uchar tmp[4 * Nb]; |
||||
|
||||
// mixing column 0
|
||||
tmp[0] = Xtime2Sbox[state[0]] ^ Xtime3Sbox[state[5]] ^ Sbox[state[10]] ^ Sbox[state[15]]; |
||||
tmp[1] = Sbox[state[0]] ^ Xtime2Sbox[state[5]] ^ Xtime3Sbox[state[10]] ^ Sbox[state[15]]; |
||||
tmp[2] = Sbox[state[0]] ^ Sbox[state[5]] ^ Xtime2Sbox[state[10]] ^ Xtime3Sbox[state[15]]; |
||||
tmp[3] = Xtime3Sbox[state[0]] ^ Sbox[state[5]] ^ Sbox[state[10]] ^ Xtime2Sbox[state[15]]; |
||||
|
||||
// mixing column 1
|
||||
tmp[4] = Xtime2Sbox[state[4]] ^ Xtime3Sbox[state[9]] ^ Sbox[state[14]] ^ Sbox[state[3]]; |
||||
tmp[5] = Sbox[state[4]] ^ Xtime2Sbox[state[9]] ^ Xtime3Sbox[state[14]] ^ Sbox[state[3]]; |
||||
tmp[6] = Sbox[state[4]] ^ Sbox[state[9]] ^ Xtime2Sbox[state[14]] ^ Xtime3Sbox[state[3]]; |
||||
tmp[7] = Xtime3Sbox[state[4]] ^ Sbox[state[9]] ^ Sbox[state[14]] ^ Xtime2Sbox[state[3]]; |
||||
|
||||
// mixing column 2
|
||||
tmp[8] = Xtime2Sbox[state[8]] ^ Xtime3Sbox[state[13]] ^ Sbox[state[2]] ^ Sbox[state[7]]; |
||||
tmp[9] = Sbox[state[8]] ^ Xtime2Sbox[state[13]] ^ Xtime3Sbox[state[2]] ^ Sbox[state[7]]; |
||||
tmp[10] = Sbox[state[8]] ^ Sbox[state[13]] ^ Xtime2Sbox[state[2]] ^ Xtime3Sbox[state[7]]; |
||||
tmp[11] = Xtime3Sbox[state[8]] ^ Sbox[state[13]] ^ Sbox[state[2]] ^ Xtime2Sbox[state[7]]; |
||||
|
||||
// mixing column 3
|
||||
tmp[12] = Xtime2Sbox[state[12]] ^ Xtime3Sbox[state[1]] ^ Sbox[state[6]] ^ Sbox[state[11]]; |
||||
tmp[13] = Sbox[state[12]] ^ Xtime2Sbox[state[1]] ^ Xtime3Sbox[state[6]] ^ Sbox[state[11]]; |
||||
tmp[14] = Sbox[state[12]] ^ Sbox[state[1]] ^ Xtime2Sbox[state[6]] ^ Xtime3Sbox[state[11]]; |
||||
tmp[15] = Xtime3Sbox[state[12]] ^ Sbox[state[1]] ^ Sbox[state[6]] ^ Xtime2Sbox[state[11]]; |
||||
|
||||
memcpy (state, tmp, sizeof(tmp)); |
||||
} |
||||
|
||||
// restore and un-mix each row in a column
|
||||
static void InvMixSubColumns (uchar *state) |
||||
{ |
||||
uchar tmp[4 * Nb]; |
||||
int i; |
||||
|
||||
// restore column 0
|
||||
tmp[0] = XtimeE[state[0]] ^ XtimeB[state[1]] ^ XtimeD[state[2]] ^ Xtime9[state[3]]; |
||||
tmp[5] = Xtime9[state[0]] ^ XtimeE[state[1]] ^ XtimeB[state[2]] ^ XtimeD[state[3]]; |
||||
tmp[10] = XtimeD[state[0]] ^ Xtime9[state[1]] ^ XtimeE[state[2]] ^ XtimeB[state[3]]; |
||||
tmp[15] = XtimeB[state[0]] ^ XtimeD[state[1]] ^ Xtime9[state[2]] ^ XtimeE[state[3]]; |
||||
|
||||
// restore column 1
|
||||
tmp[4] = XtimeE[state[4]] ^ XtimeB[state[5]] ^ XtimeD[state[6]] ^ Xtime9[state[7]]; |
||||
tmp[9] = Xtime9[state[4]] ^ XtimeE[state[5]] ^ XtimeB[state[6]] ^ XtimeD[state[7]]; |
||||
tmp[14] = XtimeD[state[4]] ^ Xtime9[state[5]] ^ XtimeE[state[6]] ^ XtimeB[state[7]]; |
||||
tmp[3] = XtimeB[state[4]] ^ XtimeD[state[5]] ^ Xtime9[state[6]] ^ XtimeE[state[7]]; |
||||
|
||||
// restore column 2
|
||||
tmp[8] = XtimeE[state[8]] ^ XtimeB[state[9]] ^ XtimeD[state[10]] ^ Xtime9[state[11]]; |
||||
tmp[13] = Xtime9[state[8]] ^ XtimeE[state[9]] ^ XtimeB[state[10]] ^ XtimeD[state[11]]; |
||||
tmp[2] = XtimeD[state[8]] ^ Xtime9[state[9]] ^ XtimeE[state[10]] ^ XtimeB[state[11]]; |
||||
tmp[7] = XtimeB[state[8]] ^ XtimeD[state[9]] ^ Xtime9[state[10]] ^ XtimeE[state[11]]; |
||||
|
||||
// restore column 3
|
||||
tmp[12] = XtimeE[state[12]] ^ XtimeB[state[13]] ^ XtimeD[state[14]] ^ Xtime9[state[15]]; |
||||
tmp[1] = Xtime9[state[12]] ^ XtimeE[state[13]] ^ XtimeB[state[14]] ^ XtimeD[state[15]]; |
||||
tmp[6] = XtimeD[state[12]] ^ Xtime9[state[13]] ^ XtimeE[state[14]] ^ XtimeB[state[15]]; |
||||
tmp[11] = XtimeB[state[12]] ^ XtimeD[state[13]] ^ Xtime9[state[14]] ^ XtimeE[state[15]]; |
||||
|
||||
for( i=0; i < 4 * Nb; i++ ) |
||||
state[i] = InvSbox[tmp[i]]; |
||||
} |
||||
|
||||
// encrypt/decrypt columns of the key
|
||||
// n.b. you can replace this with
|
||||
// byte-wise xor if you wish.
|
||||
|
||||
static void AddRoundKey (unsigned *state, unsigned *key) |
||||
{ |
||||
int idx; |
||||
|
||||
for( idx = 0; idx < 4; idx++ ) |
||||
state[idx] ^= key[idx]; |
||||
} |
||||
|
||||
static const uchar Rcon[11] = { |
||||
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; |
||||
|
||||
class CEncryption |
||||
{ |
||||
public: |
||||
// produce Nb bytes for each round
|
||||
static void SetEncryptionKey(uchar* key) |
||||
{ |
||||
uchar* expkey = &expKey[0]; |
||||
uchar tmp0, tmp1, tmp2, tmp3, tmp4; |
||||
unsigned idx; |
||||
|
||||
memcpy (expkey, key, Nk * 4); |
||||
|
||||
for( idx = Nk; idx < Nb * (Nr + 1); idx++ ) { |
||||
tmp0 = expkey[4*idx - 4]; |
||||
tmp1 = expkey[4*idx - 3]; |
||||
tmp2 = expkey[4*idx - 2]; |
||||
tmp3 = expkey[4*idx - 1]; |
||||
if( !(idx % Nk) ) { |
||||
tmp4 = tmp3; |
||||
tmp3 = Sbox[tmp0]; |
||||
tmp0 = Sbox[tmp1] ^ Rcon[idx/Nk]; |
||||
tmp1 = Sbox[tmp2]; |
||||
tmp2 = Sbox[tmp4]; |
||||
} else if( Nk > 6 && idx % Nk == 4 ) { |
||||
tmp0 = Sbox[tmp0]; |
||||
tmp1 = Sbox[tmp1]; |
||||
tmp2 = Sbox[tmp2]; |
||||
tmp3 = Sbox[tmp3]; |
||||
} |
||||
|
||||
expkey[4*idx+0] = expkey[4*idx - 4*Nk + 0] ^ tmp0; |
||||
expkey[4*idx+1] = expkey[4*idx - 4*Nk + 1] ^ tmp1; |
||||
expkey[4*idx+2] = expkey[4*idx - 4*Nk + 2] ^ tmp2; |
||||
expkey[4*idx+3] = expkey[4*idx - 4*Nk + 3] ^ tmp3; |
||||
} |
||||
} |
||||
|
||||
// encrypt one 128 bit block
|
||||
static void Encrypt(uchar* in, uchar* out) |
||||
{ |
||||
uchar* expkey = &expKey[0]; |
||||
uchar state[Nb * 4]; |
||||
unsigned round; |
||||
|
||||
memcpy (state, in, Nb * 4); |
||||
AddRoundKey ((unsigned *)state, (unsigned *)expkey); |
||||
|
||||
for( round = 1; round < Nr + 1; round++ ) { |
||||
if( round < Nr ) |
||||
MixSubColumns (state); |
||||
else |
||||
ShiftRows (state); |
||||
|
||||
AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb); |
||||
} |
||||
|
||||
memcpy (out, state, sizeof(state)); |
||||
} |
||||
|
||||
static void Decrypt(uchar* in, uchar* out) |
||||
{ |
||||
uchar* expkey = &expKey[0]; |
||||
uchar state[Nb * 4]; |
||||
unsigned round; |
||||
|
||||
memcpy (state, in, sizeof(state)); |
||||
|
||||
AddRoundKey ((unsigned *)state, (unsigned *)expkey + Nr * Nb); |
||||
InvShiftRows(state); |
||||
|
||||
for( round = Nr; round--; ) |
||||
{ |
||||
AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb); |
||||
if( round ) |
||||
InvMixSubColumns (state); |
||||
}
|
||||
|
||||
memcpy (out, state, sizeof(state)); |
||||
} |
||||
|
||||
private: |
||||
static uchar expKey[4 * Nb * (Nr + 1)]; |
||||
}; |
@ -0,0 +1,120 @@
|
||||
#ifndef IRRNET_CNM_H |
||||
#define IRRNET_CNM_H |
||||
|
||||
#include <wchar.h> |
||||
#include <iostream> |
||||
#include <string> |
||||
#include <vector> |
||||
|
||||
#include "INetManager.h" |
||||
#include "SPacket.h" |
||||
#include "enet/enet.h" |
||||
|
||||
using namespace irr; |
||||
using namespace core; |
||||
|
||||
namespace irr |
||||
{ |
||||
namespace net |
||||
{ |
||||
|
||||
class CNetManager : public INetManager |
||||
{ |
||||
public: |
||||
/// This constructor sets up a server, as it only takes a port as a parameter to bind the host to.
|
||||
CNetManager(INetCallback* handler, u32 const port = 45000, const SNetParams& params = SNetParams()); |
||||
|
||||
/// This constructor sets up a client, as it takes an address and a port to connect to. Connecting
|
||||
/// will commence immediately after the INetManager is initialised.
|
||||
CNetManager(INetCallback* handler, const c8* addressc, const u32 port = 45000, const SNetParams& params = SNetParams()); |
||||
|
||||
/// Destructor
|
||||
~CNetManager(); |
||||
|
||||
virtual void update(const u32 timeOut = 0); |
||||
virtual void setVerbose(bool isverbose); |
||||
virtual void setNetIterations(u16 iterations) {netIterations = iterations;} |
||||
virtual void setNetCallback(INetCallback* netCallback) {pHandler = netCallback;} |
||||
virtual void setGlobalPacketRelay(bool relay); |
||||
virtual void sendOutPacket(SOutPacket& outpacket); |
||||
virtual void sendOutPacket(SOutPacket& outpacket, const u16 playerId); |
||||