|
@@ -59,10 +59,11 @@ static int tftp_process_blksize ( struct tftp_session *tftp,
|
59
|
59
|
|
60
|
60
|
tftp->blksize = strtoul ( value, &end, 10 );
|
61
|
61
|
if ( *end ) {
|
62
|
|
- DBG ( "TFTP %p got invalid blksize \"%s\"\n", tftp, value );
|
|
62
|
+ DBGC ( tftp, "TFTP %p got invalid blksize \"%s\"\n",
|
|
63
|
+ tftp, value );
|
63
|
64
|
return -EINVAL;
|
64
|
65
|
}
|
65
|
|
- DBG ( "TFTP %p blksize=%d\n", tftp, tftp->blksize );
|
|
66
|
+ DBGC ( tftp, "TFTP %p blksize=%d\n", tftp, tftp->blksize );
|
66
|
67
|
|
67
|
68
|
return 0;
|
68
|
69
|
}
|
|
@@ -80,10 +81,11 @@ static int tftp_process_tsize ( struct tftp_session *tftp,
|
80
|
81
|
|
81
|
82
|
tftp->tsize = strtoul ( value, &end, 10 );
|
82
|
83
|
if ( *end ) {
|
83
|
|
- DBG ( "TFTP %p got invalid tsize \"%s\"\n", tftp, value );
|
|
84
|
+ DBGC ( tftp, "TFTP %p got invalid tsize \"%s\"\n",
|
|
85
|
+ tftp, value );
|
84
|
86
|
return -EINVAL;
|
85
|
87
|
}
|
86
|
|
- DBG ( "TFTP %p tsize=%ld\n", tftp, tftp->tsize );
|
|
88
|
+ DBGC ( tftp, "TFTP %p tsize=%ld\n", tftp, tftp->tsize );
|
87
|
89
|
|
88
|
90
|
return 0;
|
89
|
91
|
}
|
|
@@ -112,8 +114,8 @@ static int tftp_process_option ( struct tftp_session *tftp,
|
112
|
114
|
return option->process ( tftp, value );
|
113
|
115
|
}
|
114
|
116
|
|
115
|
|
- DBG ( "TFTP %p received unknown option \"%s\" = \"%s\"\n",
|
116
|
|
- tftp, name, value );
|
|
117
|
+ DBGC ( tftp, "TFTP %p received unknown option \"%s\" = \"%s\"\n",
|
|
118
|
+ tftp, name, value );
|
117
|
119
|
|
118
|
120
|
return -EINVAL;
|
119
|
121
|
}
|
|
@@ -201,7 +203,7 @@ static int tftp_send_rrq ( struct tftp_session *tftp, void *buf, size_t len ) {
|
201
|
203
|
void *data;
|
202
|
204
|
void *end;
|
203
|
205
|
|
204
|
|
- DBG ( "TFTP %p requesting \"%s\"\n", tftp, tftp->filename );
|
|
206
|
+ DBGC ( tftp, "TFTP %p requesting \"%s\"\n", tftp, tftp->filename );
|
205
|
207
|
|
206
|
208
|
data = rrq->data;
|
207
|
209
|
end = ( buf + len );
|
|
@@ -218,7 +220,7 @@ static int tftp_send_rrq ( struct tftp_session *tftp, void *buf, size_t len ) {
|
218
|
220
|
return udp_send ( &tftp->udp, buf, ( data - buf ) );
|
219
|
221
|
|
220
|
222
|
overflow:
|
221
|
|
- DBG ( "TFTP %p RRQ out of space\n", tftp );
|
|
223
|
+ DBGC ( tftp, "TFTP %p RRQ out of space\n", tftp );
|
222
|
224
|
return -ENOBUFS;
|
223
|
225
|
}
|
224
|
226
|
|
|
@@ -239,12 +241,13 @@ static int tftp_rx_oack ( struct tftp_session *tftp, void *buf, size_t len ) {
|
239
|
241
|
|
240
|
242
|
/* Sanity check */
|
241
|
243
|
if ( len < sizeof ( *oack ) ) {
|
242
|
|
- DBG ( "TFTP %p received underlength OACK packet length %d\n",
|
243
|
|
- tftp, len );
|
|
244
|
+ DBGC ( tftp, "TFTP %p received underlength OACK packet "
|
|
245
|
+ "length %d\n", tftp, len );
|
244
|
246
|
return -EINVAL;
|
245
|
247
|
}
|
246
|
248
|
if ( end[-1] != '\0' ) {
|
247
|
|
- DBG ( "TFTP %p received OACK missing final NUL\n", tftp );
|
|
249
|
+ DBGC ( tftp, "TFTP %p received OACK missing final NUL\n",
|
|
250
|
+ tftp );
|
248
|
251
|
return -EINVAL;
|
249
|
252
|
}
|
250
|
253
|
|
|
@@ -253,8 +256,8 @@ static int tftp_rx_oack ( struct tftp_session *tftp, void *buf, size_t len ) {
|
253
|
256
|
while ( name < end ) {
|
254
|
257
|
value = ( name + strlen ( name ) + 1 );
|
255
|
258
|
if ( value == end ) {
|
256
|
|
- DBG ( "TFTP %p received OACK missing value for option "
|
257
|
|
- "\"%s\"\n", tftp, name );
|
|
259
|
+ DBGC ( tftp, "TFTP %p received OACK missing value "
|
|
260
|
+ "for option \"%s\"\n", tftp, name );
|
258
|
261
|
return -EINVAL;
|
259
|
262
|
}
|
260
|
263
|
if ( ( rc = tftp_process_option ( tftp, name, value ) ) != 0 )
|
|
@@ -279,19 +282,28 @@ static int tftp_rx_oack ( struct tftp_session *tftp, void *buf, size_t len ) {
|
279
|
282
|
static int tftp_rx_data ( struct tftp_session *tftp, void *buf, size_t len ) {
|
280
|
283
|
struct tftp_data *data = buf;
|
281
|
284
|
unsigned int block;
|
|
285
|
+ size_t data_offset;
|
282
|
286
|
size_t data_len;
|
|
287
|
+ int rc;
|
283
|
288
|
|
284
|
289
|
/* Sanity check */
|
285
|
290
|
if ( len < sizeof ( *data ) ) {
|
286
|
|
- DBG ( "TFTP %p received underlength DATA packet length %d\n",
|
287
|
|
- tftp, len );
|
|
291
|
+ DBGC ( tftp, "TFTP %p received underlength DATA packet "
|
|
292
|
+ "length %d\n", tftp, len );
|
288
|
293
|
return -EINVAL;
|
289
|
294
|
}
|
290
|
295
|
|
291
|
|
- /* Pass to callback */
|
|
296
|
+ /* Fill data buffer */
|
292
|
297
|
block = ntohs ( data->block );
|
|
298
|
+ data_offset = ( ( block - 1 ) * tftp->blksize );
|
293
|
299
|
data_len = ( len - offsetof ( typeof ( *data ), data ) );
|
294
|
|
- tftp->callback ( tftp, block, data->data, data_len );
|
|
300
|
+ if ( ( rc = fill_buffer ( tftp->buffer, data->data, data_offset,
|
|
301
|
+ data_len ) ) != 0 ) {
|
|
302
|
+ DBGC ( tftp, "TFTP %p could not fill data buffer: %s\n",
|
|
303
|
+ tftp, strerror ( rc ) );
|
|
304
|
+ tftp_done ( tftp, rc );
|
|
305
|
+ return rc;
|
|
306
|
+ }
|
295
|
307
|
|
296
|
308
|
/* Mark block as received */
|
297
|
309
|
tftp_received ( tftp, block );
|
|
@@ -334,13 +346,13 @@ static int tftp_rx_error ( struct tftp_session *tftp, void *buf, size_t len ) {
|
334
|
346
|
|
335
|
347
|
/* Sanity check */
|
336
|
348
|
if ( len < sizeof ( *error ) ) {
|
337
|
|
- DBG ( "TFTP %p received underlength ERROR packet length %d\n",
|
338
|
|
- tftp, len );
|
|
349
|
+ DBGC ( tftp, "TFTP %p received underlength ERROR packet "
|
|
350
|
+ "length %d\n", tftp, len );
|
339
|
351
|
return -EINVAL;
|
340
|
352
|
}
|
341
|
353
|
|
342
|
|
- DBG ( "TFTP %p received ERROR packet with code %d, message \"%s\"\n",
|
343
|
|
- tftp, ntohs ( error->errcode ), error->errmsg );
|
|
354
|
+ DBGC ( tftp, "TFTP %p received ERROR packet with code %d, message "
|
|
355
|
+ "\"%s\"\n", tftp, ntohs ( error->errcode ), error->errmsg );
|
344
|
356
|
|
345
|
357
|
/* Determine final operation result */
|
346
|
358
|
err = ntohs ( error->errcode );
|
|
@@ -392,30 +404,31 @@ static int tftp_newdata ( struct udp_connection *conn, void *data, size_t len,
|
392
|
404
|
struct tftp_common *common = data;
|
393
|
405
|
|
394
|
406
|
if ( len < sizeof ( *common ) ) {
|
395
|
|
- DBG ( "TFTP %p received underlength packet length %d\n",
|
396
|
|
- tftp, len );
|
|
407
|
+ DBGC ( tftp, "TFTP %p received underlength packet length %d\n",
|
|
408
|
+ tftp, len );
|
397
|
409
|
return -EINVAL;
|
398
|
410
|
}
|
399
|
411
|
|
400
|
412
|
/* Filter by TID. Set TID on first response received */
|
401
|
413
|
if ( tftp->tid ) {
|
402
|
414
|
if ( tftp->tid != st_src->st_port ) {
|
403
|
|
- DBG ( "TFTP %p received packet from wrong port "
|
404
|
|
- "(got %d, wanted %d)\n", tftp,
|
405
|
|
- ntohs ( st_src->st_port ), ntohs ( tftp->tid ) );
|
|
415
|
+ DBGC ( tftp, "TFTP %p received packet from wrong port "
|
|
416
|
+ "(got %d, wanted %d)\n", tftp,
|
|
417
|
+ ntohs ( st_src->st_port ), ntohs ( tftp->tid ));
|
406
|
418
|
return -EINVAL;
|
407
|
419
|
}
|
408
|
420
|
} else {
|
409
|
421
|
tftp->tid = st_src->st_port;
|
410
|
|
- DBG ( "TFTP %p using remote port %d\n", tftp,
|
411
|
|
- ntohs ( tftp->tid ) );
|
|
422
|
+ DBGC ( tftp, "TFTP %p using remote port %d\n", tftp,
|
|
423
|
+ ntohs ( tftp->tid ) );
|
412
|
424
|
udp_connect_port ( &tftp->udp, tftp->tid );
|
413
|
425
|
}
|
414
|
426
|
|
415
|
427
|
/* Filter by source address */
|
416
|
428
|
if ( memcmp ( st_src, udp_peer ( &tftp->udp ),
|
417
|
429
|
sizeof ( *st_src ) ) != 0 ) {
|
418
|
|
- DBG ( "TFTP %p received packet from foreign source\n", tftp );
|
|
430
|
+ DBGC ( tftp, "TFTP %p received packet from foreign source\n",
|
|
431
|
+ tftp );
|
419
|
432
|
return -EINVAL;
|
420
|
433
|
}
|
421
|
434
|
|
|
@@ -427,8 +440,8 @@ static int tftp_newdata ( struct udp_connection *conn, void *data, size_t len,
|
427
|
440
|
case htons ( TFTP_ERROR ):
|
428
|
441
|
return tftp_rx_error ( tftp, data, len );
|
429
|
442
|
default:
|
430
|
|
- DBG ( "TFTP %p received strange packet type %d\n", tftp,
|
431
|
|
- ntohs ( common->opcode ) );
|
|
443
|
+ DBGC ( tftp, "TFTP %p received strange packet type %d\n", tftp,
|
|
444
|
+ ntohs ( common->opcode ) );
|
432
|
445
|
return -EINVAL;
|
433
|
446
|
};
|
434
|
447
|
}
|
|
@@ -449,16 +462,18 @@ struct async_operation * tftp_get ( struct tftp_session *tftp ) {
|
449
|
462
|
int rc;
|
450
|
463
|
|
451
|
464
|
assert ( tftp->filename != NULL );
|
452
|
|
- assert ( tftp->callback != NULL );
|
|
465
|
+ assert ( tftp->buffer != NULL );
|
453
|
466
|
assert ( tftp->udp.peer.st_family != 0 );
|
454
|
467
|
|
455
|
468
|
/* Initialise TFTP session */
|
456
|
|
- tftp->udp.udp_op = &tftp_udp_operations;
|
457
|
|
- tftp->timer.expired = tftp_timer_expired;
|
458
|
|
- tftp->state = -1;
|
459
|
|
- tftp->blksize = TFTP_DEFAULT_BLKSIZE;
|
460
|
469
|
if ( ! tftp->request_blksize )
|
461
|
470
|
tftp->request_blksize = TFTP_MAX_BLKSIZE;
|
|
471
|
+ tftp->blksize = TFTP_DEFAULT_BLKSIZE;
|
|
472
|
+ tftp->tsize = 0;
|
|
473
|
+ tftp->tid = 0;
|
|
474
|
+ tftp->state = -1;
|
|
475
|
+ tftp->udp.udp_op = &tftp_udp_operations;
|
|
476
|
+ tftp->timer.expired = tftp_timer_expired;
|
462
|
477
|
|
463
|
478
|
/* Open UDP connection */
|
464
|
479
|
if ( ( rc = udp_open ( &tftp->udp, 0 ) ) != 0 ) {
|