mirror of
https://github.com/solemnwarning/ipxwrapper
synced 2024-12-30 16:45:37 +01:00
Implemented support for Novell "raw" Ethernet frames.
Manual selection of frame type (defaults to Ethernet II) only, don't want to mess with trying to guess/detect the frame type right now.
This commit is contained in:
parent
d7c9e10349
commit
20a636b933
45
src/config.c
45
src/config.c
@ -27,11 +27,12 @@ main_config_t get_main_config(void)
|
||||
|
||||
main_config_t config;
|
||||
|
||||
config.udp_port = DEFAULT_PORT;
|
||||
config.w95_bug = true;
|
||||
config.fw_except = false;
|
||||
config.use_pcap = false;
|
||||
config.log_level = LOG_INFO;
|
||||
config.udp_port = DEFAULT_PORT;
|
||||
config.w95_bug = true;
|
||||
config.fw_except = false;
|
||||
config.use_pcap = false;
|
||||
config.frame_type = FRAME_TYPE_ETH_II;
|
||||
config.log_level = LOG_INFO;
|
||||
|
||||
HKEY reg = reg_open_main(false);
|
||||
|
||||
@ -49,11 +50,24 @@ main_config_t get_main_config(void)
|
||||
|
||||
/* Overlay with any 0.4.x config values. */
|
||||
|
||||
config.udp_port = reg_get_dword(reg, "port", config.udp_port);
|
||||
config.w95_bug = reg_get_dword(reg, "w95_bug", config.w95_bug);
|
||||
config.fw_except = reg_get_dword(reg, "fw_except", config.fw_except);
|
||||
config.use_pcap = reg_get_dword(reg, "use_pcap", config.use_pcap);
|
||||
config.log_level = reg_get_dword(reg, "log_level", config.log_level);
|
||||
config.udp_port = reg_get_dword(reg, "port", config.udp_port);
|
||||
config.w95_bug = reg_get_dword(reg, "w95_bug", config.w95_bug);
|
||||
config.fw_except = reg_get_dword(reg, "fw_except", config.fw_except);
|
||||
config.use_pcap = reg_get_dword(reg, "use_pcap", config.use_pcap);
|
||||
config.frame_type = reg_get_dword(reg, "frame_type", config.frame_type);
|
||||
config.log_level = reg_get_dword(reg, "log_level", config.log_level);
|
||||
|
||||
/* Check for valid frame_type */
|
||||
|
||||
if( config.frame_type != FRAME_TYPE_ETH_II
|
||||
&& config.frame_type != FRAME_TYPE_NOVELL)
|
||||
{
|
||||
|
||||
log_printf(LOG_WARNING, "Ignoring unknown frame_type %u",
|
||||
(unsigned int)(config.frame_type));
|
||||
|
||||
config.frame_type = FRAME_TYPE_ETH_II;
|
||||
}
|
||||
|
||||
reg_close(reg);
|
||||
|
||||
@ -64,11 +78,12 @@ bool set_main_config(const main_config_t *config)
|
||||
{
|
||||
HKEY reg = reg_open_main(true);
|
||||
|
||||
bool ok = reg_set_dword(reg, "port", config->udp_port)
|
||||
&& reg_set_dword(reg, "w95_bug", config->w95_bug)
|
||||
&& reg_set_dword(reg, "fw_except", config->fw_except)
|
||||
&& reg_set_dword(reg, "use_pcap", config->use_pcap)
|
||||
&& reg_set_dword(reg, "log_level", config->log_level);
|
||||
bool ok = reg_set_dword(reg, "port", config->udp_port)
|
||||
&& reg_set_dword(reg, "w95_bug", config->w95_bug)
|
||||
&& reg_set_dword(reg, "fw_except", config->fw_except)
|
||||
&& reg_set_dword(reg, "use_pcap", config->use_pcap)
|
||||
&& reg_set_dword(reg, "frame_type", config->frame_type)
|
||||
&& reg_set_dword(reg, "log_level", config->log_level);
|
||||
|
||||
reg_close(reg);
|
||||
|
||||
|
@ -26,12 +26,19 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum main_config_frame_type
|
||||
{
|
||||
FRAME_TYPE_ETH_II = 1,
|
||||
FRAME_TYPE_NOVELL = 2
|
||||
};
|
||||
|
||||
typedef struct main_config {
|
||||
uint16_t udp_port;
|
||||
|
||||
bool w95_bug;
|
||||
bool fw_except;
|
||||
bool use_pcap;
|
||||
enum main_config_frame_type frame_type;
|
||||
|
||||
enum ipx_log_level log_level;
|
||||
} main_config_t;
|
||||
|
@ -116,7 +116,11 @@ struct ethernet_frame
|
||||
unsigned char dest_mac[6];
|
||||
unsigned char src_mac[6];
|
||||
|
||||
uint16_t ethertype;
|
||||
union {
|
||||
/* Depends on frame type. */
|
||||
uint16_t ethertype;
|
||||
uint16_t length;
|
||||
};
|
||||
|
||||
real_ipx_packet_t packet;
|
||||
} __attribute__((__packed__));
|
||||
|
41
src/router.c
41
src/router.c
@ -505,10 +505,43 @@ static void _handle_pcap_frame(u_char *user, const struct pcap_pkthdr *pkt_heade
|
||||
|
||||
ethernet_frame_t *frame = (ethernet_frame_t*)(pkt_data);
|
||||
|
||||
if(ntohs(frame->ethertype) != 0x8137)
|
||||
uint16_t ipx_packet_len = ntohs(frame->packet.length);
|
||||
|
||||
if(main_config.frame_type == FRAME_TYPE_ETH_II)
|
||||
{
|
||||
/* The ethertype field isn't IPX. */
|
||||
return;
|
||||
/* Configured for standard Ethernet. */
|
||||
|
||||
if(ntohs(frame->ethertype) != 0x8137)
|
||||
{
|
||||
/* The ethertype field isn't IPX. */
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(main_config.frame_type == FRAME_TYPE_NOVELL)
|
||||
{
|
||||
/* Configured for Novell "raw" Ethernet. */
|
||||
|
||||
uint16_t eth_payload_len = ntohs(frame->length);
|
||||
|
||||
if(eth_payload_len > 1500)
|
||||
{
|
||||
/* Too big, must be an Ethernet II frame (or garbage). */
|
||||
return;
|
||||
}
|
||||
else if(eth_payload_len < sizeof(frame->packet))
|
||||
{
|
||||
/* Too small to hold an IPX header. */
|
||||
return;
|
||||
}
|
||||
else if(eth_payload_len < ipx_packet_len)
|
||||
{
|
||||
/* Too small to hold the IPX payload within. */
|
||||
return;
|
||||
}
|
||||
}
|
||||
else{
|
||||
/* Unknown frame type configured. */
|
||||
abort();
|
||||
}
|
||||
|
||||
if(frame->packet.checksum != 0xFFFF)
|
||||
@ -517,7 +550,7 @@ static void _handle_pcap_frame(u_char *user, const struct pcap_pkthdr *pkt_heade
|
||||
return;
|
||||
}
|
||||
|
||||
if(ntohs(frame->packet.length) > (pkt_header->caplen - (sizeof(*frame) - sizeof(frame->packet))))
|
||||
if(ipx_packet_len > (pkt_header->caplen - (sizeof(*frame) - sizeof(frame->packet))))
|
||||
{
|
||||
/* The "length" field in the IPX header is too big. */
|
||||
return;
|
||||
|
@ -1206,13 +1206,41 @@ static DWORD ipx_send_packet(
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
log_printf(LOG_DEBUG, "...packet size = %d, frame size = %d",
|
||||
log_printf(LOG_DEBUG, "...packet size = %u, frame size = %u",
|
||||
(unsigned int)(packet_size), (unsigned int)(frame_size));
|
||||
|
||||
addr48_out(frame->dest_mac, dest_node);
|
||||
addr48_out(frame->src_mac, iface->mac_addr);
|
||||
|
||||
frame->ethertype = htons(0x8137);
|
||||
if(main_config.frame_type == FRAME_TYPE_ETH_II)
|
||||
{
|
||||
/* Configured for standard Ethernet. */
|
||||
frame->ethertype = htons(0x8137);
|
||||
}
|
||||
else if(main_config.frame_type == FRAME_TYPE_NOVELL)
|
||||
{
|
||||
/* Configured for Novell "raw" Ethernet. */
|
||||
|
||||
if(packet_size > 1500)
|
||||
{
|
||||
/* Can't fit a payload this big into a
|
||||
* Novell Ethernet frame.
|
||||
*/
|
||||
|
||||
log_printf(LOG_ERROR,
|
||||
"Tried sending a %u byte packet in a Novell (\"raw\") Ethernet frame",
|
||||
(unsigned int)(packet_size));
|
||||
|
||||
free(frame);
|
||||
return WSAEMSGSIZE;
|
||||
}
|
||||
|
||||
frame->length = htons(packet_size);
|
||||
}
|
||||
else{
|
||||
/* Unknown frame type configured. */
|
||||
abort();
|
||||
}
|
||||
|
||||
frame->packet.checksum = 0xFFFF;
|
||||
frame->packet.length = htons(packet_size);
|
||||
|
Loading…
x
Reference in New Issue
Block a user