diff --git a/global_structures.h b/global_structures.h index 5aa4464b9..4f8c48459 100644 --- a/global_structures.h +++ b/global_structures.h @@ -205,7 +205,8 @@ struct timeout_info { struct seq_info { int responses; - int seqclass; /* SEQ_* defines in nmap.h */ + int seqclass; /* SEQ_* defines in nmap.h. This should be removed when + we remove osscan gen1 cruft. */ int ts_seqclass; /* TS_SEQ_* defines in nmap.h */ time_t uptime; /* time of latest system boot (or 0 if unknown ) */ int ipid_seqclass; /* IPID_SEQ_* defines in nmap.h */ diff --git a/nmap-os-db b/nmap-os-db index 1577bfceb..f85ad60d0 100644 --- a/nmap-os-db +++ b/nmap-os-db @@ -1,5 +1,115 @@ -# [DESCRIPTION] +# Nmap OS Fingerprinting 2nd Generation DB. -*- mode: fundamental; -*- +# $Id: nmap-os-fingerprints 3408 2006-05-31 23:01:19Z fyodor $ # +# Contributions to this database are welcome. If Nmap obtains a new +# fingerprint (and test conditions are favorable), it will print out a +# URL you can use to submit the fingerprint. If Nmap guesses wrong, +# please see http://insecure.org/nmap/submit/ . +# +# By submitting fingerprints you are transfering any and all copyright +# interest in the data to Insecure.Com LLC so it can modified, +# incorporated into Nmap, relicensed, etc. +# +# This collection of fingerprint data is (C) 1998-2006 by Insecure.Com +# LLC. It is distributed under the Nmap open source license as +# provided in the COPYING file of the source distribution or at +# http://insecure.org/nmap/data/COPYING . Note that this license +# requires you to license your own work under a compatable open source +# license. If you wish to embed Nmap technology into proprietary +# software, we sell alternative licenses (contact sales@insecure.com). +# Dozens of software vendors already license Nmap technology such as +# host discovery, port scanning, OS detection, and version detection. +# +# For a complete description of Nmap OS detection and the format of +# fingerprints in this file, see http://insecure.org/nmap/osdetect/ + +# Linux 2.6.12-1.1380_FC3 #1 Wed Oct 19 20:34:13 EDT 2005 i686 i686 i386 GNU/Linux +Fingerprint Linux 2.6.12-1.1380_FC3 (Fedora Core 3) +Class Linux | Linux | 2.6.X | general purpose +SEQ(CL=RI%SP=14-17%GCD=<5%TI=Z%II=I%TS=A) +OPS(O1=M5B4ST11NW2%O2=M5B4ST11NW2%O3=M5B4NNT11NW2%O4=M5B4ST11NW2%O5=M5B4ST11NW2%O6=M5B4ST11) +WIN(W1=16A0%W2=16A0%W3=16A0%W4=16A0%W5=16A0%W6=16A0) +ECN(R=Y%DF=Y%T=40%TG=40%W=16D0%O=M5B4NNSNW2%CC=N%Q=) +T1(R=Y%DF=Y%T=40%TG=40%S=O%A=S+%F=AS%RD=0%Q=) +T2(R=N) +T3(R=Y%DF=Y%T=40%TG=40%W=16A0%S=O%A=S+%F=AS%O=M5B4ST11NW2%RD=0%Q=) +T4(R=Y%DF=Y%T=40%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) +T5(R=Y%DF=Y%T=40%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) +T6(R=Y%DF=Y%T=40%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) +T7(R=Y%DF=Y%T=40%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) +U1(DF=N%T=40%TG=40%TOS=C0%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUL=G%RUD=G) +IE(DFI=N%T=40%TG=40%TOSI=S%CD=S%SI=S%DLI=S) + +# Linux 2.6.17-1.2157_FC5 #1 SMP Tue Jul 11 22:53:56 EDT 2006 x86_64 x86_64 x86_64 GNU/Linux +Fingerprint Linux 2.6.17-1.2157_FC (Fedora Core 5) +Class Linux | Linux | 2.6.X | general purpose +SEQ(CL=RI%SP=14-17%GCD=<5%TI=Z%II=I%TS=8) +OPS(O1=M400CST11NW7%O2=M400CST11NW7%O3=M400CNNT11NW7%O4=M400CST11NW7%O5=M400CST11NW7%O6=M400CST11) +WIN(W1=8000%W2=8000%W3=8000%W4=8000%W5=8000%W6=8000) +ECN(R=Y%DF=Y%T=40%TG=40%W=8018%O=M400CNNSNW7%CC=N%Q=) +T1(R=Y%DF=Y%T=40%TG=40%S=O%A=S+%F=AS%RD=0%Q=) +T2(R=N) +T3(R=Y%DF=Y%T=40%TG=40%W=8000%S=O%A=S+%F=AS%O=M400CST11NW7%RD=0%Q=) +T4(R=Y%DF=Y%T=40%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) +T5(R=Y%DF=Y%T=40%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) +T6(R=Y%DF=Y%T=40%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) +T7(R=Y%DF=Y%T=40%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) +U1(DF=N%T=40%TG=40%TOS=C0%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUL=G%RUD=G) +IE(DFI=N%T=40%TG=40%TOSI=S%CD=S%SI=S%DLI=S) + +# Taken on an SMP machine +Fingerprint Microsoft Windows 2000 SP4 +Class Microsoft | Windows | 2000 | general purpose +SEQ(CL=RI%SP=A-E%GCD=<9%TI=I%II=I%SS=S) +OPS(O1=M5B4NW0NNT00NNS%O2=M5B4NW0NNT00NNS%O3=M5B4NW0NNT00%O4=M5B4NW0NNT00NNS%O5=M5B4NW0NNT00NNS%O6=M5B4NNT00NNS) +WIN(W1=FFFF%W2=FFFF%W3=FFFF%W4=FFFF%W5=FFFF%W6=FFFF) +ECN(R=Y%DF=Y%T=80%TG=80%W=FFFF%O=M5B4NW0NNS%CC=N%Q=) +T1(R=Y%DF=Y%T=80%TG=80%S=O%A=S+%F=AS%RD=0%Q=) +T2(R=Y%DF=N%T=80%TG=80%W=0%S=Z%A=S%F=AR%O=%RD=0%Q=) +T3(R=Y%DF=Y%T=80%TG=80%W=FFFF%S=O%A=S+%F=AS%O=M5B4NW0NNT00NNS%RD=0%Q=) +T4(R=Y%DF=N%T=80%TG=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=) +T5(R=Y%DF=N%T=80%TG=80%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) +T6(R=Y%DF=N%T=80%TG=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=) +T7(R=Y%DF=N%T=80%TG=80%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) +U1(DF=N%T=80%TG=80%TOS=0%IPL=38%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUL=G%RUD=G) +IE(DFI=S%T=80%TG=80%TOSI=Z%CD=Z%SI=S%DLI=S) + +Fingerprint Sun Solaris 9 (SPARC) +Class Sun | Solaris | 9 | general purpose +SEQ(CL=RI%SP=D-11%GCD=<7%TI=I%II=I%SS=S%TS=7) +OPS(O1=NNT11M5B4NW0NNS%O2=NNT11M5B4NW0NNS%O3=NNT11M5B4NW0%O4=NNT11M5B4NW0NNS%O5=NNT11M5B4NW0NNS%O6=NNT11M5B4NNS) +WIN(W1=C050%W2=C330%W3=C1CC%W4=C068%W5=C068%W6=C0B7) +ECN(R=Y%DF=Y%T=3C%TG=3C%W=C1E8%O=M5B4NW0NNS%CC=Y%Q=) +T1(R=Y%DF=Y%T=3C%TG=3C%S=O%A=S+%F=AS%RD=0%Q=) +T2(R=N) +T3(R=N) +T4(R=Y%DF=Y%T=40%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) +T5(R=Y%DF=Y%T=40%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) +T6(R=Y%DF=Y%T=40%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) +T7(R=N) +U1(DF=Y%T=FF%TG=FF%TOS=0%IPL=70%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUL=G%RUD=G) +IE(DFI=Y%T=FF%TG=FF%TOSI=S%CD=S%SI=S%DLI=S) + +# Firmware Version 4.30.7, Linux 2.4.20 I believe +Fingerprint Linksys WRT54GL WAP (Linux kernel) +Class Class Linksys | Linux | 2.4.X | WAP +SEQ(CL=RI%SP=12-17%GCD=<5%TI=Z%II=I%TS=7) +OPS(O1=M5B4ST11NW0%O2=M5B4ST11NW0%O3=M5B4NNT11NW0%O4=M5B4ST11NW0%O5=M5B4ST11NW0%O6=M5B4ST11) +WIN(W1=16A0%W2=16A0%W3=16A0%W4=16A0%W5=16A0%W6=16A0) +ECN(R=Y%DF=Y%T=40%TG=40%W=16D0%O=M5B4NNSNW0%CC=N%Q=) +T1(R=Y%DF=Y%T=40%TG=40%S=O%A=S+%F=AS%RD=0%Q=) +T2(R=N) +T3(R=Y%DF=Y%T=40%TG=40%W=16A0%S=O%A=S+%F=AS%O=M5B4ST11NW0%RD=0%Q=) +T4(R=Y%DF=Y%T=40%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) +T5(R=Y%DF=Y%T=40%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) +T6(R=Y%DF=Y%T=40%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) +T7(R=Y%DF=Y%T=40%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) +U1(DF=N%T=40%TG=40%TOS=C0%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUL=G%RUD=G) +IE(DFI=N%T=40%TG=40%TOSI=S%CD=S%SI=S%DLI=S) + + + +# Fingerprints below this level will be removed # FreeBSD 5.5-RELEASE i386 Fingerprint FreeBSD 5.5 diff --git a/nmap.cc b/nmap.cc index 04e01cacf..c7f1dfcef 100644 --- a/nmap.cc +++ b/nmap.cc @@ -1979,7 +1979,7 @@ f --spoof \"/usr/local/bin/pico -z hello.c\" -sS -oN e.log example.com/24\n\n"); char *seqreport1(struct seq_info *seq) { static char report[512]; - snprintf(report, sizeof(report), "TCP Sequence Prediction: Class=%s\n Difficulty=%d (%s)\n", seqclass2ascii(seq->seqclass), seq->index, seqidx2difficultystr1(seq->index)); + snprintf(report, sizeof(report), "TCP Sequence Prediction: Difficulty=%d (%s)\n", seq->index, seqidx2difficultystr1(seq->index)); return report; } @@ -1992,7 +1992,7 @@ const char *seqidx2difficultystr1(unsigned long idx) { char *seqreport(struct seq_info *seq) { static char report[512]; - snprintf(report, sizeof(report), "TCP Sequence Prediction: Class=%s\n Difficulty=%d (%s)\n", seqclass2ascii(seq->seqclass), seq->index, seqidx2difficultystr(seq->index)); + snprintf(report, sizeof(report), "TCP Sequence Prediction: Difficulty=%d (%s)\n", seq->index, seqidx2difficultystr(seq->index)); return report; } diff --git a/osscan2.cc b/osscan2.cc index ad4e7a889..29abe309c 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -1601,7 +1601,8 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) { u32 ts_diffs[NUM_SEQ_SAMPLES]; unsigned long time_usec_diffs[NUM_SEQ_SAMPLES]; int avnum; - double seq_inc_sum = 0; + double seq_stddev = 0; + double seq_rate = 0; unsigned int seq_avg_inc = 0; double avg_ts_hz = 0.0; /* Avg. amount that timestamps incr. each second */ u32 seq_gcd = 1; @@ -1683,113 +1684,77 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) { /* Time to look at the TCP ISN predictability */ if (hss->si.responses >= 4 && o.scan_delay <= 1000) { + + /* First calculate the GCD */ seq_gcd = gcd_n_uint(hss->si.responses -1, seq_diffs); - /* printf("The GCD is %u\n", seq_gcd);*/ - if (seq_gcd) { + + if (!seq_gcd) { + /* Constant ISN */ + seq_rate = 0; + seq_stddev = 0; + hss->si.index = 0; + } else { + + /* First calculate the average counter rate */ + for(i=0; i < hss->si.responses - 1; i++) { + seq_rate += seq_diffs[i] / (TIMEVAL_MSEC_SUBTRACT(hss->seq_send_times[i+1], hss->seq_send_times[i]) / 1000.0); + } + seq_rate /= hss->si.responses - 1; + /* Finally we take a binary logarithm, multiply by 8, and round + to get the final result */ + seq_rate = log(seq_rate) / log(2); + seq_rate = (unsigned int) seq_rate * 8 + 0.5; + + /* Now calculate the predictability index */ for(i=0; i < hss->si.responses - 1; i++) seq_diffs[i] /= seq_gcd; for(i=0; i < hss->si.responses - 1; i++) { - if (MOD_DIFF(hss->si.seqs[i+1],hss->si.seqs[i]) > 50000000) { - hss->si.seqclass = SEQ_TR; - hss->si.index = 0xFF; - /* printf("Target is a TR box\n");*/ - break; - } seq_avg_inc += seq_diffs[i]; } - } - if (seq_gcd == 0) { - hss->si.seqclass = SEQ_CONSTANT; - hss->si.index = 0; - } else if (seq_gcd % 64000 == 0) { - hss->si.seqclass = SEQ_64K; - /* printf("Target is a 64K box\n");*/ - hss->si.index = 1; - } else if (seq_gcd % 800 == 0) { - hss->si.seqclass = SEQ_i800; - /* printf("Target is a i800 box\n");*/ - hss->si.index = 3; - } else if (hss->si.seqclass == SEQ_UNKNOWN) { seq_avg_inc = (unsigned int) ((0.5) + seq_avg_inc / (hss->si.responses - 1)); - /* printf("seq_avg_inc=%u\n", seq_avg_inc);*/ for(i=0; i < hss->si.responses -1; i++) { - /* printf("The difference is %u\n", seq_diffs[i]); - printf("Adding %u^2=%e", MOD_DIFF(seq_diffs[i], seq_avg_inc), pow(MOD_DIFF(seq_diffs[i], seq_avg_inc), 2));*/ /* pow() seems F#@!#$!ed up on some Linux systems so I will not use it for now - seq_inc_sum += pow(MOD_DIFF(seq_diffs[i], seq_avg_inc), 2); */ - - seq_inc_sum += ((double)(MOD_DIFF(seq_diffs[i], seq_avg_inc)) * ((double)MOD_DIFF(seq_diffs[i], seq_avg_inc))); - /* seq_inc_sum += pow(MOD_DIFF(seq_diffs[i], seq_avg_inc), 2);*/ - + seq_stddev += ((double)(MOD_DIFF(seq_diffs[i], seq_avg_inc)) * + ((double)MOD_DIFF(seq_diffs[i], seq_avg_inc))); } - /* printf("The sequence sum is %e\n", seq_inc_sum);*/ - seq_inc_sum /= (hss->si.responses - 1); + /* We divide by ((numelements in seq_diffs) - 1), which is + (si.responses - 2), because that gives a better approx of + std. dev when you're only looking at a subset of whole + population. */ + seq_stddev /= hss->si.responses - 2; - /* Some versions of Linux libc seem to have broken pow ... so we - avoid it */ + /* Next we need to take the square root of this value */ #ifdef LINUX - hss->si.index = (unsigned int) (0.5 + sqrt(seq_inc_sum)); + seq_stddev = (unsigned int) (0.5 + sqrt(seq_stddev)); #else - hss->si.index = (unsigned int) (0.5 + pow(seq_inc_sum, 0.5)); + seq_stddev = (unsigned int) (0.5 + pow(seq_stddev, 0.5)); #endif - /* printf("The sequence index is %d\n", hss->si.index);*/ - hss->si.index = (unsigned int) (0.5 + log((float)hss->si.index)/log(2.0)); - /* printf("The sequence index is %d\n", hss->si.index);*/ - if (hss->si.index < 6) { - hss->si.seqclass = SEQ_TD; - /* printf("Target is a Micro$oft style time dependant box\n");*/ - } - else { - hss->si.seqclass = SEQ_RI; - /* printf("Target is a random incremental box\n");*/ - } + /* Finally we take a binary logarithm, multiply by 8, and round + to get the final result */ + seq_stddev = log(seq_stddev) / log(2); + hss->si.index = (int) (seq_stddev * 8 + 0.5); } + /* Time to generate the SEQ probe line of the fingerprint */ hss->FP_TSeq = (FingerPrint *) safe_zalloc(sizeof(FingerPrint)); hss->FP_TSeq->name = "SEQ"; seq_AVs = (struct AVal *) safe_zalloc(sizeof(struct AVal) * 7); hss->FP_TSeq->results = seq_AVs; avnum = 0; - seq_AVs[avnum].attribute = "CL"; - switch(hss->si.seqclass) { - case SEQ_CONSTANT: - strcpy(seq_AVs[avnum].value, "C"); - seq_AVs[avnum].next = &seq_AVs[avnum+1]; avnum++; - seq_AVs[avnum].attribute= "Val"; - sprintf(seq_AVs[avnum].value, "%X", hss->si.seqs[0]); - break; - case SEQ_64K: - strcpy(seq_AVs[avnum].value, "64K"); - break; - case SEQ_i800: - strcpy(seq_AVs[avnum].value, "i800"); - break; - case SEQ_TD: - strcpy(seq_AVs[avnum].value, "TD"); - seq_AVs[avnum].next = &seq_AVs[avnum+1]; avnum++; - seq_AVs[avnum].attribute="SP"; - sprintf(seq_AVs[avnum].value, "%X", hss->si.index); - seq_AVs[avnum].next = &seq_AVs[avnum+1]; avnum++; - seq_AVs[avnum].attribute= "GCD"; - sprintf(seq_AVs[avnum].value, "%X", seq_gcd); - break; - case SEQ_RI: - strcpy(seq_AVs[avnum].value, "RI"); - seq_AVs[avnum].next = &seq_AVs[avnum+1]; avnum++; - seq_AVs[avnum].attribute="SP"; - sprintf(seq_AVs[avnum].value, "%X", hss->si.index); - seq_AVs[avnum].next = &seq_AVs[avnum+1]; avnum++; - seq_AVs[avnum].attribute= "GCD"; - sprintf(seq_AVs[avnum].value, "%X", seq_gcd); - break; - case SEQ_TR: - strcpy(seq_AVs[avnum].value, "TR"); - break; - } + seq_AVs[avnum].attribute = "SP"; + sprintf(seq_AVs[avnum].value, "%X", hss->si.index); + seq_AVs[avnum].next = &seq_AVs[avnum+1]; avnum++; + seq_AVs[avnum].attribute= "GCD"; + sprintf(seq_AVs[avnum].value, "%X", seq_gcd); + seq_AVs[avnum].next = &seq_AVs[avnum+1]; avnum++; + seq_AVs[avnum].attribute= "ISR"; + sprintf(seq_AVs[avnum].value, "%X", (unsigned int) seq_rate); + + /* Now it is time to deal with IPIDs */ good_tcp_ipid_num = 0; good_icmp_ipid_num = 0; diff --git a/output.cc b/output.cc index 5cc9a8175..680bc2d40 100644 --- a/output.cc +++ b/output.cc @@ -1426,11 +1426,12 @@ void printosscanoutput(Target *currenths) { log_write(LOG_XML, "\n", (long) currenths->seq.index, seqclass2ascii(currenths->seq.seqclass), seqidx2difficultystr(currenths->seq.index), numlst); if (o.verbose) { - if (osscanSys == 1) - log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"%s", seqreport1(&(currenths->seq))); - else if(osscanSys == 2) - log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"%s", seqreport(&(currenths->seq))); - } + if (osscanSys == 1) + log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"%s", seqreport1(&(currenths->seq))); + else if(osscanSys == 2) + log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"%s", seqreport(&(currenths->seq))); + } + log_write(LOG_MACHINE,"\tSeq Index: %d", currenths->seq.index); } diff --git a/scripts/fingerfix.pl b/scripts/fingerfix.pl index eb677c00d..4d4739026 100755 --- a/scripts/fingerfix.pl +++ b/scripts/fingerfix.pl @@ -68,93 +68,79 @@ foreach $line (split /\n/, $printbuf) { } # OK, time for the first real fingerprint line! The SEQ line - elsif ($line =~ /SEQ\(CL=([^%\)]+)(%SP=([^%]+)%GCD=([^%\)]+))?(%Val=([0-9A-F]+))?(%TI=([^%\)]+))?(%II=([^%\)]+))?(%SS=([^%\)]+))?(%TS=([^%\)]+))?\)/) { + elsif ($line =~ /SEQ\(SP=([^%]+)%GCD=([^%\)]+)%ISR=([^%\)]+)(%TI=([^%\)]+))?(%II=([^%\)]+))?(%SS=([^%\)]+))?(%TS=([^%\)]+))?\)/) { # SEQ - $cls = $1; - if ($cls ne "C") { - $sp = $3; - $gcd = hex($4); - } else { $cval=$6; } - $ti = $8; - $ii = $10; - $ss = $12; - $ts = $14; - if (!($fp{seq}{cls} =~ /(^|\|)$cls($|\|)/)) { - if ($fp{seq}{cls}) { - $fp{seq}{cls} = $fp{seq}{cls} . qq^|$cls^; - } else { - $fp{seq}{cls} = $cls; - } + $sp = $1; + $gcd = hex($2); + $isr = $3; + $ti = $5; + $ii = $7; + $ss = $9; + $ts = $11; + + if ($fp{seq}{gcd} =~ /<([0-9A-F]+)/) { + $oldgcd = hex($1); + } else { $oldgcd = 3; } + + $newgcd = max($oldgcd, $gcd * 2 + 3); + $fp{seq}{gcd} = sprintf ("<%X", $newgcd); + + $newhighlim = $newlowlim = -1; + if ($sp =~ /([0-9A-F]+)-([0-9A-F]+)/) { + $newlowlim = hex($1); + $newhighlim = hex($2); + } elsif ($sp =~ /<([0-9A-F]+)/) { + $newhighlim = hex($1); } - if ($cls eq "C") { - print "*******************************************************\n" . - "* WARNING: CONSTANT ISN type -- check if value changes*\n" . - "*******************************************************\n"; - if (!($fp{seq}{cval} =~ /(^|\|)$cval($|\|)/)) { - if ($fp{seq}{cval}) { - $fp{seq}{cval} = $fp{seq}{cval} . qq^|$cval^; - } else { - $fp{seq}{cval} = $cval; - } - } + # print "newhighlim: $newhighlim newlowlim: $newlowlim\n"; + + $oldhighlim = $oldlowlim = 0; + if ($fp{seq}{sp} =~ /([0-9A-F]+)-([0-9A-F]+)/) { + $oldlowlim = hex($1); + $oldhighlim = hex($2); + } elsif ($fp{seq}{sp} =~ /<([0-9A-F]+)/) { + $oldhighlim = hex($1); + } elsif ($fp{seq}{sp} =~ /^([0-9A-F]+)/) { + $oldhighlim = $oldlowlim = hex($1); + } + + # print "oldhighlim: $oldhighlim oldlowlim: $oldlowlim\n"; + + if ($oldlowlim) { + if ($newlowlim != -1) { $newlowlim = max(0, min($oldlowlim, $newlowlim)); } + else { $newlowlim = max(0, min($oldlowlim, hex($sp))); } } else { - if ($fp{seq}{gcd} =~ /<([0-9A-F]+)/) { - $oldgcd = hex($1); - } else { $oldgcd = 3; } - - $newgcd = max($oldgcd, $gcd * 2 + 3); - $fp{seq}{gcd} = sprintf ("<%X", $newgcd); - - $newhighlim = $newlowlim = -1; - if ($sp =~ /([0-9A-F]+)-([0-9A-F]+)/) { - $newlowlim = hex($1); - $newhighlim = hex($2); - } elsif ($sp =~ /<([0-9A-F]+)/) { - $newhighlim = hex($1); - } - - # print "newhighlim: $newhighlim newlowlim: $newlowlim\n"; - - $oldhighlim = $oldlowlim = 0; - if ($fp{seq}{sp} =~ /([0-9A-F]+)-([0-9A-F]+)/) { - $oldlowlim = hex($1); - $oldhighlim = hex($2); - } elsif ($fp{seq}{sp} =~ /<([0-9A-F]+)/) { - $oldhighlim = hex($1); - } elsif ($fp{seq}{sp} =~ /^([0-9A-F]+)/) { - $oldhighlim = $oldlowlim = hex($1); - } - - # print "oldhighlim: $oldhighlim oldlowlim: $oldlowlim\n"; - - if ($oldlowlim) { - if ($newlowlim != -1) { $newlowlim = max(0, min($oldlowlim, $newlowlim)); } - else { $newlowlim = max(0, min($oldlowlim, hex($sp) - 2)); } - } else { - if ($newlowlim == -1) { $newlowlim = max(0, hex($sp) - 2); } - } - - if ($newhighlim == -1) { - $newhighlim = max($oldhighlim, hex($sp) + 2); - } else { - $newhighlim = max($oldhighlim, $newhighlim); - } - - # print "oldhighlim: $oldhighlim oldlowlim: $oldlowlim newhighlim: $newhighlim newlowlim: $newlowlim oldsp: $fp{seq}{sp}"; - - if ($newlowlim eq $newhighlim) { - $fp{seq}{sp} = sprintf("%X", $newhighlim); - } elsif ($newlowlim > 0) { - $fp{seq}{sp} = sprintf("%X-%X", $newlowlim, $newhighlim); - } else { - $fp{seq}{sp} = sprintf("<%X", $newhighlim); - } - - # print " newsp: $fp{seq}{sp}\n"; - + if ($newlowlim == -1) { $newlowlim = max(0, hex($sp)); } } + if ($newhighlim == -1) { + $newhighlim = max($oldhighlim, hex($sp)); + } else { + $newhighlim = max($oldhighlim, $newhighlim); + } + + # print "oldhighlim: $oldhighlim oldlowlim: $oldlowlim newhighlim: $newhighlim newlowlim: $newlowlim oldsp: $fp{seq}{sp}"; + + if ($newlowlim eq $newhighlim) { + $fp{seq}{sp} = sprintf("%X", $newhighlim); + } elsif ($newlowlim > 0) { + $fp{seq}{sp} = sprintf("%X-%X", $newlowlim, $newhighlim); + } else { + $fp{seq}{sp} = sprintf("<%X", $newhighlim); + } + + # print " newsp: $fp{seq}{sp}\n"; + + + if (!($fp{seq}{isr} =~ /(^|\|)$isr($|\|)/)) { + if ($fp{seq}{isr}) { + $fp{seq}{isr} = $fp{seq}{isr} . qq^|$isr^; + } else { + $fp{seq}{isr} = $isr; + } + } + if (!($fp{seq}{ti} =~ /(^|\|)$ti($|\|)/)) { if ($fp{seq}{ti}) { $fp{seq}{ti} = $fp{seq}{ti} . qq^|$ti^; @@ -660,26 +646,19 @@ if ($fp{class}) { print $fp{class}; } else { print "Class \n"; } # SEQ -if ($fp{seq}{cls}) { - print("SEQ(CL=$fp{seq}{cls}"); - if ($fp{seq}{cls} ne "64K" and $fp{seq}{cls} ne "i800" - and $fp{seq}{cls} ne "C") { - if ($fp{seq}{cls} ne "TR") { - if ($fp{seq}{sp}) { - print "%SP=$fp{seq}{sp}"; - } - } - if ($fp{seq}{gcd}) { - print "%GCD=$fp{seq}{gcd}"; - } +if ($fp{seq}{sp}) { + print("SEQ(SP=$fp{seq}{sp}"); + if ($fp{seq}{gcd}) { + print "%GCD=$fp{seq}{gcd}"; } - if ($fp{seq}{cval}) {print "%Val=$fp{seq}{cval}"; } + + if ($fp{seq}{isr}) { print "%ISR=$fp{seq}{isr}"; } if ($fp{seq}{ti}) { print "%TI=$fp{seq}{ti}"; } if ($fp{seq}{ii}) { print "%II=$fp{seq}{ii}"; } if ($fp{seq}{ss}) { print "%SS=$fp{seq}{ss}"; } if ($fp{seq}{ts}) { print "%TS=$fp{seq}{ts}"; } print ")\n"; -} +} # OPS if ($fp{ops}{o1}) {