예제 #1
0
파일: netmask.c 프로젝트: BrEacK/mc
main ()
{
    char buf[1024];
    struct hostent *hp;
    struct in_addr ip, nmask;

    if (gethostname (buf, sizeof (buf) - 1) != 0)
    {
        fprintf (stderr, "gethostname failed\n");
        exit (1);
    }

    hp = gethostbyname (buf);

    if (!hp)
    {
        fprintf (stderr, "gethostbyname failed\n");
        exit (1);
    }

    memcpy ((char *) &ip, (char *) hp->h_addr, hp->h_length);

    if (get_netmask (&ip, &nmask) == 0)
        exit (0);

    fprintf (stderr, "get_netmask failed\n");
    exit (1);
}
예제 #2
0
static int
parse_addr(struct in_addr *addr, struct in_addr *net, const char *arg)
{
	char *p;
	int i;

	if (arg == NULL || *arg == '\0') {
		if (addr != NULL)
			addr->s_addr = 0;
		if (net != NULL)
			net->s_addr = 0;
		return 0;
	}
	if ((p = strchr(arg, '/')) != NULL) {
		*p++ = '\0';
		if (net != NULL &&
		    (sscanf(p, "%d", &i) != 1 ||
			inet_cidrtoaddr(i, net) != 0))
		{
			syslog(LOG_ERR, "`%s' is not a valid CIDR", p);
			return -1;
		}
	} 

	if (addr != NULL && inet_aton(arg, addr) == 0) {
		syslog(LOG_ERR, "`%s' is not a valid IP address", arg);
		return -1;
	}
	if (p != NULL)
		*--p = '/';
	else if (net != NULL)
		net->s_addr = get_netmask(addr->s_addr);
	return 0;
}
예제 #3
0
/**
 *      test case for get_netmask() functions 
 */
void 
TestEthernet::tcGet_netmask(void)
{
	cout << "获取掩码:" << endl;

	char *interface_name = NULL;
	char *strRetValue = NULL;

	if (get_netmask(interface_name, strRetValue))  
	{
		cout << "interface_name : " << interface_name << endl;
		cout << "strRetValue : " << strRetValue << endl;
	}
	else
	{
		cout << "获取掩码失败!" << endl;       
	}


	char interface_name1[] = "eth0";
	char *strRetValue1 = NULL;

	if (get_netmask(interface_name1, strRetValue1))  
	{
		cout << "interface_name : " << interface_name1 << endl;
		cout << "strRetValue : " << strRetValue1 << endl;
	}
	else
	{
		cout << "获取掩码失败!" << endl;       
	}


	char interface_name2[] = "abc";
	char *strRetValue2 = NULL;

	if (get_netmask(interface_name2, strRetValue2))  
	{
		cout << "interface_name : " << interface_name2 << endl;
		cout << "strRetValue : " << strRetValue2 << endl;
	}
	else
	{
		cout << "获取掩码失败!" << endl;       
	}
}
예제 #4
0
파일: ip.c 프로젝트: kzalewski/squirm
/* stores address & subnet in a 'struct cidr'
   assumes:
   address is already in 1.2.3.4 format
   subnet is in the format /24

   If subnet is incorrect, returns 1
*/
int load_cidr(char *cidr, struct cidr *subnet)
{
  struct in_addr addr, mask, comp;
  int valid = true;

  char *address, *copy, *strtok_netmask, *destroyable;
  static char *netmask;
  static int netmask_is_allocated = false;

  if(netmask_is_allocated) {
    if(netmask != NULL)
      free(netmask);
    netmask_is_allocated = false;
  }

  copy = safe_strdup(cidr);
  if (copy == NULL) {
    return 1;
  }

  destroyable = copy;

  address = strtok(destroyable, "/");
  strtok_netmask = strtok(NULL, "/");
  if(strtok_netmask == NULL) {
    netmask = safe_strdup("32");
    netmask_is_allocated = true;
  } else {
    netmask = safe_strdup(strtok_netmask);
    netmask_is_allocated = true;
  }

  if(netmask == NULL) {
    netmask_is_allocated = false;
    return 1;
  }

  addr = get_ip_address(address, &valid);
  if(!valid)
    return 1;

  mask = get_netmask(netmask, &valid);
  if(!valid)
    return 1;

  /* we now do a bitwise AND to find out if the network
     address given is valid */
  comp.s_addr = mask.s_addr & addr.s_addr;
  if(comp.s_addr != addr.s_addr) {
    return 1;
  }

  subnet->address = addr;
  subnet->netmask = mask;
  free(copy);
  return 0;
}
예제 #5
0
/**
 * Format a QString with the MySQL host portion for a remote host.  The
 * resulting string will use the local subnet and mask to generate something
 * like "192.168.1.0/255.255.255.0" .
 *
 * @param host string with the hostname to use for the subnet and mask.
 * @return QString with formated result.
 **/
