Statistics
| Branch: | Tag: | Revision:

root / fon-flash / fon-flash.cpp @ master

History | View | Annotate | Download (32.8 KB)

1
/*
2
 * Copyright (c) 2009, Eric Bishop
3
 * Copyright (c) 2007, Sven-Ola
4
 * All rights reserved.
5
 *
6
 *  This file is free software: you may copy, redistribute and/or modify it
7
 *  under the terms of the GNU General Public License as published by the
8
 *  Free Software Foundation, either version 2 of the License, or (at your
9
 *  option) any later version.
10
 *
11
 *  This file is distributed in the hope that it will be useful, but
12
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 *  General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
21
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <fcntl.h>
25
#include <string.h>
26
#include <pcap.h>
27
#include <stdarg.h>
28
#include <ctype.h>
29
#include "fon-flash.h"
30
31
32
#ifdef INCLUDE_BINARIES
33
#include "install_binaries.h"
34
#endif
35
36
37
38
void make_configuration_absolute(flash_configuration* config, unsigned long flash_start_address, unsigned long flash_size, unsigned long flash_page_size, const char** file_ids, unsigned long* file_sizes)
39
{
40
        partition* parts[3] = { config->part1, config->part2, config->part3 };
41
        int part_index = 0;
42
        unsigned long non_max_length_sum = 0;
43
        unsigned long next_part_start;
44
        
45
        //first, make lengths of all FILE_TYPE parts absolute and compute sum of all non-MAX type part lengths
46
        for(part_index = 0; part_index < 3; part_index++)
47
        {
48
                partition* part = parts[part_index];
49
                if(part != NULL)
50
                {
51
                        if(part->length_type == FILE_TYPE)
52
                        {
53
                                int file_id_index;
54
                                for(file_id_index=0; file_ids[file_id_index] != NULL && part->file_id != NULL && file_id_index < 3; file_id_index++)
55
                                {
56
                                        if(strcmp(part->file_id, file_ids[file_id_index]) == 0)
57
                                        {
58
                                                unsigned long raw_size = file_sizes[file_id_index];
59
                                                part->length = (((raw_size-1) / flash_page_size)+1)*flash_page_size; //round up to nearest flash_page_size
60
                                                part->length_type = SIZE_TYPE;
61
                                                
62
                                        }
63
                                }
64
                                non_max_length_sum = non_max_length_sum + part->length;
65
                        }
66
                        else if(part->length_type == SIZE_TYPE)
67
                        {
68
                                unsigned long orig_size = part->length;
69
                                part->length = (((orig_size-1) / flash_page_size)+1)*flash_page_size; //round up to nearest flash_page_size
70
                                non_max_length_sum = non_max_length_sum + part->length;
71
                        }
72
                        //ignore length of MAX_TYPE for now
73
                }
74
        }
75
76
        //iterate through again, making flash addresses absolute and making length of the MAX_TYPE part (there can be at most one) absolute
77
        //if you define more than one MAX_TYPE part, your configuration will DIE HORRIBLY, so DON'T DO IT!
78
               next_part_start = flash_start_address;
79
        for(part_index = 0; part_index < 3; part_index++)
80
        {
81
                partition* part = parts[part_index];
82
                if(part != NULL)
83
                {
84
                        
85
                        if(part->flash_address == 0)
86
                        {
87
                                part->flash_address = next_part_start;
88
                        }
89
                        
90
                        if(part->length_type == MAX_TYPE)
91
                        {
92
                                //two possible constraints: total flash size and start address of next partition
93
                                //take minimum of space bounded by these constraints
94
                                unsigned long space_max = ((flash_size - non_max_length_sum)/flash_page_size)*flash_page_size; //round DOWN to nearest page boundary
95
                                unsigned long flash_boundary_max = space_max;
96
                                if(part_index < 2)
97
                                {
98
                                        if(parts[part_index+1] != NULL)
99
                                        {
100
                                                partition* next_part = parts[part_index+1];
101
                                                if(next_part->flash_address > 0)
102
                                                {
103
                                                        flash_boundary_max = next_part->flash_address - part->flash_address;
104
                                                }
105
                                        }
106
                                }
107
                                part->length = space_max < flash_boundary_max ? space_max : flash_boundary_max;
108
                                part->length_type = SIZE_TYPE;
109
                        }
110
                        next_part_start = part->flash_address + part->length;
111
                }
112
        }
113
114
}
115
116
//returns commands for loading / creating partitions only, doesn't include setting ip_address, fis init or setting bootloader
117
char** get_partition_command_list(flash_configuration* config, unsigned long freememlow) 
118
{
119
        char** commands = (char**)malloc(sizeof(char*)*20); //way more space than we'll need, max is actually 7, since we have max of 2 lines for each part * 3 parts = 6 + 1 for null terminator
120
        int command_index = 0;
121
        int part_index = 0;
122
        
123
        partition* parts[3] = { config->part1, config->part2, config->part3 };
124
        for(part_index = 0; part_index < 3; part_index++)
125
        {
126
                partition* part = parts[part_index];
127
                if(part != NULL)
128
                {
129
                        char buf[4086];
130
                        char entry_part[100] = "";
131
                        char memory_part[100] = "";
132
                        char empty_flag[100] = " -n ";
133
                        if(part->file_id != NULL)
134
                        {
135
                                sprintf(buf, "load -r -b 0x%08lx -m tftp %s\n", freememlow, part->file_id);
136
                                empty_flag[0] = '\0';
137
                                commands[command_index] = strdup(buf);
138
                                command_index++;
139
140
                        }
141
142
                        if(part->set_entry)
143
                        {
144
                                sprintf(entry_part, " -e 0x%08lx ", part->entry_address);
145
                        }
146
                        if(part->set_memory)
147
                        {
148
                                sprintf(memory_part, " -r 0x%08lx ", part->memory_address);
149
                        }
150
                        sprintf(buf, "fis create -f 0x%08lx -l 0x%08lx %s %s %s %s\n", part->flash_address, part->length, entry_part, memory_part, empty_flag, part->name);
151
                        commands[command_index] = strdup(buf);
152
                        command_index++;
153
                }
154
        }
155
156
        commands[command_index] = NULL;
157
        return commands;
158
}
159
160
161
162
flash_configuration* get_gargoyle_configuration()
163
{
164
        flash_configuration* gargoyle_conf;
165
        partition* rootfs;
166
        partition* kernel;
167
        char** boot;
168
169
        gargoyle_conf = create_generic_config();        
170
        
171
        rootfs = create_generic_partition();
172
        rootfs->name = "rootfs";
173
        rootfs->file_id = "file_1";
174
        rootfs->flash_address = 0;         //indicates starting at first available address
175
        rootfs->length_type = MAX_TYPE; //maximum allocation size, at most there can be one MAX_TYPE in configuration
176
        rootfs->set_entry = 1;                //set entry to 0x00000000
177
        rootfs->set_memory = 0;
178
        rootfs->entry_address = 0x00000000;
179
180
        kernel = create_generic_partition();
181
        kernel->name = "vmlinux.bin.l7";
182
        kernel->file_id = "file_2";
183
        kernel->flash_address = 0;                //indicates starting at first available address
184
        kernel->length_type = FILE_TYPE;        //size determined by size of file
185
        kernel->set_entry = 1;                        //set entry & memory addresses to 0x80041000
186
        kernel->set_memory = 1;        
187
        kernel->entry_address   = 0x80041000;
188
        kernel->memory_address = 0x80041000;
189
        
190
191
        boot = (char**)malloc(3*sizeof(char*));
192
        boot[0] = strdup("fis load -l vmlinux.bin.l7\n");
193
        boot[1] = strdup("exec\n");
194
        boot[2] = NULL ;
195
        
196
        
197
        
198
        gargoyle_conf->part1 = rootfs;        
199
        gargoyle_conf->part2 = kernel;
200
        gargoyle_conf->part3 = NULL;
201
        gargoyle_conf->bootloader_lines = boot;
202
        
203
        return gargoyle_conf;
204
}
205
flash_configuration* get_fonera_configuration()
206
{
207
        flash_configuration* fon_conf;
208
        partition* loader;
209
        partition* image;
210
        partition* image2;
211
        char** boot;
212
        
213
        fon_conf = create_generic_config();
214
215
        loader = create_generic_partition();
216
        loader->name = "loader";
217
        loader->file_id = "file_1";
218
        loader->flash_address = 0; 
219
        loader->length_type = FILE_TYPE; 
220
        loader->set_entry = 1;                
221
        loader->set_memory = 1;
222
        loader->entry_address  = 0x80100000;
223
        loader->memory_address = 0x80100000;
224
225
226
227
        image = create_generic_partition();
228
        image->name = "image";
229
        image->file_id = "file_2";
230
        image->flash_address = 0; 
231
        image->length_type = MAX_TYPE; 
232
        image->set_entry = 1;                
233
        image->set_memory = 1;
234
        image->entry_address  = 0x80040400;
235
        image->memory_address = 0x80040400;
236
237
238
        image2 = create_generic_partition();
239
        image2->name = "image2";
240
        image2->file_id = "file_3";
241
        image2->flash_address = 0xA8660000;        
242
        image2->length_type = FILE_TYPE;
243
        image2->set_entry = 1;                        
244
        image2->set_memory = 0;        
245
        image2->entry_address   = 0x80040400;
246
        
247
248
        boot = (char**)malloc(3*sizeof(char*));
249
        boot[0] = strdup("fis load loader\n");
250
        boot[1] = strdup("go\n");
251
        boot[2] = NULL ;
252
        
253
        fon_conf->part1 = loader;        
254
        fon_conf->part2 = image;
255
        fon_conf->part3 = image2;
256
        fon_conf->bootloader_lines = boot;
257
258
259
260
        return fon_conf;        
261
}
262
263
flash_configuration* get_ddwrt_configuration()
264
{
265
        flash_configuration* ddwrt_conf;
266
        partition* linux_part;
267
        char** boot;
268
269
        ddwrt_conf = create_generic_config();        
270
        
271
        linux_part = create_generic_partition();
272
        linux_part->name = "linux";
273
        linux_part->file_id = "file_1";
274
        linux_part->flash_address = 0;         //indicates starting at first available address
275
        linux_part->length_type = FILE_TYPE;        
276
        linux_part->set_entry = 1;                //set entry to 0x00000000
277
        linux_part->set_memory = 1;
278
        linux_part->entry_address  = 0x80041000;
279
        linux_part->memory_address = 0x80041000;
280
281
        
282
283
        boot = (char**)malloc(3*sizeof(char*));
284
        boot[0] = strdup("fis load -l linux\n");
285
        boot[1] = strdup("exec\n");
286
        boot[2] = NULL ;
287
        
288
        
289
        
290
        ddwrt_conf->part1 = linux_part;        
291
        ddwrt_conf->part2 = NULL;
292
        ddwrt_conf->part3 = NULL;
293
        ddwrt_conf->bootloader_lines = boot;
294
        
295
        return ddwrt_conf;
296
}
297
298
299
300
301
flash_configuration* create_generic_config(void)
302
{
303
        flash_configuration* generic_conf = (flash_configuration*)malloc(sizeof(flash_configuration));
304
        generic_conf->part1 = NULL;
305
        generic_conf->part2 = NULL;
306
        generic_conf->part3 = NULL;
307
        generic_conf->bootloader_lines = NULL;
308
        return generic_conf;
309
}
310
311
partition* create_generic_partition(void)
312
{
313
        partition* generic_part = (partition*)malloc(sizeof(partition));
314
        generic_part->file_id = NULL;
315
        generic_part->name = NULL;
316
        generic_part->length_type = FILE_TYPE;
317
        generic_part->length = 0;
318
        generic_part->flash_address = 0;
319
        generic_part->entry_address = 0;
320
        generic_part->memory_address = 0;
321
        generic_part->set_entry = 0;
322
        generic_part->set_memory = 0;
323
        return generic_part;
324
}
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
#ifdef WIN32
364
365
#define ETH_ALEN 6
366
#define ETH_HLEN 14
367
#define        ETHERTYPE_ARP 0x0806
368
#define        ARPOP_REQUEST 1
369
struct ether_header
370
{
371
  u_int8_t  ether_dhost[ETH_ALEN];        /* destination eth addr        */
