home *** CD-ROM | disk | FTP | other *** search
/ Steganos Hacker Tools / SHT151.iso / programme / scanner / nmapNTsp1 / Win_2000.exe / nmapNT-src / osscan.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-07-14  |  38.6 KB  |  1,315 lines

  1. #include "osscan.h"
  2.  
  3. extern struct ops o;
  4.  
  5. FingerPrint *get_fingerprint(struct hoststruct *target, struct seq_info *si, 
  6.                  unsigned short *portarray) {
  7.     FingerPrint *FP = NULL, *FPtmp = NULL;
  8.     FingerPrint *FPtests[9];
  9.     struct AVal *seq_AVs;
  10.     int last;
  11.     struct ip *ip;
  12.     struct tcphdr *tcp;
  13.     struct icmp *icmp;
  14.     struct timeval t1,t2;
  15.     int i;
  16.     struct hostent *myhostent = NULL;
  17.     unsigned int localnet, netmask;
  18.     pcap_t *pd;
  19.     char myname[513];
  20.     double temp1=0;
  21.     int rawsd;
  22.     int tries = 0;
  23.     int newcatches;
  24.     int current_port = 0;
  25.     int testsleft;
  26.     int testno;
  27.     int  timeout;
  28.     unsigned int sequence_base;
  29.     unsigned int openport;
  30.     int bytes;
  31.     unsigned int closedport = 31337;
  32.     struct port *tport = NULL;
  33.     char *p;
  34.     int decoy;
  35.     struct bpf_program fcode;
  36.     char err0r[PCAP_ERRBUF_SIZE];
  37.     char filter[512];
  38.     double seq_inc_sum = 0;
  39.     unsigned int  seq_avg_inc = 0;
  40.     struct udpprobeinfo *upi = NULL;
  41.     unsigned int seq_gcd = 1;
  42. //#ifdef WIN32
  43. //    unsigned int seq_diffs[NUM_SEQ_SAMPLES-1];
  44. //#else
  45.         unsigned int seq_diffs[NUM_SEQ_SAMPLES];
  46. //#endif
  47.  
  48.     int ossofttimeout, oshardtimeout;
  49.  
  50.     if (target->timedout) return NULL;
  51.  
  52.     /* Init our fingerprint tests to each be NULL */
  53.     bzero(FPtests, sizeof(FPtests)); 
  54.     get_random_bytes(&sequence_base, sizeof(unsigned int));
  55.     /* Init our raw socket */
  56. #ifdef WIN32
  57.     rawsd=500;
  58. #else
  59.     if ((rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 ) pfatal("socket trobles in get_fingerprint");
  60.     unblock_socket(rawsd);
  61.     broadcast_socket(rawsd);
  62. #endif
  63.  /* Do we have a correct source address? */
  64.     if (!target->source_ip.s_addr) 
  65.     {
  66.         if (gethostname(myname, MAXHOSTNAMELEN) != 0 && !((myhostent = gethostbyname(myname)))) fatal("Cannot get hostname!  Try using -S <my_IP_address> or -e <interface to scan through>\n");
  67.         memcpy(&target->source_ip, myhostent->h_addr_list[0], sizeof(struct in_addr));
  68.         if (o.debugging || o.verbose) log_write(LOG_STDOUT, "We skillfully deduced that your address is %s\n", inet_ntoa(target->source_ip));
  69.     }
  70.     /* Now for the pcap opening nonsense ... */
  71.     /* Note that the snaplen is 152 = 64 byte max IPhdr + 24 byte max link_layer
  72.     * header + 64 byte max TCP header.  Had to up it for UDP test
  73.     */
  74.  
  75.     ossofttimeout = MAX(200000, target->to.timeout);
  76.     oshardtimeout = MAX(500000, 5 * target->to.timeout);
  77.  
  78.     pd = my_pcap_open_live(target->device.name, 650,  (o.spoofsource)? 1 : 0, (ossofttimeout + 500)/ 1000);
  79.  
  80.     if (o.debugging) log_write(LOG_STDOUT, "Wait time is %d\n", (ossofttimeout +500)/1000);
  81.  
  82.     if (pcap_lookupnet(target->device.name, &localnet, &netmask, err0r) < 0) fatal("Failed to lookup device subnet/netmask: %s", err0r);
  83.     p = strdup(inet_ntoa(target->host));
  84.  
  85.     snprintf(filter, sizeof(filter), "(icmp and dst host %s) or (tcp and src host %s and dst host %s)", inet_ntoa(target->source_ip), p, inet_ntoa(target->source_ip));
  86.     free(p);
  87.  /* Due to apparent bug in libpcap */
  88.     if (islocalhost(&(target->host))) filter[0] = '\0';
  89.     if (o.debugging) log_write(LOG_STDOUT, "Packet capture filter: %s\n", filter);
  90.     if (pcap_compile(pd, &fcode, filter, 0, netmask) < 0) fatal("Error compiling our pcap filter: %s\n", pcap_geterr(pd));
  91.     if (pcap_setfilter(pd, &fcode) < 0 ) fatal("Failed to set the pcap filter: %s\n", pcap_geterr(pd));
  92.     /* Lets find an open port to used */
  93.     openport = -1;
  94.     tport = NULL;
  95.     if (target->ports.state_counts_tcp[PORT_OPEN] > 0) 
  96.     { 
  97.         tport = nextport(&target->ports, NULL, IPPROTO_TCP, PORT_OPEN);
  98.         assert(tport);
  99.         openport = tport->portno;
  100.     }
  101.  
  102.     /* Now we should find a closed port */
  103.     if (target->ports.state_counts_tcp[PORT_CLOSED] > 0) 
  104.     {
  105.         tport = nextport(&target->ports, NULL, IPPROTO_TCP, PORT_CLOSED);
  106.         assert(tport);
  107.         closedport = tport->portno;
  108.     } 
  109.     else if (target->ports.state_counts_tcp[PORT_UNFIREWALLED] > 0) 
  110.     {
  111.         /* Well, we will settle for unfiltered */
  112.         tport = nextport(&target->ports, NULL, IPPROTO_TCP, PORT_UNFIREWALLED);
  113.         assert(tport);
  114.         closedport = tport->portno;
  115.     } 
  116.     else 
  117.     {
  118.         closedport = (get_random_uint() % 14781) + 30000;
  119.     }
  120.  
  121.     if (o.verbose && openport != -1) log_write(LOG_STDOUT, "For OSScan assuming that port %d is open and port %d is closed and neither are firewalled\n", openport, closedport);
  122.  
  123.     current_port = o.magic_port + NUM_SEQ_SAMPLES +1;
  124.  
  125.     /* Now lets do the NULL packet technique */
  126.     testsleft = (openport == -1)? 4 : 7;
  127.     FPtmp = NULL;
  128.     /* bzero(FPtests, sizeof(FPtests));*/
  129.     tries = 0;
  130.     do 
  131.     { 
  132.         newcatches = 0;
  133.         if (openport != -1) 
  134.         {
  135.             /* Test 1 */
  136.             if (!FPtests[1]) 
  137.             {
  138.                 if (o.scan_delay) enforce_scan_delay(NULL);
  139.                 send_tcp_raw_decoys(rawsd, &target->host, current_port, openport, sequence_base, 0,TH_BOGUS|TH_SYN, 0,"\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0, &target->device);
  140.             }
  141.      
  142.             /* Test 2 */
  143.             if (!FPtests[2]) 
  144.             {
  145.                 if (o.scan_delay) enforce_scan_delay(NULL);
  146.                 send_tcp_raw_decoys(rawsd, &target->host, current_port +1, openport, sequence_base, 0,0, 0,"\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0, &target->device);
  147.             }
  148.             /* Test 3 */
  149.             if (!FPtests[3]) 
  150.             {     
  151.                 if (o.scan_delay) enforce_scan_delay(NULL);
  152.                 send_tcp_raw_decoys(rawsd, &target->host, current_port +2, openport, sequence_base, 0,TH_SYN|TH_FIN|TH_URG|TH_PUSH, 0,"\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0, &target->device);
  153.             }
  154.  
  155.             /* Test 4 */
  156.             if (!FPtests[4]) 
  157.             {     
  158.                 if (o.scan_delay) enforce_scan_delay(NULL);
  159.                 send_tcp_raw_decoys(rawsd, &target->host, current_port +3, openport, sequence_base, 0,TH_ACK, 0,"\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0, &target->device);
  160.             }
  161.         }
  162.    
  163.         /* Test 5 */
  164.         if (!FPtests[5]) 
  165.         {   
  166.             if (o.scan_delay) enforce_scan_delay(NULL);
  167.             send_tcp_raw_decoys(rawsd, &target->host, current_port +4, closedport, sequence_base, 0,TH_SYN, 0,"\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0, &target->device);
  168.         }
  169.         /* Test 6 */
  170.         if (!FPtests[6]) 
  171.         {   
  172.             if (o.scan_delay) enforce_scan_delay(NULL);
  173.             send_tcp_raw_decoys(rawsd, &target->host, current_port +5, closedport, sequence_base, 0,TH_ACK, 0,"\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0, &target->device);
  174.         }
  175.         /* Test 7 */
  176.         if (!FPtests[7]) 
  177.         {
  178.             if (o.scan_delay) enforce_scan_delay(NULL);   
  179.             send_tcp_raw_decoys(rawsd, &target->host, current_port +6, closedport, sequence_base, 0,TH_FIN|TH_PUSH|TH_URG, 0,"\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0, &target->device);
  180.         }
  181.  
  182.         if (!FPtests[8]) 
  183.         {
  184.             if (o.scan_delay) enforce_scan_delay(NULL);
  185.             upi = send_closedudp_probe(rawsd, &target->host, o.magic_port, closedport,&target->device);
  186.         }
  187.         gettimeofday(&t1, NULL);
  188.         timeout = 0;
  189.         /* Insure we haven't overrun our allotted time ... */
  190.         if (o.host_timeout && (TIMEVAL_MSEC_SUBTRACT(t1, target->host_timeout) >= 0))
  191.         {
  192.             target->timedout = 1;
  193.             goto osscan_timedout;
  194.         }
  195.         while(( ip = (struct ip*) readip_pcap(pd, &bytes, oshardtimeout)) && !timeout) 
  196.         {
  197. //        printf("INPACKET\n");
  198. //        hdump(ip, bytes);
  199.  
  200.             gettimeofday(&t2, NULL);
  201.             if (TIMEVAL_SUBTRACT(t2,t1) > oshardtimeout) 
  202.             {
  203.                 timeout = 1;
  204.             }
  205.             if (o.host_timeout && (TIMEVAL_MSEC_SUBTRACT(t2, target->host_timeout) >= 0))
  206.             {
  207.                 target->timedout = 1;
  208.                 goto osscan_timedout;
  209.             }
  210.             if (bytes < (4 * ip->ip_hl) + 4) continue;
  211.             if (ip->ip_p == IPPROTO_TCP) 
  212.             {
  213.                 tcp = ((struct tcphdr *) (((char *) ip) + 4 * ip->ip_hl));
  214.                 testno = ntohs(tcp->th_dport) - current_port + 1;
  215.                 if (testno <= 0 || testno > 7) continue;
  216.                 if (o.debugging > 1) log_write(LOG_STDOUT, "Got packet for test number %d\n", testno);
  217.                 if (FPtests[testno]) continue;
  218.                 testsleft--;
  219.                 newcatches++;
  220.                 FPtests[testno] = safe_malloc(sizeof(FingerPrint));
  221.                 bzero(FPtests[testno], sizeof(FingerPrint));
  222.                 FPtests[testno]->results = fingerprint_iptcppacket(ip, 265, sequence_base);
  223.                 FPtests[testno]->name = (testno == 1)? "T1" : (testno == 2)? "T2" : (testno == 3)? "T3" : (testno == 4)? "T4" : (testno == 5)? "T5" : (testno == 6)? "T6" : (testno == 7)? "T7" : "PU";
  224.             } 
  225.             else if (ip->ip_p == IPPROTO_ICMP) 
  226.             {
  227.                 icmp = ((struct icmp *)  (((char *) ip) + 4 * ip->ip_hl));
  228.                 /* It must be a destination port unreachable */
  229.                 if (icmp->icmp_type != 3 || icmp->icmp_code != 3) 
  230.                 {
  231.                     /* This ain't no stinking port unreachable! */
  232.                     continue;
  233.                 }
  234.                 if (bytes < ntohs(ip->ip_len)) 
  235.                 {
  236.                     error("We only got %d bytes out of %d on our ICMP port unreachable packet, skipping", bytes, ntohs(ip->ip_len));
  237.                     continue;
  238.                 }
  239.                 if (FPtests[8]) continue;
  240.                 FPtests[8] = safe_malloc(sizeof(FingerPrint));
  241.                 bzero(FPtests[8], sizeof(FingerPrint));
  242.                 FPtests[8]->results = fingerprint_portunreach(ip, upi);
  243.                 if (FPtests[8]->results) 
  244.                 {       
  245.                     FPtests[8]->name = "PU";
  246.                     testsleft--;
  247.                     newcatches++;
  248.                 } 
  249.                 else 
  250.                 {
  251.                     free(FPtests[8]);
  252.                     FPtests[8] = NULL;
  253.                 }
  254.             }
  255.             if (testsleft == 0)break;
  256.         }     
  257.     } while ( testsleft > 0 && (tries++ < 5 && (newcatches || tries == 1)));
  258.  
  259.  
  260.  
  261.  /* First we send our initial NUM_SEQ_SAMPLES SYN packets  */
  262.     if (openport != -1) 
  263.     {
  264.         for(i=1; i <= NUM_SEQ_SAMPLES; i++) 
  265.         {
  266.             if (o.scan_delay) enforce_scan_delay(NULL);
  267.             for(decoy=0; decoy < o.numdecoys; decoy++) 
  268.             {
  269.                 send_tcp_raw_decoys(rawsd, &target->host, o.magic_port+i, openport, sequence_base + i, 0, TH_SYN, 0 , NULL, 0, NULL, 0, &target->device);
  270.                 if (!o.scan_delay) usleep( 5000 + target->to.srtt);
  271.             }
  272.           usleep(10000);
  273.         }
  274.    /* Now we collect  the replies */
  275.         si->responses = 0;
  276.         timeout = 0; 
  277.         gettimeofday(&t1,NULL);
  278.         while(si->responses < NUM_SEQ_SAMPLES && !timeout) 
  279.         { 
  280.             ip = (struct ip*) readip_pcap(pd, &bytes, oshardtimeout);
  281.             gettimeofday(&t2, NULL);
  282.             /* Insure we haven't overrun our allotted time ... */
  283.             if (o.host_timeout && (TIMEVAL_MSEC_SUBTRACT(t2, target->host_timeout) >= 0))
  284.             {
  285.                 target->timedout = 1;
  286.                 goto osscan_timedout;
  287.             }
  288.             if (!ip) 
  289.             { 
  290.                 if (TIMEVAL_SUBTRACT(t2,t1) > ossofttimeout) timeout = 1;
  291.                 continue; 
  292.             } 
  293.             else if (TIMEVAL_SUBTRACT(t2,t1) > oshardtimeout) 
  294.             {
  295. //                timeout = 1;
  296.             }          
  297.             if (bytes < (4 * ip->ip_hl) + 4) continue;
  298.             if (ip->ip_p == IPPROTO_TCP) 
  299.             {
  300.                 tcp = ((struct tcphdr *) (((char *) ip) + 4 * ip->ip_hl));
  301.                 if (ntohs(tcp->th_dport) < o.magic_port || ntohs(tcp->th_dport) - o.magic_port > NUM_SEQ_SAMPLES || ntohs(tcp->th_sport) != openport) 
  302.                 {
  303.                     continue;
  304.                 }
  305.                 if ((tcp->th_flags & TH_RST)) 
  306.                 {
  307.                     /*readtcppacket((char *) ip, ntohs(ip->ip_len));*/     
  308.                     if (si->responses == 0) 
  309.                     {     
  310.                         fprintf(stderr, "WARNING:  RST from port %d -- is this port really open?\n", openport);
  311.                         /* We used to quit in this case, but left-overs from a SYN
  312.                         scan or lame-ass TCP wrappers can cause this! */
  313.                     } 
  314.                     continue;
  315.                 } 
  316.                 else if ((tcp->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) 
  317.                 {
  318.                     /*readtcppacket((char *)ip, ntohs(ip->ip_len));*/
  319.                     si->seqs[si->responses++] = ntohl(tcp->th_seq);
  320.                     if (si->responses > 1) 
  321.                     {
  322.                         seq_diffs[si->responses-2] = MOD_DIFF(ntohl(tcp->th_seq), si->seqs[si->responses-2]);
  323.                     }      
  324.                 }
  325.             }
  326.         }
  327.         if (si->responses >= 4 && o.scan_delay <= 1000) 
  328.         {
  329.             seq_gcd = gcd_n_uint(si->responses -1, seq_diffs);
  330.             /*     printf("The GCD is %u\n", seq_gcd);*/
  331.             if (seq_gcd) 
  332.             {     
  333.                 for(i=0; i < si->responses - 1; i++) seq_diffs[i] /= seq_gcd;
  334.                 for(i=0; i < si->responses - 1; i++) 
  335.                 {     
  336.                     if (MOD_DIFF(si->seqs[i+1],si->seqs[i]) > 50000000) 
  337.                     {
  338.                         si->class = SEQ_TR;
  339.                         si->index = 9999999;
  340.                         /*     printf("Target is a TR box\n");*/
  341.                         break;
  342.                     }    
  343.                     seq_avg_inc += seq_diffs[i];
  344.                 }
  345.             }
  346.             if (seq_gcd == 0) 
  347.             {
  348.                 si->class = SEQ_CONSTANT;
  349.                 si->index = 0;
  350.             } 
  351.             else if (seq_gcd % 64000 == 0) 
  352.             {
  353.                 si->class = SEQ_64K;
  354.                 /*       printf("Target is a 64K box\n");*/
  355.                 si->index = 1;
  356.             } 
  357.             else if (seq_gcd % 800 == 0) 
  358.             {
  359.                 si->class = SEQ_i800;
  360.                 /*       printf("Target is a i800 box\n");*/
  361.                 si->index = 10;
  362.             } 
  363.             else if (si->class == SEQ_UNKNOWN) 
  364.             {
  365.                 
  366.                 seq_avg_inc = (0.5) + seq_avg_inc / (si->responses - 1);
  367.                 /*       printf("seq_avg_inc=%u\n", seq_avg_inc);*/
  368.                 for(i=0; i < si->responses -1; i++)       
  369.                 {
  370.                     /*     printf("The difference is %u\n", seq_diffs[i]);
  371.                     printf("Adding %u^2=%e", MOD_DIFF(seq_diffs[i], seq_avg_inc), pow(MOD_DIFF(seq_diffs[i], seq_avg_inc), 2));*/
  372.                     /* pow() seems F#@!#$!ed up on some Linux systems so I will
  373.                     not use it for now 
  374.                       seq_inc_sum += pow(MOD_DIFF(seq_diffs[i], seq_avg_inc), 2);
  375.                     */     
  376.  
  377.                     seq_inc_sum += ((double)(MOD_DIFF(seq_diffs[i], seq_avg_inc)) * ((double)MOD_DIFF(seq_diffs[i], seq_avg_inc)));
  378.                     /*     seq_inc_sum += pow(MOD_DIFF(seq_diffs[i], seq_avg_inc), 2);*/
  379.                 }
  380.                 /*       printf("The sequence sum is %e\n", seq_inc_sum);*/
  381.                 seq_inc_sum /= (si->responses - 1);
  382.                 /* Some versions of Linux libc seem to have broken pow ... so we
  383.                 avoid it */
  384.  
  385.  
  386. //                temp1 = (sqrt(seq_inc_sum));
  387.  
  388.                 si->index = (unsigned int) (0.5 + pow(seq_inc_sum, 0.5));
  389.  
  390.                 /*       printf("The sequence index is %d\n", si->index);*/
  391.                 if (si->index < 75) 
  392.                 {
  393.                     si->class = SEQ_TD;
  394.                     /*     printf("Target is a Micro$oft style time dependant box\n");*/
  395.                 }
  396.                 else 
  397.                 {
  398.                     si->class = SEQ_RI;
  399.                     /*     printf("Target is a random incremental box\n");*/
  400.                 }
  401.             }
  402.             FPtests[0] = safe_malloc(sizeof(FingerPrint));
  403.             bzero(FPtests[0], sizeof(FingerPrint));
  404.             FPtests[0]->name = "TSeq";
  405.             seq_AVs = safe_malloc(sizeof(struct AVal) * 3);
  406.             bzero(seq_AVs, sizeof(struct AVal) * 3);
  407.             FPtests[0]->results = seq_AVs;
  408.             seq_AVs[0].attribute = "Class";
  409.             switch(si->class) 
  410.             {
  411.                 case SEQ_CONSTANT:
  412.                     strcpy(seq_AVs[0].value, "C");
  413.                     seq_AVs[0].next = &seq_AVs[1];
  414.                     seq_AVs[1].attribute= "Val";     
  415.                     sprintf(seq_AVs[1].value, "%X", si->seqs[0]);
  416.                     break;
  417.                 case SEQ_64K:
  418.                     strcpy(seq_AVs[0].value, "64K");      
  419.                     break;
  420.                 case SEQ_i800:
  421.                     strcpy(seq_AVs[0].value, "i800");
  422.                     break;
  423.                 case SEQ_TD:
  424.                     strcpy(seq_AVs[0].value, "TD");
  425.                     seq_AVs[0].next = &seq_AVs[1];
  426.                     seq_AVs[1].attribute= "gcd";     
  427.                     sprintf(seq_AVs[1].value, "%X", seq_gcd);
  428.                     seq_AVs[1].next = &seq_AVs[2];
  429.                     seq_AVs[2].attribute="SI";
  430.                     sprintf(seq_AVs[2].value, "%X", si->index);
  431.                     break;
  432.                 case SEQ_RI:
  433.                     strcpy(seq_AVs[0].value, "RI");
  434.                     seq_AVs[0].next = &seq_AVs[1];
  435.                     seq_AVs[1].attribute= "gcd";     
  436.                     sprintf(seq_AVs[1].value, "%X", seq_gcd);
  437.                     seq_AVs[1].next = &seq_AVs[2];
  438.                     seq_AVs[2].attribute="SI";
  439.                     sprintf(seq_AVs[2].value, "%X", si->index);
  440.                     break;
  441.                 case SEQ_TR:
  442.                     strcpy(seq_AVs[0].value, "TR");
  443.                     break;
  444.             }
  445.         }
  446.         else 
  447.         {
  448.             log_write(LOG_STDOUT|LOG_NORMAL|LOG_SKID,"Insufficient responses for TCP sequencing (%d), OS detection will be MUCH less reliable\n", si->responses);
  449.         }
  450.     } 
  451.     else 
  452.     {
  453.     }
  454.     for(i=0; i < 9; i++) 
  455.     {
  456.         if (i > 0 && !FPtests[i] && ((openport != -1) || i > 4)) 
  457.         {
  458.             /* We create a Resp (response) attribute with value of N (no) because
  459.             it is important here to note whether responses were or were not 
  460.             received */
  461.             FPtests[i] = safe_malloc(sizeof(FingerPrint));
  462.             bzero(FPtests[i], sizeof(FingerPrint));
  463.             seq_AVs = safe_malloc(sizeof(struct AVal));
  464.             seq_AVs->attribute = "Resp";
  465.             strcpy(seq_AVs->value, "N");
  466.             seq_AVs->next = NULL;
  467.             FPtests[i]->results = seq_AVs;
  468.             FPtests[i]->name =  (i == 1)? "T1" : (i == 2)? "T2" : (i == 3)? "T3" : (i == 4)? "T4" : (i == 5)? "T5" : (i == 6)? "T6" : (i == 7)? "T7" : "PU";
  469.         }
  470.     }
  471.     last = -1;
  472.     FP = NULL;
  473.     for(i=0; i < 9 ; i++) 
  474.     {
  475.         if (!FPtests[i]) continue; 
  476.         if (!FP) FP = FPtests[i];
  477.         if (last > -1) 
  478.         {
  479.             FPtests[last]->next = FPtests[i];    
  480.         }
  481.         last = i;
  482.     }
  483.     if (last) FPtests[last]->next = NULL;
  484.     osscan_timedout:
  485.     if (target->timedout) FP = NULL;
  486.     close(rawsd);
  487.     pcap_close(pd);
  488.     return FP;
  489. }
  490.  
  491.  
  492. struct AVal *fingerprint_iptcppacket(struct ip *ip, int mss, unsigned int syn) {
  493.   struct AVal *AVs;
  494.   int length;
  495.   int opcode;
  496.   unsigned short tmpshort;
  497.   char *p,*q;
  498.   struct tcphdr *tcp = ((struct tcphdr *) (((char *) ip) + 4 * ip->ip_hl));
  499.  
  500.   AVs = malloc(6 * sizeof(struct AVal));
  501.  
  502.   /* Link them together */
  503.   AVs[0].next = &AVs[1];
  504.   AVs[1].next = &AVs[2];
  505.   AVs[2].next = &AVs[3];
  506.   AVs[3].next = &AVs[4];
  507.   AVs[4].next = &AVs[5];
  508.   AVs[5].next = NULL;
  509.  
  510.   /* First we give the "response" flag to say we did actually receive
  511.      a packet -- this way we won't match a template with Resp=N */
  512.   AVs[0].attribute = "Resp";
  513.   strcpy(AVs[0].value, "Y");
  514.  
  515.  
  516.   /* Next we check whether the Don't Fragment bit is set */
  517.   AVs[1].attribute = "DF";
  518.   if(ntohs(ip->ip_off) & 0x4000) {
  519.     strcpy(AVs[1].value,"Y");
  520.   } else strcpy(AVs[1].value, "N");
  521.  
  522.   /* Now we do the TCP Window size */
  523.   AVs[2].attribute = "W";
  524.   sprintf(AVs[2].value, "%hX", ntohs(tcp->th_win));
  525.  
  526.   /* Time for the ACK, the codes are:
  527.      S   = same as syn
  528.      S++ = syn + 1
  529.      O   = other
  530.   */
  531.   AVs[3].attribute = "ACK";
  532.   if (ntohl(tcp->th_ack) == syn + 1)
  533.     strcpy(AVs[3].value, "S++");
  534.   else if (ntohl(tcp->th_ack) == syn) 
  535.     strcpy(AVs[3].value, "S");
  536.   else strcpy(AVs[3].value, "O");
  537.     
  538.   /* Now time for the flags ... they must be in this order:
  539.      B = Bogus (64, not a real TCP flag)
  540.      U = Urgent
  541.      A = Acknowledgement
  542.      P = Push
  543.      R = Reset
  544.      S = Synchronize
  545.      F = Final
  546.   */
  547.   AVs[4].attribute = "Flags";
  548.   p = AVs[4].value;
  549.   if (tcp->th_flags & TH_BOG) *p++ = 'B';
  550.   if (tcp->th_flags & TH_URG) *p++ = 'U';
  551.   if (tcp->th_flags & TH_ACK) *p++ = 'A';
  552.   if (tcp->th_flags & TH_PUSH) *p++ = 'P';
  553.   if (tcp->th_flags & TH_RST) *p++ = 'R';
  554.   if (tcp->th_flags & TH_SYN) *p++ = 'S';
  555.   if (tcp->th_flags & TH_FIN) *p++ = 'F';
  556.   *p++ = '\0';
  557.  
  558.   /* Now for the TCP options ... */
  559.   AVs[5].attribute = "Ops";
  560.   p = AVs[5].value;
  561.   /* Partly swiped from /usr/src/linux/net/ipv4/tcp_input.c in Linux kernel */
  562.   length = (tcp->th_off * 4) - sizeof(struct tcphdr);
  563.   q = ((char *)tcp) + sizeof(struct tcphdr);
  564.  
  565.   while(length > 0) {
  566.     opcode=*q++;
  567.     length--;
  568.     if (!opcode) {
  569.       *p++ = 'L'; /* End of List */
  570.       break;
  571.     } else if (opcode == 1) {
  572.       *p++ = 'N'; /* No Op */
  573.     } else if (opcode == 2) {
  574.       *p++ = 'M'; /* MSS */
  575.       q++;
  576.       memcpy(&tmpshort, q, sizeof(unsigned short));
  577.       if(ntohs(tmpshort) == mss)
  578.     *p++ = 'E'; /* Echoed */
  579.       q += 2;
  580.       length -= 3;
  581.     } else if (opcode == 3) { /* Window Scale */
  582.       *p++ = 'W';
  583.       q += 2;
  584.       length -= 2;
  585.     } else if (opcode == 8) { /* Timestamp */
  586.       *p++ = 'T';
  587.       q += 9;
  588.       length -= 9;
  589.     }
  590.   }
  591.   *p++ = '\0';
  592.   return AVs;
  593. }
  594.  
  595. FingerPrint **match_fingerprint(FingerPrint *FP, int *matches_found) {
  596.   static FingerPrint *matches[15];
  597.   int max_matches = 14;
  598.   FingerPrint *current_os;
  599.   FingerPrint *current_test;
  600.   struct AVal *tst;
  601.   int match = 1;
  602.   int i,j;
  603.  
  604.   *matches_found = 0;
  605.  
  606.   if (!FP) {
  607.     matches[0] = NULL;
  608.     return matches;
  609.   }
  610.  
  611.   for(i = 0; o.reference_FPs[i]; i++) {
  612.     current_os = o.reference_FPs[i];
  613.     match = 1;
  614.     for(current_test = current_os; current_test; current_test = current_test->next) 
  615.       {
  616.     tst = gettestbyname(FP, current_test->name);
  617.     if (tst) {
  618.       match = AVal_match(current_test->results, tst);
  619.       if (!match) break;
  620.     }
  621.       }
  622.     if (match) {
  623.       /* Yeah, we found a match! */
  624.       if ((*matches_found) >= max_matches -1) {
  625.     matches[0] = NULL;
  626.     *matches_found = ETOOMANYMATCHES;
  627.     return matches;
  628.       }
  629.       /* Lets make sure we haven't found a match with this exact
  630.      name before */
  631.       for(j=0; j < *matches_found; j++) {
  632.     if (strcmp(current_os->OS_name, matches[j]->OS_name) == 0)
  633.       break;
  634.       }
  635.       if (j == *matches_found)
  636.     matches[(*matches_found)++] = current_os;
  637.     }
  638.   }
  639.   matches[(*matches_found)] = NULL;
  640.   return matches;
  641. }
  642.  
  643. struct AVal *gettestbyname(FingerPrint *FP, char *name) {
  644.  
  645.   if (!FP) return NULL;
  646.   do {
  647.     if (!strcmp(FP->name, name))
  648.       return FP->results;
  649.     FP = FP->next;
  650.   } while(FP);
  651.   return NULL;
  652. }
  653.  
  654. struct AVal *getattrbyname(struct AVal *AV, char *name) {
  655.  
  656.   if (!AV) return NULL;
  657.   do {
  658.     if (!strcmp(AV->attribute, name))
  659.       return AV;
  660.     AV = AV->next;
  661.   } while(AV);
  662.   return NULL;
  663. }
  664.  
  665. int AVal_match(struct AVal *reference, struct AVal *fprint) {
  666.   struct AVal *current_ref;
  667.   struct AVal *current_fp;
  668.   unsigned int number;
  669.   unsigned int val;
  670.   char *p, *q;  /* OHHHH YEEEAAAAAHHHH!#!@#$!% */
  671.   char valcpy[512];
  672.   char *endptr;
  673.   int andexp, orexp, expchar, numtrue;
  674.  
  675.   for(current_ref = reference; current_ref; current_ref = current_ref->next) {
  676.     current_fp = getattrbyname(fprint, current_ref->attribute);    
  677.     if (!current_fp) continue;
  678.     /* OK, we compare an attribute value in  cinrrent_fp->value to a 
  679.      potentially large expression in current_ref->value.  The syntax uses
  680.     < (less than), > (greather than), + (non-zero), | (or), and & (and) 
  681.     No parenthesis are allowed and an expression cannot have | AND & */
  682.     numtrue = andexp = orexp = 0;
  683.     Strncpy(valcpy, current_ref->value, sizeof(valcpy));
  684.     p = valcpy;
  685.     if (strchr(current_ref->value, '|')) {
  686.       orexp = 1; expchar = '|';
  687.     } else {
  688.       andexp = 1; expchar = '&';
  689.     }
  690.     do {
  691.       q = strchr(p, expchar);
  692.       if (q) *q = '\0';
  693.       if (!strcmp(p, "+")) {
  694.     if (!*current_fp->value) { if (andexp) return 0; }
  695.     else {
  696.       val = strtol(current_fp->value, &endptr, 16);
  697.       if (val == 0 || *endptr) { if (andexp) return 0; }
  698.       else { numtrue++; if (orexp) break; }
  699.     }
  700.       } else if (*p == '<' && isxdigit((int) p[1])) {
  701.     if (!*current_fp->value) { if (andexp) return 0; }
  702.     number = strtol(p + 1, &endptr, 16);
  703.     val = strtol(current_fp->value, &endptr, 16);
  704.     if (val >= number || *endptr) { if (andexp) return 0; }
  705.     else { numtrue++; if (orexp) break; }
  706.       } else if (*p == '>' && isxdigit((int) p[1])) {
  707.     if (!*current_fp->value) { if (andexp) return 0; }
  708.     number = strtol(p + 1, &endptr, 16);
  709.     val = strtol(current_fp->value, &endptr, 16);
  710.     if (val <= number || *endptr) { if (andexp) return 0; }
  711.     else { numtrue++; if (orexp) break; }
  712.       }
  713.       else {
  714.     if (strcmp(p, current_fp->value))
  715.       { if (andexp) return 0; }
  716.     else { numtrue++; if (orexp) break; }
  717.       }
  718.       if (q) p = q + 1;
  719.     } while(q);
  720.       if (numtrue == 0) return 0;
  721.     /* Whew, we made it past one Attribute alive , on to the next! */
  722.   }
  723.   return 1;  
  724. }
  725.  
  726. void freeFingerPrint(FingerPrint *FP) {
  727. FingerPrint *currentFP;
  728. FingerPrint *nextFP;
  729.  
  730. if (!FP) return;
  731.  
  732.  for(currentFP = FP; currentFP; currentFP = nextFP) {
  733.    nextFP = currentFP->next;
  734.    if (currentFP->results)
  735.      free(currentFP->results);
  736.    free(currentFP);
  737.  }
  738. return;
  739. }
  740.  
  741.  
  742. int os_scan(struct hoststruct *target, unsigned short *portarray) {
  743. FingerPrint **FP_matches[3];
  744. int FP_nummatches[3];
  745. struct seq_info si[3];
  746. int try;
  747. int i;
  748. struct timeval now;
  749.  
  750.  if (target->timedout)
  751.    return 1;
  752.  
  753.  bzero(si, sizeof(si));
  754.  if (target->ports.state_counts_tcp[PORT_OPEN] == 0)
  755.    log_write(LOG_STDOUT|LOG_NORMAL|LOG_SKID,"Warning:  No TCP ports found open on this machine, OS detection will be MUCH less reliable\n", si->responses);
  756.  
  757.  for(try=0; try < 3; try++) {
  758.    if (o.host_timeout) {   
  759.      gettimeofday(&now, NULL);
  760.      if (target->timedout || TIMEVAL_MSEC_SUBTRACT(now, target->host_timeout) >= 0)
  761.        {
  762.      target->timedout = 1;
  763.      return 1;
  764.        }
  765.    }
  766.    target->FPs[try] = get_fingerprint(target, &si[try], portarray); 
  767.    if (target->timedout)
  768.      return 1;
  769.    FP_matches[try] = match_fingerprint(target->FPs[try], &(FP_nummatches[try]));
  770.    if (FP_matches[try][0]) 
  771.      break;
  772.    if (try < 2)
  773.      sleep(2);
  774.  }
  775.  target->numFPs = (try == 3)? 3 : try + 1;
  776.  memcpy(&(target->seq), &si[target->numFPs - 1], sizeof(struct seq_info));
  777.  if (try != 3) {
  778.    if (try > 0) {
  779.      error("WARNING: OS didn't match until the %d try", try + 1);
  780.      for(i=0; i < try; i++) {
  781.        if (target->FPs[i]) {
  782.      if (o.debugging)
  783.        error("Failed match #%d (0-based):\n%s", i, fp2ascii(target->FPs[i]));
  784.      freeFingerPrint(target->FPs[i]);
  785.      target->FPs[i] = NULL;
  786.        }
  787.      }
  788.      target->FPs[0] = target->FPs[try];
  789.      target->FPs[try] = NULL;
  790.      try = 0;
  791.      target->numFPs = 1;
  792.    }
  793.    target->goodFP = 0;
  794.  } else  {
  795.    /* Uh-oh, we were NEVER able to match, lets take
  796.       the first fingerprint */
  797.    for(try=0; try < 3; try++) {   
  798.      if (FP_nummatches[try] == 0) {   
  799.        target->goodFP = ENOMATCHESATALL;
  800.        break;
  801.      }
  802.    }
  803.    if (try == 3) target->goodFP = ETOOMANYMATCHES;
  804.  }
  805.  
  806.  if (target->goodFP > 0)
  807.    target->FP_matches = FP_matches[target->goodFP];
  808.  else target->FP_matches = FP_matches[0];
  809.  return 1;
  810. }
  811.  
  812. char *mergeFPs(FingerPrint *FPs[], int numFPs) {
  813. static char str[10240];
  814. struct AVal *AV;
  815. FingerPrint *currentFPs[32];
  816. char *p = str;
  817. int i;
  818. int changed;
  819.  
  820. if (numFPs <=0) return "(None)";
  821. if (numFPs > 32) return "(Too many)";
  822.   
  823. bzero(str, sizeof(str));
  824. for(i=0; i < numFPs; i++) {
  825.   if (FPs[i] == NULL) {
  826.     fatal("mergeFPs was handed a pointer to null fingerprint");
  827.   }
  828.   currentFPs[i] = FPs[i];
  829. }
  830.  
  831. do {
  832.   changed = 0;
  833.   for(i = 0; i < numFPs; i++) {
  834.     if (currentFPs[i]) {
  835.       /* This junk means do not print this one if the next
  836.      one is the same */
  837.       if (i == numFPs - 1 || !currentFPs[i+1] ||
  838.       strcmp(currentFPs[i]->name, currentFPs[i+1]->name) != 0 ||
  839.       AVal_match(currentFPs[i]->results,currentFPs[i+1]->results) ==0)
  840.     {
  841.       changed = 1;
  842.       strcpy(p, currentFPs[i]->name);
  843.       p += strlen(currentFPs[i]->name);
  844.       *p++='(';
  845.       for(AV = currentFPs[i]->results; AV; AV = AV->next) {
  846.         strcpy(p, AV->attribute);
  847.         p += strlen(AV->attribute);
  848.         *p++='=';
  849.         strcpy(p, AV->value);
  850.         p += strlen(AV->value);
  851.         *p++ = '%';
  852.       }
  853.       if(*(p-1) != '(')
  854.         p--; /* Kill the final & */
  855.       *p++ = ')';
  856.       *p++ = '\n';
  857.     }
  858.       /* Now prepare for the next one */
  859.       currentFPs[i] = currentFPs[i]->next;
  860.     }
  861.   }
  862. } while(changed);
  863.  
  864. *p = '\0';
  865. return str;
  866. }
  867.  
  868.  
  869. char *fp2ascii(FingerPrint *FP) {
  870. static char str[2048];
  871. FingerPrint *current;
  872. struct AVal *AV;
  873. char *p = str;
  874. int len;
  875. bzero(str, sizeof(str));
  876.  
  877. if (!FP) return "(None)";
  878.  
  879. if(*(FP->OS_name)) {
  880.   len = snprintf(str, 128, "FingerPrint  %s\n", FP->OS_name);
  881.   if (len < 0) fatal("OS name too long");
  882.   p += len;
  883. }
  884.  
  885. for(current = FP; current ; current = current->next) {
  886.   strcpy(p, current->name);
  887.   p += strlen(current->name);
  888.   *p++='(';
  889.   for(AV = current->results; AV; AV = AV->next) {
  890.     strcpy(p, AV->attribute);
  891.     p += strlen(AV->attribute);
  892.     *p++='=';
  893.     strcpy(p, AV->value);
  894.     p += strlen(AV->value);
  895.     *p++ = '%';
  896.   }
  897.   if(*(p-1) != '(')
  898.     p--; /* Kill the final & */
  899.   *p++ = ')';
  900.   *p++ = '\n';
  901. }
  902. *p = '\0';
  903. return str;
  904. }
  905.  
  906. FingerPrint **parse_fingerprint_reference_file() {
  907. FingerPrint **FPs;
  908. FingerPrint *current;
  909. FILE *fp;
  910. char filename[256];
  911. char line[1024];
  912. int numrecords = 0;
  913. int lineno = 0;
  914. char *p, *q; /* OH YEAH!!!! */
  915.  
  916. /* If you need more than 2048 fingerprints, tough */
  917.  FPs = safe_malloc(sizeof(FingerPrint *) * 2048); 
  918.  bzero(FPs, sizeof(FingerPrint *) * 2048);
  919.  
  920. if (nmap_fetchfile(filename, sizeof(filename), "nmap-os-fingerprints") == -1){
  921.   fatal("OS scan requested but I cannot find nmap-os-fingerprints file.  It should be in %s, ~/.nmap/ or .", NMAPDATADIR);
  922. }
  923.  
  924. fp = fopen(filename, "r");
  925.  
  926.  top:
  927. while(fgets(line, sizeof(line), fp)) {  
  928.   lineno++;
  929.   /* Read in a record */
  930.   if (*line == '\n' || *line == '#')
  931.     continue;
  932.  
  933.  fparse:
  934.  
  935.   if (strncasecmp(line, "FingerPrint", 11)) {
  936.     fprintf(stderr, "Parse error on line %d of nmap-os-fingerprints file: %s\n", lineno, line);
  937.     continue;
  938.   }
  939.   p = line + 12;
  940.   while(*p && isspace((int) *p)) p++;
  941.   if (!*p) {
  942.     fprintf(stderr, "Parse error on line %d of nmap-os-fingerprints file: %s\n", lineno, line);    
  943.     continue;
  944.   }
  945.   FPs[numrecords] = safe_malloc(sizeof(FingerPrint));
  946.   bzero(FPs[numrecords], sizeof(FingerPrint));
  947.   q = FPs[numrecords]->OS_name;
  948.   while(*p && *p != '\n' && *p != '#') {
  949.     *q++ = *p++;
  950.   }
  951.  
  952.   q--;
  953.  
  954.   /* Now let us back up through any ending spaces */
  955.   while(isspace((int)*q)) 
  956.     q--;
  957.  
  958.   /* Terminate the sucker */
  959.   q++; 
  960.   *q = '\0';
  961.  
  962.   current = FPs[numrecords];
  963.   /* Now we read the fingerprint itself */
  964.   while(fgets(line, sizeof(line), fp)) {
  965.     lineno++;
  966.     if (*line == '#')
  967.       continue;
  968.     if (*line == '\n')
  969.       break;
  970.     if (!strncmp(line, "FingerPrint",11)) {
  971.       goto fparse;
  972.     }
  973.     p = line;
  974.     q = strchr(line, '(');
  975.     if (!q) {
  976.       fprintf(stderr, "Parse error on line %d of nmap-os-fingerprints file: %s\n", lineno, line);
  977.       goto top;
  978.     }
  979.     *q = '\0';
  980.     if(current->name) {
  981.       current->next = safe_malloc(sizeof(FingerPrint));
  982.       current = current->next;
  983.       bzero(current, sizeof(FingerPrint));
  984.     }
  985.     current->name = strdup(p);
  986.     p = q+1;
  987.     *q = '(';
  988.     q = strchr(p, ')');
  989.     if (!q) {
  990.       fprintf(stderr, "Parse error on line %d of nmap-os-fingerprints file: %s\n", lineno, line);
  991.       goto top;
  992.     }
  993.     *q = '\0';
  994.     current->results = str2AVal(p);
  995.   }
  996.   /* printf("Read in fingerprint:\n%s\n", fp2ascii(FPs[numrecords])); */
  997.   numrecords++;
  998. }
  999. fclose(fp);
  1000. FPs[numrecords] = NULL; 
  1001. return FPs;
  1002. }
  1003.  
  1004. struct AVal *str2AVal(char *str) {
  1005. int i = 1;
  1006. int count = 1;
  1007. char *q = str, *p=str;
  1008. struct AVal *AVs;
  1009. if (!*str) return NULL;
  1010.  
  1011. /* count the AVals */
  1012. while((q = strchr(q, '%'))) {
  1013.   count++;
  1014.   q++;
  1015. }
  1016.  
  1017. AVs = safe_malloc(count * sizeof(struct AVal));
  1018. bzero(AVs, sizeof(struct AVal) * count);
  1019. for(i=0; i < count; i++) {
  1020.   q = strchr(p, '=');
  1021.   if (!q) {
  1022.     fatal("Parse error with AVal string (%s) in nmap-os-fingerprints file", str);
  1023.   }
  1024.   *q = '\0';
  1025.   AVs[i].attribute = strdup(p);
  1026.   p = q+1;
  1027.   if (i != count - 1) {
  1028.     q = strchr(p, '%');
  1029.     if (!q) {
  1030.       fatal("Parse error with AVal string (%s) in nmap-os-fingerprints file", str);
  1031.     }
  1032.     *q = '\0';
  1033.     AVs[i].next = &AVs[i+1];
  1034.   }
  1035.   strcpy(AVs[i].value, p); 
  1036.   p = q + 1;
  1037. }
  1038. return AVs;
  1039. }
  1040.  
  1041.  
  1042. struct udpprobeinfo *send_closedudp_probe(int sd, struct in_addr *victim,
  1043. unsigned short sport, unsigned short dport,struct interface_info *ainfo) {
  1044.  
  1045. static struct udpprobeinfo upi;
  1046. static int myttl = 0;
  1047. static unsigned char patternbyte = 0;
  1048. static unsigned short id = 0; 
  1049. char packet[328]; /* 20 IP hdr + 8 UDP hdr + 300 data */
  1050. struct ip *ip = (struct ip *) packet;
  1051. udphdr_bsd *udp = (udphdr_bsd *) (packet + sizeof(struct ip));
  1052. struct in_addr *source;
  1053. int datalen = 300;
  1054. char *data = packet + 28;
  1055. unsigned short realcheck; /* the REAL checksum */
  1056. int res;
  1057. struct sockaddr_in sock;
  1058. int decoy;
  1059. struct pseudo_udp_hdr {
  1060.   struct in_addr source;
  1061.   struct in_addr dest;        
  1062.   char zero;
  1063.   char proto;        
  1064.   unsigned short length;
  1065. } *pseudo = (struct pseudo_udp_hdr *) ((char *)udp - 12) ;
  1066.  
  1067. if (!patternbyte) patternbyte = (get_random_uint() % 60) + 65;
  1068. memset(data, patternbyte, datalen);
  1069.  
  1070. while(!id) id = get_random_uint();
  1071.  
  1072. /* check that required fields are there and not too silly */
  1073. if ( !victim || !sport || !dport || sd < 0) {
  1074.   fprintf(stderr, "send_udp_raw: One or more of your parameters suck!\n");
  1075.   return NULL;
  1076. }
  1077.  
  1078. if (!myttl)  myttl = (time(NULL) % 14) + 51;
  1079. /* It was a tough decision whether to do this here for every packet
  1080.    or let the calling function deal with it.  In the end I grudgingly decided
  1081.    to do it here and potentially waste a couple microseconds... */
  1082. sethdrinclude(sd); 
  1083.  
  1084.  for(decoy=0; decoy < o.numdecoys; decoy++) {
  1085.    source = &o.decoys[decoy];
  1086.  
  1087.    /*do we even have to fill out this damn thing?  This is a raw packet, 
  1088.      after all */
  1089.    sock.sin_family = AF_INET;
  1090.    sock.sin_port = htons(dport);
  1091.    sock.sin_addr.s_addr = victim->s_addr;
  1092.  
  1093.  
  1094.    bzero((char *) packet, sizeof(struct ip) + sizeof(udphdr_bsd));
  1095.  
  1096.    udp->uh_sport = htons(sport);
  1097.    udp->uh_dport = htons(dport);
  1098.    udp->uh_ulen = htons(8 + datalen);
  1099.  
  1100.    /* Now the psuedo header for checksuming */
  1101.    pseudo->source.s_addr = source->s_addr;
  1102.    pseudo->dest.s_addr = victim->s_addr;
  1103.    pseudo->proto = IPPROTO_UDP;
  1104.    pseudo->length = htons(sizeof(udphdr_bsd) + datalen);
  1105.  
  1106.    /* OK, now we should be able to compute a valid checksum */
  1107. realcheck = in_cksum((unsigned short *)pseudo, 20 /* pseudo + UDP headers */ +
  1108.  datalen);
  1109. #if STUPID_SOLARIS_CHECKSUM_BUG
  1110.  udp->uh_sum = sizeof(struct udphdr) + datalen;
  1111. #else
  1112. udp->uh_sum = realcheck;
  1113. #endif
  1114.  
  1115.    /* Goodbye, pseudo header! */
  1116.    bzero(pseudo, 12);
  1117.  
  1118.    /* Now for the ip header */
  1119.    ip->ip_v = 4;
  1120.    ip->ip_hl = 5;
  1121.    ip->ip_len = BSDFIX(sizeof(struct ip) + sizeof(udphdr_bsd) + datalen);
  1122.    ip->ip_id = id;
  1123.    ip->ip_ttl = myttl;
  1124.    ip->ip_p = IPPROTO_UDP;
  1125.    ip->ip_src.s_addr = source->s_addr;
  1126.    ip->ip_dst.s_addr= victim->s_addr;
  1127.  
  1128.    upi.ipck = in_cksum((unsigned short *)ip, sizeof(struct ip));
  1129.  
  1130.    ip->ip_sum = upi.ipck;
  1131.  
  1132.  
  1133.    /* OK, now if this is the real she-bang (ie not a decoy) then
  1134.       we stick all the inph0 in our upi */
  1135.    if (decoy == o.decoyturn) {   
  1136.      upi.iptl = 28 + datalen;
  1137.      upi.ipid = id;
  1138.      upi.sport = sport;
  1139.      upi.dport = dport;
  1140.      upi.udpck = realcheck;
  1141.      upi.udplen = 8 + datalen;
  1142.      upi.patternbyte = patternbyte;
  1143.      upi.target.s_addr = ip->ip_dst.s_addr;
  1144.    }
  1145.    if (TCPIP_DEBUGGING > 1) {
  1146.      log_write(LOG_STDOUT, "Raw UDP packet creation completed!  Here it is:\n");
  1147.      readudppacket(packet,1);
  1148.    }
  1149.    if (TCPIP_DEBUGGING > 1)     
  1150.      log_write(LOG_STDOUT, "\nTrying sendto(%d , packet, %d, 0 , %s , %d)\n",
  1151.         sd, BSDUFIX(ip->ip_len), inet_ntoa(*victim),
  1152.         (int) sizeof(struct sockaddr_in));
  1153. /*          if ((res = sendto(sd, packet, BSDUFIX(ip->ip_len), 0,*/
  1154.    if ((res = Sendto("send_closedudp_probe",sd, packet, BSDUFIX(ip->ip_len), 0,
  1155.              (struct sockaddr *)&sock, (int) sizeof(struct sockaddr_in),ainfo)) == -1)
  1156.      {
  1157.        perror("sendto in send_udp_raw_decoys");
  1158.        return NULL;
  1159.      }
  1160.  
  1161.    if (TCPIP_DEBUGGING > 1) log_write(LOG_STDOUT, "successfully sent %d bytes of raw_tcp!\n", res);
  1162.  }
  1163.  
  1164. return &upi;
  1165.  
  1166. }
  1167.  
  1168. struct AVal *fingerprint_portunreach(struct ip *ip, struct udpprobeinfo *upi) {
  1169. struct icmp *icmp;
  1170. struct ip *ip2;
  1171. int numtests = 10;
  1172. unsigned short checksum;
  1173. unsigned short *checksumptr;
  1174. udphdr_bsd *udp;
  1175. struct AVal *AVs;
  1176. int i;
  1177. int current_testno = 0;
  1178. unsigned char *datastart, *dataend;
  1179.  
  1180. /* The very first thing we do is make sure this is the correct
  1181.    response */
  1182. if (ip->ip_p != IPPROTO_ICMP) {
  1183.   error("fingerprint_portunreach handed a non-ICMP packet!");
  1184.   return NULL;
  1185. }
  1186.  
  1187. if (ip->ip_src.s_addr != upi->target.s_addr)
  1188.   return NULL;  /* Not the person we sent to */
  1189.  
  1190. icmp = ((struct icmp *)  (((char *) ip) + 4 * ip->ip_hl));
  1191. if (icmp->icmp_type != 3 || icmp->icmp_code != 3)
  1192.   return NULL; /* Not a port unreachable */
  1193.  
  1194. ip2 = (struct ip*) ((char *)icmp + 8);
  1195. udp = (udphdr_bsd *) ((char *)ip2 + 20);
  1196.  
  1197. /* The ports better match as well ... */
  1198. if (ntohs(udp->uh_sport) != upi->sport || ntohs(udp->uh_dport) != upi->dport) {
  1199.   return NULL;
  1200. }
  1201.  
  1202. /* Create the Avals */
  1203. AVs = safe_malloc(numtests * sizeof(struct AVal));
  1204. bzero(AVs, numtests * sizeof(struct AVal));
  1205.  
  1206. /* Link them together */
  1207. for(i=0; i < numtests - 1; i++)
  1208.   AVs[i].next = &AVs[i+1];
  1209.  
  1210. /* First of all, if we got this far the response was yes */
  1211. AVs[current_testno].attribute = "Resp";
  1212. strcpy(AVs[current_testno].value, "Y");
  1213.  
  1214. current_testno++;
  1215.  
  1216. /* Now let us do an easy one, Don't fragment */
  1217. AVs[current_testno].attribute = "DF";
  1218.   if(ntohs(ip->ip_off) & 0x4000) {
  1219.     strcpy(AVs[current_testno].value,"Y");
  1220.   } else strcpy(AVs[current_testno].value, "N");
  1221.  
  1222. current_testno++;
  1223.  
  1224. /* Now lets do TOS of the response (note, I've never seen this be
  1225.    useful */
  1226. AVs[current_testno].attribute = "TOS";
  1227. sprintf(AVs[current_testno].value, "%hX", ip->ip_tos);
  1228.  
  1229. current_testno++;
  1230.  
  1231. /* Now we look at the IP datagram length that was returned, some
  1232.    machines send more of the original packet back than others */
  1233. AVs[current_testno].attribute = "IPLEN";
  1234. sprintf(AVs[current_testno].value, "%hX", ntohs(ip->ip_len));
  1235.  
  1236. current_testno++;
  1237.  
  1238. /* OK, lets check the returned IP length, some systems @$@ this
  1239.    up */
  1240. AVs[current_testno].attribute = "RIPTL";
  1241. sprintf(AVs[current_testno].value, "%hX", ntohs(ip2->ip_len));
  1242.  
  1243. current_testno++;
  1244.  
  1245. /* This next test doesn't work on Solaris because the lamers
  1246.    overwrite our ip_id */
  1247. #if !defined(SOLARIS) && !defined(SUNOS) && !defined(IRIX)
  1248. /* Now lets see how they treated the ID we sent ... */
  1249. AVs[current_testno].attribute = "RID";
  1250. if (ntohs(ip2->ip_id) == 0)
  1251.   strcpy(AVs[current_testno].value, "0");
  1252. else if (ip2->ip_id == upi->ipid)
  1253.   strcpy(AVs[current_testno].value, "E"); /* The "expected" value */
  1254. else strcpy(AVs[current_testno].value, "F"); /* They fucked it up */
  1255.  
  1256. current_testno++;
  1257. #endif
  1258.  
  1259. /* Let us see if the IP checksum we got back computes */
  1260.  
  1261. AVs[current_testno].attribute = "RIPCK";
  1262. /* Thanks to some machines not having struct ip member ip_sum we
  1263.    have to go with this BS */
  1264. checksumptr = (unsigned short *)   ((char *) ip2 + 10);
  1265. checksum =   *checksumptr;
  1266.  
  1267. if (checksum == 0)
  1268.   strcpy(AVs[current_testno].value, "0");
  1269. else {
  1270.   *checksumptr = 0;
  1271.   if (in_cksum((unsigned short *)ip2, 20) == checksum) {
  1272.     strcpy(AVs[current_testno].value, "E"); /* The "expected" value */
  1273.   } else {
  1274.     strcpy(AVs[current_testno].value, "F"); /* They fucked it up */
  1275.   }
  1276.   *checksumptr = checksum;
  1277. }
  1278.  
  1279. current_testno++;
  1280.  
  1281. /* UDP checksum */
  1282. AVs[current_testno].attribute = "UCK";
  1283. if (udp->uh_sum == 0)
  1284.   strcpy(AVs[current_testno].value, "0");
  1285. else if (udp->uh_sum == upi->udpck)
  1286.   strcpy(AVs[current_testno].value, "E"); /* The "expected" value */
  1287. else strcpy(AVs[current_testno].value, "F"); /* They fucked it up */
  1288.  
  1289. current_testno++;
  1290.  
  1291. /* UDP length ... */
  1292. AVs[current_testno].attribute = "ULEN";
  1293. sprintf(AVs[current_testno].value, "%hX", ntohs(udp->uh_ulen));
  1294.  
  1295. current_testno++;
  1296.  
  1297. /* Finally we ensure the data is OK */
  1298. datastart = ((unsigned char *)udp) + 8;
  1299. dataend = (unsigned char *)  ip + ntohs(ip->ip_len);
  1300.  
  1301. while(datastart < dataend) {
  1302.   if (*datastart != upi->patternbyte) break;
  1303.   datastart++;
  1304. }
  1305. AVs[current_testno].attribute = "DAT";
  1306. if (datastart < dataend)
  1307.   strcpy(AVs[current_testno].value, "F"); /* They fucked it up */
  1308. else  
  1309.   strcpy(AVs[current_testno].value, "E");
  1310.  
  1311. AVs[current_testno].next = NULL;
  1312.  
  1313. return AVs;
  1314. }
  1315.