QString format_remote_host(const char *hostname) {
  struct in_addr local_netmask;
  struct hostent *temp_hostent;
  struct in_addr local_ip;
  struct in_addr local_subnet;

  temp_hostent=gethostbyname(hostname);
  local_ip=*(struct in_addr *)temp_hostent->h_addr;
  // FIXME: ideally do something smarter than just testing eth0 (see above in check_remote_server() also)
  get_netmask("eth0", &local_netmask);
  local_subnet.s_addr=(local_ip.s_addr & local_netmask.s_addr);
  return QString().sprintf("%s/%s", strdupa(inet_ntoa(local_subnet)), strdupa(inet_ntoa(local_netmask)) );
}
예제 #6
0
int get_prefix_1(inet_prefix *dst, char *arg, int family)
{
	int err;
	unsigned plen;
	char *slash;

	memset(dst, 0, sizeof(*dst));

	if (strcmp(arg, "default") == 0 ||
	    strcmp(arg, "any") == 0 ||
	    strcmp(arg, "all") == 0) {
		if (family == AF_DECnet)
			return -1;
		dst->family = family;
		dst->bytelen = 0;
		dst->bitlen = 0;
		return 0;
	}

	slash = strchr(arg, '/');
	if (slash)
		*slash = 0;

	err = get_addr_1(dst, arg, family);
	if (err == 0) {
		switch(dst->family) {
			case AF_INET6:
				dst->bitlen = 128;
				break;
			case AF_DECnet:
				dst->bitlen = 16;
				break;
			default:
			case AF_INET:
				dst->bitlen = 32;
		}
		if (slash) {
			if (get_netmask(&plen, slash+1, 0)
					|| plen > dst->bitlen) {
				err = -1;
				goto done;
			}
			dst->flags |= PREFIXLEN_SPECIFIED;
			dst->bitlen = plen;
		}
	}
done:
	if (slash)
		*slash = '/';
	return err;
}
예제 #7
0
/**
 * Check if creating the database on the local machine or on a remote server in
 * the same subnet.
 *
 * @param host QString with the hostname of machine to create the database.
 * @return true if database is to be created on a remote server.
 **/
