Exemplo n.º 1
0
void refreshInterfaceData(struct lldp_port *lldp_port) {
  _getmac(lldp_port);
  
  debug_printf(DEBUG_INT, "%s MAC: ", lldp_port->if_name);
  debug_hex_printf(DEBUG_INT, lldp_port->source_mac, 6);

  _getip(lldp_port);

  debug_printf(DEBUG_INT, "%s IP: %d.%d.%d.%d\n",
	       lldp_port->if_name,
	       lldp_port->source_ipaddr[0],
	       lldp_port->source_ipaddr[1],
	       lldp_port->source_ipaddr[2],
	       lldp_port->source_ipaddr[3]);

}
Exemplo n.º 2
0
int do_v1_at_mac(struct generic_eap_data *thisint, char *K_int, char *indata, int in_size, int inoffset, char *noncemt, char *vlist, int vlistlen, uint16_t selver, char *resultmac)
{
  char *framecpy, *mac_calc;
  int saved_offset, i;
  uint16_t value16;

  if ((!thisint) || (!K_int) || (!indata) || (!noncemt) || (!vlist) ||
      (!resultmac))
    {
      debug_printf(DEBUG_NORMAL, "Invalid data passed to do_v1_at_mac()!\n");
      return XEMALLOC;
    }

  if (indata[inoffset] != AT_MAC)
    {
      debug_printf(DEBUG_NORMAL, "Error!  The offset passed in is not of type AT_MAC!\n");
      return -1;
    }
  
  inoffset++;
	      
  if (indata[inoffset] != 5) printf("AT_MAC length isn't 5!\n");
  inoffset+=2;  // Skip the reserved bytes.

  saved_offset = inoffset;

  framecpy = (char *)malloc(in_size+50);  // We need extra to
	                                  // reconstruct the eap 
	                                  // piece.
  if (framecpy == NULL)
    {
      printf("Couldn't allocate memory for framecpy!\n");
      return -1;
    }

  // Now, reconstruct the header for the EAP piece, so we can
  // calculate the MAC across all of it.
  framecpy[0] = 1;  // It was a request.
  framecpy[1] = thisint->eapid;
  value16 = in_size + 5;
  value16 = htons(value16);

  memcpy((char *)&framecpy[2], &value16, 2);
  framecpy[4] = 18;  // EAP-SIM
  
  memcpy((char *)&framecpy[5], (char *)&indata[0], in_size);

  // Now, zero out the MAC value.
  for (i=(saved_offset+5);i<=(in_size+5);i++)
    {
      framecpy[i] = 0x00;
    }

  memcpy(&framecpy[(in_size+5)], noncemt, 16);
  
  // We should now be ready to calculate the AT_MAC for 
  // ourselves.

  debug_printf(DEBUG_AUTHTYPES, "Hashing this frame to get AT_MAC: \n");
  debug_hex_dump(DEBUG_AUTHTYPES, framecpy, (in_size+5+16));

  mac_calc = (char *)malloc(100);
  if (mac_calc == NULL) return -1;
  
  HMAC(EVP_sha1(), &K_int[0], 16, framecpy, (in_size+5+16), mac_calc, &i);

  memcpy(resultmac, mac_calc, 16);  // We get 20 back, but we only want 16.

  debug_printf(DEBUG_AUTHTYPES, "Result MAC = ");
  debug_hex_printf(DEBUG_AUTHTYPES, resultmac, 16);

  free(framecpy);
  framecpy = NULL;
  
  free(mac_calc);
  mac_calc = NULL;
  return 0;
}
Exemplo n.º 3
0
int eapsim_process(struct generic_eap_data *thisint, u_char *dataoffs,
		   int insize, u_char *out, int *outsize)
{
  int packet_offset, outptr, numVers, i, value16, maxver, saved_offset;
  int tlen;
  struct typelength *typelen;
  struct typelengthres *typelenres;
  struct eaptypedata *mydata;
  char *hash, *at_mac_sres, *nsres=NULL, *framecpy, *username;
  char sha1resp[20], K_sres[16], K_encr[16], K_recv[32], K_send[32];
  char mac_val[16], mac_calc[16], K_int[16];
  struct config_eap_sim *userdata;

  if ((!thisint) || (!thisint->eap_data))
    {
      debug_printf(DEBUG_NORMAL, "Invalid interface struct passed in to eapsim_process()!\n");
      return XEMALLOC;
    }

  mydata = (struct eaptypedata *)thisint->eap_data;
  userdata = (struct config_eap_sim *)thisint->eap_conf_data;

  if (!userdata)
    {
      debug_printf(DEBUG_NORMAL, "Invalid user data struct in eapsim_process()!\n");
      return XEMALLOC;
    }

  if ((thisint->tempPwd == NULL) && (userdata->password == NULL))
    {
      thisint->need_password = 1;
      thisint->eaptype = strdup("EAP-SIM");
      thisint->eapchallenge = NULL;
      
      *outsize = 0;
      return XENONE;
    }

  // Make sure we have something to process...
  if (dataoffs == NULL) return XENONE;

  if (sc_need_init()==1)
    {
      init_smartcard(thisint);
    }

  if (userdata->username == NULL)
    {
      username = thisint->identity;
    } else {
      username = userdata->username;
    }

  if ((userdata->password == NULL) && (thisint->tempPwd != NULL))
    {
      userdata->password = thisint->tempPwd;
      thisint->tempPwd = NULL;
    }

  *outsize = 0;
  bzero(&mac_calc[0], 16);
  bzero(&mac_val[0], 16);

  switch (dataoffs[0])
    {
    case SIM_START:
      debug_printf(DEBUG_AUTHTYPES, "Got SIM_START!\n");
      bzero(out, 100);
      packet_offset = 3;

      typelen = (struct typelength *)&out[0];
      typelen->type = SIM_START;
      typelen->length = 0;

      typelenres = (struct typelengthres *)&out[3];
      typelenres->type = AT_NONCE_MT;
      typelenres->length = 5;
      typelenres->reserved = 0;

      // Generate a few random bytes for our NONCE MT.
      mydata->nonce_mt = (char *)malloc(16);
      if (mydata->nonce_mt == NULL) return XEMALLOC;

      RAND_bytes(mydata->nonce_mt,16);

      debug_printf(DEBUG_AUTHTYPES, "NONCE MT = ");
      debug_hex_printf(DEBUG_AUTHTYPES, mydata->nonce_mt, 16);

      outptr = 7;
      memcpy(&out[outptr], mydata->nonce_mt, 16);
      outptr += 16;
     
      // Process SIM value fields.
      while (packet_offset < insize)
	{
	  switch (dataoffs[packet_offset])
	    {
	    case AT_MAC:
	      debug_printf(DEBUG_NORMAL, "You cannot have an AT_MAC in a Start packet!\n");
	      return XESIMNOATMAC;

	    case AT_ANY_ID_REQ:
	    case AT_FULLAUTH_ID_REQ:
	    case AT_PERMANENT_ID_REQ:
	      debug_printf(DEBUG_AUTHTYPES, "Got AT_FULLAUTH_ID_REQ or AT_PERMANENT_ID_REQ!\n");
	      typelenres = (struct typelengthres *)&dataoffs[packet_offset];
	      if ((typelenres->length != 5) && (typelenres->length != 1))
		{
		  debug_printf(DEBUG_NORMAL, "Invalid AT_FULLAUTH_ID_REQ length!\n");
		  return XESIMBADLEN;
		}
	      
	      packet_offset+=4;  // Skip the reserved and length bytes.
	      
	      // Build an AT_IDENTITY response.
	      typelenres = (struct typelengthres *)&out[outptr];
	      typelenres->type = AT_IDENTITY;
	      typelenres->length = (strlen(username)/4)+1;
	      typelenres->reserved = htons(strlen(username));
	      outptr+=sizeof(struct typelengthres);
	      
	      memcpy(&out[outptr], username, strlen(username));

	      outptr += strlen(username);

	      break;
	      
	    case AT_VERSION_LIST:
	      debug_printf(DEBUG_AUTHTYPES, "Got an AT_VERSION_LIST request!\n");
	      typelenres = (struct typelengthres *)&dataoffs[packet_offset];
	      
	      debug_printf(DEBUG_AUTHTYPES, "Version List Length (# versions) : %d\n", typelenres->length);
	      numVers = typelenres->length;
	      
	      mydata->verlistlen = ntohs(typelenres->reserved);
	      debug_printf(DEBUG_AUTHTYPES, "Version List Length (bytes) : %d\n",
			   mydata->verlistlen);
	      packet_offset+=sizeof(struct typelengthres);
	      maxver = 0;    // Set the starting value to be 0.

	      mydata->verlist = (char *)malloc(mydata->verlistlen);
	      if (mydata->verlist == NULL) return XEMALLOC;

	      memcpy(mydata->verlist, &dataoffs[packet_offset], 
		     mydata->verlistlen);
	      
	      for (i=0;i<numVers;i++)
		{
		  memcpy(&value16, &dataoffs[packet_offset], 2);
		  value16 = ntohs(value16);
		  debug_printf(DEBUG_AUTHTYPES, "AT_VERSION_LIST Value : %d\n",
			       value16);
		  if (value16 > maxver) maxver = value16;
		  
		  packet_offset += 2;
		}
	      
	      if (maxver > EAPSIM_MAX_SUPPORTED_VER) 
		maxver = EAPSIM_MAX_SUPPORTED_VER;
	      
	      debug_printf(DEBUG_AUTHTYPES, "Setting version to %d\n",maxver);
	      typelenres = (struct typelengthres *)&out[outptr];
	      typelenres->type = AT_SELECTED_VERSION;
	      typelenres->length = 1;
	      typelenres->reserved = htons(maxver);
	      outptr += sizeof(struct typelengthres);

	      mydata->workingversion = maxver;
	      break;
	      
	    default:
	      debug_printf(DEBUG_NORMAL, "Unknown SIM type!\n");
	      return XESIMBADTYPE;
	    }
	}
      // Write the length in the response header.
      value16 = htons(outptr);
      memcpy((char *)&out[1], &value16, 2); 
      *outsize = (outptr);
      break;

    case SIM_CHALLENGE:
      debug_printf(DEBUG_AUTHTYPES, "Got SIM_CHALLENGE!\n");
      packet_offset = 3;

      typelen = (struct typelength *)&out[0];
      typelen->type = SIM_CHALLENGE;
      outptr = 3;

      while (packet_offset < insize)
	{
	  switch (dataoffs[packet_offset])
	    {
	    case AT_RAND:
	      debug_printf(DEBUG_AUTHTYPES, "Got an AT_RAND.\n");
	      typelenres = (struct typelengthres *)&dataoffs[packet_offset];
	      packet_offset+=4;

	      memcpy(mydata->triplet[0].random, &dataoffs[packet_offset], 16);
	      debug_printf(DEBUG_AUTHTYPES, "Random1 = ");
	      debug_hex_printf(DEBUG_AUTHTYPES, mydata->triplet[0].random, 16);
	      do_gsm(mydata->triplet[0].random, mydata->triplet[0].response,
		     mydata->triplet[0].ckey);
	      packet_offset+=16;

	      memcpy(mydata->triplet[1].random, &dataoffs[packet_offset], 16);
	      debug_printf(DEBUG_AUTHTYPES, "Random2 = ");
	      debug_hex_printf(DEBUG_AUTHTYPES, mydata->triplet[1].random, 16);
	      do_gsm(mydata->triplet[1].random, mydata->triplet[1].response,
		     mydata->triplet[1].ckey);
	      packet_offset+=16;

	      memcpy(mydata->triplet[2].random, &dataoffs[packet_offset], 16);
	      debug_printf(DEBUG_AUTHTYPES, "Random3 = ");
	      debug_hex_printf(DEBUG_AUTHTYPES, mydata->triplet[2].random, 16);
	      do_gsm(mydata->triplet[2].random, mydata->triplet[2].response,
		     mydata->triplet[2].ckey);
	      packet_offset+=16;
	      
	      if (mydata->workingversion == 0)
		{
		  hash = (char *)malloc((8*3)+16);  // 3 keys + 16 nonce.
		  if (hash == NULL)
		    {
		      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to build hash!\n");
		      return XEMALLOC;
		    }

		  bzero(hash, ((8*3)+16));
		  memcpy(&hash[0], mydata->triplet[0].ckey, 8);
		  memcpy(&hash[8], mydata->triplet[1].ckey, 8);
		  memcpy(&hash[16], mydata->triplet[2].ckey, 8);
		  memcpy(&hash[24], mydata->nonce_mt, 16);

		  SHA1(hash, 40, &sha1resp[0]);
		} else {
		  tlen = strlen(username)+(8*3)+16+
		    mydata->verlistlen+2;
		  hash = (char *)malloc(tlen);
		  if (hash == NULL) return XEMALLOC;

		  nsres = (char *)malloc(4*3);
		  if (nsres == NULL) return XEMALLOC;

		  bzero(nsres, 12);
		  memcpy(&nsres[0], mydata->triplet[0].response, 4);
		  memcpy(&nsres[4], mydata->triplet[1].response, 4);
		  memcpy(&nsres[8], mydata->triplet[2].response, 4);

		  bzero(hash, tlen);
		  memcpy(&hash[0], username, strlen(username));
		  memcpy(&hash[strlen(username)], mydata->triplet[0].ckey, 8);
		  memcpy(&hash[strlen(username)+8], mydata->triplet[1].ckey, 8);
		  memcpy(&hash[strlen(username)+16],
			 mydata->triplet[2].ckey, 8);
		  memcpy(&hash[strlen(username)+24],
			 mydata->nonce_mt, 16);
		  memcpy(&hash[strlen(username)+24+16],
			 mydata->verlist, mydata->verlistlen);

		  value16 = htons(mydata->workingversion);
		  memcpy(&hash[strlen(username)+24+16+
			       mydata->verlistlen], &value16, 2);

      		  SHA1(hash, (strlen(username)+24+16+
				  mydata->verlistlen+2), sha1resp);

		  free(hash);
		  hash = NULL;
		}

	      debug_printf(DEBUG_AUTHTYPES, "MK = ");
	      debug_hex_printf(DEBUG_AUTHTYPES, &sha1resp[0], 20);

	      at_mac_sres = (char *)malloc(120);
	      if (at_mac_sres == NULL)
		{
		  debug_printf(DEBUG_NORMAL, "Couldn't malloc at_mac_sres!\n");
		  return XEMALLOC;
		}

	      fips186_2_prng(sha1resp, 20, NULL, 0, at_mac_sres, 120);

	      if (mydata->workingversion == 0)
		{
		  memcpy(&K_sres[0], &at_mac_sres[0], 16);
		  memcpy(&K_encr[0], &at_mac_sres[16], 16);
		  memcpy(&K_int[0], &at_mac_sres[32], 16);
		  
		  bzero(&K_recv[0], 32);
		  bzero(&K_send[0], 32);
		  
		  memcpy(&K_recv[0], &at_mac_sres[48], 20);
		  memcpy(&K_send[0], &at_mac_sres[68], 20);
		} else {
		  // K_int is the same as K_aut in Version 1.
       		  memcpy(&K_int[0], &at_mac_sres[16], 16);
		  memcpy(&K_recv[0], &at_mac_sres[32], 32);
		  memcpy(&K_send[0], &at_mac_sres[64], 32);
		}

	      // We should be done with at_mac_sres, so free it.
	      free(at_mac_sres);
	      at_mac_sres = NULL;
	      
	      if (mydata->keyingMaterial != NULL)
		{
		  free(mydata->keyingMaterial);
		  mydata->keyingMaterial = NULL;
		}
	      mydata->keyingMaterial = (char *)malloc(64);
	      if (mydata->keyingMaterial == NULL) return XEMALLOC;

	      bzero(mydata->keyingMaterial, 64);

	      memcpy(mydata->keyingMaterial, &K_recv[0], 32);
	      memcpy(&mydata->keyingMaterial[32], &K_send[0], 32);
	      
	      if (mydata->workingversion == 0)
		{
		  hash = (char *)malloc((4*3)+16);
		  if (hash == NULL) return XEMALLOC;

		  memcpy(&hash[0], mydata->triplet[0].response, 4);
		  memcpy(&hash[4], mydata->triplet[1].response, 4);
		  memcpy(&hash[8], mydata->triplet[2].response, 4);
		  hash[12] = 11;

		  HMAC(EVP_sha1(), &K_sres[0], 16, &hash[0], 13, (char *)&sha1resp[0], &i);
		  debug_printf(DEBUG_AUTHTYPES, "Final return value : ");
		  debug_hex_printf(DEBUG_AUTHTYPES, &sha1resp[0], i);

		  typelenres = (struct typelengthres *)&out[outptr];
		  typelenres->type = AT_MAC_SRES;
		  typelenres->length = 5;
		  typelenres->reserved = 0;

		  outptr += sizeof(struct typelengthres);
		  memcpy(&out[outptr], &sha1resp, i);
		  outptr += i;
		}
	      break;

	    case AT_IV:
	      debug_printf(DEBUG_AUTHTYPES, "Got an IV (Not supported)\n");
	      packet_offset+=5;
	      break;

	    case AT_ENCR_DATA:
	      debug_printf(DEBUG_AUTHTYPES, "Got an AT_ENCR_DATA (Not supported)\n");
	      packet_offset+=5;
	      break;

	    case AT_MAC:
	      debug_printf(DEBUG_AUTHTYPES, "Got an AT_MAC\n");
	      
	      saved_offset = packet_offset;

	      memcpy(&mac_val[0], &dataoffs[packet_offset+4], 16);
	      packet_offset+=20;

	      if (mydata->workingversion == 0)
		{
		  if (do_v0_at_mac(thisint, &K_int[0], dataoffs, insize, 
				   saved_offset, &mac_calc[0]) == -1)
		    {
		      debug_printf(DEBUG_NORMAL, "Error calculating AT_MAC for Version 0!\n");
		      return XESIMBADMAC;
		    }
		} else {
		  debug_printf(DEBUG_AUTHTYPES, "K_int[0] = ");
		  debug_hex_printf(DEBUG_AUTHTYPES, &K_int[0], 16);
		  if (do_v1_at_mac(thisint, &K_int[0], dataoffs, insize, 
				   saved_offset, mydata->nonce_mt, 
				   mydata->verlist, mydata->verlistlen, 
				   mydata->workingversion, &mac_calc[0]) == -1)
		    {
		      debug_printf(DEBUG_NORMAL, "Error calculating AT_MAC for Version 1!\n");
		      return XESIMBADMAC;
		    }
		}

	      if (memcmp(&mac_calc[0], &mac_val[0], 16) != 0)
		{
		  debug_printf(DEBUG_NORMAL, "ERROR : AT_MAC failed MAC check!\n");
		  debug_printf(DEBUG_AUTHTYPES, "mac_calc = ");
		  debug_hex_printf(DEBUG_AUTHTYPES, &mac_calc[0], 16);
		  debug_printf(DEBUG_AUTHTYPES, "mac_val  = ");
		  debug_hex_printf(DEBUG_AUTHTYPES, &mac_val[0], 16);
       		  //return XESIMBADMAC;
		}
	    }
	}

      if (mydata->workingversion == 1)
	{
	  framecpy = (char *)malloc(outptr+8+20+(8*3));
	  if (framecpy == NULL) return XEMALLOC;

	  bzero(framecpy, (outptr+5+20+(4*3)));
	  
	  framecpy[0] = 2;
	  framecpy[1] = thisint->eapid;
	  value16 = htons(outptr+5+20);
	  memcpy(&framecpy[2], &value16, 2);
	  framecpy[4] = EAP_TYPE_SIM;
	  memcpy(&framecpy[5], &out[0], outptr);
	  
	  framecpy[5+outptr] = AT_MAC;
	  framecpy[5+outptr+1] = 5;
	  memcpy(&framecpy[5+outptr+20], nsres, (4*3));

	  debug_printf(DEBUG_AUTHTYPES, "Hashing against :\n");
	  debug_hex_dump(DEBUG_AUTHTYPES, &framecpy[0], outptr+25+12);

	  HMAC(EVP_sha1(), &K_int[0], 16, framecpy, (outptr+5+20+12), &mac_calc[0], &i);
      	  memcpy(&out[outptr], &framecpy[5+outptr], 20);
	  memcpy(&out[outptr+4], &mac_calc[0], 16);
	  outptr += 20;

	  free(framecpy);
	  framecpy = NULL;
	}

      if (nsres != NULL)
	{
	  free(nsres);
	  nsres = NULL;
	}

      value16 = htons(outptr);
      memcpy((char *)&out[1], &value16, 2);

      *outsize = outptr;
      break;
	  
    case SIM_NOTIFICATION:
      debug_printf(DEBUG_NORMAL, "Got SIM_NOTIFICATION! (Unsupported)\n");
      break;
      
    case SIM_REAUTHENTICATION:
      debug_printf(DEBUG_NORMAL, "Got SIM_REAUTHENTICATION! (Unsupported)\n");
      break;
      
    default:
      debug_printf(DEBUG_NORMAL, "Unknown SubType value! (%d)\n", 
		   dataoffs[0]);
      break;
    }
  out[2] = 0;

  return XENONE;
}
Exemplo n.º 4
0
/*****************************************************
 *
 * Process OTP EAP Requests
 *
 *
 ******************************************************/
