1
0
mirror of https://github.com/nmap/nmap.git synced 2026-02-09 15:06:35 +00:00

Added new SEQ.ISR element, removed SEQ.CL, changed calculation of SEQ.SP

This commit is contained in:
fyodor
2006-08-27 02:43:44 +00:00
parent 1f6fbad3dd
commit 87c4dbdf39
6 changed files with 243 additions and 187 deletions

View File

@@ -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 */

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -1426,11 +1426,12 @@ void printosscanoutput(Target *currenths) {
log_write(LOG_XML, "<tcpsequence index=\"%li\" class=\"%s\" difficulty=\"%s\" values=\"%s\" />\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);
}

View File

@@ -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}) {