summaryrefslogtreecommitdiffstats
path: root/external/meta-openembedded/meta-networking/recipes-daemons/atftp/files/atftpd-0.7_circumvent_tftp_size_restrictions.patch
blob: 280b570b2276324532510d47a63c50b3281e08ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
Fate #303031: Circumvent TFTP size restrictions in atftpd
The size of a single image file that can be transferred with TFTP is limited to
2^(2*8) *BLOCKSIZE (as per RFC 1350 there are only two bytes for the block
counter). This is problematic for one of our customers who needs to transfer
100+ MB Windows images using a TFTP client (NT bootloader) which has a
hardwared BLOCKSIZE setting of 1432).

block rollover
http://www.compuphase.com/tftp.htm

Patch originally from OpenSUSE:
https://build.opensuse.org/package/show?package=atftp&project=openSUSE%3A12.2

Upstream-Status: Pending

Index: git/tftp_def.h
===================================================================
--- git.orig/tftp_def.h	2012-11-19 16:28:50.221027144 -0800
+++ git/tftp_def.h	2012-11-20 17:40:54.391206979 -0800
@@ -32,6 +32,7 @@
 #define TIMEOUT       5         /* Client timeout */
 #define S_TIMEOUT     5         /* Server timout. */
 #define NB_OF_RETRY   5
+#define MAXBLOCKS   1000000      /* maximum number of blocks in a download */
 
 /* definition to use tftp_options structure */
 #define OPT_FILENAME  0
Index: git/tftp_file.c
===================================================================
--- git.orig/tftp_file.c	2012-11-19 16:28:50.221027144 -0800
+++ git/tftp_file.c	2012-11-19 16:28:51.201027167 -0800
@@ -622,8 +622,8 @@
      int state = S_SEND_REQ;    /* current state in the state machine */
      int timeout_state = state; /* what state should we go on when timeout */
      int result;
-     int block_number = 0;
-     int last_block = -1;
+     long block_number = 0;
+     long last_block = -1;
      int data_size;             /* size of data received */
      int sockfd = data->sockfd; /* just to simplify calls */
      struct sockaddr_storage sa; /* a copy of data.sa_peer */
@@ -637,8 +637,8 @@
      int convert = 0;           /* if true, do netascii convertion */
      char string[MAXLEN];
 
-     int prev_block_number = 0; /* needed to support netascii convertion */
-     int prev_file_pos = 0;
+     long prev_block_number = 0; /* needed to support netascii convertion */
+     long prev_file_pos = 0;
      int temp = 0;
 
      data->file_size = 0;
@@ -745,7 +745,7 @@
                               data_size, data->data_buffer);
                data->file_size += data_size;
                if (data->trace)
-                    fprintf(stderr, "sent DATA <block: %d, size: %d>\n",
+                    fprintf(stderr, "sent DATA <block: %ld, size: %d>\n",
                             block_number + 1, data_size - 4);
                state = S_WAIT_PACKET;
                break;
@@ -785,7 +785,7 @@
                     }
                     block_number = ntohs(tftphdr->th_block);
                     if (data->trace)