int eapotp_process(struct generic_eap_data *thisint, u_char *dataoffs, 
		   int insize, u_char *outframe, int *outsize)
{
  char *otp_chal;
  char resp[512];
  struct config_eap_otp *userdata;

  debug_printf(DEBUG_EVERYTHING, "(EAP-OTP) Processing.\n");

  if ((!thisint) || (!dataoffs) || (!outframe))
    {
      debug_printf(DEBUG_NORMAL, "Invalid paramaters passed to eapotp_process()!\n");
      return XEMALLOC;
    }

  if (!outsize)
    {
      debug_printf(DEBUG_NORMAL, "Invalid pointer to out size in eapotp_process()!\n");
      return XEMALLOC;
    }
  
  debug_printf(DEBUG_AUTHTYPES, "OTP/GTC packet dump : \n");
  debug_hex_printf(DEBUG_AUTHTYPES, dataoffs, insize);

  *outsize = 0;

  userdata = thisint->eap_conf_data;

  if (!userdata)
    {
      debug_printf(DEBUG_NORMAL, "Invalid configuration data in eapotp_process()!\n");
      return XENOUSERDATA;
    }

  if (thisint->tempPwd == NULL) 
    {
      otp_chal = (char *)malloc(insize+1);
      if (otp_chal == NULL)
	{
	  debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for OTP/GTC challenge!\n");
	  *outsize = 0;
	  return 0;
	}

      bzero(otp_chal, insize+1);

      memcpy(otp_chal, dataoffs, insize);
      debug_printf(DEBUG_NORMAL, "Challenge : %s\n",otp_chal);

      // We need a password.
      thisint->need_password = 1;
      thisint->eaptype = strdup("EAP-OTP/GTC");
      thisint->eapchallenge = otp_chal;

      *outsize = 0;
      return XENONE;
    }

  // Make sure we have something to process...
  if (dataoffs == NULL) return XENONE;


  /*  debug_printf(DEBUG_NORMAL, "Response : ");
      gets(&resp); */

  strcpy(outframe, resp);
  *outsize = strlen(resp);

  return *outsize;
}
Exemplo n.º 5
0
int socketInitializeLLDP(struct lldp_port *lldp_port)
{
    struct ifreq *ifr = malloc(sizeof(struct ifreq));
    struct sockaddr_ll *sll = malloc(sizeof(struct sockaddr_ll));
    int retval             = 0;

    if(lldp_port->if_name == NULL)
    {
        debug_printf(DEBUG_NORMAL, "Got NULL interface in %s():%d\n", __FUNCTION__, __LINE__);
        return XENOSOCK;
    }

    if(lldp_port->if_index <= 0)
    {
        debug_printf(DEBUG_NORMAL, "'%s' does not appear to be a valid interface name!\n", lldp_port->if_name);
        return XENOSOCK;
    }

    debug_printf(DEBUG_INT, "'%s' is index %d\n", lldp_port->if_name, lldp_port->if_index);

    // Set up the raw socket for the LLDP ethertype
    lldp_port->socket = socket(PF_PACKET, SOCK_RAW, htons(0x88CC));

    if(lldp_port->socket < 0)
    {
        debug_printf(DEBUG_NORMAL, "Couldn't initialize raw socket for interface %s!\n", lldp_port->if_name);
        return XENOSOCK;
    }

    // Set up the interface for binding
    sll->sll_family = PF_PACKET;
    sll->sll_ifindex = lldp_port->if_index;
    sll->sll_protocol = htons(0x88CC);

    // Bind the socket and the interface together to form a useable socket:
    retval = bind(lldp_port->socket, (struct sockaddr *)sll, sizeof(struct sockaddr_ll));

    if(retval < 0) {
        debug_printf(DEBUG_NORMAL, "Error binding raw socket to interface %s in %s():%d!\n", lldp_port->if_name, __FUNCTION__, __LINE__);

        return XENOSOCK;
    }

    ifr->ifr_ifindex = lldp_port->if_index;

    strncpy(ifr->ifr_name, &lldp_port->if_name[0], strlen(lldp_port->if_name));

    if(strlen(ifr->ifr_name) == 0) {
        debug_printf(DEBUG_NORMAL, "Invalid interface name in %s():%d\n", __FUNCTION__, __LINE__);
        return XENOSOCK;
    }
    
    retval = _getmac(lldp_port);

    if(retval < 0) {
        debug_printf(DEBUG_NORMAL, "Error getting hardware (MAC) address for interface '%s' in %s():%d - %d:%s!\n", lldp_port->if_name, __FUNCTION__, __LINE__, errno, strerror(errno));

        return retval;
    }

    debug_printf(DEBUG_INT, "Source MAC is: ");
    debug_hex_printf(DEBUG_INT, lldp_port->source_mac, 6);

    retval = _getip(lldp_port);

    if (retval < 0) {
        debug_printf(DEBUG_NORMAL, "Error getting interface IP address for interface '%s' in %s():%d!\n", lldp_port->if_name, __FUNCTION__, __LINE__);   
    }

    retval = ioctl(lldp_port->socket, SIOCGIFFLAGS, ifr);

    if (retval == -1)
    {
        debug_printf(DEBUG_NORMAL, "Can't get flags for interface '%s' in %s():%d!\n", lldp_port->if_name, __FUNCTION__, __LINE__);
    }


    if ((ifr->ifr_flags & IFF_UP) == 0) {

        debug_printf(DEBUG_INT, "Interface '%s' is down. portEnabled = 0.\n", lldp_port->if_name);  

        lldp_port->portEnabled = 0;
    } 

    // set allmulti on interface
    // need to devise a graceful way to turn off allmulti otherwise it is left on for the interface when problem is terminated.
    retval = ioctl(lldp_port->socket, SIOCGIFFLAGS, ifr);

    if (retval == -1)
    {
        debug_printf(DEBUG_NORMAL, "Can't get flags for interface '%s' in %s():%d!\n", lldp_port->if_name, __FUNCTION__, __LINE__);
    }

    ifr->ifr_flags |=  IFF_ALLMULTI; // allmulti on (verified via ifconfig)
    //  ifr.ifr_flags &= ~IFF_ALLMULTI; // allmulti off (I think)

    retval = ioctl(lldp_port->socket, SIOCSIFFLAGS, ifr);

    if (retval == -1)
    {
        debug_printf(DEBUG_NORMAL, "Can't set flags for interface '%s' in %s():%d!\n", lldp_port->if_name, __FUNCTION__, __LINE__);
    }

    // Discover MTU of our interface.
    retval = ioctl(lldp_port->socket, SIOCGIFMTU, ifr);

    if(retval < 0) 
    {
        debug_printf(DEBUG_NORMAL, "Can't determine MTU for interface '%s' in %s():%d!\n", lldp_port->if_name, __FUNCTION__, __LINE__);

        return retval;
    }   

    lldp_port->mtu = ifr->ifr_ifru.ifru_mtu;

    debug_printf(DEBUG_INT, "[%s] MTU is %d\n", lldp_port->if_name, lldp_port->mtu);

    lldp_port->rx.frame = malloc(lldp_port->mtu - 4);
    lldp_port->tx.frame = malloc((lldp_port->mtu - 2));

    if(!lldp_port->rx.frame) {
        debug_printf(DEBUG_NORMAL, "[ERROR] Unable to malloc buffer in %s() at line: %d!\n", __FUNCTION__, __LINE__);
    } else {
        debug_printf(DEBUG_INT, "Created framebuffer for %s at %x\n", lldp_port->if_name, &lldp_port->rx.frame);
    }

    if(!lldp_port->tx.frame) {
        debug_printf(DEBUG_NORMAL, "[ERROR] Unable to malloc buffer in %s() at line: %d!\n", __FUNCTION__, __LINE__);
    } else {
        debug_printf(DEBUG_INT, "Created framebuffer for %s at %x\n", lldp_port->if_name, &lldp_port->tx.frame);
    }

    debug_printf(DEBUG_INT, "Interface (%s) MTU is %d.\n", lldp_port->if_name, lldp_port->mtu);

    free(ifr);
    free(sll);

    return 0;
}