
/*
 * Copyright 2000-2001 pilot <pilot@monkey.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <signal.h>
#include "grabhead.h"

int 
recvtimeout(int s, char *buf, int len, int timeout)
{
 fd_set fds;
 int n;
 struct timeval tv;
 FD_ZERO(&fds);
 FD_SET(s,&fds);
 tv.tv_sec=timeout;
 tv.tv_usec =0;

 n=select(s+1,&fds,NULL,NULL,&tv);
 if (n ==0) return -2; 
 if (n ==-1) return -1;
 return recv(s,buf,len,0);
}


void
grabhead(char *scanhost,unsigned int port)
{
int sock,nb;
struct sockaddr_in http;
struct hostent *he;


char osfinger[20];
char headBuff[180];

char *ptr,*ptr2,*buffer_pointer;


       
        if ((he = gethostbyname(scanhost)) == NULL){
           perror("gethostbyname"); 
           close(sock);
           exit(0);
        }
        if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1){
           perror("socket"); 
          close(sock);
           exit(0);
        }
        http.sin_family = AF_INET;
        http.sin_port = htons(port);
        http.sin_addr= *((struct in_addr *)he->h_addr);
        bzero(&(http.sin_zero),8);

        if (connect(sock, (struct sockaddr *)&http, sizeof(struct sockaddr)) == -1){
        close(sock);
        exit(0);
        }
        
        snprintf(osfinger,sizeof(osfinger),"%s\n\n",SEND_URI);
        send(sock,osfinger,strlen(osfinger),0);
        nb=recvtimeout(sock,headBuff,sizeof(headBuff),11);
        
        if (nb==-1||nb==-2){
        fprintf(stdout,"\n%s\nmaybe router or unknown network device\n",scanhost); 
        close(sock);
        exit(0);
        }
 
        if(strstr(headBuff,"3Com")!=NULL){
        close(sock);
        exit(0);
        }

        ptr = strstr(headBuff,"Server");

        if (ptr == NULL) {
        fprintf(stderr,"%s\n Can't find Server in Header\n",scanhost);
        }
        else{
        ptr2 = strstr(ptr,"\n");
        *ptr2 = '\0';
        buffer_pointer = strdup(ptr);
        *ptr2 = '\n';
        fprintf(stdout,"%s\n%s\n\n",scanhost,buffer_pointer);
        free(buffer_pointer);
        }

 close(sock);

}



void
grabheadW(unsigned long host,unsigned int port)
{
int sock,nb;
struct sockaddr_in http;


char osfinger[20];
char headBuff[180];

char *ptr,*ptr2,*buffer_pointer;

 
	sock = socket(AF_INET,SOCK_STREAM,0);
        http.sin_family = AF_INET;
        http.sin_port = htons(port);
        http.sin_addr.s_addr= htonl(host);
	
        if (connect(sock, (struct sockaddr *)&http, sizeof(struct sockaddr)) == -1){
        close(sock);
	exit(0);
        }
        snprintf(osfinger,sizeof(osfinger),"%s\n\n",SEND_URI);
       
        send(sock,osfinger,strlen(osfinger),0);
        nb=recvtimeout(sock,headBuff,sizeof(headBuff),10);
        
        if (nb== -1 || nb== -2) {
        /*fprintf(stdout,"\n%16s maybe router,unknown network device\n\n",inet_ntoa(http.sin_addr));*/
        close(sock);
        exit(0);
        }
  
        if(strstr(headBuff,"Server Error")!=NULL){
        close(sock);
        exit(0);
        } 
        ptr = strstr(headBuff,"Server");

        if (ptr == NULL) {
        fprintf(stderr,"%s\nCan't find Server in Header\n",inet_ntoa(http.sin_addr));
        }
        else{
        ptr2 = strstr(ptr,"\n");
        *ptr2 = '\0';
        buffer_pointer = strdup(ptr);
        *ptr2 = '\n';
        fprintf(stdout,"\n%16s %s\n",inet_ntoa(http.sin_addr),buffer_pointer); 
        free(buffer_pointer);
        }
        fprintf(stdout,"\n");

 close(sock);

}
