- TFTP write support implemented (doesn't overwrite files)
- missing DHCP symbol added
This commit is contained in:
parent
57f1cfd8ff
commit
f67552df29
@ -594,10 +594,11 @@ private_colormap: enabled=0
|
||||
# you can use the following 'ethmod's to simulate a virtual network.
|
||||
# null: All packets are discarded, but logged to a few files.
|
||||
# arpback: ARP is simulated. Disabled by default.
|
||||
# vnet: ARP, ICMP-echo(ping), DHCP and read-only TFTP are simulated.
|
||||
# vnet: ARP, ICMP-echo(ping), DHCP and read/write TFTP are simulated.
|
||||
# The virtual host uses 192.168.10.1.
|
||||
# DHCP assignes 192.168.10.2 to the guest.
|
||||
# TFTP uses the ethdev value for the root directory.
|
||||
# TFTP uses the ethdev value for the root directory and doesn't
|
||||
# overwrite files.
|
||||
#
|
||||
#=======================================================================
|
||||
# ne2k: ioaddr=0x240, irq=9, mac=fe:fd:00:00:00:01, ethmod=fbsd, ethdev=en0 #macosx
|
||||
|
@ -1,10 +1,10 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: eth_vnet.cc,v 1.16 2005-06-08 21:11:54 vruppert Exp $
|
||||
// $Id: eth_vnet.cc,v 1.17 2005-06-12 08:59:32 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// virtual Ethernet locator
|
||||
//
|
||||
// An implementation of ARP, ping(ICMP-echo), DHCP and read-only TFTP.
|
||||
// An implementation of ARP, ping(ICMP-echo), DHCP and read/write TFTP.
|
||||
// Virtual host acts as a DHCP server for guest.
|
||||
// There are no connections between the virtual host and real ethernets.
|
||||
//
|
||||
@ -13,7 +13,7 @@
|
||||
// Guest IP: 192.168.10.2
|
||||
// Guest netmask: 255.255.255.0
|
||||
// Guest broadcast: 192.168.10.255
|
||||
// TFTP server uses ethdev value for the root directory
|
||||
// TFTP server uses ethdev value for the root directory and doesn't overwrite files
|
||||
|
||||
#define BX_PLUGGABLE
|
||||
|
||||
@ -81,6 +81,7 @@ typedef void (*layer4_handler_t)(
|
||||
|
||||
#define BOOTREQUEST 1
|
||||
#define BOOTREPLY 2
|
||||
|
||||
#define BOOTPOPT_PADDING 0
|
||||
#define BOOTPOPT_END 255
|
||||
#define BOOTPOPT_SUBNETMASK 1
|
||||
@ -110,12 +111,13 @@ typedef void (*layer4_handler_t)(
|
||||
#define BOOTPOPT_CLIENT_IDENTIFIER 61
|
||||
|
||||
#define DHCPDISCOVER 1
|
||||
#define DHCPOFFER 2
|
||||
#define DHCPREQUEST 3
|
||||
#define DHCPDECLINE 4
|
||||
#define DHCPACK 5
|
||||
#define DHCPNAK 6
|
||||
#define DHCPRELEASE 7
|
||||
#define DHCPOFFER 2
|
||||
#define DHCPREQUEST 3
|
||||
#define DHCPDECLINE 4
|
||||
#define DHCPACK 5
|
||||
#define DHCPNAK 6
|
||||
#define DHCPRELEASE 7
|
||||
#define DHCPINFORM 8
|
||||
|
||||
class bx_vnet_pktmover_c : public eth_pktmover_c {
|
||||
public:
|
||||
@ -175,16 +177,21 @@ private:
|
||||
unsigned sourceport, unsigned targetport,
|
||||
const Bit8u *data, unsigned data_len);
|
||||
void tftp_send_error(
|
||||
Bit8u *buffer,
|
||||
Bit8u *buffer,
|
||||
unsigned sourceport, unsigned targetport,
|
||||
unsigned code, const char *msg);
|
||||
void tftp_send_data(
|
||||
Bit8u *buffer,
|
||||
unsigned sourceport, unsigned targetport,
|
||||
Bit8u *buffer,
|
||||
unsigned sourceport, unsigned targetport,
|
||||
unsigned block_nr);
|
||||
void tftp_send_ack(
|
||||
Bit8u *buffer,
|
||||
unsigned sourceport, unsigned targetport,
|
||||
unsigned block_nr);
|
||||
|
||||
char tftp_filename[BX_PATHNAME_LEN];
|
||||
char tftp_rootdir[BX_PATHNAME_LEN];
|
||||
bx_bool tftp_write;
|
||||
Bit16u tftp_tid;
|
||||
|
||||
Bit8u host_macaddr[6];
|
||||
@ -286,6 +293,7 @@ bx_vnet_pktmover_c::pktmover_init(
|
||||
this->rxarg = rxarg;
|
||||
strcpy(this->tftp_rootdir, netif);
|
||||
this->tftp_tid = 0;
|
||||
this->tftp_write = 0;
|
||||
|
||||
memcpy(&host_macaddr[0], macaddr, 6);
|
||||
memcpy(&guest_macaddr[0], macaddr, 6);
|
||||
@ -1112,6 +1120,11 @@ bx_vnet_pktmover_c::udpipv4_tftp_handler_ns(
|
||||
const Bit8u *data, unsigned data_len)
|
||||
{
|
||||
Bit8u buffer[TFTP_BUFFER_SIZE + 4];
|
||||
char path[BX_PATHNAME_LEN];
|
||||
FILE *fp;
|
||||
unsigned block_nr;
|
||||
unsigned tftp_len;
|
||||
|
||||
switch (get_net2(data)) {
|
||||
case TFTP_RRQ:
|
||||
if (tftp_tid == 0) {
|
||||
@ -1129,6 +1142,7 @@ bx_vnet_pktmover_c::udpipv4_tftp_handler_ns(
|
||||
|
||||
strcpy(tftp_filename, (char*)buffer);
|
||||
tftp_tid = sourceport;
|
||||
tftp_write = 0;
|
||||
tftp_send_data(buffer, sourceport, targetport, 1);
|
||||
} else {
|
||||
tftp_send_error(buffer, sourceport, targetport, 4, "Illegal request");
|
||||
@ -1148,7 +1162,54 @@ bx_vnet_pktmover_c::udpipv4_tftp_handler_ns(
|
||||
}
|
||||
}
|
||||
|
||||
tftp_send_error(buffer, sourceport, targetport, 4, "TFTP WRQ not supported yet");
|
||||
strcpy(tftp_filename, (char*)buffer);
|
||||
sprintf(path, "%s/%s", tftp_rootdir, tftp_filename);
|
||||
fp = fopen(path, "rb");
|
||||
if (fp) {
|
||||
tftp_send_error(buffer, sourceport, targetport, 6, "File exists");
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
fp = fopen(path, "wb");
|
||||
if (!fp) {
|
||||
tftp_send_error(buffer, sourceport, targetport, 2, "Access violation");
|
||||
return;
|
||||
}
|
||||
fclose(fp);
|
||||
tftp_tid = sourceport;
|
||||
tftp_write = 1;
|
||||
|
||||
tftp_send_ack(buffer, sourceport, targetport, 0);
|
||||
} else {
|
||||
tftp_send_error(buffer, sourceport, targetport, 4, "Illegal request");
|
||||
}
|
||||
break;
|
||||
case TFTP_DATA:
|
||||
if ((tftp_tid == sourceport) && (tftp_write == 1)) {
|
||||
block_nr = get_net2(data + 2);
|
||||
strncpy((char*)buffer, (const char*)data + 4, data_len - 4);
|
||||
tftp_len = data_len - 4;
|
||||
buffer[tftp_len] = 0;
|
||||
if (tftp_len <= 512) {
|
||||
sprintf(path, "%s/%s", tftp_rootdir, tftp_filename);
|
||||
fp = fopen(path, "ab");
|
||||
if (!fp) {
|
||||
tftp_send_error(buffer, sourceport, targetport, 2, "Access violation");
|
||||
return;
|
||||
}
|
||||
if (fseek(fp, (block_nr - 1) * TFTP_BUFFER_SIZE, SEEK_SET) < 0) {
|
||||
tftp_send_error(buffer, sourceport, targetport, 3, "Block not seekable");
|
||||
return;
|
||||
}
|
||||
fwrite(buffer, 1, tftp_len, fp);
|
||||
fclose(fp);
|
||||
tftp_send_ack(buffer, sourceport, targetport, block_nr);
|
||||
if (tftp_len < 512) {
|
||||
tftp_tid = 0;
|
||||
}
|
||||
} else {
|
||||
tftp_send_error(buffer, sourceport, targetport, 4, "Illegal request");
|
||||
}
|
||||
} else {
|
||||
tftp_send_error(buffer, sourceport, targetport, 4, "Illegal request");
|
||||
}
|
||||
@ -1226,5 +1287,16 @@ bx_vnet_pktmover_c::tftp_send_data(
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bx_vnet_pktmover_c::tftp_send_ack(
|
||||
Bit8u *buffer,
|
||||
unsigned sourceport, unsigned targetport,
|
||||
unsigned block_nr)
|
||||
{
|
||||
put_net2(buffer, TFTP_ACK);
|
||||
put_net2(buffer + 2, block_nr);
|
||||
host_to_guest_udpipv4_packet(sourceport, targetport, buffer, 4);
|
||||
}
|
||||
|
||||
|
||||
#endif /* if BX_NETWORKING */
|
||||
|
Loading…
Reference in New Issue
Block a user