Lines 133-151
Link Here
|
133 |
int mcast_sockfd = 0; |
133 |
int mcast_sockfd = 0; |
134 |
struct sockaddr_in sa_mcast; |
134 |
struct sockaddr_in sa_mcast; |
135 |
struct ip_mreq mreq; |
135 |
struct ip_mreq mreq; |
136 |
struct hostent *host; |
136 |
struct hostent *host; |
137 |
int master_client = 0; |
137 |
int master_client = 0; |
138 |
unsigned int file_bitmap[NB_BLOCK]; |
138 |
unsigned int file_bitmap[NB_BLOCK]; |
139 |
int prev_bitmap_hole = -1; /* the previous hole found in the bitmap */ |
139 |
int prev_bitmap_hole = -1; /* the previous hole found in the bitmap */ |
140 |
char string[MAXLEN]; |
140 |
char string[MAXLEN]; |
|
|
141 |
int rx_block_number; |
141 |
|
142 |
|
142 |
int prev_block_number = 0; /* needed to support netascii convertion */ |
143 |
int prev_block_number = 0; /* needed to support netascii convertion */ |
143 |
int temp = 0; |
144 |
int temp = 0; |
|
|
145 |
size_t ignore; |
144 |
|
146 |
|
145 |
data->file_size = 0; |
147 |
data->file_size = 0; |
146 |
tftp_cancel = 0; |
148 |
tftp_cancel = 0; |
147 |
from.sin_addr.s_addr = 0; |
149 |
from.sin_addr.s_addr = 0; |
148 |
|
150 |
|
149 |
memset(&sa_mcast, 0, sizeof(struct sockaddr_in)); |
151 |
memset(&sa_mcast, 0, sizeof(struct sockaddr_in)); |
150 |
memset(&file_bitmap, 0, sizeof(file_bitmap)); |
152 |
memset(&file_bitmap, 0, sizeof(file_bitmap)); |
151 |
|
153 |
|
Lines 300-316
Link Here
|
300 |
{ |
302 |
{ |
301 |
connect(sockfd, (struct sockaddr *)&sa, sizeof(sa)); |
303 |
connect(sockfd, (struct sockaddr *)&sa, sizeof(sa)); |
302 |
connected = 1; |
304 |
connected = 1; |
303 |
} |
305 |
} |
304 |
state = S_OACK_RECEIVED; |
306 |
state = S_OACK_RECEIVED; |
305 |
break; |
307 |
break; |
306 |
case GET_ERROR: |
308 |
case GET_ERROR: |
307 |
fprintf(stderr, "tftp: error received from server <"); |
309 |
fprintf(stderr, "tftp: error received from server <"); |
308 |
fwrite(tftphdr->th_msg, 1, data_size - 4 - 1, stderr); |
310 |
ignore = fwrite(tftphdr->th_msg, 1, data_size - 4 - 1, stderr); |
309 |
fprintf(stderr, ">\n"); |
311 |
fprintf(stderr, ">\n"); |
310 |
state = S_ABORT; |
312 |
state = S_ABORT; |
311 |
break; |
313 |
break; |
312 |
case GET_DATA: |
314 |
case GET_DATA: |
313 |
number_of_timeout = 0; |
315 |
number_of_timeout = 0; |
314 |
/* if the socket if not connected, connect it */ |
316 |
/* if the socket if not connected, connect it */ |
315 |
if (!connected) |
317 |
if (!connected) |
316 |
{ |
318 |
{ |
Lines 513-533
Link Here
|
513 |
state = S_WAIT_PACKET; |
515 |
state = S_WAIT_PACKET; |
514 |
break; |
516 |
break; |
515 |
case S_DATA_RECEIVED: |
517 |
case S_DATA_RECEIVED: |
516 |
if ((multicast && master_client) || (!multicast)) |
518 |
if ((multicast && master_client) || (!multicast)) |
517 |
timeout_state = S_SEND_ACK; |
519 |
timeout_state = S_SEND_ACK; |
518 |
else |
520 |
else |
519 |
timeout_state = S_WAIT_PACKET; |
521 |
timeout_state = S_WAIT_PACKET; |
520 |
|
522 |
|
521 |
block_number = ntohs(tftphdr->th_block); |
523 |
rx_block_number = ntohs(tftphdr->th_block); |
522 |
if (data->trace) |
524 |
if (data->trace) |
523 |
fprintf(stderr, "received DATA <block: %d, size: %d>\n", |
525 |
fprintf(stderr, "received DATA <block: %d, size: %d>\n", |
524 |
ntohs(tftphdr->th_block), data_size - 4); |
526 |
ntohs(tftphdr->th_block), data_size - 4); |
525 |
|
527 |
|
|
|
528 |
if ((uint16_t)rx_block_number == (uint16_t)(block_number+1)) |
529 |
++block_number; |
530 |
|
526 |
if (tftp_file_write(fp, tftphdr->th_data, data->data_buffer_size - 4, block_number, |
531 |
if (tftp_file_write(fp, tftphdr->th_data, data->data_buffer_size - 4, block_number, |
527 |
data_size - 4, convert, &prev_block_number, &temp) |
532 |
data_size - 4, convert, &prev_block_number, &temp) |
528 |
!= data_size - 4) |
533 |
!= data_size - 4) |
529 |
{ |
534 |
{ |
530 |
|
535 |
|
531 |
fprintf(stderr, "tftp: error writing to file %s\n", |
536 |
fprintf(stderr, "tftp: error writing to file %s\n", |
532 |
data->local_file); |
537 |
data->local_file); |
533 |
tftp_send_error(sockfd, &sa, ENOSPACE, data->data_buffer, |
538 |
tftp_send_error(sockfd, &sa, ENOSPACE, data->data_buffer, |
Lines 613-631
Link Here
|
613 |
int connected; /* 1 when sockfd is connected */ |
618 |
int connected; /* 1 when sockfd is connected */ |
614 |
struct tftphdr *tftphdr = (struct tftphdr *)data->data_buffer; |
619 |
struct tftphdr *tftphdr = (struct tftphdr *)data->data_buffer; |
615 |
FILE *fp; /* the local file pointer */ |
620 |
FILE *fp; /* the local file pointer */ |
616 |
int number_of_timeout = 0; |
621 |
int number_of_timeout = 0; |
617 |
struct stat file_stat; |
622 |
struct stat file_stat; |
618 |
int convert = 0; /* if true, do netascii convertion */ |
623 |
int convert = 0; /* if true, do netascii convertion */ |
619 |
char string[MAXLEN]; |
624 |
char string[MAXLEN]; |
620 |
|
625 |
|
|
|
626 |
int ack_block_number; |
621 |
int prev_block_number = 0; /* needed to support netascii convertion */ |
627 |
int prev_block_number = 0; /* needed to support netascii convertion */ |
622 |
int prev_file_pos = 0; |
628 |
int prev_file_pos = 0; |
623 |
int temp = 0; |
629 |
int temp = 0; |
|
|
630 |
size_t ignore; |
624 |
|
631 |
|
625 |
data->file_size = 0; |
632 |
data->file_size = 0; |
626 |
tftp_cancel = 0; |
633 |
tftp_cancel = 0; |
627 |
from.sin_addr.s_addr = 0; |
634 |
from.sin_addr.s_addr = 0; |
628 |
|
635 |
|
629 |
/* make sure the socket is not connected */ |
636 |
/* make sure the socket is not connected */ |
630 |
sa.sin_family = AF_UNSPEC; |
637 |
sa.sin_family = AF_UNSPEC; |
631 |
connect(sockfd, (struct sockaddr *)&sa, sizeof(sa)); |
638 |
connect(sockfd, (struct sockaddr *)&sa, sizeof(sa)); |
Lines 759-778
Link Here
|
759 |
case GET_ACK: |
766 |
case GET_ACK: |
760 |
number_of_timeout = 0; |
767 |
number_of_timeout = 0; |
761 |
/* if the socket if not connected, connect it */ |
768 |
/* if the socket if not connected, connect it */ |
762 |
if (!connected) |
769 |
if (!connected) |
763 |
{ |
770 |
{ |
764 |
//connect(sockfd, (struct sockaddr *)&sa, sizeof(sa)); |
771 |
//connect(sockfd, (struct sockaddr *)&sa, sizeof(sa)); |
765 |
connected = 1; |
772 |
connected = 1; |
766 |
} |
773 |
} |
767 |
block_number = ntohs(tftphdr->th_block); |
774 |
ack_block_number = ntohs(tftphdr->th_block); |
|
|
775 |
if ((uint16_t)(block_number+1) == ack_block_number) |
776 |
++block_number; |
768 |
if (data->trace) |
777 |
if (data->trace) |
769 |
fprintf(stderr, "received ACK <block: %d>\n", |
778 |
fprintf(stderr, "received ACK <block: %d>\n", |
770 |
block_number); |
779 |
ack_block_number); |
|
|
780 |
|
771 |
if ((last_block != -1) && (block_number > last_block)) |
781 |
if ((last_block != -1) && (block_number > last_block)) |
772 |
{ |
782 |
{ |
773 |
state = S_END; |
783 |
state = S_END; |
774 |
break; |
784 |
break; |
775 |
} |
785 |
} |
776 |
state = S_SEND_DATA; |
786 |
state = S_SEND_DATA; |
777 |
break; |
787 |
break; |
778 |
case GET_OACK: |
788 |
case GET_OACK: |
Lines 782-798
Link Here
|
782 |
{ |
792 |
{ |
783 |
//connect(sockfd, (struct sockaddr *)&sa, sizeof(sa)); |
793 |
//connect(sockfd, (struct sockaddr *)&sa, sizeof(sa)); |
784 |
connected = 1; |
794 |
connected = 1; |
785 |
} |
795 |
} |
786 |
state = S_OACK_RECEIVED; |
796 |
state = S_OACK_RECEIVED; |
787 |
break; |
797 |
break; |
788 |
case GET_ERROR: |
798 |
case GET_ERROR: |
789 |
fprintf(stderr, "tftp: error received from server <"); |
799 |
fprintf(stderr, "tftp: error received from server <"); |
790 |
fwrite(tftphdr->th_msg, 1, data_size - 4 - 1, stderr); |
800 |
ignore = fwrite(tftphdr->th_msg, 1, data_size - 4 - 1, stderr); |
791 |
fprintf(stderr, ">\n"); |
801 |
fprintf(stderr, ">\n"); |
792 |
state = S_ABORT; |
802 |
state = S_ABORT; |
793 |
break; |
803 |
break; |
794 |
case GET_DISCARD: |
804 |
case GET_DISCARD: |
795 |
/* consider discarded packet as timeout to make sure when don't lock up |
805 |
/* consider discarded packet as timeout to make sure when don't lock up |
796 |
if routing is broken */ |
806 |
if routing is broken */ |
797 |
number_of_timeout++; |
807 |
number_of_timeout++; |
798 |
fprintf(stderr, "tftp: packet discard <%s:%d>.\n", |
808 |
fprintf(stderr, "tftp: packet discard <%s:%d>.\n", |