Opened 16 years ago
Closed 16 years ago
#1959 closed defect (fixed)
Internal TFTP server is not RFC2347 compliant => Fixed in SVN
Reported by: | Martin Ducar | Owned by: | |
---|---|---|---|
Component: | network/NAT | Version: | VirtualBox 1.6.4 |
Keywords: | Cc: | ||
Guest type: | Solaris | Host type: | other |
Description
Solaris netboot is not working with NAT mode by using internal TFTP server. Using Crossbow project to add bridging support is also not solution because it is not build for every Solaris build and will be only for OpenSolaris and S11. Also for Linux it is working only because of bit of luck (or at least it looks like that). Also it is not RFC2347 compliant. Attatched is full nictracefile this is just for explanation
02:00:06.309159 IP 10.0.2.2.tftp > 10.0.2.15.2071: 244 DATA block 267 02:00:06.309352 IP 10.0.2.15.2071 > 10.0.2.2.tftp: 4 ACK block 267 02:00:06.326516 IP 10.0.2.15.2072 > 10.0.2.2.tftp: 40 RRQ "menu.lst.0100144FFFFFFE" octet tsize 0 02:00:06.326537 IP 10.0.2.2.tftp > 10.0.2.15.2072: 12 OACK tsize 198 // here it should wait for ACK of options according to specification 02:00:06.326554 IP 10.0.2.2.tftp > 10.0.2.15.2072: 202 DATA block 1 // this shouldn't be send at all 02:00:06.326816 IP 10.0.2.15.2072 > 10.0.2.2.tftp: 17 ERROR EUNDEF "TFTP Aborted" // this error is because of that 02:00:06.330472 IP 10.0.2.15.2073 > 10.0.2.2.tftp: 45 RRQ "menu.lst.0100144FFFFFFE" octet blksize 1432 02:00:06.330489 IP 10.0.2.2.tftp > 10.0.2.15.2073: 202 DATA block 1 // here is correct behavior but according to old 1350 specification. 02:00:06.330955 IP 10.0.2.15.2073 > 10.0.2.2.tftp: 4 ACK block 1 02:00:06.332510 IP 10.0.2.15.2074 > 10.0.2.2.tftp: 45 RRQ "menu.lst.0100144FFFFFFE" octet blksize 1432 // this is Solaris bug it shouldn't request data again and accept DATA block as reply from old RFC 1350 server 02:00:06.332528 IP 10.0.2.2.tftp > 10.0.2.15.2074: 202 DATA block 1 02:00:06.332934 IP 10.0.2.15.2074 > 10.0.2.2.tftp: 4 ACK block 1 02:00:06.334699 IP 10.0.2.15.2075 > 10.0.2.2.tftp: 40 RRQ "menu.lst.0100144FFFFFFE" octet tsize 0 //the same 02:00:06.334712 IP 10.0.2.2.tftp > 10.0.2.15.2075: 12 OACK tsize 198 02:00:06.334726 IP 10.0.2.2.tftp > 10.0.2.15.2075: 202 DATA block 1 02:00:06.334842 IP 10.0.2.15.2075 > 10.0.2.2.tftp: 17 ERROR EUNDEF "TFTP Aborted" 02:00:06.336512 IP 10.0.2.15.2076 > 10.0.2.2.tftp: 45 RRQ "menu.lst.0100144FFFFFFE" octet blksize 1432 02:00:06.336527 IP 10.0.2.2.tftp > 10.0.2.15.2076: 202 DATA block 1 02:00:06.336907 IP 10.0.2.15.2076 > 10.0.2.2.tftp: 4 ACK block 1 02:00:06.338250 IP 10.0.2.15.2077 > 10.0.2.2.tftp: 45 RRQ "menu.lst.0100144FFFFFFE" octet blksize 1432 02:00:06.338266 IP 10.0.2.2.tftp > 10.0.2.15.2077: 202 DATA block 1 02:00:06.338550 IP 10.0.2.15.2077 > 10.0.2.2.tftp: 4 ACK block 1 // he somehow got through this as menu.lst fits into 1 DATA block 02:00:07.165177 IP 10.0.2.15.2078 > 10.0.2.2.tftp: 64 RRQ "/I86PC.Solaris_11-33/platform/i86pc/kernel/unix" octet tsize 0 02:00:07.165260 IP 10.0.2.2.tftp > 10.0.2.15.2078: 16 OACK tsize 1169708 02:00:07.165304 IP 10.0.2.2.tftp > 10.0.2.15.2078: 516 DATA block 1 02:00:07.165510 IP 10.0.2.15.2078 > 10.0.2.2.tftp: 17 ERROR EUNDEF "TFTP Aborted" 02:00:07.167159 IP 10.0.2.15.2079 > 10.0.2.2.tftp: 69 RRQ "/I86PC.Solaris_11-33/platform/i86pc/kernel/unix" octet blksize 1432 02:00:07.167179 IP 10.0.2.2.tftp > 10.0.2.15.2079: 516 DATA block 1 02:00:07.167581 IP 10.0.2.15.2079 > 10.0.2.2.tftp: 4 ACK block 1 02:00:07.167594 IP 10.0.2.2.tftp > 10.0.2.15.2079: 516 DATA block 2 02:00:08.513572 IP 10.0.2.15.2080 > 10.0.2.2.tftp: 64 RRQ "/I86PC.Solaris_11-33/platform/i86pc/kernel/unix" octet tsize 0 02:00:44.511320 IP 10.0.2.15.2081 > 10.0.2.2.tftp: 64 RRQ "/I86PC.Solaris_11-33/platform/i86pc/kernel/unix" octet tsize 0 02:00:44.511396 IP 10.0.2.2.tftp > 10.0.2.15.2081: 16 OACK tsize 1169708 02:00:44.511428 IP 10.0.2.2.tftp > 10.0.2.15.2081: 516 DATA block 1 02:00:44.511720 IP 10.0.2.15.2081 > 10.0.2.2.tftp: 17 ERROR EUNDEF "TFTP Aborted" 02:00:44.515003 IP 10.0.2.15.2082 > 10.0.2.2.tftp: 69 RRQ "/I86PC.Solaris_11-33/platform/i86pc/kernel/unix" octet blksize 1432 02:00:44.515024 IP 10.0.2.2.tftp > 10.0.2.15.2082: 516 DATA block 1 02:00:44.515405 IP 10.0.2.15.2082 > 10.0.2.2.tftp: 4 ACK block 1 02:00:44.515418 IP 10.0.2.2.tftp > 10.0.2.15.2082: 516 DATA block 2 02:00:44.517850 IP 10.0.2.15.2083 > 10.0.2.2.tftp: 69 RRQ "/I86PC.Solaris_11-33/platform/i86pc/kernel/unix" octet blksize 1432 02:00:44.517889 IP 10.0.2.2.tftp > 10.0.2.15.2083: 516 DATA block 1 02:01:20.542699 IP 10.0.2.15.2084 > 10.0.2.2.tftp: 69 RRQ "/I86PC.Solaris_11-33/platform/i86pc/kernel/unix" octet blksize 1432 02:01:20.542780 IP 10.0.2.2.tftp > 10.0.2.15.2084: 516 DATA block 1 02:01:20.543347 IP 10.0.2.15.2084 > 10.0.2.2.tftp: 4 ACK block 1 02:01:20.543361 IP 10.0.2.2.tftp > 10.0.2.15.2084: 516 DATA block 2 //here it fails 02:01:20.546788 IP 10.0.2.15.2085 > 10.0.2.2.tftp: 50 RRQ "/I86PC.Solaris_11-33/x86.miniroot" octet tsize 0
Neither VirtualBox nor Solaris are rfc 2347 compliant. Going to log Solaris bug also. Specification handle this kind of situation and it is best to comply with it and it will solve most of the problems.
Correct me if i'm wrong but problematic code is here: http://www.virtualbox.org/browser/trunk/src/VBox/Devices/Network/slirp/tftp.c#L342
342 while (k < n) { 343 const char *key, *value; 344 345 key = (const char *)src + k; 346 k += strlen(key) + 1; 347 348 if (k >= n) { 349 tftp_send_error(pData, spt, 2, "Access violation", tp); 350 return; 351 } 352 353 value = (const char *)src + k; 354 k += strlen(value) + 1; 355 356 if (strcmp(key, "tsize") == 0) { 357 int tsize = atoi(value); 358 struct stat stat_p; 359 360 if (tsize == 0 && tftp_prefix) { 361 char buffer[1024]; 362 int len; 363 364 len = RTStrPrintf(buffer, sizeof(buffer), "%s/%s", 365 tftp_prefix, spt->filename); 366 367 if (stat(buffer, &stat_p) == 0) 368 tsize = stat_p.st_size; 369 else { 370 tftp_send_error(pData, spt, 1, "File not found", tp); 371 return; 372 } 373 } 374 375 tftp_send_oack(pData, spt, "tsize", tsize, tp); //here it sends OACK only if tsize is specified which is wrong and this code shloud be outside of while and it should contain all of the options and send one OACK with all options specified. 376 } 377 } 378 379 tftp_send_data(pData, spt, 1, tp);
On linux this will go throught as gnu grub sends rrq with more options and therefor before the while cicle ends, debians is quick enough to send ACK before server sends data after OACK. Linux trace file is in attachment also.
Attachments (2)
Change History (6)
by , 16 years ago
comment:1 by , 16 years ago
Thanks for this report. Actually we are currently doing a big overhaul of our networking subsystem. This will include a rewrite of the TFTP engine as well. The current sources are taken from the slirp project. We fixed several bugs but there are still many known problems. The new network subsystem will be available in future releases. This will take some time but we are working on it.
comment:2 by , 16 years ago
Summary: | Internal TFTP server is not RFC2347 compliant → Internal TFTP server is not RFC2347 compliant => Fixed in SVN |
---|
I think we fixed this problem properly in SVN.
comment:3 by , 16 years ago
Component: | network → network/NAT |
---|
comment:4 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Solaris guest netboot