372
  u_int8_t  ether_shost[ETH_ALEN];        /* source ether addr        */
373
  u_int16_t ether_type;                        /* packet type ID field        */
374
};
375
struct arphdr
376
{
377
        unsigned short        ar_hrd;                /* format of hardware address        */
378
        unsigned short        ar_pro;                /* format of protocol address        */
379
        unsigned char        ar_hln;                /* length of hardware address        */
380
        unsigned char        ar_pln;                /* length of protocol address        */
381
        unsigned short        ar_op;                /* ARP opcode (command)                */
382
383
};
384
385
#else /* WIN32 */
386
387
#define O_BINARY 0
388
#include <unistd.h>
389
#include <netinet/if_ether.h>
390
391
#endif /* WIN32 */
392
393
#ifndef ETH_ALEN
394
#define ETH_ALEN 6
395
#endif
396
397
#ifndef ETH_HLEN
398
#define ETH_HLEN 14
399
#endif
400
401
402
#include "uip.h"
403
#include "uip_arp.h"
404
#include "timer.h"
405
406
407
408
409
410
411
412
413
414
415
#define FLASH_PAGE_SIZE 0x10000
416
417
static unsigned char* tftp_buf = 0;
418
static unsigned long tftp_send = 0;
419
static unsigned long tftp_size = 0;
420
421
422
static unsigned char* file_1_buf = 0;
423
static unsigned char* file_2_buf = 0;
424
static unsigned char* file_3_buf = 0;
425
static unsigned long file_1_size=0;
426
static unsigned long file_2_size=0;
427
static unsigned long file_3_size=0;
428
429
430
static unsigned long flash_start_address = 0xa8030000;
431
static unsigned long flash_size = 0x007A0000;
432
static unsigned long freememlow = 0x80100000;
433
434
435
436
437
438
439
440
441
442
443
static uip_ipaddr_t srcipaddr;
444
static uip_ipaddr_t dstipaddr;
445
446
#define P(var) ((unsigned char*)var)
447
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
448
449
void uip_log(const char *m)
450
{
451
#if defined(_DEBUG) || defined(DEBUG_ALL)
452
        fprintf(stderr, "uIP log message: %s\n", m);
453
#endif
454
}
455
456
static pcap_t *pcap_fp = NULL;
457
458
#ifdef WIN32
459
#define PCAP_TIMEOUT_MS 1000
460
#else
461
#define PCAP_TIMEOUT_MS 200
462
#endif
463
464
int pcap_init(char *dev, uip_ipaddr_t* sip, uip_ipaddr_t* dip, struct uip_eth_addr* smac, struct uip_eth_addr* dmac, int special)
465
{
466
        int i;
467
        int gotarp = 0;
468
        char error[PCAP_ERRBUF_SIZE];
469
        const unsigned char* packet;
470
        struct pcap_pkthdr hdr;
471
472
        /* Open the output adapter */
473
        if (NULL == (pcap_fp = pcap_open_live(dev, 1500, 1, PCAP_TIMEOUT_MS, error)))
474
        {
475
                fprintf(stderr,"Error opening adapter: %s\n", error);
476
                return -1;
477
        }
478
479
        while(!gotarp)
480
        {
481
                while (NULL == (packet = pcap_next(pcap_fp, &hdr)))
482
                {
483
                        printf("No packet.\n");
484
                }
485
                if (ETHERTYPE_ARP == myntohs(((struct ether_header *)packet)->ether_type))
486
                {
487
                        if (60 != hdr.len)
488
                        {
489
                                fprintf(stderr, "Expect arp with length 60, received %d\n", hdr.len);
490
                        }
491
                        else if (ARPOP_REQUEST != myntohs(((struct arphdr*)(packet + ETH_HLEN))->ar_op))
492
                        {
493
                                fprintf(stderr, "Unexpected arp packet, opcode=%d\n",
494
                                        myntohs(((struct arphdr*)(packet + ETH_HLEN))->ar_op));
495
                        }
496
                        else
497
                        {
498
                                gotarp = 1;
499
                        }
500
                }
501
                else
502
                {
503
                        fprintf(stderr, "Non arp received. Make sure, the device is connected directly!\n");
504
                }
505
        }
506
        
507
        /* Grab MAC adress of router */
508
        memmove(dmac, ((struct ether_header *)packet)->ether_shost, sizeof(*dmac));
509
        /* Grab IP adress of router */
510
        memmove(dip, packet + ETH_HLEN + sizeof(struct arphdr) + ETH_ALEN, 4);
511
        memmove(sip, packet + ETH_HLEN + sizeof(struct arphdr) + ETH_ALEN, 4);
512
        
513
        printf("Peer MAC: ");
514
        for (i = 0; i < (int)sizeof(*dmac); i++)
515
        {
516
                printf("%s%02x", 0 == i ? "" : ":", dmac->addr[i]);
517
        }
518
        printf("\n");
519
        printf("Peer IP : %d.%d.%d.%d\n", P(*dip)[0], P(*dip)[1], P(*dip)[2], P(*dip)[3]);
520
521
        if (!special && 0 == P(*dip)[0] && 0 == P(*dip)[1] && 0 == P(*dip)[2] && 0 == P(*dip)[3])
522
        {
523
                fprintf(stderr, "Telnet for RedBoot not enabled.\n");
524
                return -1;
525
        }
526
527
        printf("Your MAC: ");
528
        for (i = 0; i < (int)sizeof(*smac); i++)
529
        {
530
                printf("%s%02x", 0 == i ? "" : ":", smac->addr[i]);
531
        }
532
        printf("\n");
533
534
        P(*sip)[3] = 0 == P(*sip)[3] ? 1 : 0;
535
        printf("Your IP : %d.%d.%d.%d\n", P(*sip)[0], P(*sip)[1], P(*sip)[2], P(*sip)[3]);
536
        if (0 > pcap_setnonblock(pcap_fp, 1, error))
537
        {
538
                fprintf(stderr,"Error setting non-blocking mode: %s\n", error);
539
                return -1;
540
        }
541
        return 0;
542
}
543
544
void handler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
545
{
546
#ifdef DEBUG_ALL
547
        {
548
                int i;
549
                fprintf(stderr, "handler(%p, %d, bytes=%p)\n", user, h->len, bytes);
550
                for(i = 0; i < 32 && h->len; i++)
551
                {
552
                        fprintf(stderr, "%02x%s", bytes[i], 15 == i % 16 ? "\n" : " ");
553
                }
554
                if (0 != i % 16) fprintf(stderr, "\n");
555
        }
556
#endif
557
        *((int *)user) = h->len;
558
        if (UIP_BUFSIZE < h->len)
559
        {
560
                fprintf(stderr, "Buffer(%d) too small for %d bytes\n", UIP_BUFSIZE, h->len);
561
                *((int *)user) = UIP_BUFSIZE;
562
        }
563
        memmove(uip_buf, bytes, *((int *)user));
564
}
565
566
unsigned int pcap_read(void)
567
{
568
        int ret = 0; 
569
        if (0 == pcap_dispatch(pcap_fp, 1, handler, (u_char *)&ret))
570
        {
571
                return 0;
572
        }
573
        return ret;
574
}
575
576
void pcap_send(void)
577
{
578
#ifdef DEBUG_ALL
579
        {
580
                int i;
581
                fprintf(stderr, "send(%p, %d)\n", uip_buf, uip_len);
582
                for(i = 0; i < 32 && i < uip_len; i++)
583
                {
584
                        fprintf(stderr, "%02x%s", uip_buf[i], 15 == i % 16 ? "\n" : " ");
585
                }
586
                if (0 != i % 16) fprintf(stderr, "\n");
587
        }
588
#endif
589
        if (0 > pcap_sendpacket(pcap_fp, uip_buf, uip_len))
590
        {
591
                perror("pcap_sendpacket");
592
                exit(1);
593
        }
594
}
595
596
597
flash_configuration* final_flash_configuration;
598
char** create_partition_commands = { NULL };
599
char** bootloader_lines = { NULL };
600
static int configuration_initialization_complete = 0;
601
static int initialization_complete = 0;
602
static int command_line_index = 0;
603
static int load_found = 0;
604
static int bootloader_line_index = 0;        
605
606
607
static int handle_connection(struct fon_flash_state *s)
608
{
609
        char str[4096];
610
        char* next_command = NULL;
611
        char* read_test;
612
        
613
        char* file_ids[3] = { (char*)"file_1", (char*)"file_2", (char*)"file_3"};
614
        unsigned long file_sizes[3] = { file_1_size, file_2_size, file_3_size };
615
616
617
618
        PSOCK_BEGIN(&s->p);
619
620
621
        //initialize
622
        if(!initialization_complete)
623
        {
624
                load_found = 0;
625
                s->inputbuffer[0] = 0;
626
                PSOCK_READTO(342, &s->p, '\n');
627
                PSOCK_SEND_STR(343, &s->p, "\x03");
628
                s->inputbuffer[0] = 0;
629
                PSOCK_READTO(345, &s->p, '>');
630
                if (NULL == strstr(s->inputbuffer, ">")) {
631
                        fprintf(stderr, "No RedBoot prompt. Exit in line %d\n", __LINE__);
632
                        PSOCK_CLOSE(&s->p);
633
                        PSOCK_EXIT(&s->p);
634
                }
635
                printf("\nSetting IP address...\n");
636
                sprintf(str, "ip_addr -l %d.%d.%d.%d/8 -h %d.%d.%d.%d\n", 
637
                        P(&dstipaddr)[0], P(&dstipaddr)[1], P(&dstipaddr)[2], P(&dstipaddr)[3],
638
                        P(&srcipaddr)[0], P(&srcipaddr)[1], P(&srcipaddr)[2], P(&srcipaddr)[3]);
639
                printf("%s\n", str);
640
                PSOCK_SEND_STR(356, &s->p, str);
641
                s->inputbuffer[0] = 0;
642
                PSOCK_READTO(358, &s->p, '>');
643
                if (NULL == strstr(s->inputbuffer, ">")) 
644
                {
645
                        fprintf(stderr, "No RedBoot prompt. Exit in line %d\n", __LINE__);
646
                        PSOCK_CLOSE(&s->p);
647
                        PSOCK_EXIT(&s->p);
648
                }
649
                
650
                //load device address configuration
651
                if(!configuration_initialization_complete)
652
                {
653
654
                        //determine flash start & and flash length
655
                        PSOCK_SEND_STR(360, &s->p, "fis list\n");
656
                        s->inputbuffer[0] = 0;
657
                        PSOCK_READTO(361, &s->p, '>');
658
                        if (NULL == strstr(s->inputbuffer, ">")) 
659
                        {
660
                                fprintf(stderr, "No RedBoot prompt. Exit in line %d\n", __LINE__);
661
                                PSOCK_CLOSE(&s->p);
662
                                PSOCK_EXIT(&s->p);
663
                        }        
664
                        read_test = strstr(s->inputbuffer, "RedBoot");
665
                        if(read_test != NULL)
666
                        {
667
                                if(read_test[6] != '>')
668
                                {
669
                                        unsigned int red_start, red_length, fisdir_start;
670
                                        char* read1 = strstr(read_test, "0x");
671
                                        char* read2 = strstr(read1+2, "0x");
672
                                        char* read3 = strstr(read2+2, "0x");
673
                                        
674
                                        sscanf(read1+2, "%x", &red_start);
675
                                        sscanf(read3+2, "%x", &red_length);
676
                                        
677
                                        read_test = strstr(read_test, "FIS directory");
678
                                        if(read_test != NULL)
679
                                        {
680
                                                read1 = strstr(read_test, "0x");
681
                                                sscanf(read1+2, "%x", &fisdir_start);
682
                                        
683
                                
684
                                                flash_start_address = red_start + red_length;
685
                                                flash_size =  fisdir_start - flash_start_address;
686
687
                                                //printf("flash_start_address = 0x%08x, flash_size = 0x%08x\n", flash_start_address, flash_size);
688
                                        }
689
                                }
690
                        }
691
                        
692
                        //if freememlo variable is defined, load it, otherwise use default (guess)
693
                        PSOCK_SEND_STR(365, &s->p, "\%{FREEMEMLO}\n");
694
                        s->inputbuffer[0] = 0;
695
                        PSOCK_READTO(366, &s->p, '>');
696
                        if (NULL == strstr(s->inputbuffer, ">")) 
697
                        {
698
                                fprintf(stderr, "No RedBoot prompt. Exit in line %d\n", __LINE__);
699
                                PSOCK_CLOSE(&s->p);
700
                                PSOCK_EXIT(&s->p);
701
                        }
702
                        read_test = strstr(s->inputbuffer, "0x");
703
                        if(read_test != NULL)
704
                        {
705
                                unsigned int mem;
706
                                sscanf(read_test+2, "%x", &mem);
707
                                freememlow = mem;
708
                                //printf("freememlo = %08x\n", mem);
709
                        }
710
711
                        make_configuration_absolute(final_flash_configuration, flash_start_address, flash_size, FLASH_PAGE_SIZE, (const char**)file_ids, file_sizes);
712
                        create_partition_commands = get_partition_command_list(final_flash_configuration, freememlow);
713
                        bootloader_lines = final_flash_configuration->bootloader_lines;
714
                        configuration_initialization_complete = 1;
715
                }        
716
717
718
719
720
                
721
                printf("\nInitializing partitions ...\nfis init\n");
722
                PSOCK_SEND_STR(388, &s->p, "fis init\n");
723
                s->inputbuffer[0] = 0;
724
                PSOCK_READTO(390, &s->p, ')');
725
                PSOCK_SEND_STR(391, &s->p, "y\n");
726
                s->inputbuffer[0] = 0;
727
                PSOCK_READTO(393, &s->p, '>');
728
729
                initialization_complete = 1;
730
        }
731
732
        
733
734
        //create partitions
735
        while( create_partition_commands[ command_line_index ] != NULL )
736
        {
737
                if(load_found)
738
                {
739
                        uip_udp_remove(s->tftpconn);
740
                }
741
742
743
                next_command = create_partition_commands[ command_line_index ];
744
                load_found = strncmp(next_command, "load ", strlen("load ")) == 0 ? 1 : 0;
745
                if(load_found)
746
                {
747
                        printf("\nloading file:\n%s", next_command);
748
                        tftp_send = 0;
749
                        s->tftpconn = uip_udp_new(&srcipaddr, myhtons(0xffff));
750
                        uip_udp_bind(s->tftpconn, myhtons(69));
751
                }
752
                else
753
                {
754
                        printf("\ncreating flash partition (this may take some time)\n%s", next_command);
755
                }
756
                sprintf(str, "%s", next_command);
757
                PSOCK_SEND_STR(395, &s->p, str);
758
                s->inputbuffer[0] = 0;
759
                PSOCK_READTO(397, &s->p, '>');
760
                command_line_index++;
761
        }
762
        
763
764
        //set bootloader data
765
        if( create_partition_commands[ command_line_index ] == NULL )
766
        {
767
768
                PSOCK_SEND_STR(473, &s->p, "fconfig -d boot_script_data\n");
769
                s->inputbuffer[0] = 0;
770
                PSOCK_READTO(475, &s->p, '>');
771
                bootloader_line_index=0;
772
                printf("\nSetting boot_script_data...\n");
773
                while(bootloader_lines[bootloader_line_index] != NULL )
774
                {
775
                        sprintf(str, "%s", bootloader_lines[bootloader_line_index]);
776
                        printf("%s", str);
777
                        PSOCK_SEND_STR(477, &s->p, str);
778
                        s->inputbuffer[0] = 0;
779
                        PSOCK_READTO(479, &s->p, '>');
780
                        bootloader_line_index++;
781
                }
782
                PSOCK_SEND_STR(480, &s->p, "\n");
783
                s->inputbuffer[0] = 0;
784
                PSOCK_READTO(482, &s->p, ')');
785
                PSOCK_SEND_STR(483, &s->p, "y\n");
786
                s->inputbuffer[0] = 0;
787
                PSOCK_READTO(485, &s->p, '>');
788
                printf("\n");
789
790
                if (NULL == strstr(s->inputbuffer, ">")) {
791
                        fprintf(stderr, "No RedBoot prompt. Exit in line %d\n", __LINE__);
792
                        PSOCK_CLOSE(&s->p);
793
                        PSOCK_EXIT(&s->p);
794
                }
795
                PSOCK_SEND_STR(495, &s->p, "reset\n");
796
                printf("Done. Restarting device...\n");
797
                exit(0);
798
799
        }
800
801
802
803
        PSOCK_END(&s->p);
804
}
805
806
void fon_flash_appcall(void)
807
{
808
        struct fon_flash_state *s = &(uip_conn->appstate);
809
        if (uip_connected())
810
        {
811
#ifdef _DEBUG
812
                fprintf(stderr, "PSOCK_INIT()\n");
813
#endif
814
                PSOCK_INIT(&s->p, s->inputbuffer, sizeof(s->inputbuffer));
815
        }
816
        handle_connection(s);
817
}
818
819
void fon_flash_tftp_appcall(void)
820
{
821
        if(uip_udp_conn->lport == myhtons(69)) {
822
                if (uip_poll());
823
                if (uip_newdata())
824
                {
825
                        unsigned short block = 0;
826
                        unsigned short opcode = myntohs(*(unsigned short*)((unsigned char*)uip_appdata + 0));
827
#ifdef _DEBUG
828
                        fprintf(stderr, "tftp opcode=%d\n", opcode);
829
                        {
830
                                int i;
831
                                char* p = (char*)uip_appdata;
832
                                for(i = 0; i < 48; i++)
833
                                {
834
                                        fprintf(stderr, "%02x%s", p[i], 15 == i % 16 ? "\n" : " ");
835
                                }
836
                        }
837
#endif
838
                        switch(opcode)
839
                        {
840
                                /* Read Request */
841
                                case 1:
842
                                {
843
                                        if (0 == strcmp(((char*)uip_appdata) + 2, "file_1"))
844
                                        {
845
                                                tftp_buf = file_1_buf;
846
                                                tftp_size = file_1_size;
847
                                                //printf("Sending file_1, %ld blocks...\n", ((tftp_size + 511) / 512));
848
                                        }
849
                                        else if (0 == strcmp(((char*)uip_appdata) + 2, "file_2"))
850
                                        {
851
                                                tftp_buf = file_2_buf;
852
                                                tftp_size = file_2_size;
853
                                                //printf("Sending file_2, %ld blocks...\n", ((tftp_size + 511) / 512));
854
                                        }
855
                                        else if (0 == strcmp(((char*)uip_appdata) + 2, "file_3"))
856
                                        {
857
                                                tftp_buf = file_3_buf;
858
                                                tftp_size = file_3_size;
859
                                                //printf("Sending file_3, %ld blocks...\n", ((tftp_size + 511) / 512));
860
861
                                        }
862
                                        else
863
                                        {
864
                                                fprintf(stderr, "Unknown file name: %s\n", ((char*)uip_appdata) + 2);
865
                                                exit(1);
866
                                        }
867
                                }
868
                                break;
869
                                /* TFTP ack */
870
                                case 4:
871
                                {
872
                                        block = myntohs(*(unsigned short*)((unsigned char*)uip_appdata + 2));
873
                                        if (block <= tftp_send / 512) {
874
                                                fprintf(stderr, "tftp repeat block %d\n", block);
875
                                        }
876
#ifdef WIN32
877
                                        /* 
878
                                         * Dunno why, If fixed IP and all microsoft protocols
879
                                         * are enabled, tftp simply stops. This Sleep(1) prevent
880
                                         * TFTP from failing
881
                                         */
882
                                        Sleep(1);
883
#endif
884
                                }
885
                                break;
886
                                default:
887
                                        fprintf(stderr, "Unknown opcode: %d\n", opcode);
888
                                        exit(1);
889
                                break;
890
                        }
891
                        {
892
                                unsigned short nextblock = block + 1;
893
                                *(unsigned short*)((unsigned char*)uip_appdata + 0) = myhtons(3);
894
                                *(unsigned short*)((unsigned char*)uip_appdata + 2) = myhtons(nextblock);
895
                        }
896
#ifdef _DEBUG
897
                        fprintf(stderr, "tftp: block=%d, offs=%p\n", block, tftp_buf + 512 * block);
898
#endif
899
                        if (block < ((tftp_size + 511) / 512)) {
900
                                if(tftp_buf == NULL)
901
                                {
902
                                        printf("tftp buff is null!\n");
903
                                }
904
                                tftp_send = 512 * block;
905
                                memmove((unsigned char*)uip_appdata + 4, (void *)(tftp_buf + tftp_send), 512);
906
                                uip_send(uip_appdata, 512 + 4);
907
                        }
908
                        else if (block == ((tftp_size + 511) / 512)) {
909
                                tftp_send = 512 * block;
910
                                uip_send(uip_appdata, 4);
911
                        }
912
                }
913
        }
914
}
915
916
int initialize_buffers_from_files(char* file_1_filename, char* file_2_filename, char* file_3_filename)
917
{
918
        char* file_names[3] = { file_1_filename, file_2_filename, file_3_filename };
919
        unsigned char* file_buffers[3] = { file_1_buf, file_2_buf, file_3_buf };
920
        unsigned long* file_size_ptrs[3] = { &file_1_size, &file_2_size, &file_3_size };
921
        int file_index;
922
923
        for(file_index = 0; file_index < 3; file_index++)
924
        {
925
                int fd, raw_size;
926
                unsigned long rounded_size;
927
                char* file_name = file_names[file_index];
928
                unsigned char* file_buffer = file_buffers[file_index];
929
                if(file_name != NULL)
930
                {
931
                        unsigned long* file_size_ptr;
932
                        if (-1 == (fd = open(file_name, O_RDONLY | O_BINARY)))
933
                        {
934
                                perror(file_name);
935
                                return 1;
936
                        }
937
                        raw_size = lseek(fd, 0, SEEK_END);
938
                        rounded_size = (((raw_size-1)/FLASH_PAGE_SIZE)+1)*FLASH_PAGE_SIZE;
939
                        
940
                
941
                        lseek(fd, 0, SEEK_SET);
942
                        if (0 != (file_buffer = (unsigned char*)malloc(rounded_size*sizeof(unsigned char))))
943
                        {
944
                                if (raw_size != read(fd, file_buffer, raw_size) || 0 >= raw_size )
945
                                {
946
                                        char s[265];
947
                                        sprintf(s, "%s fails: buf=%p, size=%d", file_name, file_buffer, raw_size);
948
                                        perror(s);
949
                                        return 1;
950
                                }
951
                        }
952
                        else
953
                        {
954
                                perror("no mem");
955
                                return 1;
956
                        }
957
                        file_buffers[file_index] = file_buffer;
958
                        printf("Reading image file %s with %d bytes, rounded to 0x%08lx\n", file_name, raw_size, rounded_size);
959
                        file_size_ptr = file_size_ptrs[file_index];
960
                        *file_size_ptr = rounded_size;
961
                }
962
        }
963
        
964
        //set buffers to initialized values
965
        file_1_buf = file_buffers[0];
966
        file_2_buf = file_buffers[1];
967
        file_3_buf = file_buffers[2];
968
969
970
        return 0;
971
}
972
973
974
int initialize_buffers_from_data(unsigned char* raw_1, unsigned char* raw_2, unsigned char* raw_3, unsigned long raw_size_1, unsigned long raw_size_2, unsigned long raw_size_3)
975
{
976
        unsigned char* file_buffers[3]   = { file_1_buf, file_2_buf, file_3_buf };
977
        unsigned long* file_size_ptrs[3] = { &file_1_size, &file_2_size, &file_3_size };
978
        unsigned char* raw_buffers[3]    = { raw_1, raw_2, raw_3 };
979
        unsigned long  raw_sizes[3]      = { raw_size_1, raw_size_2, raw_size_3};
980
        int file_index;
981
        for(file_index = 0; file_index < 3; file_index++)
982
        {
983
                unsigned long raw_size = raw_sizes[file_index];
984
                unsigned char* raw_buffer = raw_buffers[file_index];
985
                printf("raw size %d = %ld\n", (file_index+1), raw_size);
986
                if(raw_size > 0 && raw_buffer != NULL)
987
                {
988
989
                        unsigned long rounded_size = (((raw_size-1)/FLASH_PAGE_SIZE)+1)*FLASH_PAGE_SIZE;
990
                        unsigned char* next_buf = (unsigned char*)malloc(rounded_size);
991
                        unsigned long* file_size_ptr;
992
993
                        /*
994
                        unsigned long i =0;
995
                        for(i=0; i < raw_size; i++)
996
                        {
997
                                if(i % 2 == 0) { printf("i = %ld\n", i); }
998
                                next_buf[i] = raw_buffer[i];
999
                        }
1000
                        */
1001
                        
1002
                        memcpy(next_buf, raw_buffer, raw_size);
1003
                        file_buffers[file_index] = next_buf;
1004
                        file_size_ptr = file_size_ptrs[file_index];
1005
                        *file_size_ptr = rounded_size;
1006
                }
1007
        }
1008
1009
        //set buffers to initialized values
1010
        file_1_buf = file_buffers[0];
1011
        file_2_buf = file_buffers[1];
1012
        file_3_buf = file_buffers[2];
1013
1014
        return 0;
1015
}
1016
1017
1018
int fon_flash(flash_configuration* conf, char* device)
1019
{
1020
        uip_ipaddr_t netmask;
1021
        struct uip_eth_addr srcmac, dstmac, brcmac;
1022
        struct timer periodic_timer, arp_timer;
1023
1024
1025
        uip_init();
1026
        uip_arp_init();
1027
1028
        final_flash_configuration = conf;
1029
1030
1031
1032
1033
        /*
1034
        int i = 0; 
1035
        for(i=0; create_partition_commands[i] != NULL; i++)
1036
        {
1037
                printf("%s", create_partition_commands[i]);
1038
        }
1039
        for(i=0; bootloader_lines[i] != NULL; i++)
1040
        {
1041
                printf("%s", (conf->bootloader_lines)[i] );
1042
        }
1043
        */
1044
1045
1046
1047
1048
1049
1050
        srcmac.addr[0] = 0x00;
1051
        srcmac.addr[1] = 0xba;
1052
        srcmac.addr[2] = 0xbe;
1053
        srcmac.addr[3] = 0xca;
1054
        srcmac.addr[4] = 0xff;
1055
        srcmac.addr[5] = 0xee;
1056
        dstmac.addr[0] = 0xde;
1057
        dstmac.addr[1] = 0xad;
1058
        dstmac.addr[2] = 0xde;
1059
        dstmac.addr[3] = 0xad;
1060
        dstmac.addr[4] = 0xde;
1061
        dstmac.addr[5] = 0xad;
1062
        memset(&brcmac, 0xff, sizeof(brcmac));
1063
1064
1065
1066
1067
        if (0 > pcap_init(device, &srcipaddr, &dstipaddr, &srcmac, &dstmac, 0))
1068
        {
1069
                return 1;
1070
        }
1071
1072
        uip_sethostaddr(srcipaddr);
1073
        uip_setdraddr(dstipaddr);
1074
        uip_setethaddr(srcmac);
1075
        uip_ipaddr(netmask, 255,255,0,0);
1076
        uip_setnetmask(netmask);
1077
        uip_arp_update(dstipaddr, &dstmac);
1078
        
1079
        timer_set(&periodic_timer, CLOCK_SECOND / 2);
1080
        timer_set(&arp_timer, CLOCK_SECOND * 10);
1081
1082
#ifndef WIN32
1083
        usleep(3750000);
1084
#endif
1085
        
1086
        
1087
        if (NULL == uip_connect(&dstipaddr, myhtons(9000)))
1088
        {
1089
                fprintf(stderr, "Cannot connect to port 9000\n");
1090
                return 1;
1091
        }
1092
        
1093
        while(1)
1094
        {
1095
                uip_len = pcap_read();
1096
                if(uip_len > 0)
1097
                {
1098
                        if (0 == memcmp(&BUF->src, &srcmac, sizeof(srcmac)))
1099
                        {
1100
#ifdef _DEBUG
1101
                                printf("ignored %d byte from %02x:%02x:%02x:%02x:%02x:%02x\n", uip_len,
1102
                                        BUF->src.addr[0], BUF->src.addr[1], BUF->src.addr[2],
1103
                                        BUF->src.addr[3], BUF->src.addr[4], BUF->src.addr[5]);
1104
#endif
1105
                            uip_len = 0;
1106
                        }
1107
                        else if(0 != memcmp(&BUF->dest, &srcmac, sizeof(srcmac)) &&
1108
                                0 != memcmp(&BUF->dest, &brcmac, sizeof(brcmac)))
1109
                        {
1110
#ifdef _DEBUG
1111
                                fprintf(stderr, "ignored %d byte to %02x:%02x:%02x:%02x:%02x:%02x\n", uip_len,
1112
                                        BUF->dest.addr[0], BUF->dest.addr[1], BUF->dest.addr[2],
1113
                                        BUF->dest.addr[3], BUF->dest.addr[4], BUF->dest.addr[5]);
1114
#endif
1115
                                uip_len = 0;
1116
                        }
1117
                        else if(BUF->type == myhtons(UIP_ETHTYPE_IP))
1118
                        {
1119
                                uip_arp_ipin();
1120
#ifdef _DEBUG
1121
                                fprintf(stderr, "uip_input(), uip_len=%d, uip_buf[2f]=%02x\n", uip_len, uip_buf[0x2f]);
1122
                                if (0 != (uip_buf[0x2f] & 0x02))
1123
                                {
1124
                                        fprintf(stderr, "Got you!\n");
1125
                                }
1126
#endif
1127
                                uip_input();
1128
                                
1129
                                // If the above function invocation resulted in data that
1130
                                // should be sent out on the network, the global variable
1131
                                // uip_len is set to a value > 0.
1132
                                //
1133
                                if(uip_len > 0)
1134
                                {
1135
                                        uip_arp_out();
1136
                                        pcap_send();
1137
                                }
1138
                        } 
1139
                        else if(BUF->type == myhtons(UIP_ETHTYPE_ARP))
1140
                        {
1141
                                uip_arp_arpin();
1142
1143
                                // If the above function invocation resulted in data that
1144
                                // should be sent out on the network, the global variable
1145
                                // uip_len is set to a value > 0.
1146
                                //
1147
                                if(uip_len > 0)
1148
                                {
1149
                                        pcap_send();
1150
                                }
1151
                        }
1152
1153
                } 
1154
                else if(timer_expired(&periodic_timer))
1155
                {
1156
                        int i;
1157
                        timer_reset(&periodic_timer);
1158
                        for(i = 0; i < UIP_CONNS; i++)
1159
                        {
1160
                                uip_periodic(i);
1161
                                // If the above function invocation resulted in data that
1162
                                // should be sent out on the network, the global variable
1163
                                // uip_len is set to a value > 0.
1164
                                //
1165
                                if(uip_len > 0)
1166
                                {
1167
                                        uip_arp_out();
1168
                                        pcap_send();
1169
                                }
1170
                        }
1171
1172
                        // Call the ARP timer function every 10 seconds. 
1173
                        if(timer_expired(&arp_timer)) 
1174
                        {
1175
                                timer_reset(&arp_timer);
1176
                                uip_arp_timer();
1177
                        }
1178
                }
1179
#ifdef WIN32
1180
                Sleep(1);
1181
#else
1182
                usleep(1000);
1183
#endif
1184
        }
1185
        
1186
        return 0;
1187
}
1188
1189
1190
int ends_with(const char* str, const char* end)
1191
{
1192
        if(str == NULL || end == NULL) { return 0; }
1193
        int slen = strlen(str);
1194
        int elen = strlen(end);
1195
        const char* end_test = str + (slen-elen);
1196
        char* t1 = strdup(end);
1197
        char* t2 = strdup(end_test);
1198
        int i;
1199
        
1200
        for(i=0; t1[i] != '\0' ; i++) { t1[i] = toupper( t1[i] ); }
1201
        for(i=0; t2[i] != '\0' ; i++) { t2[i] = toupper( t2[i] ); }
1202
        i = strcmp(t1,t2) == 0 ? 1 : 0;
1203
1204
        free(t1);
1205
        free(t2);
1206
        return i;
1207
}        
1208
1209
1210
#ifndef GUI
1211
1212
#ifndef INCLUDE_BINARIES
1213
void print_usage(char *prgname)
1214
{
1215
        printf("Usage: %s -i [network interface] -c [configuration] [configuration files]\n", prgname);
1216
        printf("Valid configurations are currently:\n");
1217
        printf("\t\tgargoyle [rootfs file path] [kernel file path]\n");
1218
        printf("\t\topenwrt  [rootfs file path] [kernel file path]\n");
1219
        printf("\t\tfonera   [loader file path] [image file path] [image2 file path]\n");
1220
        printf("\t\tddwrt    [firmware file path]\n");
1221
}
1222
1223
1224
int main(int argc, char* argv[])
1225
{
1226
        flash_configuration* conf = NULL;
1227
        char* interface = NULL;
1228
        char* f1 = NULL;
1229
        char* f2 = NULL;
1230
        char* f3 = NULL;
1231
        int num_files_expected = 0;
1232
        int num_files_found = 0;
1233
        
1234
        char c;        
1235
        while((c = getopt(argc, argv, "C:c:I:i:")) != -1)
1236
        {        
1237
                switch(c)
1238
                {
1239
                        case 'C':
1240
                        case 'c':
1241
                                if(strcmp(optarg, "gargoyle") == 0 || strcmp(optarg, "openwrt") == 0)
1242
                                {
1243
                                        conf =  get_gargoyle_configuration();
1244
                                        num_files_expected = 2;
1245
                                }
1246
                                else if(strcmp(optarg, "fonera") == 0)
1247
                                {
1248
                                        conf = get_fonera_configuration();
1249
                                        num_files_expected = 3;
1250
                                }
1251
                                else if(strcmp(optarg, "ddwrt") == 0)
1252
                                {
1253
                                        conf = get_ddwrt_configuration();
1254
                                        num_files_expected = 1;
1255
                                }
1256
                                break;
1257
1258
                        case 'I':
1259
                        case 'i':
1260
                                interface = strdup(optarg);
1261
                                break;
1262
                }
1263
        }
1264
        if(optind < argc)
1265
        {
1266
                int arg_index;
1267
                for(arg_index =optind; arg_index < argc && arg_index-optind < 3; arg_index++)
1268
                {
1269
                        int file_index = arg_index-optind;
1270
                        if(file_index == 0)
1271
                        {
1272
                                f1 = strdup(argv[arg_index]);
1273
                        }
1274
                        else if(file_index == 1)
1275
                        {
1276
                                f2 = strdup(argv[arg_index]);
1277
                        }
1278
                        else if(file_index == 2)
1279
                        {
1280
                                f3 = strdup(argv[arg_index]);
1281
                        }
1282
                        num_files_found++;
1283
                }
1284
        }
1285
        if(interface == NULL)
1286
        {
1287
                printf("ERROR: you must specify a network interface\n");
1288
                print_usage(argv[0]);
1289
                exit(0);
1290
        }
1291
        
1292
        else if(conf == NULL)
1293
        {
1294
                printf("ERROR: you must specify a valid configuration\n");
1295
                print_usage(argv[0]);
1296
                exit(0);
1297
        }
1298
        if(num_files_found != num_files_expected)
1299
        {
1300
                printf("ERROR: incorrect number of files specified for selected configuration\n");
1301
                print_usage(argv[0]);
1302
                exit(0);
1303
        }
1304
        
1305
1306
        int is_gz = ends_with(f1, ".gz") == 1 || ends_with(f2, ".gz") == 1 || ends_with(f3, ".gz") == 1 ? 1 : 0;
1307
        if(is_gz == 1)
1308
        {
1309
                char** boot = conf->bootloader_lines;
1310
                int boot_index=0;
1311
                for(boot_index=0; boot[boot_index] != NULL; boot_index++)
1312
                {
1313
                        if(strstr(boot[boot_index], "fis load -l") != NULL)
1314
                        {
1315
                                char* old_boot = boot[boot_index];
1316
                                char* boot_end = old_boot + strlen("fis load -l");
1317
                                char new_boot[100];
1318
                                sprintf(new_boot, "fis load -d%s", boot_end);
1319
                                boot[boot_index] = strdup(new_boot);
1320
                                free(old_boot);
1321
                        }
1322
                }
1323
        }
1324
1325
1326
1327
        if(initialize_buffers_from_files(f1, f2, f3) == 0)
1328
        {
1329
                return fon_flash(conf, interface);
1330
        }
1331
        else
1332
        {
1333
                return 1;
1334
        }
1335
1336
}
1337
#else
1338
1339
1340
int main(int argc, char* argv[])
1341
{
1342
        char* iface = NULL;
1343
1344
        char c;        
1345
        while((c = getopt(argc, argv, "I:i:")) != -1)
1346
        {        
1347
                switch(c)
1348
                {
1349
                        case 'I':
1350
                        case 'i':
1351
                                iface = strdup(optarg);
1352
                                break;
1353
                }
1354
        }
1355
        if(iface == NULL)
1356
        {
1357
                printf("ERROR: you must specify a network iface\n");
1358
                printf("Usage: %s -i [iface]\n", argv[0]);
1359
                return 1;
1360
        }
1361
1362
1363
        /*
1364
        if(_binary_1_data != NULL)
1365
        {
1366
                printf("bin1 size = %ld\n", _binary_1_size);
1367
                printf("first byte = %d\n", _binary_1_data[0]);
1368
        }
1369
        */
1370
1371
        //binary 1-3 and binary_size 1-3 along with default_conf defined in install_binaries header
1372
        initialize_buffers_from_data(_binary_1_data, _binary_2_data, _binary_3_data, _binary_1_size, _binary_2_size, _binary_3_size);
1373
        fon_flash(default_conf, iface);
1374
        
1375
        return 0;
1376
1377
}
1378
1379
1380
1381
#endif
1382
1383
1384
#endif