Esempio n. 1
0
/** Create ip_address out of xfrm_address_t.
 * 
 * @param family 
 * @param src xfrm formatted IP address
 * @param dst ip_address formatted destination 
 * @return err_t NULL if okay, otherwise an error
 */
static err_t
xfrm_to_ip_address(unsigned family, const xfrm_address_t *src, ip_address *dst)
{
    switch (family)
    {
    case AF_INET: /* IPv4 */
	initaddr((const void *) &src->a4, sizeof(src->a4), family, dst);
	return NULL;
    case AF_INET6: /* IPv6 */
	initaddr((const void *) &src->a6, sizeof(src->a6), family, dst);
	return NULL;
    default:
	return "unknown address family";
    }
}
Esempio n. 2
0
/*
 - anyaddr - initialize to the any-address value
 */
err_t anyaddr(int af, ip_address * dst)
{
	uint32_t v4any = htonl(INADDR_ANY);

	switch (af) 
	{
		case AF_INET:
			return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
			break;
		case AF_INET6:
			return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
			break;
		default:
			return "unknown address family in anyaddr/unspecaddr";
			break;
	}
}
int
starter_iface_find(char *iface, int af, ip_address *dst, ip_address *nh)
{
    char *phys;
    struct ifreq req;
    struct sockaddr_in *sa = (struct sockaddr_in *)(&req.ifr_addr);
    int sock;

    if (!iface)
	return -1;

    sock = socket(af, SOCK_DGRAM, 0);
    if (sock < 0)
	return -1;

    phys = _find_physical_iface(sock, iface);
    if (!phys)
	goto failed;

    strncpy(req.ifr_name, phys, IFNAMSIZ);
    if (ioctl(sock, SIOCGIFFLAGS, &req)!=0)
	goto failed;
    if (!(req.ifr_flags & IFF_UP))
	 goto failed;

    if ((req.ifr_flags & IFF_POINTOPOINT)
    && nh
    && ioctl(sock, SIOCGIFDSTADDR, &req) == 0)
    {
	if (sa->sin_family == af)
	    initaddr((const void *)&sa->sin_addr, sizeof(struct in_addr), af, nh);
    }
    if ((dst) && (ioctl(sock, SIOCGIFADDR, &req) == 0))
    {
	if (sa->sin_family == af)
	    initaddr((const void *)&sa->sin_addr, sizeof(struct in_addr), af, dst);
    }
    close(sock);
    return 0;

failed:
    close(sock);
    return -1;
}
Esempio n. 4
0
int open_clientsock(char * address, int port)
{
  struct sockaddr_in servadr;
  int client_handle;
 
  /* Create a new socket */
  if ((client_handle = socket (AF_INET, SOCK_STREAM, 0)) == -1)
    exit_fatal ("Error opening socket Abort !");
  
/* Now set the server address struct and connect client socket to the port*/
  initaddr (&servadr,address,port);

  if (connect(client_handle,(struct sockaddr *) &servadr,
       sizeof (struct sockaddr)) == -1)
	  exit_fatal ("connect failed Abort !");
  return client_handle;
}
Esempio n. 5
0
int
open_sock (int port)
{

  struct sockaddr_in servadr;
  int server_handle;
  int O_on = 1;
/* Create a new socket */
  if ((server_handle = socket (AF_INET, SOCK_STREAM, 0)) == -1)
    exit_fatal ("Error opening socket Abort !");
  if (setsockopt (server_handle, SOL_SOCKET, SO_REUSEADDR, &O_on, sizeof (int)) == -1)
    exit_fatal ("Setting reused address fail Abort !");
/* Now set the server address struct and bind socket to the port*/
  initaddr (&servadr,NULL, port);
  if (bind 
      (server_handle, (struct sockaddr *) &servadr,
       sizeof (struct sockaddr)) == -1)
    exit_fatal ("error bind socket");
/* Listen on the socket */
  if (listen (server_handle, MAXCONNECT) == -1)
    exit_fatal ("Damned errors when listen Abort !");
  return server_handle;
}
Esempio n. 6
0
void recv_pcap_packet_gen(u_char *user,
			  const struct pcap_pkthdr *h,
			  const u_char *bytes)
{
	struct msg_digest *md;
	u_int32_t *dlt;
	struct iphdr  *ip;
	struct udphdr *udp;
	u_char    *ike;
	const struct iface_port *ifp = &if1;
	int packet_len;
	err_t from_ugh;

	union {
		struct sockaddr sa;
		struct sockaddr_in sa_in4;
		struct sockaddr_in6 sa_in6;
	} from;

	md = alloc_md();
	dlt = (u_int32_t *)bytes;
	if (*dlt != PF_INET)
		return;

	ip  = (struct iphdr *)(dlt + 1);
	udp = (struct udphdr *)(dlt + ip->ihl + 1);
	ike = (u_char *)(udp + 1);

	from.sa_in4.sin_addr.s_addr = ip->saddr;
	from.sa_in4.sin_port        = udp->source;

	md->iface = ifp;
	packet_len = h->len - (ike - bytes);

	happy(anyaddr(addrtypeof(&ifp->ip_addr), &md->sender));

	from_ugh = initaddr((void *) &from.sa_in4.sin_addr,
			    sizeof(from.sa_in4.sin_addr),
			    AF_INET, &md->sender);
	setportof(from.sa_in4.sin_port, &md->sender);
	md->sender_port = ntohs(from.sa_in4.sin_port);

	cur_from      = &md->sender;
	cur_from_port = md->sender_port;

	/* Clone actual message contents
	 * and set up md->packet_pbs to describe it.
	 */
	init_pbs(&md->packet_pbs,
		 clone_bytes(ike, packet_len,
			     "message buffer in comm_handle()"),
		 packet_len, "packet");

	DBG_log("*received %d bytes from %s:%u on %s (port=%d)",
		(int) pbs_room(&md->packet_pbs),
		ip_str(&md->sender), (unsigned) md->sender_port,
		ifp->ip_dev->id_rname,
		ifp->port);

	DBG_dump("", md->packet_pbs.start, pbs_room(&md->packet_pbs));

	process_packet(&md);

	if (md != NULL)
		release_md(md);

	cur_state = NULL;
	reset_cur_connection();
	cur_from = NULL;
}
Esempio n. 7
0
struct raw_iface *
find_raw_ifaces4(void)
{
    static const int on = TRUE;	/* by-reference parameter; constant, we hope */
    int j;	/* index into buf */
    static int    num=64;    /* number of interfaces */
    struct ifconf ifconf;
    struct ifreq *buf;	     /* for list of interfaces -- arbitrary limit */
    struct raw_iface *rifaces = NULL;
    int master_sock = safe_socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);    /* Get a UDP socket */

    /* get list of interfaces with assigned IPv4 addresses from system */

    if (master_sock == -1)
	exit_log_errno((e, "socket() failed in find_raw_ifaces4()"));

    if (setsockopt(master_sock, SOL_SOCKET, SO_REUSEADDR
		   , (const void *)&on, sizeof(on)) < 0)
	    exit_log_errno((e, "setsockopt() in find_raw_ifaces4()"));

    /* bind the socket */
    {
	ip_address any;

	happy(anyaddr(AF_INET, &any));
	setportof(htons(pluto_port), &any);
	if (bind(master_sock, sockaddrof(&any), sockaddrlenof(&any)) < 0)
	    exit_log_errno((e, "bind() failed in find_raw_ifaces4()"));
    }

    buf = NULL;
   
    /* a million interfaces is probably the maximum, ever... */
    while(num < (1024*1024)) {
	    /* Get local interfaces.  See netdevice(7). */
	    ifconf.ifc_len = num * sizeof(struct ifreq);
	    buf = (void *) realloc(buf, ifconf.ifc_len);
	    if (!buf)
		    exit_log_errno((e, "realloc of %d in find_raw_ifaces4()",
				    ifconf.ifc_len));
	    memset(buf, 0, num*sizeof(struct ifreq));
	    ifconf.ifc_buf = (void *) buf;
	    
	    if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
		    exit_log_errno((e, "ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));
	    
	    /* if we got back less than we asked for, we have them all */
	    if (ifconf.ifc_len < (int)(sizeof(struct ifreq) * num))
		    break;
	    
	    /* try again and ask for more this time */
	    num *= 2;
    }
  
    /* Add an entry to rifaces for each interesting interface. */
    for (j = 0; (j+1) * sizeof(struct ifreq) <= (size_t)ifconf.ifc_len; j++)
    {
	struct raw_iface ri;
	const struct sockaddr_in *rs = (struct sockaddr_in *) &buf[j].ifr_addr;
	struct ifreq auxinfo;

	/* ignore all but AF_INET interfaces */
	if (rs->sin_family != AF_INET)
	    continue;	/* not interesting */

	/* build a NUL-terminated copy of the rname field */
	memcpy(ri.name, buf[j].ifr_name, IFNAMSIZ);
	ri.name[IFNAMSIZ] = '\0';

	/* ignore if our interface names were specified, and this isn't one */
	if (pluto_ifn_roof != 0)
	{
	    int i;

	    for (i = 0; i != pluto_ifn_roof; i++)
		if (streq(ri.name, pluto_ifn[i]))
		    break;
	    if (i == pluto_ifn_roof)
		continue;	/* not found -- skip */
	}

	/* Find out stuff about this interface.  See netdevice(7). */
	zero(&auxinfo);	/* paranoia */
	memcpy(auxinfo.ifr_name, buf[j].ifr_name, IFNAMSIZ);
	if (ioctl(master_sock, SIOCGIFFLAGS, &auxinfo) == -1)
	    exit_log_errno((e
		, "ioctl(SIOCGIFFLAGS) for %s in find_raw_ifaces4()"
		, ri.name));
	if (!(auxinfo.ifr_flags & IFF_UP))
	   {
		DBG(DBG_CONTROL, DBG_log("Ignored interface %s - it is not up"
	    , ri.name));
	    continue;	/* ignore an interface that isn't UP */
	   }
        if (auxinfo.ifr_flags & IFF_SLAVE)
	   {
		DBG(DBG_CONTROL, DBG_log("Ignored interface %s - it is a slave interface"
	    , ri.name));
            continue;   /* ignore slave interfaces; they share IPs with their master */
	   }

	/* ignore unconfigured interfaces */
	if (rs->sin_addr.s_addr == 0)
	   {
		DBG(DBG_CONTROL, DBG_log("Ignored interface %s - it is unconfigured"
	    , ri.name));
	    continue;
	   }

	happy(initaddr((const void *)&rs->sin_addr, sizeof(struct in_addr)
	    , AF_INET, &ri.addr));

	DBG(DBG_CONTROL, DBG_log("found %s with address %s"
	    , ri.name, ip_str(&ri.addr)));
	ri.next = rifaces;
	rifaces = clone_thing(ri, "struct raw_iface");
    }

    close(master_sock);

    return rifaces;
}
Esempio n. 8
0
err_t parse_redirect_payload(pb_stream *input_pbs,
			     const char *allowed_targets_list,
			     const chunk_t *nonce,
			     ip_address *redirect_ip /* result */)
{
	struct ikev2_redirect_part gw_info;

	if (!in_struct(&gw_info, &ikev2_redirect_desc, input_pbs, NULL))
		return "received deformed REDIRECT payload";

	int af;

	switch (gw_info.gw_identity_type) {
	case GW_IPV4:
		af = AF_INET;
		break;
	case GW_IPV6:
		af = AF_INET6;
		break;
	case GW_FQDN:
		af  = AF_UNSPEC;
		break;
	default:
		return "bad GW Ident Type";
	}

	/* in_raw() actual GW Identity */
	switch (af) {
	case AF_UNSPEC:
	{
		/*
		 * The FQDN string isn't NUL-terminated.
		 *
		 * The length is stored in a byte so it cannot be
		 * larger than 0xFF.
		 * Some helpful compilers moan about this test being always true
		 * so I eliminated it:
		 *	passert(gw_info.gw_identity_len <= 0xFF);
		 */
		unsigned char gw_str[0xFF];

		if (!in_raw(&gw_str, gw_info.gw_identity_len, input_pbs, "GW Identity"))
			return "error while extracting GW Identity from variable part of IKEv2_REDIRECT Notify payload";

		err_t ugh = ttoaddr((char *) gw_str, gw_info.gw_identity_len,
					AF_UNSPEC, redirect_ip);
		if (ugh != NULL)
			return ugh;
		break;
	}
	case AF_INET:
	case AF_INET6:
	{
		if (pbs_left(input_pbs) < gw_info.gw_identity_len)
			return "variable part of payload is smaller than transfered GW Identity Length";

		/* parse address directly to redirect_ip */
		err_t ugh = initaddr(input_pbs->cur, gw_info.gw_identity_len, af, redirect_ip);
		if (ugh != NULL)
			return ugh;

		DBG(DBG_PARSING, {
			ip_address_buf b;
			DBG_log("   GW Identity IP: %s", ipstr(redirect_ip, &b));
		});
		input_pbs->cur += gw_info.gw_identity_len;
		break;
	}
	}
Esempio n. 9
0
struct raw_iface *find_raw_ifaces4(void)
{
	static const int on = TRUE;	/* by-reference parameter; constant, we hope */
	int j;	/* index into buf */
	struct ifconf ifconf;
	struct ifreq *buf = NULL;	/* for list of interfaces -- arbitrary limit */
	struct ifreq *bp;	/* cursor into buf */
	struct raw_iface *rifaces = NULL;
	int master_sock = safe_socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);        /* Get a UDP socket */

	/*
	 * Current upper bound on number of interfaces.
	 * Tricky: because this is a static, we won't have to start from
	 * 64 in subsequent calls.
	 */
	static int num = 64;	/* number of interfaces */

	/* get list of interfaces with assigned IPv4 addresses from system */

	if (master_sock == -1)
		exit_log_errno((e, "socket() failed in find_raw_ifaces4()"));

	if (setsockopt(master_sock, SOL_SOCKET, SO_REUSEADDR,
		       (const void *)&on, sizeof(on)) < 0)
		exit_log_errno((e, "setsockopt() in find_raw_ifaces4()"));

	/* bind the socket */
	{
		ip_address any;

		happy(anyaddr(AF_INET, &any));
		setportof(htons(pluto_port), &any);
		if (bind(master_sock, sockaddrof(&any),
			 sockaddrlenof(&any)) < 0)
			exit_log_errno((e,
					"bind() failed in find_raw_ifaces4()"));
	}

	/* a million interfaces is probably the maximum, ever... */
	for (; num < (1024 * 1024); num *= 2) {
		/* Get num local interfaces.  See netdevice(7). */
		ifconf.ifc_len = num * sizeof(struct ifreq);
		buf = realloc(buf, ifconf.ifc_len);
		if (buf == NULL) {
			exit_log_errno((e,
					"realloc of %d in find_raw_ifaces4()",
					ifconf.ifc_len));
		}
		memset(buf, 0xDF, ifconf.ifc_len);	/* stomp */
		ifconf.ifc_buf = (void *) buf;

		if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
			exit_log_errno((e,
					"ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));


		/* if we got back less than we asked for, we have them all */
		if (ifconf.ifc_len < (int)(sizeof(struct ifreq) * num))
			break;
	}

	/* Add an entry to rifaces for each interesting interface.
	   On Apple, the size of struct ifreq depends on the contents of
	   the union. See if.h */
	for (bp = buf, j = 0;
	     bp < (unsigned char *)buf + (size_t)ifconf.ifc_len;
	     bp = (struct ifreq *)
		((unsigned char *)bp +_SIZEOF_ADDR_IFREQ(*bp)),
	     j++) {
		struct raw_iface ri;
		const struct sockaddr_in *rs =
			(struct sockaddr_in *) &bp->ifr_addr;
		struct ifreq auxinfo;

		/* ignore all but AF_INET interfaces */
		if (rs->sin_family != AF_INET)
			continue; /* not interesting */

		/* build a NUL-terminated copy of the rname field */
		memcpy(ri.name, bp->ifr_name, IFNAMSIZ);
		ri.name[IFNAMSIZ] = '\0';

		/* ignore if our interface names were specified, and this isn't one */
		if (pluto_ifn_roof != 0) {
			int i;

			for (i = 0; i != pluto_ifn_roof; i++)
				if (streq(ri.name, pluto_ifn[i]))
					break;
			if (i == pluto_ifn_roof)
				continue; /* not found -- skip */
		}

		/* Find out stuff about this interface.  See netdevice(7). */
		zero(&auxinfo); /* paranoia */
		memcpy(auxinfo.ifr_name, bp->ifr_name, IFNAMSIZ);
		if (ioctl(master_sock, SIOCGIFFLAGS, &auxinfo) == -1) {
			exit_log_errno((e,
					"ioctl(SIOCGIFFLAGS) for %s in find_raw_ifaces4()",
					ri.name));
		}
		if (!(auxinfo.ifr_flags & IFF_UP))
			continue; /* ignore an interface that isn't UP */

		/* ignore unconfigured interfaces */
		if (rs->sin_addr.s_addr == 0)
			continue;

		happy(initaddr((const void *)&rs->sin_addr,
			       sizeof(struct in_addr),
			       AF_INET, &ri.addr));

		DBG(DBG_CONTROL, {
			ipstr_buf b;
			DBG_log("found %s with address %s",
				ri.name, ipstr(&ri.addr, &b));
		});
		ri.next = rifaces;
		rifaces = clone_thing(ri, "struct raw_iface");
	}
Esempio n. 10
0
/*
 * Process an incoming DAG Advertisement Object.
 * the DAO is the upward announcement.
 *
 */
void dag_network::receive_dao(network_interface *iface,
                              struct in6_addr from,
                              struct in6_addr ip6_to,
                              const time_t    now,
                              const struct nd_rpl_dao *dao,
                              unsigned char *data, int dao_len)
{
    /* it has already been checked to be at least sizeof(*dio) */
    //int dao_payload_len = dao_len - sizeof(*dao);

    /* increment stat of number of packets processed */
    this->mStats[PS_PACKET_RECEIVED]++;
    this->mStats[PS_DAO_PACKET_RECEIVED]++;

    /* validate this packet, if possible */
    bool secure = this->check_security(dao, dao_len);

    rpl_node *peer;

    /* find the node entry from this source IP, and update seen time */
    /* this will create the node if it does not already exist! */
    if((peer = this->update_child(iface, from, ip6_to, now)) == NULL) {
        return;
    }

    if(mActive == false) {
	this->mStats[PS_PACKETS_WATCHED]++;
	return;
    }

    /* look for the suboptions, process them */
    rpl_dao decoded_dao(data, dao_len, this);
    unsigned int addrcount = 0;

    struct rpl_dao_target *rpltarget;
    while((rpltarget = decoded_dao.rpltarget()) != NULL) {
        char addrfound[SUBNETTOT_BUF];
        unsigned char v6bytes[16];
        int prefixbytes = ((rpltarget->rpl_dao_prefixlen+7) / 8);
        ip_subnet prefix;
        prefix.maskbits = rpltarget->rpl_dao_prefixlen;
        memset(v6bytes, 0, 16);
        memcpy(v6bytes, rpltarget->rpl_dao_prefix, prefixbytes);
        initaddr(v6bytes, 16, AF_INET6, &prefix.addr);

        addrcount++;

        subnettot(&prefix, 0, addrfound, sizeof(addrfound));


        /* need to look at dag_members, and see if the child node already
         * exists, and add if not
         */
        debug->verbose("  recv DAO rpltarget re: network %s, target %s (added)\n",
                       addrfound, peer->node_name());

        add_childnode(peer, iface, prefix);
    }
    maybe_send_dao();

    /* now send a DAO-ACK back this the node, using the interface it arrived on, if asked to. */
    if(RPL_DAO_K(dao->rpl_flags)) {
        debug->verbose("sending DAOACK about %u networks, to %s\n",
                       addrcount, peer->node_name());
        iface->send_daoack(*peer, *this, dao->rpl_daoseq);
    }

    /* increment stat of number of packets processed */
    this->mStats[PS_PACKET_PROCESSED]++;
}
Esempio n. 11
0
void dag_network::potentially_lower_rank(rpl_node &peer,
                                         network_interface *iface,
                                         const struct nd_rpl_dio *dio,
                                         int dio_len)
{
    unsigned int rank = ntohs(dio->rpl_dagrank);

    debug->verbose("  does peer '%s' have better rank? (%u < %u)\n",
                   peer.node_name(), rank, mBestRank);

    this->mStats[PS_LOWER_RANK_CONSIDERED]++;

    if(rank > mBestRank) {
        this->mStats[PS_LOWER_RANK_REJECTED]++;
        return;
    }

    debug->verbose("  Yes, '%s' has best rank %u\n",
                   peer.node_name(), rank);

    if(dag_bestparent == &peer || dag_parent == &peer) {
	debug->verbose("  But it is the same parent as before: ignored\n");
        this->mStats[PS_SAME_PARENT_IGNORED]++;
	return;
    }
    /* XXX
     * this is actually quite a big deal (SEE rfc6550), setting my RANK.
     * just fake it for now by adding 1.
     */
    if(mDTSN != INVALID_SEQUENCE && mDTSN >= dio->rpl_dtsn) {
	debug->verbose("  Same sequence number, ignore\n");
        this->mStats[PS_SAME_SEQUENCE_IGNORED]++;
	return;
    }

    mDTSN     = dio->rpl_dtsn;
    mBestRank     = rank;

    /* XXX
     * this is actually quite a big deal (SEE rfc6550), setting my RANK.
     * just fake it for now by adding 1.
     */
    mMyRank       = rank + 1;   // XXX
    mGrounded     = RPL_DIO_GROUNDED(dio->rpl_mopprf);
    mInstanceid   = dio->rpl_instanceid;
    mVersion      = dio->rpl_version;
    mMode         = RPL_DIO_MOP(dio->rpl_mopprf);

    dag_bestparentif = iface;
    dag_bestparent   = &peer;

    /* now see if we have already an address on this new network */
    /*
     * to do this, we have to crack open the DIO.  UP to this point
     * we haven't taken the DIO apart, so do, keeping stuff on the stack.
     */
    rpl_dio decoded_dio(peer, this, dio, dio_len);

    unsigned int optcount = 0;

    struct rpl_dio_destprefix *dp;
    while((dp = decoded_dio.destprefix()) != NULL) {
        unsigned char v6bytes[16];
        int prefixbytes = ((dp->rpl_dio_prefixlen+7) / 8);
        ip_subnet prefix;
        prefix.maskbits = dp->rpl_dio_prefixlen;
        memset(v6bytes, 0, 16);
        memcpy(v6bytes, dp->rpl_dio_prefix, prefixbytes);
        initaddr(v6bytes, 16, AF_INET6, &prefix.addr);

        optcount++;
        add_prefix(peer, iface, prefix);
    }
    debug->verbose("  processed %u pio options\n", optcount);

    /* now schedule sending out packets */
    if(dag_parent) {
        /* can only send DIOs once we are sure about our parent! */
        maybe_schedule_dio();
    }
    maybe_send_dao();
}