00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <stdio.h>
00021 #include <pcap.h>
00022 #include <conf.h>
00023
00024 #include <e100boot.h>
00025 #include <common.h>
00026 #include <network.h>
00027
00028
00029 #define CRC_LEN 4
00030
00031
00032
00033 udword highest_ack_received;
00034 udword last_ack_received = -1;
00035 int new_ack = FALSE;
00036 int got_new_packet = FALSE;
00037
00038
00039 const unsigned char axis_000200[] = { 0x01, 0x40, 0x8c, 0x00, 0x02, 0x00 };
00040
00041
00042
00043 const unsigned char axis_000400[] = { 0x01, 0x40, 0x8c, 0x00, 0x04, 0x00 };
00044
00045
00046 unsigned char eth_addr_local[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00047
00048 struct sockaddr sock_addr;
00049 int sock_fd;
00050 int pPacket = 0;
00051 pcap_t *pd;
00052
00053 pcap_handler handler;
00054
00055 struct packet_buf first_rec_packet;
00056 struct packet_buf *last_rec_packet = &first_rec_packet;
00057
00058 int promisc = 1;
00059 int all_ids = TRUE;
00060
00061 int both_addresses = FALSE;
00062 int p_packet_bpl = 8;
00063 int printPacketType = CHAR;
00064
00065 unsigned int id = 0;
00066 int one_id_only = TRUE;
00067
00068
00069 #define PKT_BUF_LEN 200
00070 unsigned char buf[PKT_BUF_LEN];
00071
00072 const struct pcap_pkthdr *hdrG;
00073
00074 char host1[MAX_STRING_LEN];
00075 char host2[MAX_STRING_LEN];
00076
00077
00078
00079 int timeout (struct timeval *tvThen, int ms);
00080 int InitSendSocket (char *device_name);
00081 int highest_seq_received (void);
00082 struct packet_buf* ack_on_seq (int seq);
00083 struct packet_buf* packet_with_seq (int seq);
00084 struct timeval timeval_subtract (struct timeval *x, struct timeval *y);
00085 void GetNextPacket (void);
00086 void PrintPacket (const unsigned char *p, int size, int type);
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 void
00103 net_init(void)
00104 {
00105 char *dev;
00106 char errBuf[1000];
00107
00108 GetLocalEthAddr();
00109 first_rec_packet.data = malloc(PACKET_SIZE);
00110
00111 if ((dev = pcap_lookupdev(errBuf)) == NULL) {
00112 printf("Error, %s.\n", errBuf);
00113 exit(EXIT_FAILURE);
00114 }
00115
00116 if ((pd = pcap_open_live(device, PKT_BUF_LEN, promisc, 10, errBuf)) == NULL) {
00117 printf("Error, %s.\n", errBuf);
00118 exit(EXIT_FAILURE);
00119 }
00120
00121 handler = (pcap_handler) Handler;
00122
00123 InitSendSocket(device);
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 void
00143 NetBoot(void)
00144 {
00145 struct packet_buf *p;
00146 struct timeval tv;
00147 unsigned print_last = FALSE;
00148
00149 gettimeofday(&tv, NULL);
00150
00151 p = create_packet(0);
00152 if (p->size > 1514) {
00153 printf("Ethernet package to large (%d). A bug somewhere...\n", p->size);
00154 exit(EXIT_FAILURE);
00155 }
00156 SendToDevice(p->data, p->size);
00157
00158 while(1) {
00159 static int all_trans = FALSE;
00160
00161 if (got_new_packet) {
00162 got_new_packet = FALSE;
00163
00164 if (new_ack && first_packet) {
00165 if (db4) {
00166 printf("* got ACK %d.\n", last_ack_received);
00167 printf("* ACK wanted %d.\n", first_packet->seq);
00168 }
00169
00170
00171 if (last_ack_received == first_packet->seq) {
00172
00173
00174 if ((p = create_packet(first_packet->seq+1))) {
00175
00176 ((struct packet_header_T*)p->data)->id = htonl(id);
00177
00178
00179 first_packet = free_packet(first_packet);
00180 }
00181 }
00182 }
00183 }
00184
00185 if (new_ack || timeout(&tv, 500)) {
00186 if (p) {
00187 SendToDevice(p->data, p->size);
00188 }
00189 else {
00190 if (print_last) {
00191 printf("Last packet\n");
00192 print_last = 0;
00193 }
00194 }
00195 new_ack = FALSE;
00196 gettimeofday(&tv, NULL);
00197 }
00198
00199 GetNextPacket();
00200
00201 }
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 void
00220 GetNextPacket(void)
00221 {
00222 int ret;
00223
00224 if (db2) printf("> GetNextPacket\n");
00225
00226
00227 if ((ret = pcap_dispatch(pd, 1, handler, buf)) == -1) {
00228 pcap_perror(pd, "Error in pcap_dispatch");
00229 exit(EXIT_FAILURE);
00230 }
00231
00232 if (db2) printf("< GetNextPacket\n");
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 void
00253 Handler(unsigned char *buf, const struct pcap_pkthdr *hdr,
00254 const unsigned char *p)
00255 {
00256 const unsigned char *src = &p[6];
00257 const unsigned char *dst = &p[0];
00258 struct packet_header_T *h = (struct packet_header_T*)p;
00259
00260 if (db2) printf("> Handler\n");
00261
00262
00263 if(all_ids == FALSE) {
00264 if(id != ntohl(h->id)) {
00265 return;
00266 }
00267 }
00268
00269 got_new_packet = TRUE;
00270
00271 #if 0
00272 if (
00273
00274 (!memcmp(src, eth_addr_local, 6) && !memcmp(dst, axis_000200, 6))
00275
00276 || (!memcmp(src, axis_000200, 6) && (!memcmp(dst, eth_addr_local, 6)
00277 || !memcmp(dst, axis_000400, 6)))) {
00278 #endif
00279
00280 if (
00281
00282 (!memcmp(src, axis_000200, 6) && (!memcmp(dst, eth_addr_local, 6)
00283 || !memcmp(dst, axis_000400, 6)))) {
00284
00285 if (db1) printf("#RX######################################################\n");
00286 if (db1) printf("Length: %u(0x%x)\n", (udword)hdr->len, (udword)hdr->len);
00287 if (pPacket) PrintPacket(p, hdr->caplen, printPacketType);
00288 DecodeSvintoBoot(p);
00289 if (!listenOnly) {
00290
00291 if ((ntohl(h->type) == ACK)) {
00292 if (all_ids || (ntohl(h->id) == id)) {
00293 if (all_ids && one_id_only) {
00294 if (ntohl(h->id) != 0) {
00295 all_ids = FALSE;
00296 id = ntohl(h->id);
00297 printf("Connected. Booting device with random id %8.8x.\n", id);
00298 }
00299 } else {
00300
00301
00302 }
00303 }
00304 else {
00305 printf("Got ACK from a new id, %8.8lx. Ignoring.\n",
00306 (unsigned long)ntohl(h->id));
00307 return;
00308 }
00309 new_ack = TRUE;
00310 last_ack_received = ntohl(h->seq);
00311 if (last_ack_received > highest_ack_received) {
00312 highest_ack_received = last_ack_received;
00313 }
00314 }
00315 }
00316
00317 if (db1) printf("#########################################################\n");
00318
00319 }
00320 if (db2) printf("< Handler\n");
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 struct packet_buf *
00341 packet_with_seq(int seq)
00342 {
00343 static int last_seq = 0;
00344 struct packet_buf *p = first_packet;
00345 struct packet_header_T *h;
00346
00347 if (seq < last_seq) {
00348 p = first_packet;
00349 }
00350
00351 while(p) {
00352 h = (struct packet_header_T*)p->data;
00353 if (ntohl(h->seq) == seq) {
00354 return(p);
00355 }
00356 p = p->next;
00357 }
00358 return(NULL);
00359 }
00360
00361 struct packet_buf *
00362 ack_on_seq(int seq)
00363 {
00364 struct packet_buf *p = &first_rec_packet;
00365 struct packet_header_T *h;
00366
00367 if (db1) printf("***> ack_on_seq: %d.\n", seq);
00368
00369 while (p) {
00370
00371
00372 h = (struct packet_header_T*)p->data;
00373 if ( (ntohl(h->type) == ACK) && (ntohl(h->seq) == seq) ) {
00374 if (all_ids || ntohl(h->id) == id) {
00375 printf("***< ack_on_seq %d, ok.\n", seq);
00376 return(p);
00377 }
00378 }
00379 p = p->next;
00380 }
00381 if (db1) printf("***< ack_on_seq, no.\n");
00382 return(NULL);
00383 }
00384
00385 int
00386 highest_seq_received(void)
00387 {
00388 struct packet_buf *p = &first_rec_packet;
00389 struct packet_header_T *h;
00390 int highest_seq = -1;
00391
00392 if (db1) printf("***> highest_seq_received\n");
00393
00394 while (p) {
00395
00396
00397 h = (struct packet_header_T*)p->data;
00398 if ((ntohl(h->type) == ACK) && (all_ids || (ntohl(h->id) == id))) {
00399 if ((int)ntohl(h->seq) > highest_seq) {
00400 highest_seq = ntohl(h->seq);
00401 if (db4) printf("Highest seq: %d\n", highest_seq);
00402 }
00403 }
00404 p = p->next;
00405 }
00406
00407 if (db1) printf("***< highest_seq_received: %d\n", highest_seq);
00408 return(highest_seq);
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 void
00430 PrintPacket(const unsigned char *p, int size, int type)
00431 {
00432 int i;
00433
00434
00435 for (i = 0; i != size; i++) {
00436 if (i % p_packet_bpl == 0)
00437 printf("\n%-4.4d: ", i);
00438 if (type == UDEC) {
00439 printf("%-3d ", p[i]);
00440 }
00441 else if (type == HEX) {
00442 printf("%-2.2x ", p[i]);
00443 }
00444 else if (type == CHAR) {
00445 if (isprint(p[i])) {
00446 printf("%-3c ", p[i]);
00447 }
00448 else {
00449 printf("%-3d ", p[i]);
00450 }
00451 }
00452 else if (type == ASCII) {
00453 if (isprint(p[i])) {
00454 printf("%c", p[i]);
00455 }
00456 else {
00457 printf(".");
00458 }
00459 }
00460 }
00461 printf("\n");
00462 }
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 void
00482 DecodeSvintoBoot(const unsigned char *p)
00483 {
00484 char *str;
00485 volatile struct packet_header_T *ph = (struct packet_header_T*)p;
00486
00487
00488
00489 if (db4) printf("\n>DecodeSvintoBoot. Packet at 0x%x\n", (unsigned int)p);
00490 if (db1) {
00491 printf("%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x -> ", p[6],p[7],p[8],p[9],p[10], p[11]);
00492 printf("%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x\n", p[0],p[1],p[2],p[3],p[4], p[5]);
00493
00494 printf("length : %4.4lx\n", (long)ntohs(ph->length));
00495 printf("snap1 : %8.8lx\n", (long)ntohl(ph->snap1));
00496 printf("snap2 : %8.8lx\n", (long)ntohl(ph->snap2));
00497
00498 switch (ntohl(ph->tag)) {
00499 case 0xffffffff:
00500 str = "(host > ETRAX)";
00501 break;
00502 case 0xfffffffe:
00503 str = "(ETRAX > host)";
00504 break;
00505 default:
00506 str = "(unknown)";
00507 break;
00508 }
00509 printf("tag : %8.8lx %s\n", (unsigned long)ntohl(ph->tag), str);
00510 printf("seq : %8.8lx\n", (unsigned long)ntohl(ph->seq));
00511 }
00512
00513 switch (ntohl(ph->type)) {
00514
00515 case STRING:
00516 str = "(STRING)";
00517 fprintf(stderr, "%s", &p[sizeof(struct packet_header_T)]);
00518 find_string((char*)&p[sizeof(struct packet_header_T)]);
00519 break;
00520
00521 case NET_INT: {
00522 char search_str[20];
00523
00524 str = "(NET_INT)";
00525 sprintf(search_str, "0x%8.8x", ntohl(*(udword*)&p[sizeof(struct packet_header_T)]));
00526 fprintf(stderr, search_str);
00527 find_string(search_str);
00528 break;
00529 }
00530
00531 case NET_INT_NL: {
00532 char search_str[20];
00533
00534 str = "(NET_INT_NL)";
00535 sprintf(search_str, "0x%8.8x\n", ntohl(*(udword*)&p[sizeof(struct packet_header_T)]));
00536 fprintf(stderr, search_str);
00537 find_string(search_str);
00538 break;
00539 }
00540
00541 case ACK:
00542 str = "(ACK)";
00543 break;
00544
00545 case BOOT_PACKET:
00546 str = "(bootpacket)";
00547 break;
00548
00549 case FILE_PACKET:
00550 str = "(filepacket)";
00551 break;
00552
00553 case BOOT_CMDS:
00554 str = "(bootcmds)";
00555 break;
00556
00557 default:
00558 str = "(unknown)";
00559 break;
00560 }
00561
00562 if (db1) {
00563 printf("(type : %8.8lx %s)\n", (unsigned long)ntohl(ph->type), str);
00564 printf("(id : %8.8lx)\n", (unsigned long)ntohl(ph->id));
00565 id = ntohl(ph->id);
00566 }
00567
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 void
00587 GetLocalEthAddr(void)
00588 {
00589 int fd;
00590 struct ifreq ifr;
00591
00592 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
00593 perror("socket (GetLocalEthAddr)");
00594 exit(EXIT_FAILURE);
00595 }
00596
00597 strcpy(ifr.ifr_name, device);
00598 if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
00599 perror("ioctl");
00600 exit(EXIT_FAILURE);
00601 }
00602
00603 memcpy(eth_addr_local, ifr.ifr_hwaddr.sa_data, 6);
00604 if (db1) printf("Ethernet adress for device %s is %2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x\n",
00605 device,
00606 eth_addr_local[0],
00607 eth_addr_local[1],
00608 eth_addr_local[2],
00609 eth_addr_local[3],
00610 eth_addr_local[4],
00611 eth_addr_local[5]);
00612 shutdown(fd, 2);
00613 }
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631 void
00632 SendToDevice(unsigned char *data, int data_len)
00633 {
00634 char fName[MAX_STRING_LEN];
00635 FILE *fd;
00636 struct packet_header_T *h = (struct packet_header_T*) data;
00637
00638 if (listenOnly) {
00639 return;
00640 }
00641
00642 if (db2) printf("***> SendToDevice\n");
00643
00644 if (db2) printf("Sending %d bytes at 0x%x to %s.\n", data_len, (unsigned int)data, device);
00645 if (db1) printf("#TX %3d/%3d #############################################\n",
00646 ntohl(h->seq)+1, nrof_net_packets);
00647 if (db1) DecodeSvintoBoot(data);
00648
00649 if (db1) printf("#########################################################\n");
00650 if (toFiles || cmdsOnly) {
00651 if (cmdsOnly) {
00652 sprintf(fName, "fsboot.cmds");
00653 }
00654 else {
00655 static unsigned seq = 0;
00656
00657 if (netBoot) {
00658 seq = ntohl(h->seq);
00659 }
00660 sprintf(fName, "tx%d.pkt", seq++);
00661 }
00662 if (db2) printf("Writing packet to file '%s'.\n", fName);
00663 if ((fd = fopen(fName, "w+")) == NULL) {
00664 printf("Cannot open/create '%s'. %s.\n", fName, strerror(errno));
00665 exit(EXIT_FAILURE);
00666 }
00667 fwrite(data, data_len, 1, fd);
00668 fclose(fd);
00669 }
00670 else {
00671 fd_set set;
00672 struct timeval timeout;
00673
00674
00675 FD_ZERO (&set);
00676 FD_SET (sock_fd, &set);
00677
00678
00679 timeout.tv_sec = 0;
00680 timeout.tv_usec = 1;
00681
00682 if (select(sock_fd+1, NULL, &set, NULL, &timeout) > 0) {
00683 if (sendto(sock_fd, data, data_len, 0, &sock_addr, sizeof(sock_addr)) < 0) {
00684 perror("Sendto failed:");
00685 exit(EXIT_FAILURE);
00686 }
00687 }
00688 else {
00689
00690
00691
00692
00693 }
00694 }
00695
00696
00697 if (db2) printf("<*** SendToDevice\n");
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 int
00715 InitSendSocket(char *device_name)
00716 {
00717 if ((sock_fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) {
00718 perror("Socket call failed:");
00719 exit(EXIT_FAILURE);
00720 }
00721
00722 fcntl(sock_fd, F_SETFL, O_NDELAY);
00723
00724 sock_addr.sa_family = AF_INET;
00725 strcpy(sock_addr.sa_data, device_name);
00726
00727 return sock_fd;
00728 }
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747 int
00748 timeout(struct timeval *tvThen, int ms)
00749 {
00750 struct timeval tvNow;
00751 struct timeval tvDiff;
00752
00753 (void) gettimeofday(&tvNow, NULL);
00754 tvDiff = timeval_subtract(&tvNow, tvThen);
00755 if (db4) printf("sec %d.%d\n", (int)tvDiff.tv_sec, (int)tvDiff.tv_usec);
00756 if (ms * 1000 < (tvDiff.tv_sec * 1000000 + tvDiff.tv_usec)) {
00757 if (db4) printf("TIMEOUT\n");
00758 return(TRUE);
00759 }
00760
00761 return(FALSE);
00762 }
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778 struct timeval
00779 timeval_subtract(struct timeval *x, struct timeval *y)
00780 {
00781 struct timeval diff;
00782
00783 diff.tv_sec = x->tv_sec - y->tv_sec;
00784 diff.tv_usec = x->tv_usec - y->tv_usec;
00785
00786 if (diff.tv_usec < 0) {
00787 diff.tv_sec--;
00788 diff.tv_usec = 1000000 + diff.tv_usec;
00789 }
00790
00791 return diff;
00792 }
00793
00794