Cannot get interface flags: Invalid argument

  • Thread starter Thread starter nasim751
  • Start date Start date
  • Replies Replies 0
  • Views Views 1,393

nasim751

Newbie
Messages
1
Location
NA
ISP
Broadband
hello,
Actually i want to capture packet and watch the network is there any suspicious or attack is coming. So i used this following program but flag is not getting interface. how can i overcome this problem.
Please help me.
Code:
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define __FAVOR_BSD#include  //#include #include #include #include #include #define PKTLEN 96    /* Should be enough for what we want */#ifndef IP_MF#define IP_MF    0x2000#endif/***** WATCH LEVELS ******/#define MYSELFONLY    1#define MYSUBNET    2#define HUMANITARIAN    3/***** REPORT LEVELS *****/#define REPORTALL    1#define REPORTDOS    2#define REPORTSCAN    3struct floodinfo {    u_short sport;    struct floodinfo *next;};struct addrlist {    u_long saddr;    int cnt;    int wwwcnt;    struct addrlist *next;};struct atk {    u_long saddr;    u_char eaddr[ETH_ALEN];    time_t atktime;};struct pktin {    u_long saddr;    u_short sport;    u_short dport;    time_t timein;    u_char eaddr[ETH_ALEN];    struct floodinfo *fi;    struct pktin *next;};struct scaninfo {    u_long addr;    struct atk teardrop;    struct atk land;    struct atk icmpfrag;    struct pktin *tcpin;    struct pktin *udpin;    struct scaninfo *next;    u_long icmpcnt;} ;struct scaninfo *Gsilist = NULL, *Gsi;u_long Gmaddr;time_t Gtimer = 10, Gtimein;int Gportlimit = 7;int Gsynflood = 8;int Gwebcount = 40;int Gicmplimit = 5;int Gwatchlevel = MYSELFONLY;int Greportlevel = REPORTALL;char *Gprogramname, *Gdevice = "eth0";/******** IP packet info ********/u_long Gsaddr, Gdaddr;int Giplen, Gisfrag, Gid;/****** Externals *************/extern int errno;extern char *optarg;extern int optind, opterr;void do_tcp(), do_udp(), do_icmp(), print_info(), process_packet();void addtcp(), addudp(), clear_pktin(), buildnet();void doargs(), usage(), addfloodinfo(), rmfloodinfo();struct scaninfo *doicare(), *addtarget();char *anetaddr(), *ether_ntoa();u_char *readdevice();int SIOCGIFFLAGS;int SIOCSIFFLAGS;main(argc, argv)int argc;char *argv[];{    int pktlen = 0, i, netfd;    u_char *pkt;    char hostname[32];    struct hostent *hp;    time_t t;    doargs(argc, argv);    openlog("WATCHER", 0, LOG_DAEMON);    if(gethostname(hostname, sizeof(hostname)) < 0)    {    perror("gethostname");    exit(-1);    }    if((hp = gethostbyname(hostname)) == NULL)    {    fprintf(stderr, "Cannot find own address\n");    exit(-1);    }    memcpy((char *)&Gmaddr, hp->h_addr, hp->h_length);    buildnet();    if((netfd = initdevice(O_RDWR, 0)) < 0)    exit(-1);    /* Now read packets forever and process them. */    t = time((time_t *)0);    while(pkt = readdevice(netfd, &pktlen))    {    process_packet(pkt, pktlen);    if(time((time_t *)0) - t > Gtimer)    {        /* Times up.  Print what we found and clean out old stuff. */        for(Gsi = Gsilist, i = 0; Gsi; Gsi = Gsi->next, i++)        {                clear_pktin(Gsi);            print_info();        Gsi->icmpcnt = 0;        }        t = time((time_t *)0);    }    }}/**********************************************************************Function: doargsPurpose:  sets values from environment or command line arguments.**********************************************************************/void doargs(argc, argv)int argc;char **argv;{    char c;    Gprogramname = argv[0];    while((c = getopt(argc,argv,"d:f:hi:m:p:r:t:w:")) != EOF)    {        switch(c)        {        case 'd':        Gdevice = optarg;        break;            case 'f':                Gsynflood = atoi(optarg);                break;        case 'h':        usage();        exit(0);        case 'i':        Gicmplimit = atoi(optarg);        break;        case 'm':        if(strcmp(optarg, "all") == 0)            Gwatchlevel = HUMANITARIAN;        else if(strcmp(optarg, "subnet") == 0)            Gwatchlevel = MYSUBNET;        else        {            usage();            exit(-1);        }        break;        case 'p':        Gportlimit = atoi(optarg);        break;        case 'r':        if(strcmp(optarg, "dos") == 0)            Greportlevel = REPORTDOS;        else if(strcmp(optarg, "scan") == 0)            Greportlevel = REPORTSCAN;        else        {            exit(-1);        }        break;        case 't':                Gtimer = atoi(optarg);                break;        case 'w':        Gwebcount = atoi(optarg);        break;        default:                usage();                exit(-1);        }    }}/**********************************************************************Function: usagePurpose:  Display the usage of the program**********************************************************************/void usage(){printf("Usage: %s [options]\n", Gprogramname);printf("  -d device       Use 'device' as the network interface device\n");printf("                  The first non-loopback interface is the default\n");printf("  -f flood        Assume a synflood attack occurred if more than\n");printf("                  'flood' uncompleted connections are received\n");printf("  -h              A little help here\n");printf("  -i icmplimit    Assume we may be part of a smurf attack if more\n");printf("                  than icmplimit ICMP ECHO REPLIES are seen\n");printf("  -m level        Monitor more than just our own host.\n");printf("                  A level of 'subnet' watches all addresses in our\n");printf("                  subnet and 'all' watches all addresses\n");printf("  -p portlimit    Logs a portscan alert if packets are received for\n");printf("                  more than portlimit ports in the timeout period.\n");printf("  -r reporttype   If reporttype is dos, only Denial Of Service\n");printf("                  attacks are reported.  If reporttype is scan\n");printf("                  then only scanners are reported.  Everything is\n");printf("                  reported by default.\n");printf("  -t timeout      Count packets and print potential attacks every\n");printf("                  timeout seconds\n");printf("  -w webcount     Assume we are being portscanned if more than\n");printf("                  webcount packets are received from port 80\n");}/**********************************************************************Function: buildnetPurpose:  Setup for monitoring of our host or entire subnet.**********************************************************************/void buildnet(){    u_long addr;    u_char *p;    int i;    if(Gwatchlevel == MYSELFONLY)        /* Just care about me */    {    (void) addtarget(Gmaddr);    }    else if(Gwatchlevel == MYSUBNET)        /* Friends and neighbors */    {    addr = htonl(Gmaddr);    addr = addr & 0xffffff00;    for(i = 0; i < 256; i++)        (void) addtarget(ntohl(addr + i));    }}/**********************************************************************Function: doicarePurpose:  See if we monitor this address**********************************************************************/struct scaninfo *doicare(addr)u_long addr;{    struct scaninfo *si;    int i;    for(si = Gsilist; si; si = si->next)    {    if(si->addr == addr)        return(si);    }    if(Gwatchlevel == HUMANITARIAN)    /* Add a new address, we always care */    {    si = addtarget(addr);    return(si);    }    return(NULL);}/**********************************************************************Function: addtargetPurpose:  Adds a new IP address to the list of hosts to watch.**********************************************************************/struct scaninfo *addtarget(addr)u_long addr;{    struct scaninfo *si;    if((si = (struct scaninfo *)malloc(sizeof(struct scaninfo))) == NULL)    {    perror("malloc scaninfo");    exit(-1);    }    memset(si, 0, sizeof(struct scaninfo));    si->addr = addr;    si->next = Gsilist;    Gsilist = si;    return(si);}/**********************************************************************Function: process_packetPurpose:  Process raw packet and figure out what we need to to with it.Pulls the packet apart and stores key data in global areas for referenceby other functions.**********************************************************************/void process_packet(pkt, pktlen)u_char *pkt;int pktlen;{    struct ethhdr *ep;    struct iphdr *ip;    static struct align { struct iphdr ip; char buf[PKTLEN]; } a1;    u_short off;    Gtimein = time((time_t *)0);    ep = (struct ethhdr *) pkt;    if(ntohs(ep->h_proto) != ETH_P_IP)    return;    pkt += sizeof(struct ethhdr);    pktlen -= sizeof(struct ethhdr);    memcpy(&a1, pkt, pktlen);    ip = &a1.ip;    Gsaddr = ip->saddr;    Gdaddr = ip->daddr;    if((Gsi = doicare(Gdaddr)) == NULL)    return;    off = ntohs(ip->frag_off);    Gisfrag = (off & IP_MF);    /* Set if packet is fragmented */    Giplen = ntohs(ip->tot_len);    Gid = ntohs(ip->id);    pkt = (u_char *)ip + (ip->ihl ihl protocol)    {    case IPPROTO_TCP:        do_tcp(ep, pkt);        break;    case IPPROTO_UDP:        do_udp(ep, pkt);        break;    case IPPROTO_ICMP:        do_icmp(ep, pkt);        break;    default:        break;    }}/**********************************************************************Function: do_tcpPurpose:  Process this TCP packet if it is important.**********************************************************************/void do_tcp(ep, pkt)struct ethhdr *ep;u_char *pkt;{    struct tcphdr *thdr;    u_short sport, dport;    thdr = (struct tcphdr *) pkt;    if(thdr->th_flags & TH_RST) /* RST generates no response */    return;            /* Therefore can't be used to scan. */    sport = ntohs(thdr->th_sport);    dport = ntohs(thdr->th_dport);    if(thdr->th_flags & TH_SYN)    {    if(Gsaddr == Gdaddr && sport == dport)    {        Gsi->land.atktime = Gtimein;        Gsi->land.saddr = Gsaddr;        memcpy(Gsi->land.eaddr, ep->h_source, ETH_ALEN);    }    }    addtcp(sport, dport, thdr->th_flags, ep->h_source);}/**********************************************************************Function: addtcpPurpose:  Add this TCP packet to our list.**********************************************************************/void addtcp(sport, dport, flags, eaddr)u_short sport;u_short dport;u_char flags;u_char *eaddr;{    struct pktin *pi, *last, *tpi;    /* See if this packet relates to other packets already received. */    for(pi = Gsi->tcpin; pi; pi = pi->next)    {    if(pi->saddr == Gsaddr && pi->dport == dport)    {        if(flags == TH_SYN)        addfloodinfo(pi, sport);        else if((flags & TH_FIN) || (flags & TH_ACK))        rmfloodinfo(pi, sport);        return;    }    last = pi;    }    /* Must be new entry */    if((tpi = (struct pktin *)malloc(sizeof(struct pktin))) == NULL)    {    perror("Malloc");    exit(-1);    }    memset(tpi, 0, sizeof(struct pktin));    memcpy(tpi->eaddr, eaddr, ETH_ALEN);    tpi->saddr = Gsaddr;    tpi->sport = sport;    tpi->dport = dport;    tpi->timein = Gtimein;    if(flags == TH_SYN)    addfloodinfo(tpi, sport);    if(Gsi->tcpin)    last->next = tpi;    else    Gsi->tcpin = tpi;}/**********************************************************************Function: addfloodinfoPurpose:  Add floodinfo information**********************************************************************/void addfloodinfo(pi, sport)struct pktin *pi;u_short sport;{    struct floodinfo *fi;    fi = (struct floodinfo *)malloc(sizeof(struct floodinfo));    if(fi == NULL)    {        perror("Malloc of floodinfo");        exit(-1);    }    memset(fi, 0, sizeof(struct floodinfo));    fi->sport = sport;    fi->next = pi->fi;    pi->fi = fi;}/**********************************************************************Function: rmfloodinfoPurpose:  Removes floodinfo information**********************************************************************/void rmfloodinfo(pi, sport)struct pktin *pi;u_short sport;{    struct floodinfo *fi, *prev = NULL;    for(fi = pi->fi; fi; fi = fi->next)    {    if(fi->sport == sport)        break;    prev = fi;    }    if(fi == NULL)    return;    if(prev == NULL)    /* First element */    pi->fi = fi->next;    else    prev->next = fi->next;    free(fi);}/**********************************************************************Function: do_udpPurpose:  Process this udp packet.Currently teardrop and all its derivitives put 242 in the IP id field.This could obviously be changed.  The truly paranoid might want to flag allfragmented UDP packets.  The truly adventurous might enhance the code totrack fragments and check them for overlaping boundaries.**********************************************************************/void do_udp(ep, pkt)struct ethhdr *ep;u_char *pkt;{    struct udphdr *uhdr;    u_short sport, dport;    uhdr = (struct udphdr *) pkt;    if(Gid == 242 && Gisfrag)    /* probable teardrop */    {    Gsi->teardrop.saddr = Gsaddr;    memcpy(Gsi->teardrop.eaddr, ep->h_source, ETH_ALEN);    Gsi->teardrop.atktime = Gtimein;    }    sport = ntohs(uhdr->source);    dport = ntohs(uhdr->dest);    addudp(sport, dport, ep->h_source);}/**********************************************************************Function: addudpPurpose:  Add this udp packet to our list.**********************************************************************/void addudp(sport, dport, eaddr)u_short sport;u_short dport;u_char *eaddr;{    struct pktin *pi, *last, *tpi;    for(pi = Gsi->udpin; pi; pi = pi->next)    {    if(pi->saddr == Gsaddr && pi->dport == dport)    {        pi->timein = Gtimein;        return;    }    last = pi;    }    /* Must be new entry */    if((tpi = (struct pktin *)malloc(sizeof(struct pktin))) == NULL)    {    perror("Malloc");    exit(-1);    }    memset(tpi, 0, sizeof(struct pktin));    memcpy(tpi->eaddr, eaddr, ETH_ALEN);    tpi->saddr = Gsaddr;    tpi->sport = sport;    tpi->dport = dport;    tpi->timein = Gtimein;    if(Gsi->udpin)    last->next = tpi;    else    Gsi->udpin = tpi;}/**********************************************************************Function: do_icmpPurpose:  Process an ICMP packet.We assume there is no valid reason to receive a fragmented ICMP packet.**********************************************************************/void do_icmp(ep, pkt)struct ethhdr *ep;u_char *pkt;{    struct icmphdr *icmp;    icmp = (struct icmphdr *) pkt;    if(Gisfrag)    /* probable ICMP attack (i.e. Ping of Death) */    {    Gsi->icmpfrag.saddr = Gsaddr;    memcpy(Gsi->icmpfrag.eaddr, ep->h_source, ETH_ALEN);    Gsi->icmpfrag.atktime = Gtimein;    }    if(icmp->type == ICMP_ECHOREPLY)    Gsi->icmpcnt++;    return;}/**********************************************************************Function: clear_pktPurpose:  Delete and free space for any old packets.**********************************************************************/void clear_pktin(si)struct scaninfo *si;{    struct pktin *pi;    struct floodinfo *fi, *tfi;    time_t t, t2;    t = time((time_t *)0);    while(si->tcpin)    {    t2 = t - si->tcpin->timein;    if(t2 > Gtimer)    {        pi = si->tcpin;        fi = pi->fi;        while(fi)        {        tfi = fi;        fi = fi->next;        free(tfi);        }        si->tcpin = pi->next;        free(pi);    }    else        break;    }    while(si->udpin)    {    t2 = t - si->udpin->timein;    if(t2 > Gtimer)    {        pi = si->udpin;        si->udpin = pi->next;        free(pi);    }    else        break;    }}/**********************************************************************Function: print_infoPurpose:  Print out any alerts.**********************************************************************/void print_info(){    struct pktin *pi;    struct addrlist *tcplist = NULL, *udplist = NULL, *al;    struct floodinfo *fi;    char buf[1024], *eaddr, abuf[32];    int i;    strcpy(abuf, anetaddr(Gsi->addr));    if(Greportlevel == REPORTALL || Greportlevel == REPORTDOS)    {        if(Gsi->teardrop.atktime)        {        eaddr = ether_ntoa(Gsi->teardrop.eaddr);        sprintf(buf, "Possible teardrop attack from %s (%s) against %s",            anetaddr(Gsi->teardrop), eaddr, abuf);        syslog(LOG_ALERT, buf);        memset(&Gsi->teardrop, 0, sizeof(struct atk));        }        if(Gsi->land.atktime)        {        eaddr = ether_ntoa(Gsi->land.eaddr);        sprintf(buf, "Possible land attack from (%s) against %s",            eaddr, abuf);        syslog(LOG_ALERT, buf);        memset(&Gsi->land, 0, sizeof(struct atk));        }        if(Gsi->icmpfrag.atktime)        {        eaddr = ether_ntoa(Gsi->icmpfrag.eaddr);        sprintf(buf, "ICMP fragment detected from %s (%s) against %s",            anetaddr(Gsi->icmpfrag), eaddr, abuf);        syslog(LOG_ALERT, buf);        memset(&Gsi->icmpfrag, 0, sizeof(struct atk));        }        if(Gsi->icmpcnt > Gicmplimit)        {        sprintf(buf, "ICMP ECHO threshold exceeded, smurfs up.  I saw %d packets\n", Gsi->icmpcnt);        syslog(LOG_ALERT, buf);        Gsi->icmpcnt = 0;        }        }    for(pi = Gsi->tcpin; pi; pi = pi->next)    {    i = 0;    for(fi = pi->fi; fi; fi = fi->next)        i++;            if(Greportlevel == REPORTALL || Greportlevel == REPORTDOS)    {        if(i > Gsynflood)        {            eaddr = ether_ntoa(pi->eaddr);            sprintf(buf, "Possible SYNFLOOD from %s (%s), against %s.  I saw %d packets\n",            anetaddr(pi->saddr), eaddr, abuf, i);            syslog(LOG_ALERT, buf);        }    }    for(al = tcplist; al; al = al->next)    {        if(pi->saddr == al->saddr)        {        al->cnt++;        if(pi->sport == 80)            al->wwwcnt++;        break;        }    }    if(al == NULL)    /* new address */    {        al = (struct addrlist *)malloc(sizeof(struct addrlist));        if(al == NULL)        {        perror("Malloc address list");        exit(-1);        }        memset(al, 0, sizeof(struct addrlist));        al->saddr = pi->saddr;        al->cnt = 1;        if(pi->sport == 80)        al->wwwcnt = 1;        al->next = tcplist;        tcplist = al;        }    }    if(Greportlevel == REPORTALL || Greportlevel == REPORTSCAN)    {        for(al = tcplist; al; al = al->next)        {        if((al->cnt - al->wwwcnt) > Gportlimit || al->wwwcnt > Gwebcount)        {            sprintf(buf, "Possible TCP port scan from %s (%d ports) against %s\n",            anetaddr(al->saddr), al->cnt, abuf);            syslog(LOG_ALERT, buf);        }        }        for(pi = Gsi->udpin; pi; pi = pi->next)        {        for(al = udplist; al; al = al->next)        {            if(pi->saddr == al->saddr)            {            al->cnt++;            break;            }        }        if(al == NULL)    /* new address */        {            al = (struct addrlist *)malloc(sizeof(struct addrlist));            if(al == NULL)            {            perror("Malloc address list");            exit(-1);            }            memset(al, 0, sizeof(struct addrlist));            al->saddr = pi->saddr;            al->cnt = 1;            al->next = udplist;            udplist = al;        }        }        for(al = udplist; al; al = al->next)        {        if(al->cnt > Gportlimit)        {            sprintf(buf, "Possible UDP port scan from %s (%d ports) against %s\n",            anetaddr(al->saddr), al->cnt, abuf);            syslog(LOG_ALERT, buf);        }        }    }    while(tcplist)    {    al = tcplist->next;    free(tcplist);    tcplist = al;    }    while(udplist)    {    al = udplist->next;    free(udplist);    udplist = al;    }}/************************************************************************Function:  anetaddrDescription:Another version of the intoa function.************************************************************************/char *anetaddr(addr)u_long addr;{    u_long naddr;    static char buf[16];    u_char b[4];    int i;    naddr = ntohl(addr);    for(i = 3; i >= 0; i--)    {        b[i] = (u_char) (naddr & 0xff);        naddr >>= 8;    }    sprintf(buf, "%d.%d.%d.%d", b[0], b[1], b[2], b[3]);    return(buf);}/************************************************************************Function:  initdeviceDescription: Set up the network device so we can read it.**************************************************************************/initdevice(fd_flags, dflags)int fd_flags;u_long dflags;{    struct ifreq ifr;    int fd, flags = 0;    if((fd = socket(PF_INET, SOCK_PACKET, htons(0x0003))) < 0)    {    perror("Cannot open device socket");    exit(-1);    }    /* Get the existing interface flags */    strcpy(ifr.ifr_name, Gdevice);    if(ioctl(fd, SIOCGIFFLAGS, &ifr) < 0)    {    perror("Cannot get interface flags");    exit(-1);    }    ifr.ifr_flags |= IFF_PROMISC;    if(ioctl(fd, SIOCSIFFLAGS,  &ifr) < 0)    {    perror("Cannot set interface flags");    exit(-1);    }        return(fd);}/************************************************************************Function:  readdeviceDescription: Read a packet from the device.**************************************************************************/u_char *readdevice(fd, pktlen)int fd;int *pktlen;{    int cc = 0, from_len, readmore = 1;    struct sockaddr from;    static u_char pktbuffer[PKTLEN];    u_char *cp;    while(readmore)    {    from_len = sizeof(from);    if((cc = recvfrom(fd, pktbuffer, PKTLEN, 0, &from, &from_len)) < 0)    {        if(errno != EWOULDBLOCK)        return(NULL);    }    if(strcmp(Gdevice, from.sa_data) == 0)        readmore = 0;    }    *pktlen = cc;    return(pktbuffer);}/*************************************************************************Function: ether_ntoa Description:Translates a MAC address into ascii.  This function emulatesthe ether_ntoa function that exists on Sun and Solaris, but not on Linux.It could probably (almost certainly) be more efficent, but it will do.*************************************************************************/char *ether_ntoa(etheraddr)u_char etheraddr[ETH_ALEN];{    int i, j;    static char eout[32];    char tbuf[10];    for(i = 0, j = 0; i < 5; i++)    {    eout[j++] = etheraddr[i] >> 4;    eout[j++] = etheraddr[i] & 0xF;    eout[j++] = ':';    }    eout[j++] = etheraddr[i] >> 4;    eout[j++] = etheraddr[i] & 0xF;    eout[j++] = '\0';    for(i = 0; i < 17; i++)    {    if(eout[i] < 10)        eout[i] += 0x30;    else if(eout[i] < 16)        eout[i] += 0x57;    }    return(eout);}
 

Top