/* * copyprom.c -- copy fastpath K-STAR image * Phil Budne 2/4/2003 * from copyprom.c * copyies memory starting at 0x60000 */ #define HOST "fp5" #define OUT "kstar.out" #define START 0x60000 #include #include #include #include #include #include #include #define BLKSIZE 512 /**************** * from KIP gwctl.h * * (c) 1986, Stanford, BBN, Kinetics. * May be used but not sold without permission. * */ /* * Gateway debug protocol (via ddt68 on UNIX). */ struct gwdb { u_long magic; /* magic number */ u_char op,seq; /* op code, sequence number */ u_short count; /* byte count */ u_long address; /* address of read/write */ u_char data[BLKSIZE]; }; #define gwdbMagic 0xFF068020 #define gwdbPort 900 /* udp port number */ /* op codes */ #define gwdbRead 1 /**************** end from gwctl.h */ jmp_buf jmpbuf; unsigned char seq = 0; ding() { fprintf(stderr, "retry seq %d\n", seq); longjmp(jmpbuf, 1); } void usage() { fprintf(stderr, "Usage: copyprom fpname outfile len(K)\n"); exit(1); } main(argc, argv) int argc; char *argv[]; { struct hostent *host; unsigned long addr; struct sockaddr_in sin; int s; int promk; FILE *out; if (argc != 4) usage(); out = fopen(argv[2], "w"); if (!out) { perror(argv[2]); usage(); } if ((s = socket(AF_INET, SOCK_DGRAM, 0, 0)) < 0) { perror("socket"); exit(1); } if ((host = gethostbyname(argv[1])) == 0) { fprintf(stderr, "unknown host %s\n", argv[1]); usage(); } promk = atoi(argv[3]); bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons((u_short)gwdbPort); bcopy(host->h_addr, &sin.sin_addr, host->h_length); if (connect(s, &sin, sizeof(sin)) < 0) { perror("connect"); exit(1); } for (addr = START; addr < START + promk*1024; addr += BLKSIZE) { struct gwdb gwdb; int cc; int retries; for (retries = 0; ; retries++) { if (retries > 10) { fprintf(stderr, "too many retries\n"); exit(1); } bzero(&gwdb, sizeof(gwdb)); gwdb.magic = htonl(gwdbMagic); gwdb.op = gwdbRead; gwdb.seq = seq; gwdb.count = htons(BLKSIZE); gwdb.address = htonl(addr); write(s, &gwdb, sizeof(gwdb)); if (setjmp(jmpbuf)) continue; signal(SIGALRM, ding); alarm(2); cc = read(s, &gwdb, sizeof(gwdb)); if (cc < 0 || cc < sizeof(gwdb)-sizeof(gwdb.data)) goto breakloop; if (gwdb.seq == seq) break; /* XXX drain read queue? */ } fwrite(gwdb.data, htons(gwdb.count), 1, out); seq++; } breakloop: fclose(out); exit(0); }