bool check_remote_server(QString host) {
  char local_hostname[256];
  int rc;
  struct hostent *temp_hostent;
  struct hostent local_hostent;
  struct hostent host_hostent;
  struct in_addr local_ip;
  struct in_addr host_ip;
  struct in_addr local_netmask;

  // check if host is 'localhost'
  if (0==strncasecmp("localhost", (const char *)host, 255))
    return false;

  rc=gethostname(local_hostname, 255);
  // compare hostnames
  if ((0==rc) && (0!=strncasecmp(local_hostname, (const char *)host, 255))) {
    if ((temp_hostent=gethostbyname(local_hostname)))
      local_hostent=*temp_hostent;
    else
      return false;
    local_ip=*(struct in_addr *)temp_hostent->h_addr;

    if ((temp_hostent=gethostbyname((const char *)host)))
      host_hostent=*temp_hostent;
    else
      return false;
    host_ip=*(struct in_addr *)temp_hostent->h_addr;

    // compare IPs
    if ((local_hostent.h_addrtype == AF_INET) &&
        (host_hostent.h_addrtype == AF_INET) &&
        (local_ip.s_addr != host_ip.s_addr)) {
      // FIXME: ideally do something smarter than just testing eth0 (note use
      // below in format_remote_host() also)
      //   get list of interfaces   if_nameindex()
      //   loop through list of interfaces, get IP, see if it matches local IP
      //   once have good interface, get netmask
      rc=get_netmask("eth0", &local_netmask);

      // compare if IPs are on same subnet.  note: use of bitwise sum
      if ( (local_ip.s_addr & local_netmask.s_addr) == 
                (host_ip.s_addr & local_netmask.s_addr) )
        return true;
    } // endif compare IPs
  } // endif compare hostnames
  return false;
}
예제 #8
0
파일: interface.c 프로젝트: Acidburn0zzz/mc
/****************************************************************************
  get the broadcast address for our address 
([email protected])
****************************************************************************/
static void
get_broadcast (struct in_addr *if_ipaddr, struct in_addr *if_bcast, struct in_addr *if_nmask)
{
    uint32 nm;
    short onbc;
    short offbc;

    /* get a default netmask and broadcast */
    default_netmask (if_nmask, if_ipaddr);

    get_netmask (if_ipaddr, if_nmask);

    /* sanity check on the netmask */
    nm = ntohl (if_nmask->s_addr);
    onbc = 0;
    offbc = 0;
    while ((onbc + offbc) < 32)
    {
        if (nm & 0x80000000)
        {
            onbc++;
            if (offbc)
            {
                /* already found an off bit, so mask
                   is wrong */
                onbc = 34;
            }
        }
        else
        {
            offbc++;
        }
        nm <<= 1;
    }
    if ((onbc < 8) || (onbc == 34))
    {
        DEBUG (0, ("Impossible netmask %s - using defaults\n", inet_ntoa (*if_nmask)));
        default_netmask (if_nmask, if_ipaddr);
    }

    /* derive the broadcast assuming a 1's broadcast, as this is what
       all MS operating systems do, we have to comply even if the unix
       box is setup differently */
    if_bcast->s_addr = MKBCADDR (if_ipaddr->s_addr, if_nmask->s_addr);

    DEBUG (4, ("Derived broadcast address %s\n", inet_ntoa (*if_bcast)));
}
예제 #9
0
파일: utils.c 프로젝트: onestraw/ip-xfrm
int get_prefix_1(inet_prefix *dst, char *arg, int family)
{
	int err;
	unsigned plen;
	char *slash;

	memset(dst, 0, sizeof(*dst));

	if (strcmp(arg, "default") == 0 ||
	    strcmp(arg, "any") == 0 ||
	    strcmp(arg, "all") == 0) {
		if ((family == AF_DECnet) || (family == AF_MPLS))
			return -1;
		dst->family = family;
		dst->bytelen = 0;
		dst->bitlen = 0;
		return 0;
	}

	slash = strchr(arg, '/');
	if (slash)
		*slash = 0;

	err = get_addr_1(dst, arg, family);
	if (err == 0) {
		dst->bitlen = af_bit_len(dst->family);

		if (slash) {
			if (get_netmask(&plen, slash+1, 0)
			    || plen > dst->bitlen) {
				err = -1;
				goto done;
			}
			dst->flags |= PREFIXLEN_SPECIFIED;
			dst->bitlen = plen;
		}
	}
done:
	if (slash)
		*slash = '/';
	return err;
}
예제 #10
0
파일: utils.c 프로젝트: dtaht/tc-adv
int get_prefix_1(inet_prefix *dst, char *arg, int family)
{
	char *slash;
	int err, bitlen, flags;

	slash = strchr(arg, '/');
	if (slash)
		*slash = 0;

	err = get_addr_1(dst, arg, family);

	if (slash)
		*slash = '/';

	if (err)
		return err;

	bitlen = af_bit_len(dst->family);

	flags = 0;
	if (slash) {
		unsigned int plen;

		if (dst->bitlen == -2)
			return -1;
		if (get_netmask(&plen, slash + 1, 0))
			return -1;
		if (plen > bitlen)
			return -1;

		flags |= PREFIXLEN_SPECIFIED;
		bitlen = plen;
	} else {
		if (dst->bitlen == -2)
			bitlen = 0;
	}

	dst->flags |= flags;
	dst->bitlen = bitlen;

	return 0;
}
예제 #11
0
int
main(int argc, char *argv[])
{
    struct dhcp_message *dhcp;
    struct dhcp_lease *lease;
    char leasefile[PATH_MAX];

    if (argc < 2) {
        fprintf(stderr, "Usage: %s <interface>\n", argv[0]);
        exit(1);
    }
    snprintf(leasefile, PATH_MAX, LEASEFILE, argv[1]);
    if ((dhcp = get_lease_from_file(leasefile)) == NULL) {
        fprintf(stderr, "Couldn't read lease file: %s\n", strerror(errno));
        exit(1);
    }
    lease = malloc(sizeof(*lease));
    lease->frominfo = 0;
    lease->addr.s_addr = dhcp->yiaddr;

    if (get_option_addr32(&lease->net.s_addr, dhcp, DHO_SUBNETMASK) == -1)
        lease->net.s_addr = get_netmask(dhcp->yiaddr);
    if (get_option_uint32(&lease->leasetime, dhcp, DHO_LEASETIME) != 0)
        lease->leasetime = DEFAULT_LEASETIME;
    get_option_addr32(&lease->server.s_addr, dhcp, DHO_SERVERID);
    /* Dm: limit lease time value to avoid negative numbers when
       converting to milliseconds */		
    if ((lease->leasetime != ~0U) && (lease->leasetime > MAX_LEASETIME))
        lease->leasetime = MAX_LEASETIME;
    if (get_option_uint32(&lease->renewaltime, dhcp, DHO_RENEWALTIME) != 0)
        lease->renewaltime = 0;
    if (get_option_uint32(&lease->rebindtime, dhcp, DHO_REBINDTIME) != 0)
        lease->rebindtime = 0;
    showlease(lease);
    free(lease);
    return 0;
}
예제 #12
0
ssize_t
configure_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
	      const struct options *options)
{
	unsigned int i;
	const uint8_t *p;
	int pl;
	struct in_addr addr;
	struct in_addr net;
	struct in_addr brd;
	char *val, *v;
	const struct dhcp_opt *opt;
	ssize_t len, e = 0;
	char **ep;
	char cidr[4];
	uint8_t overl = 0;

	get_option_uint8(&overl, dhcp, DHO_OPTIONSOVERLOADED);

	if (!env) {
		for (opt = dhcp_opts; opt->option; opt++) {
			if (!opt->var)
				continue;
			if (has_option_mask(options->nomask, opt->option))
				continue;
			if (get_option_raw(dhcp, opt->option))
				e++;
		}
		if (dhcp->yiaddr)
			e += 5;
		if (*dhcp->bootfile && !(overl & 1))
			e++;
		if (*dhcp->servername && !(overl & 2))
			e++;
		return e;
	}

	ep = env;
	if (dhcp->yiaddr) {
		/* Set some useful variables that we derive from the DHCP
		 * message but are not necessarily in the options */
		addr.s_addr = dhcp->yiaddr;
		setvar(&ep, prefix, "ip_address", inet_ntoa(addr));
		if (get_option_addr(&net, dhcp, DHO_SUBNETMASK) == -1) {
			net.s_addr = get_netmask(addr.s_addr);
			setvar(&ep, prefix, "subnet_mask", inet_ntoa(net));
		}
		i = inet_ntocidr(net);
		snprintf(cidr, sizeof(cidr), "%d", inet_ntocidr(net));
		setvar(&ep, prefix, "subnet_cidr", cidr);
		if (get_option_addr(&brd, dhcp, DHO_BROADCAST) == -1) {
			brd.s_addr = addr.s_addr | ~net.s_addr;
			setvar(&ep, prefix, "broadcast_address", inet_ntoa(brd));
		}
		addr.s_addr = dhcp->yiaddr & net.s_addr;
		setvar(&ep, prefix, "network_number", inet_ntoa(addr));
	}

	if (*dhcp->bootfile && !(overl & 1))
		setvar(&ep, prefix, "filename", (const char *)dhcp->bootfile);
	if (*dhcp->servername && !(overl & 2))
		setvar(&ep, prefix, "server_name", (const char *)dhcp->servername);

	for (opt = dhcp_opts; opt->option; opt++) {
		if (!opt->var)
			continue;
		if (has_option_mask(options->nomask, opt->option))
			continue;
		val = NULL;
		p = get_option(dhcp, opt->option, &pl, NULL);
		if (!p)
			continue;
		/* We only want the FQDN name */
		if (opt->option == DHO_FQDN) {
			p += 3;
			pl -= 3;
		}
		len = print_option(NULL, 0, opt->type, pl, p);
		if (len < 0)
			return -1;
		e = strlen(prefix) + strlen(opt->var) + len + 4;
		v = val = *ep++ = xmalloc(e);
		v += snprintf(val, e, "%s_%s=", prefix, opt->var);
		if (len != 0)
			print_option(v, len, opt->type, pl, p);
	}

	return ep - env;
}
예제 #13
0
int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message)
{
	const unsigned char *p = message->options;
	const unsigned char *end = p; /* Add size later for gcc-3 issue */
	unsigned char option;
	unsigned char length;
	unsigned int len = 0;
	int i;
	int retval = -1;
	struct timeval tv;
	route_t *routers = NULL;
	route_t *routersp = NULL;
	route_t *static_routes = NULL;
	route_t *static_routesp = NULL;
	route_t *csr = NULL;
	bool in_overload = false;
	bool parse_sname = false;
	bool parse_file = false;
 
 	end += sizeof (message->options);

	if (gettimeofday (&tv, NULL) == -1) {
		logger (LOG_ERR, "gettimeofday: %s", strerror (errno));
		return (-1);
	}

 	dhcp->address.s_addr = message->yiaddr;
	dhcp->leasedfrom = tv.tv_sec;
	dhcp->frominfo = false;
	dhcp->address.s_addr = message->yiaddr;
	strlcpy (dhcp->servername, (char *) message->servername,
			 sizeof (dhcp->servername));

#define LEN_ERR \
	{ \
		logger (LOG_ERR, "invalid length %d for option %d", length, option); \
		p += length; \
		continue; \
	}

parse_start:
	while (p < end) {
		option = *p++;
		if (! option)
			continue;

		if (option == DHCP_END)
			goto eexit;

		length = *p++;

		if (option != DHCP_PAD && length == 0) {
			logger (LOG_ERR, "option %d has zero length", option);
			retval = -1;
			goto eexit;
		}

		if (p + length >= end) {
			logger (LOG_ERR, "dhcp option exceeds message length");
			retval = -1;
			goto eexit;
		}

		switch (option) {
			case DHCP_MESSAGETYPE:
				retval = (int) *p;
				p += length;
				continue;

			default:
				if (length == 0) {
					logger (LOG_DEBUG, "option %d has zero length, skipping",
							option);
					continue;
				}
		}

#define LENGTH(_length) \
		if (length != _length) \
		LEN_ERR;
#define MIN_LENGTH(_length) \
		if (length < _length) \
		LEN_ERR;
#define MULT_LENGTH(_mult) \
		if (length % _mult != 0) \
		LEN_ERR;
#define GET_UINT8(_val) \
		LENGTH (sizeof (uint8_t)); \
		memcpy (&_val, p, sizeof (uint8_t));
#define GET_UINT16(_val) \
		LENGTH (sizeof (uint16_t)); \
		memcpy (&_val, p, sizeof (uint16_t));
#define GET_UINT32(_val) \
		LENGTH (sizeof (uint32_t)); \
		memcpy (&_val, p, sizeof (uint32_t));
#define GET_UINT16_H(_val) \
		GET_UINT16 (_val); \
		_val = ntohs (_val);
#define GET_UINT32_H(_val) \
		GET_UINT32 (_val); \
		_val = ntohl (_val);

		switch (option) {
			case DHCP_ADDRESS:
				GET_UINT32 (dhcp->address.s_addr);
				break;
			case DHCP_NETMASK:
				GET_UINT32 (dhcp->netmask.s_addr);
				break;
			case DHCP_BROADCAST:
				GET_UINT32 (dhcp->broadcast.s_addr);
				break;
			case DHCP_SERVERIDENTIFIER:
				GET_UINT32 (dhcp->serveraddress.s_addr);
				break;
			case DHCP_LEASETIME:
				GET_UINT32_H (dhcp->leasetime);
				break;
			case DHCP_RENEWALTIME:
				GET_UINT32_H (dhcp->renewaltime);
				break;
			case DHCP_REBINDTIME:
				GET_UINT32_H (dhcp->rebindtime);
				break;
			case DHCP_MTU:
				GET_UINT16_H (dhcp->mtu);
				/* Minimum legal mtu is 68 accoridng to RFC 2132.
				   In practise it's 576 (minimum maximum message size) */
				if (dhcp->mtu < MTU_MIN) {
					logger (LOG_DEBUG, "MTU %d is too low, minimum is %d; ignoring", dhcp->mtu, MTU_MIN);
					dhcp->mtu = 0;
				}
				break;

#undef GET_UINT32_H
#undef GET_UINT32
#undef GET_UINT16_H
#undef GET_UINT16
#undef GET_UINT8

#define GETSTR(_var) \
				MIN_LENGTH (sizeof (char)); \
				if (_var) free (_var); \
				_var = xmalloc (length + 1); \
				memcpy (_var, p, length); \
				memset (_var + length, 0, 1);
			case DHCP_HOSTNAME:
				GETSTR (dhcp->hostname);
				break;
			case DHCP_DNSDOMAIN:
				GETSTR (dhcp->dnsdomain);
				break;
			case DHCP_MESSAGE:
				GETSTR (dhcp->message);
				break;
			case DHCP_ROOTPATH:
				GETSTR (dhcp->rootpath);
				break;
			case DHCP_NISDOMAIN:
				GETSTR (dhcp->nisdomain);
				break;
#undef GETSTR

#define GETADDR(_var) \
				MULT_LENGTH (4); \
				if (! dhcp_add_address (&_var, p, length)) \
				{ \
					retval = -1; \
					goto eexit; \
				}
			case DHCP_DNSSERVER:
				GETADDR (dhcp->dnsservers);
				break;
			case DHCP_NTPSERVER:
				GETADDR (dhcp->ntpservers);
				break;
			case DHCP_NISSERVER:
				GETADDR (dhcp->nisservers);
				break;
#undef GETADDR

			case DHCP_DNSSEARCH:
				MIN_LENGTH (1);
				free (dhcp->dnssearch);
				if ((len = decode_search (p, length, NULL)) > 0) {
					dhcp->dnssearch = xmalloc (len);
					decode_search (p, length, dhcp->dnssearch);
				}
				break;

			case DHCP_CSR:
				MIN_LENGTH (5);
				free_route (csr);
				csr = decode_CSR (p, length);
				break;

			case DHCP_SIPSERVER:
				free (dhcp->sipservers);
				dhcp->sipservers = decode_sipservers (p, length);
				break;

			case DHCP_STATICROUTE:
				MULT_LENGTH (8);
				for (i = 0; i < length; i += 8) {
					if (static_routesp) {
						static_routesp->next = xmalloc (sizeof (route_t));
						static_routesp = static_routesp->next;
					} else
						static_routesp = static_routes = xmalloc (sizeof (route_t));
					memset (static_routesp, 0, sizeof (route_t));
					memcpy (&static_routesp->destination.s_addr, p + i, 4);
					memcpy (&static_routesp->gateway.s_addr, p + i + 4, 4);
					static_routesp->netmask.s_addr =
						route_netmask (static_routesp->destination.s_addr); 
				}
				break;

			case DHCP_ROUTERS:
				MULT_LENGTH (4); 
				for (i = 0; i < length; i += 4)
				{
					if (routersp) {
						routersp->next = xmalloc (sizeof (route_t));
						routersp = routersp->next;
					} else
						routersp = routers = xmalloc (sizeof (route_t));
					memset (routersp, 0, sizeof (route_t));
					memcpy (&routersp->gateway.s_addr, p + i, 4);
				}
				break;

			case DHCP_OPTIONSOVERLOADED:
				LENGTH (1);
				/* The overloaded option in an overloaded option
				 * should be ignored, overwise we may get an infinite loop */
				if (! in_overload) {
					if (*p & 1)
						parse_file = true;
					if (*p & 2)
						parse_sname = true;
				}
				break;

#undef LENGTH
#undef MIN_LENGTH
#undef MULT_LENGTH

			default:
				logger (LOG_DEBUG, "no facility to parse DHCP code %u", option);
				break;
		}

		p += length;
	}

eexit:
	/* We may have options overloaded, so go back and grab them */
	if (parse_file) {
		parse_file = false;
		p = message->bootfile;
		end = p + sizeof (message->bootfile);
		in_overload = true;
		goto parse_start;
	} else if (parse_sname) {
		parse_sname = false;
		p = message->servername;
		end = p + sizeof (message->servername);
		memset (dhcp->servername, 0, sizeof (dhcp->servername));
		in_overload = true;
		goto parse_start;
	}

	/* Fill in any missing fields */
	if (! dhcp->netmask.s_addr)
		dhcp->netmask.s_addr = get_netmask (dhcp->address.s_addr);
	if (! dhcp->broadcast.s_addr)
		dhcp->broadcast.s_addr = dhcp->address.s_addr | ~dhcp->netmask.s_addr;

	/* If we have classess static routes then we discard
	   static routes and routers according to RFC 3442 */
	if (csr) {
		dhcp->routes = csr;
		free_route (routers);
		free_route (static_routes);
	} else {
		/* Ensure that we apply static routes before routers */
		if (static_routes)
		{
			dhcp->routes = static_routes;
			static_routesp->next = routers;
		} else
			dhcp->routes = routers;
	}

	return retval;
}
예제 #14
0
int packet_filter()
{
	char *dev, *nextdev;
	bpf_u_int32 mask;
	bpf_u_int32 net;
	struct bpf_program fp;
	char filter_exp[] = "ip and not dst host 172.16.205.1";
	char errbuf[PCAP_ERRBUF_SIZE];
	struct pcap_pkthdr header;
	const u_char *packet;
	libnet_t *int_llif, *ext_llif;
	struct ether_addr *t_hwaddr;
	pthread_t ntid;


/*	if ((dev = pcap_lookupdev(errbuf)) == NULL) {
		fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
		return(2);
	}
	printf("Device: %s\n", dev);
*/

	if (get_default_gateway(&def_gw) != 0) {
		fprintf(stderr, "Couldn't get default gateway\n");
		return(2);
	}
	printf("gw: %s\n", inet_ntoa(def_gw));

	/* initialize handler/filter for external network interface */
	dev = ext_ifname;
	if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
		fprintf(stderr, "Couldn't get netmask for the device %s\n", dev);
		return(2);
	}
	printf("net: %s, mask %s\n", inet_ntoa(*(struct in_addr *)&net), inet_ntoa(*(struct in_addr *)&mask));
	if ((ext_if = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf)) == NULL) {
		fprintf(stderr, "Couldn't open device %s: %s\n", dev,errbuf);
		return(2);
	}

	if(pcap_compile(ext_if, &fp, filter_exp, 0, net) == -1) {
		fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(ext_if));
		return(2);
	}
	if(pcap_setfilter(ext_if, &fp) == -1) {
		fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(ext_if));
		return(2);
	}
	if ((ext_llif = libnet_init(LIBNET_LINK, ext_ifname, errbuf)) == 0) {
		fprintf(stderr, "Couldn't open local network interface %s: %s\n", ext_ifname, errbuf);
		return(2);
	}
	if ((*((u_int *)&ext_ip) = libnet_get_ipaddr4(ext_llif)) == -1) {
		fprintf(stderr, "Couldn't get local ip address for %s \n", ext_ifname);
		return(2);
	}
	if ((t_hwaddr = (struct ether_addr *)libnet_get_hwaddr(ext_llif)) == NULL) {
		fprintf(stderr, "Couldn't get local network interface address for %s \n", ext_ifname);
		return(2);
	}
	memcpy((u_char *)&ext_hwaddr, (u_char *)t_hwaddr, ETHER_ADDR_LEN);
	libnet_destroy(ext_llif);
	if (get_netmask(ext_ifname, &ext_mask) == -1) {
		fprintf(stderr, "Couldn't get local netmask for %s \n", ext_ifname);
		return(2);
	}
	printf("ext_ip : %s ", inet_ntoa(ext_ip) );
	printf("ext_ip : %s\n", inet_ntoa(ext_mask));
	
	/* initialize handler/filter for internal network interface */
	dev = int_ifname;
	if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
		fprintf(stderr, "Couldn't get netmask for the device %s\n", dev);
		return(2);
	}
	printf("net: %s, mask %s\n", inet_ntoa(*(struct in_addr *)&net), inet_ntoa(*(struct in_addr *)&mask));
	if ((int_if = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf)) == NULL) {
		fprintf(stderr, "Couldn't open device %s: %s\n", dev,errbuf);
		return(2);
	}

	if(pcap_compile(int_if, &fp, filter_exp, 0, net) == -1) {
		fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(int_if));
		return(2);
	}
	if(pcap_setfilter(int_if, &fp) == -1) {
		fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(int_if));
		return(2);
	}
	if ((int_llif = libnet_init(LIBNET_LINK, int_ifname, errbuf)) == 0) {
		fprintf(stderr, "Couldn't open local network interface %s: %s\n", int_ifname, errbuf);
		return(2);
	}
	if ((*((u_int *)&int_ip) = libnet_get_ipaddr4(int_llif)) == -1) {
		fprintf(stderr, "Couldn't get local ip address for %s \n", int_ifname);
		return(2);
	}
	if ((t_hwaddr = (struct ether_addr *)libnet_get_hwaddr(int_llif)) == NULL) {
		fprintf(stderr, "Couldn't get local network interface address for %s \n", int_ifname);
		return(2);
	}
	memcpy((u_char *)&int_hwaddr, (u_char *)t_hwaddr, ETHER_ADDR_LEN);
	libnet_destroy(int_llif);

	if (pthread_create(&ntid, NULL, clean_thread, NULL) != 0) {
		fprintf(stderr, "Couldn't create thread\n");
	}
	if (pthread_create(&ntid, NULL, ext_thread, NULL) != 0) {
		fprintf(stderr, "Couldn't create thread\n");
	}
	if(pcap_loop(int_if, -1, got_packet, (void *)FROM_INT) == -1) {
		fprintf(stderr, "Couldn't  filte packet %s: %s\n", filter_exp, pcap_geterr(int_if));
	}

	pcap_close(int_if);
	return(0);
}