-                         fprintf(stderr, "received ACK <block: %d>\n",
+                         fprintf(stderr, "received ACK <block: %ld>\n",
                                  block_number);
                     if ((last_block != -1) && (block_number > last_block))
                     {
Index: git/tftp_io.c
===================================================================
--- git.orig/tftp_io.c	2012-11-19 16:28:50.221027144 -0800
+++ git/tftp_io.c	2012-11-19 16:28:51.201027167 -0800
@@ -350,8 +350,8 @@
 /*
  * Read from file and do netascii conversion if needed
  */
-int tftp_file_read(FILE *fp, char *data_buffer, int data_buffer_size, int block_number,
-                   int convert, int *prev_block_number, int *prev_file_pos, int *temp)
+int tftp_file_read(FILE *fp, char *data_buffer, int data_buffer_size, long block_number,
+                   int convert, long *prev_block_number, long *prev_file_pos, int *temp)
 {
      int i;
      int c;
Index: git/tftp_io.h
===================================================================
--- git.orig/tftp_io.h	2012-11-19 16:28:50.221027144 -0800
+++ git/tftp_io.h	2012-11-19 16:28:51.201027167 -0800
@@ -52,8 +52,8 @@
 int tftp_get_packet(int sock1, int sock2, int *sock, struct sockaddr_storage *sa,
                     struct sockaddr_storage *from, struct sockaddr_storage *to,
                     int timeout, int *size, char *data);
-int tftp_file_read(FILE *fp, char *buffer, int buffer_size, int block_number, int convert,
-                   int *prev_block_number, int *prev_file_pos, int *temp);
+int tftp_file_read(FILE *fp, char *buffer, int buffer_size, long block_number, int convert,
+                   long *prev_block_number, long *prev_file_pos, int *temp);
 int tftp_file_write(FILE *fp, char *data_buffer, int data_buffer_size, int block_number,
                     int data_size, int convert, int *prev_block_number, int *temp);
 #endif
Index: git/tftpd_file.c
===================================================================
--- git.orig/tftpd_file.c	2012-11-19 16:28:50.225027144 -0800
+++ git/tftpd_file.c	2012-11-19 16:28:51.201027167 -0800
@@ -407,8 +407,9 @@
      int state = S_BEGIN;
      int timeout_state = state;
      int result;
-     int block_number = 0;
-     int last_block = -1;
+     long block_number = 0;
+     long last_block = -1;
+     int block_loops = 0;
      int data_size;
      struct sockaddr_storage *sa = &data->client_info->client;
      struct sockaddr_storage from;
@@ -431,8 +432,8 @@
      struct client_info *client_old = NULL;
      struct tftp_opt options[OPT_NUMBER];
 
-     int prev_block_number = 0; /* needed to support netascii convertion */
-     int prev_file_pos = 0;
+     long prev_block_number = 0; /* needed to support netascii convertion */
+     long prev_file_pos = 0;
      int temp = 0;
 
      /* look for mode option */
@@ -565,11 +566,12 @@
           logger(LOG_INFO, "blksize option -> %d", result);
      }
 
-     /* Verify that the file can be sent in 2^16 block of BLKSIZE octets */
-     if ((file_stat.st_size / (data->data_buffer_size - 4)) > 65535)
+     /* Verify that the file can be sent in MAXBLOCKS blocks of BLKSIZE octets */
+     if ((file_stat.st_size / (data->data_buffer_size - 4)) > MAXBLOCKS)
      {
           tftp_send_error(sockfd, sa, EUNDEF, data->data_buffer, data->data_buffer_size);
-          logger(LOG_NOTICE, "Requested file to big, increase BLKSIZE");
+          logger(LOG_NOTICE, "Requested file too big, increase BLKSIZE");
+          logger(LOG_NOTICE, "Only %d blocks of %d bytes can be served.", MAXBLOCKS, data->data_buffer_size);
           if (data->trace)
                logger(LOG_DEBUG, "sent ERROR <code: %d, msg: %s>", EUNDEF,
                       tftp_errmsg[EUNDEF]);
@@ -880,10 +882,15 @@
                     }
                     /* The ACK is from the current client */
                     number_of_timeout = 0;
-                    block_number = ntohs(tftphdr->th_block);
+                    block_number = (block_loops * 65536) + ntohs(tftphdr->th_block);
                     if (data->trace)
-                         logger(LOG_DEBUG, "received ACK <block: %d>",
-                                block_number);
+                    {
+                         logger(LOG_DEBUG, "received ACK <block: %d>", block_number);
+                    }
+                    if (ntohs(tftphdr->th_block) == 65535)
+                    {
+                         block_loops++;
+                    };
                     if ((last_block != -1) && (block_number > last_block))
                     {
                          state = S_END;