/* * Copyright (c) 2000-2004 QoSient, LLC * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef ArgusArp #define ArgusArp #endif #include #include #if !defined(__OpenBSD__) #include #endif #include #include #ifndef REVARP_REQUEST #define REVARP_REQUEST 3 #endif #ifndef REVARP_REPLY #define REVARP_REPLY 4 #endif void ArgusUpdateArpState (struct ArgusFlowStruct *flowstr, unsigned char *state) { struct ether_arp *arp = (struct ether_arp *)(ArgusThisEpHdr + 1); struct ArgusARPObject *arpobj = NULL; ArgusTallyTime (flowstr, *state); if (STRUCTCAPTURED(*arp)) { ArgusThisLength -= sizeof(*arp); ArgusSnapLength -= sizeof(*arp); ArgusThisUpHdr = (unsigned char *)(arp + 1); ArgusUpdateAppState (flowstr, state); if (*state == ARGUS_START) { if (flowstr->NetworkDSRBuffer != NULL) ArgusFree(flowstr->NetworkDSRBuffer); if ((arpobj = (void *) ArgusCalloc (1, sizeof(struct ArgusARPObject))) == NULL) ArgusLog (LOG_ERR, "ArgusNewFlow: ArgusCalloc %s", strerror(errno)); else flowstr->NetworkDSRBuffer = (void *) arpobj; } else arpobj = (void *) flowstr->NetworkDSRBuffer; switch (arp->arp_op) { case ARPOP_REQUEST: ArgusInProtocol = 0; break; case ARPOP_REPLY: bcopy ((unsigned char *)&SHA(arp), arpobj->respaddr, 6); break; } } } int ArgusCreateArpFlow (struct ether_arp *arp) { int retn = 0; unsigned char *srcehost = NULL; unsigned char *tarehost = NULL; unsigned int arp_tpa, arp_spa; ArgusThisUpHdr = (unsigned char *) arp; if (STRUCTCAPTURED(*arp)) { #ifdef _LITTLE_ENDIAN arp->arp_hrd = ntohs(arp->arp_hrd); arp->arp_pro = ntohs(arp->arp_pro); arp->arp_op = ntohs(arp->arp_op); #endif switch (arp->arp_op) { case ARPOP_REQUEST: srcehost = (unsigned char *) &ArgusThisEpHdr->ether_shost; bcopy ((char *)&arp->arp_tpa, &arp_tpa, sizeof(arp_tpa)); bcopy ((char *)&arp->arp_spa, &arp_spa, sizeof(arp_spa)); if (arp_spa > arp_tpa) ArgusThisDir = 1; bcopy (srcehost, ArgusThisFlow->arp_flow.etheraddr, sizeof (ArgusThisFlow->arp_flow.etheraddr)); #ifdef _LITTLE_ENDIAN arp_tpa = ntohl(arp_tpa); arp_spa = ntohl(arp_spa); #endif ArgusThisFlow->arp_flow.arp_tpa = arp_tpa; ArgusThisFlow->arp_flow.arp_spa = arp_spa; break; case ARPOP_REPLY: srcehost = (unsigned char *) &ArgusThisEpHdr->ether_dhost; bcopy ((char *)&arp->arp_spa, &arp_tpa, sizeof(arp_tpa)); bcopy ((char *)&arp->arp_tpa, &arp_spa, sizeof(arp_spa)); if (arp_tpa > arp_spa) ArgusThisDir = 1; bcopy (srcehost, ArgusThisFlow->arp_flow.etheraddr, sizeof (ArgusThisFlow->arp_flow.etheraddr)); #ifdef _LITTLE_ENDIAN arp_tpa = ntohl(arp_tpa); arp_spa = ntohl(arp_spa); #endif ArgusThisFlow->arp_flow.arp_tpa = arp_tpa; ArgusThisFlow->arp_flow.arp_spa = arp_spa; break; case REVARP_REQUEST: srcehost = (unsigned char *)&SHA(arp); tarehost = (unsigned char *)&THA(arp); bcopy (srcehost, ArgusThisFlow->rarp_flow.srceaddr, sizeof (ArgusThisFlow->rarp_flow.srceaddr)); bcopy (tarehost, ArgusThisFlow->rarp_flow.tareaddr, sizeof (ArgusThisFlow->rarp_flow.tareaddr)); break; case REVARP_REPLY: srcehost = (unsigned char *)&SHA(arp); tarehost = (unsigned char *)&THA(arp); bcopy (srcehost, ArgusThisFlow->rarp_flow.srceaddr, sizeof (ArgusThisFlow->rarp_flow.srceaddr)); bcopy (tarehost, ArgusThisFlow->rarp_flow.tareaddr, sizeof (ArgusThisFlow->rarp_flow.tareaddr)); break; } retn = 1; } #ifdef ARGUSDEBUG ArgusDebug (8, "ArgusCreateArpFlow (0x%x) returning %d\n", arp, retn); #endif return (retn); }