Some work on the 'socket' networking module.
- bxhub.cc: Put all client data in a structure and added send_packet() function. - bxhub.cc: Added SVN ID line. - netmod.cc: Changed some DHCP messages to BX_DEBUG. - eth_socket.cc: Minor cleanups.
This commit is contained in:
parent
d6166344eb
commit
027b3ffd41
@ -28,8 +28,8 @@
|
||||
// - author definitely doesn't know C++ and generally doesn't know what
|
||||
// he is doing :)
|
||||
//
|
||||
// the idea is to provide a software multiport 'ethernet hub' and allow
|
||||
// communication between multiple bochs instances on the same machine
|
||||
// the idea is to provide a software multiport 'ethernet hub' and allow
|
||||
// communication between multiple bochs instances on the same machine
|
||||
// entirely in userspace and without need for root priviledges.
|
||||
//
|
||||
// The config line in .bochsrc should look like:
|
||||
@ -40,12 +40,12 @@
|
||||
//
|
||||
// ne2k: ioaddr=0x280, irq=10, mac=00:a:b:c:1:2, ethmod=socket, ethdev=40000
|
||||
//
|
||||
// this module will bind to 127.0.0.1:<socknum> for RX packets
|
||||
// this module will bind to 127.0.0.1:<socknum> for RX packets
|
||||
// TX packets will be sent to 127.0.0.1:<socknum + 1>
|
||||
|
||||
|
||||
// Define BX_PLUGGABLE in files that can be compiled into plugins. For
|
||||
// platforms that require a special tag on exported symbols, BX_PLUGGABLE
|
||||
// platforms that require a special tag on exported symbols, BX_PLUGGABLE
|
||||
// is used to know when we are exporting symbols and when we are importing.
|
||||
#define BX_PLUGGABLE
|
||||
|
||||
@ -80,8 +80,6 @@ extern "C" {
|
||||
|
||||
#define BX_PACKET_POLL 1000 // Poll for a frame every 1000 usecs
|
||||
|
||||
#define BX_PACKET_BUFSIZ 2048 // Enough for an ether frame
|
||||
|
||||
//
|
||||
// Define the class. This is private to this module
|
||||
//
|
||||
@ -171,7 +169,7 @@ bx_socket_pktmover_c::bx_socket_pktmover_c(const char *netif,
|
||||
//
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(this->ifindex);
|
||||
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); // localhost
|
||||
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); // localhost
|
||||
|
||||
|
||||
if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
|
||||
@ -205,7 +203,7 @@ bx_socket_pktmover_c::bx_socket_pktmover_c(const char *netif,
|
||||
|
||||
// Start the rx poll
|
||||
//
|
||||
this->rx_timer_index =
|
||||
this->rx_timer_index =
|
||||
bx_pc_system.register_timer(this, this->rx_timer_handler, BX_PACKET_POLL,
|
||||
1, 1, "eth_socket"); // continuous, active
|
||||
|
||||
@ -215,7 +213,6 @@ bx_socket_pktmover_c::bx_socket_pktmover_c(const char *netif,
|
||||
}
|
||||
|
||||
|
||||
|
||||
// the output routine - called with pre-formatted ethernet frame.
|
||||
void bx_socket_pktmover_c::sendpkt(void *buf, unsigned io_len)
|
||||
{
|
||||
@ -244,7 +241,7 @@ void bx_socket_pktmover_c::rx_timer_handler(void *this_ptr)
|
||||
void bx_socket_pktmover_c::rx_timer(void)
|
||||
{
|
||||
int nbytes = 0;
|
||||
Bit8u rxbuf[BX_PACKET_BUFSIZ];
|
||||
Bit8u rxbuf[BX_PACKET_BUFSIZE];
|
||||
|
||||
// is socket open and bound?
|
||||
if (this->fd == -1)
|
||||
|
@ -506,7 +506,7 @@ int process_dhcp(const Bit8u *data, unsigned data_len, Bit8u *reply, dhcp_cfg_t
|
||||
opts_len = sizeof(replybuf)/sizeof(replybuf[0])-240;
|
||||
switch (dhcpmsgtype) {
|
||||
case DHCPDISCOVER:
|
||||
BX_INFO(("dhcp server: DHCPDISCOVER"));
|
||||
BX_DEBUG(("dhcp server: DHCPDISCOVER"));
|
||||
// reset guest address; answer must be broadcasted to unconfigured IP
|
||||
memcpy(dhcp->guest_ipv4addr, broadcast_ipv4addr1, 4);
|
||||
*replyopts ++ = BOOTPOPT_DHCP_MESSAGETYPE;
|
||||
@ -521,7 +521,7 @@ int process_dhcp(const Bit8u *data, unsigned data_len, Bit8u *reply, dhcp_cfg_t
|
||||
dhcpreqparam_default_validflag = true;
|
||||
break;
|
||||
case DHCPREQUEST:
|
||||
BX_INFO(("dhcp server: DHCPREQUEST"));
|
||||
BX_DEBUG(("dhcp server: DHCPREQUEST"));
|
||||
// check ciaddr.
|
||||
if (found_serverid || found_guest_ipaddr || (!memcmp(&data[12], dhcp->default_guest_ipv4addr, 4))) {
|
||||
*replyopts ++ = BOOTPOPT_DHCP_MESSAGETYPE;
|
||||
@ -557,7 +557,7 @@ int process_dhcp(const Bit8u *data, unsigned data_len, Bit8u *reply, dhcp_cfg_t
|
||||
while (dhcpreqparams_len-- > 0) {
|
||||
switch (*dhcpreqparams++) {
|
||||
case BOOTPOPT_SUBNETMASK:
|
||||
BX_INFO(("provide BOOTPOPT_SUBNETMASK"));
|
||||
BX_DEBUG(("provide BOOTPOPT_SUBNETMASK"));
|
||||
if (opts_len < 6) {
|
||||
BX_ERROR(("option buffer is insufficient"));
|
||||
return 0;
|
||||
@ -569,7 +569,7 @@ int process_dhcp(const Bit8u *data, unsigned data_len, Bit8u *reply, dhcp_cfg_t
|
||||
replyopts += 4;
|
||||
break;
|
||||
case BOOTPOPT_ROUTER_OPTION:
|
||||
BX_INFO(("provide BOOTPOPT_ROUTER_OPTION"));
|
||||
BX_DEBUG(("provide BOOTPOPT_ROUTER_OPTION"));
|
||||
if (opts_len < 6) {
|
||||
BX_ERROR(("option buffer is insufficient"));
|
||||
return 0;
|
||||
@ -582,7 +582,7 @@ int process_dhcp(const Bit8u *data, unsigned data_len, Bit8u *reply, dhcp_cfg_t
|
||||
break;
|
||||
case BOOTPOPT_DOMAIN_NAMESERVER:
|
||||
if (dhcp->dns_ipv4addr[0] != 0) {
|
||||
BX_INFO(("provide BOOTPOPT_DOMAIN_NAMESERVER"));
|
||||
BX_DEBUG(("provide BOOTPOPT_DOMAIN_NAMESERVER"));
|
||||
if (opts_len < 6) {
|
||||
BX_ERROR(("option buffer is insufficient"));
|
||||
return 0;
|
||||
@ -595,7 +595,7 @@ int process_dhcp(const Bit8u *data, unsigned data_len, Bit8u *reply, dhcp_cfg_t
|
||||
}
|
||||
break;
|
||||
case BOOTPOPT_BROADCAST_ADDRESS:
|
||||
BX_INFO(("provide BOOTPOPT_BROADCAST_ADDRESS"));
|
||||
BX_DEBUG(("provide BOOTPOPT_BROADCAST_ADDRESS"));
|
||||
if (opts_len < 6) {
|
||||
BX_ERROR(("option buffer is insufficient"));
|
||||
return 0;
|
||||
@ -608,7 +608,7 @@ int process_dhcp(const Bit8u *data, unsigned data_len, Bit8u *reply, dhcp_cfg_t
|
||||
*replyopts ++ = 0xff;
|
||||
break;
|
||||
case BOOTPOPT_IP_ADDRESS_LEASE_TIME:
|
||||
BX_INFO(("provide BOOTPOPT_IP_ADDRESS_LEASE_TIME"));
|
||||
BX_DEBUG(("provide BOOTPOPT_IP_ADDRESS_LEASE_TIME"));
|
||||
if (opts_len < 6) {
|
||||
BX_ERROR(("option buffer is insufficient"));
|
||||
return 0;
|
||||
@ -624,7 +624,7 @@ int process_dhcp(const Bit8u *data, unsigned data_len, Bit8u *reply, dhcp_cfg_t
|
||||
replyopts += 4;
|
||||
break;
|
||||
case BOOTPOPT_SERVER_IDENTIFIER:
|
||||
BX_INFO(("provide BOOTPOPT_SERVER_IDENTIFIER"));
|
||||
BX_DEBUG(("provide BOOTPOPT_SERVER_IDENTIFIER"));
|
||||
if (opts_len < 6) {
|
||||
BX_ERROR(("option buffer is insufficient"));
|
||||
return 0;
|
||||
@ -636,7 +636,7 @@ int process_dhcp(const Bit8u *data, unsigned data_len, Bit8u *reply, dhcp_cfg_t
|
||||
replyopts += 4;
|
||||
break;
|
||||
case BOOTPOPT_RENEWAL_TIME:
|
||||
BX_INFO(("provide BOOTPOPT_RENEWAL_TIME"));
|
||||
BX_DEBUG(("provide BOOTPOPT_RENEWAL_TIME"));
|
||||
if (opts_len < 6) {
|
||||
BX_ERROR(("option buffer is insufficient"));
|
||||
return 0;
|
||||
@ -648,7 +648,7 @@ int process_dhcp(const Bit8u *data, unsigned data_len, Bit8u *reply, dhcp_cfg_t
|
||||
replyopts += 4;
|
||||
break;
|
||||
case BOOTPOPT_REBINDING_TIME:
|
||||
BX_INFO(("provide BOOTPOPT_REBINDING_TIME"));
|
||||
BX_DEBUG(("provide BOOTPOPT_REBINDING_TIME"));
|
||||
if (opts_len < 6) {
|
||||
BX_ERROR(("option buffer is insufficient"));
|
||||
return 0;
|
||||
@ -661,7 +661,7 @@ int process_dhcp(const Bit8u *data, unsigned data_len, Bit8u *reply, dhcp_cfg_t
|
||||
break;
|
||||
case BOOTPOPT_HOST_NAME:
|
||||
if (hostname != NULL) {
|
||||
BX_INFO(("provide BOOTPOPT_HOST_NAME"));
|
||||
BX_DEBUG(("provide BOOTPOPT_HOST_NAME"));
|
||||
if (opts_len < (hostname_len + 2)) {
|
||||
free(hostname);
|
||||
BX_ERROR(("option buffer is insufficient"));
|
||||
@ -919,7 +919,7 @@ void tftp_parse_options(const char *mode, const Bit8u *data, unsigned data_len,
|
||||
}
|
||||
mode += strlen(mode)+1;
|
||||
} else {
|
||||
BX_INFO(("tftp req: unknown option %s", mode));
|
||||
BX_ERROR(("tftp req: unknown option %s", mode));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -969,7 +969,7 @@ int process_tftp(const Bit8u *data, unsigned data_len, Bit16u req_tid, Bit8u *re
|
||||
s->options &= ~TFTP_OPTION_TSIZE;
|
||||
} else {
|
||||
s->tsize_val = (size_t)stbuf.st_size;
|
||||
BX_INFO(("tftp filesize: %lu", (unsigned long)s->tsize_val));
|
||||
BX_DEBUG(("tftp filesize: %lu", (unsigned long)s->tsize_val));
|
||||
}
|
||||
}
|
||||
if ((s->options & ~TFTP_OPTION_OCTET) > 0) {
|
||||
|
@ -1,3 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* bxhub.c: a simple, two-port software 'ethernet hub' for use with
|
||||
* eth_socket Bochs ethernet pktmover.
|
||||
@ -78,9 +81,19 @@ typedef struct arp_header {
|
||||
#endif
|
||||
arp_header_t;
|
||||
|
||||
typedef struct {
|
||||
int so;
|
||||
struct sockaddr_in sin, sout;
|
||||
bx_bool init;
|
||||
dhcp_cfg_t dhcp;
|
||||
Bit8u *reply_buffer;
|
||||
int pending_reply_size;
|
||||
} hub_client_t;
|
||||
|
||||
const Bit8u default_host_macaddr[6] = {0xb0, 0xc4, 0x20, 0x00, 0x00, 0x03};
|
||||
const Bit8u default_host_ipv4addr[4] = {10, 0, 2, 2};
|
||||
const Bit8u default_dns_ipv4addr[4] = {10, 0, 2, 3};
|
||||
|
||||
const Bit8u default_guest_ipv4addr[2][4] =
|
||||
{
|
||||
{10, 0, 2, 15},
|
||||
@ -97,24 +110,20 @@ const Bit8u broadcast_ipv4addr[3][4] =
|
||||
static Bit16u port_base = 40000;
|
||||
static char tftp_root[BX_PATHNAME_LEN];
|
||||
static Bit8u host_macaddr[6];
|
||||
int client_count;
|
||||
int dhcp_init[2];
|
||||
dhcp_cfg_t dhcp[2];
|
||||
Bit8u reply_buffer[2][1024];
|
||||
int pending_reply_size[2];
|
||||
static int client_count;
|
||||
|
||||
|
||||
void prepare_builtin_reply(int client, unsigned type)
|
||||
void prepare_builtin_reply(hub_client_t *client, unsigned type)
|
||||
{
|
||||
ethernet_header_t *ethhdr;
|
||||
dhcp_cfg_t *dhcpc = &client->dhcp;
|
||||
ethernet_header_t *ethhdr = (ethernet_header_t *)client->reply_buffer;
|
||||
|
||||
ethhdr = (ethernet_header_t *)reply_buffer[client];
|
||||
memcpy(ethhdr->dst_mac_addr, dhcp[client].guest_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||
memcpy(ethhdr->src_mac_addr, dhcp[client].host_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||
memcpy(ethhdr->dst_mac_addr, dhcpc->guest_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||
memcpy(ethhdr->src_mac_addr, dhcpc->host_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||
ethhdr->type = htons(type);
|
||||
}
|
||||
|
||||
bx_bool handle_ipv4(int client, Bit8u *buf, unsigned len)
|
||||
bx_bool handle_ipv4(hub_client_t *client, Bit8u *buf, unsigned len)
|
||||
{
|
||||
unsigned total_len;
|
||||
unsigned fragment_flags;
|
||||
@ -128,8 +137,8 @@ bx_bool handle_ipv4(int client, Bit8u *buf, unsigned len)
|
||||
unsigned udp_reply_size = 0;
|
||||
unsigned icmptype;
|
||||
unsigned icmpcode;
|
||||
Bit8u *replybuf = reply_buffer[client];
|
||||
dhcp_cfg_t *dhcpc = &dhcp[client];
|
||||
Bit8u *replybuf = client->reply_buffer;
|
||||
dhcp_cfg_t *dhcpc = &client->dhcp;
|
||||
|
||||
// guest-to-host IPv4
|
||||
if (len < (14U+20U)) {
|
||||
@ -210,7 +219,7 @@ bx_bool handle_ipv4(int client, Bit8u *buf, unsigned len)
|
||||
memcpy(&replybuf[30], dhcpc->guest_ipv4addr, 4);
|
||||
put_net2(&replybuf[24], 0);
|
||||
put_net2(&replybuf[24], ip_checksum(&replybuf[14], l3header_len) ^ (Bit16u)0xffff);
|
||||
pending_reply_size[client] = udp_reply_size + 42;
|
||||
client->pending_reply_size = udp_reply_size + 42;
|
||||
prepare_builtin_reply(client, ETHERNET_TYPE_IPV4);
|
||||
}
|
||||
// don't forward DHCP / TFTP requests to other client
|
||||
@ -246,7 +255,7 @@ bx_bool handle_ipv4(int client, Bit8u *buf, unsigned len)
|
||||
memcpy(&replybuf[30], dhcpc->guest_ipv4addr, 4);
|
||||
put_net2(&replybuf[24], 0);
|
||||
put_net2(&replybuf[24], ip_checksum(&replybuf[14], l3header_len) ^ (Bit16u)0xffff);
|
||||
pending_reply_size[client] = 14U+l3header_len+l4pkt_len;
|
||||
client->pending_reply_size = 14U+l3header_len+l4pkt_len;
|
||||
prepare_builtin_reply(client, ETHERNET_TYPE_IPV4);
|
||||
return 1;
|
||||
}
|
||||
@ -260,13 +269,13 @@ bx_bool handle_ipv4(int client, Bit8u *buf, unsigned len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bx_bool handle_arp(int client, Bit8u *buf, unsigned len)
|
||||
bx_bool handle_arp(hub_client_t *client, Bit8u *buf, unsigned len)
|
||||
{
|
||||
dhcp_cfg_t *dhcpc = &client->dhcp;
|
||||
arp_header_t *arphdr = (arp_header_t *)((Bit8u *)buf +
|
||||
sizeof(ethernet_header_t));
|
||||
|
||||
if (pending_reply_size[client] > 0)
|
||||
return 0;
|
||||
arp_header_t *arprhdr = (arp_header_t *)((Bit8u *)client->reply_buffer +
|
||||
sizeof(ethernet_header_t));
|
||||
|
||||
if ((ntohs(arphdr->hw_addr_space) != 0x0001) ||
|
||||
(ntohs(arphdr->proto_addr_space) != 0x0800) ||
|
||||
@ -278,23 +287,21 @@ bx_bool handle_arp(int client, Bit8u *buf, unsigned len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
arp_header_t *arprhdr = (arp_header_t *)((Bit8u *)reply_buffer[client] +
|
||||
sizeof(ethernet_header_t));
|
||||
switch(ntohs(arphdr->opcode)) {
|
||||
case ARP_OPCODE_REQUEST:
|
||||
if (((Bit8u *)arphdr)[27] > 3)
|
||||
break;
|
||||
memset(reply_buffer[client], 0, MIN_RX_PACKET_LEN);
|
||||
memset(client->reply_buffer, 0, MIN_RX_PACKET_LEN);
|
||||
arprhdr->hw_addr_space = htons(0x0001);
|
||||
arprhdr->proto_addr_space = htons(0x0800);
|
||||
arprhdr->hw_addr_len = ETHERNET_MAC_ADDR_LEN;
|
||||
arprhdr->proto_addr_len = 4;
|
||||
arprhdr->opcode = htons(ARP_OPCODE_REPLY);
|
||||
memcpy((Bit8u *)arprhdr+8, dhcp[client].host_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||
memcpy((Bit8u *)arprhdr+8, dhcpc->host_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||
memcpy((Bit8u *)arprhdr+14, (Bit8u *)arphdr+24, 4);
|
||||
memcpy((Bit8u *)arprhdr+18, dhcp[client].guest_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||
memcpy((Bit8u *)arprhdr+18, dhcpc->guest_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||
memcpy((Bit8u *)arprhdr+24, (Bit8u *)arphdr+14, 4);
|
||||
pending_reply_size[client] = MIN_RX_PACKET_LEN;
|
||||
client->pending_reply_size = MIN_RX_PACKET_LEN;
|
||||
prepare_builtin_reply(client, ETHERNET_TYPE_ARP);
|
||||
return 1;
|
||||
case ARP_OPCODE_REPLY:
|
||||
@ -305,24 +312,24 @@ bx_bool handle_arp(int client, Bit8u *buf, unsigned len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_packet(int client, Bit8u *buf, unsigned len)
|
||||
int handle_packet(hub_client_t *client, Bit8u *buf, unsigned len)
|
||||
{
|
||||
ethernet_header_t *ethhdr = (ethernet_header_t *)buf;
|
||||
dhcp_cfg_t *dhcpc = &dhcp[client];
|
||||
dhcp_cfg_t *dhcpc = &client->dhcp;
|
||||
int ret = 1;
|
||||
|
||||
if (!dhcp_init[client]) {
|
||||
if (!client->init) {
|
||||
if (memcmp(ethhdr->src_mac_addr, host_macaddr, 6) == 0) {
|
||||
dhcp_init[client] = -1;
|
||||
client->init = -1;
|
||||
} else {
|
||||
memcpy(dhcpc->host_macaddr, host_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||
memcpy(dhcpc->guest_macaddr, ethhdr->src_mac_addr, ETHERNET_MAC_ADDR_LEN);
|
||||
memcpy(dhcpc->host_ipv4addr, &default_host_ipv4addr[0], 4);
|
||||
memcpy(dhcpc->guest_ipv4addr, &broadcast_ipv4addr[1][0], 4);
|
||||
dhcpc->default_guest_ipv4addr = default_guest_ipv4addr[client];
|
||||
dhcpc->default_guest_ipv4addr = default_guest_ipv4addr[client_count++];
|
||||
memcpy(dhcpc->dns_ipv4addr, &default_dns_ipv4addr[0], 4);
|
||||
dhcp_init[client] = 1;
|
||||
client_count++;
|
||||
client->reply_buffer = new Bit8u[BUFSIZE];
|
||||
client->init = 1;
|
||||
}
|
||||
}
|
||||
if ((memcmp(ethhdr->dst_mac_addr, host_macaddr, ETHERNET_MAC_ADDR_LEN) != 0) &&
|
||||
@ -330,6 +337,9 @@ int handle_packet(int client, Bit8u *buf, unsigned len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (client->pending_reply_size > 0)
|
||||
return 0;
|
||||
|
||||
switch (ntohs(ethhdr->type)) {
|
||||
case ETHERNET_TYPE_IPV4:
|
||||
ret = handle_ipv4(client, buf, len);
|
||||
@ -397,18 +407,20 @@ int parse_cmdline(int argc, char *argv[])
|
||||
return ret;
|
||||
}
|
||||
|
||||
void send_packet(hub_client_t *client, Bit8u *buf, unsigned len)
|
||||
{
|
||||
sendto(client->so, (char*)buf, len, (MSG_DONTROUTE|MSG_NOSIGNAL|MSG_DONTWAIT),
|
||||
(struct sockaddr*) &client->sout, sizeof(client->sout));
|
||||
}
|
||||
|
||||
int CDECL main(int argc, char **argv)
|
||||
{
|
||||
int s1, s2, n;
|
||||
struct sockaddr_in s1in, s1out, s2in, s2out;
|
||||
hub_client_t hclient[2];
|
||||
int i, n;
|
||||
fd_set rfds;
|
||||
Bit8u buf[BUFSIZE];
|
||||
|
||||
client_count = 0;
|
||||
dhcp_init[0] = 0;
|
||||
dhcp_init[1] = 0;
|
||||
pending_reply_size[0] = 0;
|
||||
pending_reply_size[1] = 0;
|
||||
|
||||
if (!parse_cmdline(argc, argv))
|
||||
exit(0);
|
||||
@ -425,53 +437,33 @@ int CDECL main(int argc, char **argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* create sockets */
|
||||
for (i = 0; i < 2; i++) {
|
||||
memset(&hclient[i], 0, sizeof(hub_client_t));
|
||||
|
||||
if ((s1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
|
||||
perror("bxhub - cannot create socket");
|
||||
exit(1);
|
||||
/* create sockets */
|
||||
if ((hclient[i].so = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
|
||||
perror("bxhub - cannot create socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* fill addres structures */
|
||||
hclient[i].sin.sin_family = AF_INET;
|
||||
hclient[i].sin.sin_port = htons(port_base + (i * 2) + 1);
|
||||
hclient[i].sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
hclient[i].sout.sin_family = AF_INET;
|
||||
hclient[i].sout.sin_port = htons(port_base + (i * 2));
|
||||
hclient[i].sout.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
/* configure (bind) sockets */
|
||||
if (bind(hclient[i].so, (struct sockaddr *) &hclient[i].sin, sizeof(hclient[i].sin)) < 0) {
|
||||
perror("bxhub - cannot bind socket");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
printf("RX port #%d in use: %d\n", i + 1, ntohs(hclient[i].sin.sin_port));
|
||||
}
|
||||
|
||||
if ((s2 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
|
||||
perror("bxhub - cannot create socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* fill addres structures */
|
||||
|
||||
s1in.sin_family = AF_INET;
|
||||
s1in.sin_port = htons(port_base + 1);
|
||||
s1in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
s1out.sin_family = AF_INET;
|
||||
s1out.sin_port = htons(port_base);
|
||||
s1out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
s2in.sin_family = AF_INET;
|
||||
s2in.sin_port = htons(port_base + 3);
|
||||
s2in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
s2out.sin_family = AF_INET;
|
||||
s2out.sin_port = htons(port_base + 2);
|
||||
s2out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
|
||||
/* configure (bind) sockets */
|
||||
|
||||
if (bind(s1, (struct sockaddr *) &s1in, sizeof(s1in)) < 0) {
|
||||
perror("bxhub - cannot bind socket");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
printf("1st RX port in use: %d\n", ntohs(s1in.sin_port));
|
||||
|
||||
if (bind(s2, (struct sockaddr *) &s2in, sizeof(s2in)) < 0) {
|
||||
perror("bxhub - cannot bind socket");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
printf("2nd RX port in use: %d\n", ntohs(s2in.sin_port));
|
||||
|
||||
printf("Host MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
host_macaddr[0], host_macaddr[1], host_macaddr[2],
|
||||
host_macaddr[3], host_macaddr[4], host_macaddr[5]
|
||||
@ -487,55 +479,52 @@ int CDECL main(int argc, char **argv)
|
||||
/* wait for input */
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(s1, &rfds);
|
||||
FD_SET(s2, &rfds);
|
||||
FD_SET(hclient[0].so, &rfds);
|
||||
FD_SET(hclient[1].so, &rfds);
|
||||
|
||||
n = select(s2+1, &rfds, NULL, NULL, NULL);
|
||||
n = select(hclient[1].so+1, &rfds, NULL, NULL, NULL);
|
||||
|
||||
/* data is available somewhere */
|
||||
|
||||
if (FD_ISSET(s1, &rfds)) { // check input 1
|
||||
n = recv(s1, (char*)buf, sizeof(buf), 0);
|
||||
if (FD_ISSET(hclient[0].so, &rfds)) { // check input 1
|
||||
n = recv(hclient[0].so, (char*)buf, sizeof(buf), 0);
|
||||
if (n > 0) {
|
||||
if (!handle_packet(0, buf, n)) {
|
||||
sendto(s2, (char*)buf, n, (MSG_DONTROUTE|MSG_NOSIGNAL|MSG_DONTWAIT),
|
||||
(struct sockaddr*) &s2out, sizeof(s2out));
|
||||
if (!handle_packet(&hclient[0], buf, n)) {
|
||||
send_packet(&hclient[1], buf, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(s2, &rfds)) { // check input 2
|
||||
n = recv(s2, (char*)buf, sizeof(buf), 0);
|
||||
if (FD_ISSET(hclient[1].so, &rfds)) { // check input 2
|
||||
n = recv(hclient[1].so, (char*)buf, sizeof(buf), 0);
|
||||
if (n > 0) {
|
||||
if (!handle_packet(1, buf, n)) {
|
||||
sendto(s1, (char*)buf, n, (MSG_DONTROUTE|MSG_NOSIGNAL|MSG_DONTWAIT),
|
||||
(struct sockaddr*) &s1out, sizeof(s1out));
|
||||
if (!handle_packet(&hclient[1], buf, n)) {
|
||||
send_packet(&hclient[0], buf, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((dhcp_init[0] < 0) || (dhcp_init[1] < 0)) {
|
||||
perror("bxhub - wrong MAC address configuration");
|
||||
if ((hclient[0].init < 0) || (hclient[1].init < 0)) {
|
||||
fprintf(stderr, "bxhub - wrong MAC address configuration\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (pending_reply_size[0] > 0) {
|
||||
n = pending_reply_size[0];
|
||||
sendto(s1, (char*)reply_buffer[0], n, (MSG_DONTROUTE|MSG_NOSIGNAL|MSG_DONTWAIT),
|
||||
(struct sockaddr*) &s1out, sizeof(s1out));
|
||||
pending_reply_size[0] = 0;
|
||||
if (hclient[0].pending_reply_size > 0) {
|
||||
send_packet(&hclient[0], hclient[0].reply_buffer, hclient[0].pending_reply_size);
|
||||
hclient[0].pending_reply_size = 0;
|
||||
}
|
||||
|
||||
if (pending_reply_size[1] > 0) {
|
||||
n = pending_reply_size[1];
|
||||
sendto(s2, (char*)reply_buffer[1], n, (MSG_DONTROUTE|MSG_NOSIGNAL|MSG_DONTWAIT),
|
||||
(struct sockaddr*) &s2out, sizeof(s2out));
|
||||
pending_reply_size[1] = 0;
|
||||
if (hclient[1].pending_reply_size > 0) {
|
||||
send_packet(&hclient[1], hclient[1].reply_buffer, hclient[1].pending_reply_size);
|
||||
hclient[1].pending_reply_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
close(s2);
|
||||
close(s1);
|
||||
if (hclient[0].init) delete [] hclient[0].reply_buffer;
|
||||
if (hclient[1].init) delete [] hclient[1].reply_buffer;
|
||||
|
||||
close(hclient[0].so);
|
||||
close(hclient[1].so);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user