port-tunnel/src/main.c

154 lines
5.8 KiB
C

#include "../kerep/src/base/base.h"
#include "../kerep/src/Network/network.h"
extern const char* help_message;
int errs(char* err_msg){
throw(err_msg);
return -1;
}
#define argIs(STR) cptr_equals(arg, STR)
#define argNext() argv[++argi < argc ? argi : errs(cptr_concat("option '",arg,"' must have a parameter"))]
typedef enum {
TunnelProtocol_None,
TunnelProtocol_TCP,
TunnelProtocol_UDP
} TunnelProtocol;
typedef enum {
InputMode_None,
InputMode_Listen,
InputMode_Connect
} InputMode;
typedef enum {
OutputMode_None,
OutputMode_Bind,
OutputMode_Send
} OutputMode;
int main(int argc, const char* const* argv){
kt_beginInit(false);
kt_initKerepTypes();
// kt_register(...);
kt_endInit();
TunnelProtocol tunnel_protocol = TunnelProtocol_None;
InputMode input_mode = InputMode_None;
OutputMode output_mode = OutputMode_None;
knIPV4Endpoint input_end = knIPV4Endpoint_INVALID;
knIPV4Endpoint output_end = knIPV4Endpoint_INVALID;
const char* encryption_key = NULL;
const char* decryption_key = NULL;
if(argc < 2)
throw("No arguments provided. Run the program with argument -h to see help message");
for(int argi = 1; argi < argc; argi++){
const char* arg = argv[argi];
if(argIs("-h") || argIs("--help") || argIs("/?")){
kprintf("%s"FGRY"\n", help_message);
return 0;
}
else if(argIs("-p") || argIs("--protocol")){
if(tunnel_protocol != TunnelProtocol_None)
throw(cptr_concat("invalid option '",arg,"': tunnel protocol has been set already"));
const char* protocol_str = argNext();
char* protocol_str_lower = cptr_toLower(protocol_str);
if(cptr_equals(protocol_str_lower, "tcp"))
tunnel_protocol = TunnelProtocol_TCP;
else if(cptr_equals(protocol_str_lower, "udp"))
tunnel_protocol = TunnelProtocol_UDP;
else throw(cptr_concat("invalid parameter '",protocol_str,"': unknown protocol"));
free(protocol_str_lower);
}
else if(argIs("-l") || argIs("--listen")){
if(input_mode != InputMode_None)
throw(cptr_concat("invalid option '",arg,"': input mode has been set already"));
input_mode = InputMode_Listen;
const char* input_end_str = argNext();
tryLast(knIPV4Endpoint_fromStr(input_end_str, &input_end), _m8612, ;);
}
else if(argIs("-c") || argIs("--connect")){
if(input_mode != InputMode_None)
throw(cptr_concat("invalid option '",arg,"': input mode has been set already"));
input_mode = InputMode_Connect;
const char* input_end_str = argNext();
tryLast(knIPV4Endpoint_fromStr(input_end_str, &input_end), _m2612, ;);
}
else if(argIs("-s") || argIs("--send-to")){
if(output_mode != OutputMode_None)
throw(cptr_concat("invalid option '",arg,"': output mode has been set already"));
if(input_mode != InputMode_Connect)
throw(cptr_concat("invalid option '",arg,"': out endpoint setting is avaliable only in 'connect' program mode"));
output_mode = OutputMode_Send;
const char* output_end_str = argNext();
tryLast(knIPV4Endpoint_fromStr(output_end_str, &output_end), _m8613, ;);
}
else if(argIs("-b") || argIs("--bind-to")){
if(output_mode != OutputMode_None)
throw(cptr_concat("invalid option '",arg,"': output mode has been set already"));
if(input_mode != InputMode_Connect)
throw(cptr_concat("invalid option '",arg,"': out endpoint setting is avaliable only in 'connect' program mode"));
output_mode = OutputMode_Bind;
const char* output_end_str = argNext();
tryLast(knIPV4Endpoint_fromStr(output_end_str, &output_end), _m2613, ;);
}
else if(argIs("-e") || argIs("--encrypt")){
if(encryption_key != NULL)
throw(cptr_concat("invalid option '",arg,"': encryption key has been set already"));
encryption_key = argNext();
if(cptr_length(encryption_key) < 16)
throw("too short encryption key (min length 16)");
if(cptr_length(encryption_key) > 512)
throw("too long encryption key (max length 512)");
}
else if(argIs("-d") || argIs("--decrypt")){
if(decryption_key != NULL)
throw(cptr_concat("invalid option '",arg,"': decryption key has been set already"));
decryption_key = argNext();
if(cptr_length(decryption_key) < 16)
throw("too short decryption key (min length 16)");
if(cptr_length(decryption_key) > 512)
throw("too long decryption key (max length 512)");
}
else {
throw(cptr_concat("invalid argument: ", arg));
}
}
kprintf("tunnel_protocol: %i\n", tunnel_protocol);
kprintf("input_mode: %i\n", input_mode);
kprintf("output_mode: %i\n", output_mode);
char* temps;
if(!knIPV4Endpoint_isINVALID(input_end)){
temps = knIPV4Endpoint_toString(&input_end);
kprintf("input_end: %s\n", temps);
free(temps);
}
else kprintf("input_end: INVALID\n");
if(!knIPV4Endpoint_isINVALID(output_end)){
temps = knIPV4Endpoint_toString(&output_end);
kprintf("output_end: %s\n", temps);
free(temps);
}
else kprintf("output_end: INVALID\n");
kprintf("encryption_key: %s\n", encryption_key ? encryption_key : "NULL");
kprintf("decryption_key: %s\n", decryption_key ? decryption_key : "NULL");
return 0;
}