Esempio n. 1
0
/**
 * Logs information about a connection to the console.
 */
static void
blesplit_print_conn_desc(struct ble_gap_conn_desc *desc)
{
    BLESPLIT_LOG(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=",
                desc->conn_handle, desc->our_ota_addr.type);
    print_addr(desc->our_ota_addr.val);
    BLESPLIT_LOG(INFO, " our_id_addr_type=%d our_id_addr=",
                desc->our_id_addr.type);
    print_addr(desc->our_id_addr.val);
    BLESPLIT_LOG(INFO, " peer_ota_addr_type=%d peer_ota_addr=",
                desc->peer_ota_addr.type);
    print_addr(desc->peer_ota_addr.val);
    BLESPLIT_LOG(INFO, " peer_id_addr_type=%d peer_id_addr=",
                desc->peer_id_addr.type);
    print_addr(desc->peer_id_addr.val);
    BLESPLIT_LOG(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d "
                 "encrypted=%d authenticated=%d bonded=%d\n",
                 desc->conn_itvl, desc->conn_latency,
                 desc->supervision_timeout,
                 desc->sec_state.encrypted,
                 desc->sec_state.authenticated,
                 desc->sec_state.bonded);
}
Esempio n. 2
0
void
print_conn_desc(const struct ble_gap_conn_desc *desc)
{
    console_printf("handle=%d our_ota_addr_type=%d our_ota_addr=",
                   desc->conn_handle, desc->our_ota_addr.type);
    print_addr(desc->our_ota_addr.val);
    console_printf(" our_id_addr_type=%d our_id_addr=",
                   desc->our_id_addr.type);
    print_addr(desc->our_id_addr.val);
    console_printf(" peer_ota_addr_type=%d peer_ota_addr=",
                   desc->peer_ota_addr.type);
    print_addr(desc->peer_ota_addr.val);
    console_printf(" peer_id_addr_type=%d peer_id_addr=",
                   desc->peer_id_addr.type);
    print_addr(desc->peer_id_addr.val);
    console_printf(" conn_itvl=%d conn_latency=%d supervision_timeout=%d "
                   "encrypted=%d authenticated=%d bonded=%d\n",
                   desc->conn_itvl, desc->conn_latency,
                   desc->supervision_timeout,
                   desc->sec_state.encrypted,
                   desc->sec_state.authenticated,
                   desc->sec_state.bonded);
}
Esempio n. 3
0
int  internet::init (char *name, protocol *higher, protocol *lower, 
 char *addr, int port, int client)
{
  // curlen keeps track of the length we currently expect, it is only 
  // used for testing
  curlen = 2;
  cout << "This is the internet init routine for " << name << endl;
  print_addr("Internet Address", addr, IP_ADDRESS_LEN);
  strcpy(prot_name , name);
  prot_higher = higher;
  prot_lower = lower;
  popit = client;

  return 0;
}
Esempio n. 4
0
static void				print_addr(unsigned long addr)
{
	char	hex[16];
	int		i;

	i = 0;
	while (i < 10)
	{
		hex[i] = i + 48;
		i++;
	}
	while (i < 16)
	{
		hex[i] = i + 55;
		i++;
	}
	if (addr < 16)
		write(1, &hex[addr], 1);
	if (addr > 15)
	{
		print_addr(addr / 16);
		print_addr(addr % 16);
	}
}
Esempio n. 5
0
File: util.c Progetto: ju5t/npd6
/*****************************************************************************
 * tDump
 *  This is the action used when walking tRoot from dumpData()
 *
 * Inputs:
 *  node, type of visit, depth - Check the man page for more...
 *
 * Outputs:
 *  Data dumped to log.
 *
 * Return:
 *  void
 */
void tDump(const void *nodep, const VISIT which, const int depth)
{
    struct in6_addr *data;
    char addressString[INET6_ADDRSTRLEN];

    switch (which) {
        case preorder:
        case endorder:
            break;
        case postorder:
        case leaf:
            data = *(struct in6_addr **) nodep;
            print_addr(data, addressString);
            flog(LOG_INFO, "Address: %s", addressString);
            break;
    }
}
Esempio n. 6
0
int
main(int argc, char **argv)
{
    krb5_context context;
    krb5_error_code ret;

    setprogname(argv[0]);

    ret = krb5_init_context(&context);
    if (ret)
	errx (1, "krb5_init_context failed: %d", ret);

    print_addr(context, "RANGE:127.0.0.0/8");
    print_addr(context, "RANGE:127.0.0.0/24");
    print_addr(context, "RANGE:IPv4:127.0.0.0-IPv4:127.0.0.255");
    print_addr(context, "RANGE:130.237.237.4/29");
#ifdef HAVE_IPV6
    print_addr(context, "RANGE:fe80::209:6bff:fea0:e522/64");
    print_addr(context, "RANGE:IPv6:fe80::209:6bff:fea0:e522/64");
    print_addr(context, "RANGE:IPv6:fe80::-IPv6:fe80::ffff:ffff:ffff:ffff");
    print_addr(context, "RANGE:fe80::-fe80::ffff:ffff:ffff:ffff");
#endif

    check_truncation(context, "IPv4:127.0.0.0");
    check_truncation(context, "RANGE:IPv4:127.0.0.0-IPv4:127.0.0.255");
#ifdef HAVE_IPV6
    check_truncation(context, "IPv6:::1");
    check_truncation(context, "IPv6:fe80::ffff:ffff:ffff:ffff");
#endif

    match_addr(context, "RANGE:127.0.0.0/8", "inet:127.0.0.0", 1);
    match_addr(context, "RANGE:127.0.0.0/8", "inet:127.255.255.255", 1);
    match_addr(context, "RANGE:127.0.0.0/8", "inet:128.0.0.0", 0);

    match_addr(context, "RANGE:130.237.237.8/29", "inet:130.237.237.7", 0);
    match_addr(context, "RANGE:130.237.237.8/29", "inet:130.237.237.8", 1);
    match_addr(context, "RANGE:130.237.237.8/29", "inet:130.237.237.15", 1);
    match_addr(context, "RANGE:130.237.237.8/29", "inet:130.237.237.16", 0);

    krb5_free_context(context);

    return 0;
}
Esempio n. 7
0
int
on_attvar_chain(Word avp)
{ GET_LD
  Word p, next;

  for(p = LD->attvar.attvars; p; p = next)
  { Word avp0 = p+1;
    next = isRef(*p) ? unRef(*p) : NULL;

    if ( avp0 == avp )
      return TRUE;
  }

  DEBUG(0, char buf[256];
	Sdprintf("%s: not on attvar chain\n", print_addr(avp, buf)));

  return FALSE;
}
Esempio n. 8
0
void fork_for_client(int cfd, int sfd)
{
    int chid = fork();
    if(chid > 0){
        /* Accept The Require Again*/
        struct sockaddr_in caddr;
        socklen_t caddrsz = sizeof(caddr); // For Receiving Information of ClientAddr
        int _cfd = accept(sfd, (struct sockaddr *)&caddr, &caddrsz);
        print_addr(caddr);
        fork_for_client(_cfd, sfd);
    }else if(chid ==  0){

        /* Client Does Its Work */
        client_work(getpid());

    }else if(chid < 0){
         printf("Fork Error!\n");
    }
}
Esempio n. 9
0
/** Dump a NEW_CTL_RESPONSE structure in the logs.
 * It must be called with network byte order (before calls to ntoh*)
 * @param cp a string to identify the log output
 * @param mp the address of the NEW_CTL_RESPONSE structure */
void print_response(char *cp,register NEW_CTL_RESPONSE *rp)
{
	char tbuf[80], *tp, abuf[80], *ap;
        short int type = rp->type;
        short int answer = rp->answer;
	
	if (type > NTYPES) {
		(void)snprintf(tbuf, sizeof(tbuf), "type %d", type);
		tp = tbuf;
	} else
		tp = types[type];
	if (answer > NANSWERS) {
		(void)snprintf(abuf, sizeof(abuf), "answer %d", answer);
		ap = abuf;
	} else
		ap = answers[answer];
	syslog(LOG_DEBUG, "%s: %s: %s, id %d", cp, tp, ap, ntohl(rp->id_num));
        if ((rp->type == LOOK_UP) && (rp->answer == SUCCESS))
            print_addr("    resp addr", (struct sockaddr_in *)&rp->addr);
}
Esempio n. 10
0
void print_node(struct station *sta)
{
	if (sta->color != 0)
		print_colormark(sta->color);
	if (opt_simpleaddr)
	{
		if (sta->color == 0)
			printf("Broadcast");
		else if (sta->ssid != NULL)
			printf("%8.8s", sta->ssid);
		else
			printf("Node %c  ", sta->color+64);
	}
	else
	{
		if (sta->color == 0)
			printf("Broadcast");
		else
			print_addr(sta->addr);
	}
	reset_colormark();
}
Esempio n. 11
0
void
print_host(struct pf_addr *addr, u_int16_t port, sa_family_t af, u_int16_t rdom,
    const char *proto, int opts)
{
	struct servent	*s = NULL;
	char		ps[6];

	if (rdom)
		printf("(%u) ", ntohs(rdom));

	if (opts & PF_OPT_USEDNS)
		print_name(addr, af);
	else {
		struct pf_addr_wrap aw;

		memset(&aw, 0, sizeof(aw));
		aw.v.a.addr = *addr;
		if (af == AF_INET)
			aw.v.a.mask.addr32[0] = 0xffffffff;
		else {
			memset(&aw.v.a.mask, 0xff, sizeof(aw.v.a.mask));
			af = AF_INET6;
		}
		print_addr(&aw, af, opts & PF_OPT_VERBOSE2);
	}

	if (port) {
		snprintf(ps, sizeof(ps), "%u", ntohs(port));
		if (opts & PF_OPT_PORTNAMES)
			s = getservbyport(port, proto);
		if (af == AF_INET)
			printf(":%s", s ? s->s_name : ps);
		else
			printf("[%s]", s ? s->s_name : ps);
	}
}
Esempio n. 12
0
void		print_memory(t_block *b, size_t *total)
{
	t_block	*tmp;

	tmp = b;
	while (tmp)
	{
		if (IS_START_HEAP(tmp))
		{
			if (GET_ZONE(tmp) == TINY)
				ft_putstr("TINY");
			else if (GET_ZONE(tmp) == SMALL)
				ft_putstr("SMALL");
			else
				ft_putstr("LARGE");
			ft_putstr(" : ");
			print_addr(tmp, 1);
		}
		print_and_count(tmp, total);
		tmp = tmp->next;
		if (tmp && IS_START_HEAP(tmp))
			break ;
	}
}
Esempio n. 13
0
void
process(int sock, struct Interface *ifacel, unsigned char *msg, int len, 
	struct sockaddr_in6 *addr, struct in6_pktinfo *pkt_info, int hoplimit)
{
	struct Interface *iface;
	struct icmp6_hdr *icmph;
	char addr_str[INET6_ADDRSTRLEN];

	if ( ! pkt_info )
	{
		flog(LOG_WARNING, "received packet with no pkt_info!" );
		return;
	}

	/*
	 * can this happen?
	 */

	if (len < sizeof(struct icmp6_hdr))
	{
		flog(LOG_WARNING, "received icmpv6 packet with invalid length: %d",
			len);
		return;
	}

	icmph = (struct icmp6_hdr *) msg;

	if (icmph->icmp6_type != ND_ROUTER_SOLICIT &&
	    icmph->icmp6_type != ND_ROUTER_ADVERT)
	{
		/*
		 *	We just want to listen to RSs and RAs
		 */
		
		flog(LOG_ERR, "icmpv6 filter failed");
		return;
	}

	if (icmph->icmp6_type == ND_ROUTER_ADVERT)
	{
		if (len < sizeof(struct nd_router_advert)) {
			flog(LOG_WARNING, "received icmpv6 RA packet with invalid length: %d",
				len);
			return;
		}

		if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
			flog(LOG_WARNING, "received icmpv6 RA packet with non-linklocal source address");
			return;
		}
	}			
	
	if (icmph->icmp6_type == ND_ROUTER_SOLICIT)
	{
		if (len < sizeof(struct nd_router_solicit)) {
			flog(LOG_WARNING, "received icmpv6 RS packet with invalid length: %d",
				len);
			return;
		}
	}			

	if (icmph->icmp6_code != 0)
	{
		flog(LOG_WARNING, "received icmpv6 RS/RA packet with invalid code: %d",
			icmph->icmp6_code);
		return;
	}
	
	dlog(LOG_DEBUG, 4, "if_index %u", pkt_info->ipi6_ifindex);

	/* get iface by received if_index */

	for (iface = ifacel; iface; iface=iface->next)
	{
		if (iface->if_index == pkt_info->ipi6_ifindex)
		{
			break;
		}
	}

	if (iface == NULL)
	{
		dlog(LOG_DEBUG, 2, "received packet from unknown interface: %d",
			pkt_info->ipi6_ifindex);
		return;
	}
	
	if (hoplimit != 255)
	{
		print_addr(&addr->sin6_addr, addr_str);
		flog(LOG_WARNING, "received RS or RA with invalid hoplimit %d from %s",
			hoplimit, addr_str);
		return;
	}
	
	if (!iface->AdvSendAdvert)
	{
		dlog(LOG_DEBUG, 2, "AdvSendAdvert is off for %s", iface->Name);
		return;
	}

	dlog(LOG_DEBUG, 4, "found Interface: %s", iface->Name);

	if (icmph->icmp6_type == ND_ROUTER_SOLICIT)
	{
		process_rs(sock, iface, msg, len, addr);
	}
	else if (icmph->icmp6_type == ND_ROUTER_ADVERT)
	{
		process_ra(iface, msg, len, addr);
	}
}
Esempio n. 14
0
/*
 * Disassemble instruction 'insn' nominally at 'loc'.
 * 'loc' may in fact contain a breakpoint instruction.
 */
db_addr_t
db_disasm_insn(int insn, db_addr_t loc, bool altfmt)
{
	bool bdslot = false;
	InstFmt i;

	i.word = insn;

	switch (i.JType.op) {
	case OP_SPECIAL:
		if (i.word == 0) {
			db_printf("nop");
			break;
		}
		/* XXX
		 * "addu" is a "move" only in 32-bit mode.  What's the correct
		 * answer - never decode addu/daddu as "move"?
		 */
		if (i.RType.func == OP_ADDU && i.RType.rt == 0) {
			db_printf("move\t%s,%s",
			    reg_name[i.RType.rd],
			    reg_name[i.RType.rs]);
			break;
		}
		db_printf("%s", spec_name[i.RType.func]);
		switch (i.RType.func) {
		case OP_SLL:
		case OP_SRL:
		case OP_SRA:
		case OP_DSLL:

		case OP_DSRL:
		case OP_DSRA:
		case OP_DSLL32:
		case OP_DSRL32:
		case OP_DSRA32:
			db_printf("\t%s,%s,%d",
			    reg_name[i.RType.rd],
			    reg_name[i.RType.rt],
			    i.RType.shamt);
			break;

		case OP_SLLV:
		case OP_SRLV:
		case OP_SRAV:
		case OP_DSLLV:
		case OP_DSRLV:
		case OP_DSRAV:
			db_printf("\t%s,%s,%s",
			    reg_name[i.RType.rd],
			    reg_name[i.RType.rt],
			    reg_name[i.RType.rs]);
			break;

		case OP_MFHI:
		case OP_MFLO:
			db_printf("\t%s", reg_name[i.RType.rd]);
			break;

		case OP_JR:
		case OP_JALR:
			db_printf("\t%s", reg_name[i.RType.rs]);
			bdslot = true;
			break;
		case OP_MTLO:
		case OP_MTHI:
			db_printf("\t%s", reg_name[i.RType.rs]);
			break;

		case OP_MULT:
		case OP_MULTU:
		case OP_DMULT:
		case OP_DMULTU:
		case OP_DIV:
		case OP_DIVU:
		case OP_DDIV:
		case OP_DDIVU:
			db_printf("\t%s,%s",
			    reg_name[i.RType.rs],
			    reg_name[i.RType.rt]);
			break;


		case OP_SYSCALL:
		case OP_SYNC:
			break;

		case OP_BREAK:
			db_printf("\t%d", (i.RType.rs << 5) | i.RType.rt);
			break;

		default:
			db_printf("\t%s,%s,%s",
			    reg_name[i.RType.rd],
			    reg_name[i.RType.rs],
			    reg_name[i.RType.rt]);
		}
		break;

	case OP_SPECIAL2:
		if (i.RType.func == OP_MUL)
			db_printf("%s\t%s,%s,%s",
				spec2_name[i.RType.func & 0x3],
		    		reg_name[i.RType.rd],
		    		reg_name[i.RType.rs],
		    		reg_name[i.RType.rt]);
		else
			db_printf("%s\t%s,%s",
				spec2_name[i.RType.func & 0x3],
		    		reg_name[i.RType.rs],
		    		reg_name[i.RType.rt]);
			
		break;

	case OP_BCOND:
		db_printf("%s\t%s,", bcond_name[i.IType.rt],
		    reg_name[i.IType.rs]);
		goto pr_displ;

	case OP_BLEZ:
	case OP_BLEZL:
	case OP_BGTZ:
	case OP_BGTZL:
		db_printf("%s\t%s,", op_name[i.IType.op],
		    reg_name[i.IType.rs]);
		goto pr_displ;

	case OP_BEQ:
	case OP_BEQL:
		if (i.IType.rs == 0 && i.IType.rt == 0) {
			db_printf("b\t");
			goto pr_displ;
		}
		/* FALLTHROUGH */
	case OP_BNE:
	case OP_BNEL:
		db_printf("%s\t%s,%s,", op_name[i.IType.op],
		    reg_name[i.IType.rs],
		    reg_name[i.IType.rt]);
	pr_displ:
		print_addr(loc + 4 + ((short)i.IType.imm << 2));
		bdslot = true;
		break;

	case OP_COP0:
		switch (i.RType.rs) {
		case OP_BCx:
		case OP_BCy:

			db_printf("bc0%c\t",
			    "ft"[i.RType.rt & COPz_BC_TF_MASK]);
			goto pr_displ;

		case OP_MT:
			db_printf("mtc0\t%s,%s",
			    reg_name[i.RType.rt],
			    c0_reg[i.RType.rd]);
			break;

		case OP_DMT:
			db_printf("dmtc0\t%s,%s",
			    reg_name[i.RType.rt],
			    c0_reg[i.RType.rd]);
			break;

		case OP_MF:
			db_printf("mfc0\t%s,%s",
			    reg_name[i.RType.rt],
			    c0_reg[i.RType.rd]);
			break;

		case OP_DMF:
			db_printf("dmfc0\t%s,%s",
			    reg_name[i.RType.rt],
			    c0_reg[i.RType.rd]);
			break;

		default:
			db_printf("%s", c0_opname[i.FRType.func]);
		}
		break;

	case OP_COP1:
		switch (i.RType.rs) {
		case OP_BCx:
		case OP_BCy:
			db_printf("bc1%c\t",
			    "ft"[i.RType.rt & COPz_BC_TF_MASK]);
			goto pr_displ;

		case OP_MT:
			db_printf("mtc1\t%s,f%d",
			    reg_name[i.RType.rt],
			    i.RType.rd);
			break;

		case OP_MF:
			db_printf("mfc1\t%s,f%d",
			    reg_name[i.RType.rt],
			    i.RType.rd);
			break;

		case OP_CT:
			db_printf("ctc1\t%s,f%d",
			    reg_name[i.RType.rt],
			    i.RType.rd);
			break;

		case OP_CF:
			db_printf("cfc1\t%s,f%d",
			    reg_name[i.RType.rt],
			    i.RType.rd);
			break;

		default:
			db_printf("%s.%s\tf%d,f%d,f%d",
			    cop1_name[i.FRType.func],
			    fmt_name[i.FRType.fmt],
			    i.FRType.fd, i.FRType.fs, i.FRType.ft);
		}
		break;

	case OP_J:
	case OP_JAL:
		db_printf("%s\t", op_name[i.JType.op]);
		print_addr((loc & 0xF0000000) | (i.JType.target << 2));
		bdslot = true;
		break;

	case OP_LWC1:
	case OP_SWC1:
		db_printf("%s\tf%d,", op_name[i.IType.op],
		    i.IType.rt);
		goto loadstore;

	case OP_LB:
	case OP_LH:
	case OP_LW:
	case OP_LD:
	case OP_LBU:
	case OP_LHU:
	case OP_LWU:
	case OP_SB:
	case OP_SH:
	case OP_SW:
	case OP_SD:
		db_printf("%s\t%s,", op_name[i.IType.op],
		    reg_name[i.IType.rt]);
	loadstore:
		db_printf("%d(%s)", (short)i.IType.imm,
		    reg_name[i.IType.rs]);
		break;

	case OP_ORI:
	case OP_XORI:
		if (i.IType.rs == 0) {
			db_printf("li\t%s,0x%x",
			    reg_name[i.IType.rt],
			    i.IType.imm);
			break;
		}
		/* FALLTHROUGH */
	case OP_ANDI:
		db_printf("%s\t%s,%s,0x%x", op_name[i.IType.op],
		    reg_name[i.IType.rt],
		    reg_name[i.IType.rs],
		    i.IType.imm);
		break;

	case OP_LUI:
		db_printf("%s\t%s,0x%x", op_name[i.IType.op],
		    reg_name[i.IType.rt],
		    i.IType.imm);
		break;

	case OP_CACHE:
		db_printf("%s\t0x%x,0x%x(%s)",
		    op_name[i.IType.op],
		    i.IType.rt,
		    i.IType.imm,
		    reg_name[i.IType.rs]);
		break;

	case OP_ADDI:
	case OP_DADDI:
	case OP_ADDIU:
	case OP_DADDIU:
		if (i.IType.rs == 0) {
			db_printf("li\t%s,%d",
			    reg_name[i.IType.rt],
			    (short)i.IType.imm);
			break;
		}
		/* FALLTHROUGH */
	default:
		db_printf("%s\t%s,%s,%d", op_name[i.IType.op],
		    reg_name[i.IType.rt],
		    reg_name[i.IType.rs],
		    (short)i.IType.imm);
	}
	db_printf("\n");
	if (bdslot) {
		db_printf("\t\tbdslot:\t");
		db_disasm(loc+4, false);
		return (loc + 8);
	}
	return (loc + 4);
}
Esempio n. 15
0
/*
 * check router advertisements according to RFC 2461, 6.2.7
 */
static void
process_ra(struct Interface *iface, unsigned char *msg, int len, 
	struct sockaddr_in6 *addr)
{
	struct nd_router_advert *radvert;
	char addr_str[INET6_ADDRSTRLEN];
	uint8_t *opt_str;

	print_addr(&addr->sin6_addr, addr_str);

	radvert = (struct nd_router_advert *) msg;

	if ((radvert->nd_ra_curhoplimit && iface->AdvCurHopLimit) && 
	   (radvert->nd_ra_curhoplimit != iface->AdvCurHopLimit))
	{
		flog(LOG_WARNING, "our AdvCurHopLimit on %s doesn't agree with %s",
			iface->Name, addr_str);
	}

	if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) && !iface->AdvManagedFlag)
	{
		flog(LOG_WARNING, "our AdvManagedFlag on %s doesn't agree with %s",
			iface->Name, addr_str);
	}
	
	if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) && !iface->AdvOtherConfigFlag)
	{
		flog(LOG_WARNING, "our AdvOtherConfigFlag on %s doesn't agree with %s",
			iface->Name, addr_str);
	}

	/* note: we don't check the default router preference here, because they're likely different */

	if ((radvert->nd_ra_reachable && iface->AdvReachableTime) &&
	   (ntohl(radvert->nd_ra_reachable) != iface->AdvReachableTime))
	{
		flog(LOG_WARNING, "our AdvReachableTime on %s doesn't agree with %s",
			iface->Name, addr_str);
	}
	
	if ((radvert->nd_ra_retransmit && iface->AdvRetransTimer) &&
	   (ntohl(radvert->nd_ra_retransmit) != iface->AdvRetransTimer))
	{
		flog(LOG_WARNING, "our AdvRetransTimer on %s doesn't agree with %s",
			iface->Name, addr_str);
	}

	len -= sizeof(struct nd_router_advert);

	if (len == 0)
		return;
		
	opt_str = (uint8_t *)(msg + sizeof(struct nd_router_advert));
		
	while (len > 0)
	{
		int optlen;
		struct nd_opt_prefix_info *pinfo;
		struct nd_opt_rdnss_info_local *rdnssinfo;
		struct nd_opt_mtu *mtu;
		struct AdvPrefix *prefix;
		struct AdvRDNSS *rdnss;
		char prefix_str[INET6_ADDRSTRLEN];
		char rdnss_str[INET6_ADDRSTRLEN];
		uint32_t preferred, valid, count;

		if (len < 2)
		{
			flog(LOG_ERR, "trailing garbage in RA on %s from %s", 
				iface->Name, addr_str);
			break;
		}
		
		optlen = (opt_str[1] << 3);

		if (optlen == 0) 
		{
			flog(LOG_ERR, "zero length option in RA on %s from %s",
				iface->Name, addr_str);
			break;
		} 
		else if (optlen > len)
		{
			flog(LOG_ERR, "option length greater than total"
				" length in RA on %s from %s",
				iface->Name, addr_str);
			break;
		} 		

		switch (*opt_str)
		{
		case ND_OPT_MTU:
			mtu = (struct nd_opt_mtu *)opt_str;

			if (iface->AdvLinkMTU && (ntohl(mtu->nd_opt_mtu_mtu) != iface->AdvLinkMTU))
			{
				flog(LOG_WARNING, "our AdvLinkMTU on %s doesn't agree with %s",
					iface->Name, addr_str);
			}
			break;
		case ND_OPT_PREFIX_INFORMATION:
			pinfo = (struct nd_opt_prefix_info *) opt_str;
			preferred = ntohl(pinfo->nd_opt_pi_preferred_time);
			valid = ntohl(pinfo->nd_opt_pi_valid_time);
			
			prefix = iface->AdvPrefixList;
			while (prefix)
			{
				if (prefix->enabled &&
				    (prefix->PrefixLen == pinfo->nd_opt_pi_prefix_len) &&
				    addr_match(&prefix->Prefix, &pinfo->nd_opt_pi_prefix,
				    	 prefix->PrefixLen))
				{
					print_addr(&prefix->Prefix, prefix_str);

					if (valid != prefix->AdvValidLifetime)
					{
						flog(LOG_WARNING, "our AdvValidLifetime on"
						 " %s for %s doesn't agree with %s",
						 iface->Name,
						 prefix_str,
						 addr_str
						 );
					}
					if (preferred != prefix->AdvPreferredLifetime)
					{
						flog(LOG_WARNING, "our AdvPreferredLifetime on"
						 " %s for %s doesn't agree with %s",
						 iface->Name,
						 prefix_str,
						 addr_str
						 );
					}
				}

				prefix = prefix->next;
			}			
			break;
		case ND_OPT_ROUTE_INFORMATION:
			/* not checked: these will very likely vary a lot */
			break;
		case ND_OPT_SOURCE_LINKADDR:
			/* not checked */
			break;
		case ND_OPT_TARGET_LINKADDR:
		case ND_OPT_REDIRECTED_HEADER:
			flog(LOG_ERR, "invalid option %d in RA on %s from %s",
				(int)*opt_str, iface->Name, addr_str);
			break;
		/* Mobile IPv6 extensions */
		case ND_OPT_RTR_ADV_INTERVAL:
		case ND_OPT_HOME_AGENT_INFO:
			/* not checked */
			break;
		case ND_OPT_RDNSS_INFORMATION:
			rdnssinfo = (struct nd_opt_rdnss_info_local *) opt_str;
			count = rdnssinfo->nd_opt_rdnssi_len;
			
			/* Check the RNDSS addresses received */
			switch (count) {
				case 7:
					rdnss = iface->AdvRDNSSList;
					if (!check_rdnss_presence(rdnss, &rdnssinfo->nd_opt_rdnssi_addr3 )) {
						/* no match found in iface->AdvRDNSSList */
						print_addr(&rdnssinfo->nd_opt_rdnssi_addr3, rdnss_str);
						flog(LOG_WARNING, "RDNSS address %s received on %s from %s is not advertised by us",
							rdnss_str, iface->Name, addr_str);
					}
					/* FALLTHROUGH */
				case 5:
					rdnss = iface->AdvRDNSSList;
					if (!check_rdnss_presence(rdnss, &rdnssinfo->nd_opt_rdnssi_addr2 )) {
						/* no match found in iface->AdvRDNSSList */
						print_addr(&rdnssinfo->nd_opt_rdnssi_addr2, rdnss_str);
						flog(LOG_WARNING, "RDNSS address %s received on %s from %s is not advertised by us",
							rdnss_str, iface->Name, addr_str);
					}
					/* FALLTHROUGH */
				case 3:
					rdnss = iface->AdvRDNSSList;
					if (!check_rdnss_presence(rdnss, &rdnssinfo->nd_opt_rdnssi_addr1 )) {
						/* no match found in iface->AdvRDNSSList */
						print_addr(&rdnssinfo->nd_opt_rdnssi_addr1, rdnss_str);
						flog(LOG_WARNING, "RDNSS address %s received on %s from %s is not advertised by us",
							rdnss_str, iface->Name, addr_str);
					}
					
					break;
				default:
					flog(LOG_ERR, "invalid len %i in RDNSS option on %s from %s",
							count, iface->Name, addr_str);
			}
			
			break;	
		default:
			dlog(LOG_DEBUG, 1, "unknown option %d in RA on %s from %s",
				(int)*opt_str, iface->Name, addr_str);
			break;
		}
		
		len -= optlen;
		opt_str += optlen;
	}
}
Esempio n. 16
0
/* Saves the matchinfo in parsable form to stdout. */
static void
matchinfo_print(const struct ipt_ip *ip, const struct ipt_entry_match *match, int numeric, const char *optpfx)
{
	struct ipt_conntrack_info *sinfo = (struct ipt_conntrack_info *)match->data;

	if(sinfo->flags & IPT_CONNTRACK_STATE) {
		printf("%sctstate ", optpfx);
        	if (sinfo->invflags & IPT_CONNTRACK_STATE)
                	printf("! ");
		print_state(sinfo->statemask);
	}

	if(sinfo->flags & IPT_CONNTRACK_PROTO) {
		printf("%sctproto ", optpfx);
        	if (sinfo->invflags & IPT_CONNTRACK_PROTO)
                	printf("! ");
		printf("%u ", sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum);
	}

	if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) {
		printf("%sctorigsrc ", optpfx);

		print_addr(
		    (struct in_addr *)&sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip,
		    &sinfo->sipmsk[IP_CT_DIR_ORIGINAL],
		    sinfo->invflags & IPT_CONNTRACK_ORIGSRC,
		    numeric);
	}

	if(sinfo->flags & IPT_CONNTRACK_ORIGDST) {
		printf("%sctorigdst ", optpfx);

		print_addr(
		    (struct in_addr *)&sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip,
		    &sinfo->dipmsk[IP_CT_DIR_ORIGINAL],
		    sinfo->invflags & IPT_CONNTRACK_ORIGDST,
		    numeric);
	}

	if(sinfo->flags & IPT_CONNTRACK_REPLSRC) {
		printf("%sctreplsrc ", optpfx);

		print_addr(
		    (struct in_addr *)&sinfo->tuple[IP_CT_DIR_REPLY].src.ip,
		    &sinfo->sipmsk[IP_CT_DIR_REPLY],
		    sinfo->invflags & IPT_CONNTRACK_REPLSRC,
		    numeric);
	}

	if(sinfo->flags & IPT_CONNTRACK_REPLDST) {
		printf("%sctrepldst ", optpfx);

		print_addr(
		    (struct in_addr *)&sinfo->tuple[IP_CT_DIR_REPLY].dst.ip,
		    &sinfo->dipmsk[IP_CT_DIR_REPLY],
		    sinfo->invflags & IPT_CONNTRACK_REPLDST,
		    numeric);
	}

	if(sinfo->flags & IPT_CONNTRACK_STATUS) {
		printf("%sctstatus ", optpfx);
        	if (sinfo->invflags & IPT_CONNTRACK_STATUS)
                	printf("! ");
		print_status(sinfo->statusmask);
	}

	if(sinfo->flags & IPT_CONNTRACK_EXPIRES) {
		printf("%sctexpire ", optpfx);
        	if (sinfo->invflags & IPT_CONNTRACK_EXPIRES)
                	printf("! ");

#ifdef KERNEL_64_USERSPACE_32
        	if (sinfo->expires_max == sinfo->expires_min)
                	printf("%llu ", sinfo->expires_min);
        	else
                	printf("%llu:%llu ", sinfo->expires_min, sinfo->expires_max);
#else
        	if (sinfo->expires_max == sinfo->expires_min)
                	printf("%lu ", sinfo->expires_min);
        	else
                	printf("%lu:%lu ", sinfo->expires_min, sinfo->expires_max);
#endif
	}
}
Esempio n. 17
0
void
print_ff(unsigned char *msg, int len, struct sockaddr_in6 *addr, int hoplimit, int if_index, int edefs)
{
	struct nd_router_advert *radvert;
	char addr_str[INET6_ADDRSTRLEN];
	uint8_t *opt_str;
	int orig_len = len;
	char if_name[IFNAMSIZ];

	print_addr(&addr->sin6_addr, addr_str);
	printf("#\n# radvd configuration generated by radvdump %s\n", VERSION);
	printf("# based on Router Advertisement from %s\n", addr_str);
	if_indextoname(if_index, if_name);
	printf("# received by interface %s\n", if_name);
	printf("#\n\ninterface %s\n{\n\tAdvSendAdvert on;\n", if_name);

	printf("\t# Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump\n");

	radvert = (struct nd_router_advert *) msg;

	if (!edefs || DFLT_AdvManagedFlag != (ND_RA_FLAG_MANAGED == (radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED)))
	printf("\tAdvManagedFlag %s;\n", 
		(radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED)?"on":"off");

	if (!edefs || DFLT_AdvOtherConfigFlag != (ND_RA_FLAG_OTHER == (radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)))
	printf("\tAdvOtherConfigFlag %s;\n", 
		(radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)?"on":"off");

	if (!edefs || DFLT_AdvReachableTime != (unsigned long)ntohl(radvert->nd_ra_reachable))
	printf("\tAdvReachableTime %lu;\n", (unsigned long)ntohl(radvert->nd_ra_reachable));

	if (!edefs || DFLT_AdvRetransTimer != (unsigned long)ntohl(radvert->nd_ra_retransmit))
	printf("\tAdvRetransTimer %lu;\n", (unsigned long)ntohl(radvert->nd_ra_retransmit));

	if (!edefs || DFLT_AdvCurHopLimit != (int) radvert->nd_ra_curhoplimit)
	printf("\tAdvCurHopLimit %d;\n", (int) radvert->nd_ra_curhoplimit);

	/* Mobile IPv6 ext */
	if (!edefs || DFLT_AdvHomeAgentFlag != (ND_RA_FLAG_HOME_AGENT == (radvert->nd_ra_flags_reserved & ND_RA_FLAG_HOME_AGENT)))
	printf("\tAdvHomeAgentFlag %s;\n", 
		(radvert->nd_ra_flags_reserved & ND_RA_FLAG_HOME_AGENT)?"on":"off");

	len -= sizeof(struct nd_router_advert);

	if (len == 0)
		return;
		
	opt_str = (uint8_t *)(msg + sizeof(struct nd_router_advert));
		
	while (len > 0)
	{
		int optlen;
		struct nd_opt_mtu *mtu;
		struct AdvInterval *a_ival;
		struct HomeAgentInfo *ha_info;

		if (len < 2)
		{
			log(LOG_ERR, "trailing garbage in RA from %s", 
				addr_str);
			break;
		}
		
		optlen = (opt_str[1] << 3);

		if (optlen == 0) 
		{
			log(LOG_ERR, "zero length option in RA");
			break;
		} 
		else if (optlen > len)
		{
			log(LOG_ERR, "option length greater than total"
				" length in RA (type %d, optlen %d, len %d)", 
				(int)*opt_str, optlen, len);
			break;
		} 		

		switch (*opt_str)
		{
		case ND_OPT_MTU:
			mtu = (struct nd_opt_mtu *)opt_str;

			if (!edefs || DFLT_AdvLinkMTU != (unsigned long)ntohl(mtu->nd_opt_mtu_mtu))
			printf("\tAdvLinkMTU %lu;\n", (unsigned long)ntohl(mtu->nd_opt_mtu_mtu));
			break;
		case ND_OPT_SOURCE_LINKADDR:
			/* XXX: !DFLT depends on current DFLT_ value */
			if (!edefs || !DFLT_AdvSourceLLAddress)
			printf("\tAdvSourceLLAddress on;\n");
			break;
		/* Mobile IPv6 ext */
		case ND_OPT_RTR_ADV_INTERVAL:
			a_ival = (struct AdvInterval *)opt_str;

			/* XXX: !DFLT depends on current DFLT_ value */
			if (!edefs || !DFLT_AdvIntervalOpt)
			printf("\tAdvIntervalOpt on;\n");
			break;
		/* Mobile IPv6 ext */
		case ND_OPT_HOME_AGENT_INFO:
			ha_info = (struct HomeAgentInfo *)opt_str;

			/* XXX: !DFLT depends on current DFLT_ value */
			if (!edefs || !DFLT_AdvHomeAgentInfo)
			printf("\tAdvHomeAgentInfo on;\n");

			if (!edefs || DFLT_HomeAgentPreference != (unsigned short)ntohs(ha_info->preference))
			printf("\tHomeAgentPreference %hu;\n", (unsigned short)ntohs(ha_info->preference));
			/* Hum.. */
			if (!edefs || (3*DFLT_MaxRtrAdvInterval) != (unsigned short)ntohs(ha_info->lifetime))
			printf("\tHomeAgentLifetime %hu;\n", (unsigned short)ntohs(ha_info->lifetime));
			break;
		case ND_OPT_TARGET_LINKADDR:
		case ND_OPT_REDIRECTED_HEADER:
			log(LOG_ERR, "invalid option %d in RA", (int)*opt_str);
			break;
		case ND_OPT_PREFIX_INFORMATION:
			break;
		default:
			dlog(LOG_DEBUG, 1, "unknown option %d in RA",
				(int)*opt_str);
			break;
		}
		
		len -= optlen;
		opt_str += optlen;
	}

	orig_len -= sizeof(struct nd_router_advert);

	if (orig_len == 0)
		return;

	opt_str = (uint8_t *)(msg + sizeof(struct nd_router_advert));
		
	while (orig_len > 0)
	{
		int optlen;
		struct nd_opt_prefix_info *pinfo;
		char prefix_str[INET6_ADDRSTRLEN];

		if (orig_len < 2)
		{
			log(LOG_ERR, "trailing garbage in RA from %s", 
				addr_str);
			break;
		}
		
		optlen = (opt_str[1] << 3);

		if (optlen == 0) 
		{
			log(LOG_ERR, "zero length option in RA");
			break;
		} 
		else if (optlen > orig_len)
		{
			log(LOG_ERR, "option length greater than total"
				" length in RA (type %d, optlen %d, len %d)", 
				(int)*opt_str, optlen, orig_len);
			break;
		} 		

		switch (*opt_str)
		{
		case ND_OPT_PREFIX_INFORMATION:
			pinfo = (struct nd_opt_prefix_info *) opt_str;
			
			print_addr(&pinfo->nd_opt_pi_prefix, prefix_str);	
				
			printf("\n\tprefix %s/%d\n\t{\n", prefix_str, pinfo->nd_opt_pi_prefix_len);

			if (ntohl(pinfo->nd_opt_pi_valid_time) == 0xffffffff)
			{		
				if (!edefs || DFLT_AdvValidLifetime != 0xffffffff)
				printf("\t\tAdvValidLifetime infinity; # (0xffffffff)\n");
			}
			else
			{
				if (!edefs || DFLT_AdvValidLifetime != (unsigned long)ntohl(pinfo->nd_opt_pi_valid_time))
				printf("\t\tAdvValidLifetime %lu;\n", (unsigned long)ntohl(pinfo->nd_opt_pi_valid_time));
			}
			if (ntohl(pinfo->nd_opt_pi_preferred_time) == 0xffffffff)
			{
				if (!edefs || DFLT_AdvPreferredLifetime != 0xffffffff)
				printf("\t\tAdvPreferredLifetime infinity; # (0xffffffff)\n");
			}
			else
			{
				if (!edefs || DFLT_AdvPreferredLifetime != (unsigned long)ntohl(pinfo->nd_opt_pi_preferred_time))
				printf("\t\tAdvPreferredLifetime %lu;\n", (unsigned long)ntohl(pinfo->nd_opt_pi_preferred_time));
			}

			if (!edefs || DFLT_AdvOnLinkFlag != (ND_OPT_PI_FLAG_ONLINK == (pinfo->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK)))
			printf("\t\tAdvOnLink %s;\n", 
				(pinfo->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK)?"on":"off");

			if (!edefs || DFLT_AdvAutonomousFlag != (ND_OPT_PI_FLAG_AUTO == (pinfo->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_AUTO)))
			printf("\t\tAdvAutonomous %s;\n", 
				(pinfo->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_AUTO)?"on":"off");

			/* Mobile IPv6 ext */
			if (!edefs || DFLT_AdvRouterAddr != (ND_OPT_PI_FLAG_RADDR == (pinfo->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_RADDR)))
			printf("\t\tAdvRouterAddr %s;\n", 
				(pinfo->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_RADDR)?"on":"off");

			printf("\t}; # End of prefix definition\n\n");
			break;
		default:
			break;
		}
		orig_len -= optlen;
		opt_str += optlen;
	}

	printf("}; # End of interface definition\n");

	fflush(stdout);
}
Esempio n. 18
0
static void
matchinfo_print(const void *ip, const struct xt_entry_match *match, int numeric, const char *optpfx)
{
	struct xt_conntrack_info *sinfo = (void *)match->data;

	if(sinfo->flags & XT_CONNTRACK_STATE) {
        	if (sinfo->invflags & XT_CONNTRACK_STATE)
                	printf("! ");
		printf("%sctstate ", optpfx);
		print_state(sinfo->statemask);
	}

	if(sinfo->flags & XT_CONNTRACK_PROTO) {
        	if (sinfo->invflags & XT_CONNTRACK_PROTO)
                	printf("! ");
		printf("%sctproto ", optpfx);
		printf("%u ", sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum);
	}

	if(sinfo->flags & XT_CONNTRACK_ORIGSRC) {
		if (sinfo->invflags & XT_CONNTRACK_ORIGSRC)
			printf("! ");
		printf("%sctorigsrc ", optpfx);

		print_addr(
		    (struct in_addr *)&sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip,
		    &sinfo->sipmsk[IP_CT_DIR_ORIGINAL],
		    false,
		    numeric);
	}

	if(sinfo->flags & XT_CONNTRACK_ORIGDST) {
		if (sinfo->invflags & XT_CONNTRACK_ORIGDST)
			printf("! ");
		printf("%sctorigdst ", optpfx);

		print_addr(
		    (struct in_addr *)&sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip,
		    &sinfo->dipmsk[IP_CT_DIR_ORIGINAL],
		    false,
		    numeric);
	}

	if(sinfo->flags & XT_CONNTRACK_REPLSRC) {
		if (sinfo->invflags & XT_CONNTRACK_REPLSRC)
			printf("! ");
		printf("%sctreplsrc ", optpfx);

		print_addr(
		    (struct in_addr *)&sinfo->tuple[IP_CT_DIR_REPLY].src.ip,
		    &sinfo->sipmsk[IP_CT_DIR_REPLY],
		    false,
		    numeric);
	}

	if(sinfo->flags & XT_CONNTRACK_REPLDST) {
		if (sinfo->invflags & XT_CONNTRACK_REPLDST)
			printf("! ");
		printf("%sctrepldst ", optpfx);

		print_addr(
		    (struct in_addr *)&sinfo->tuple[IP_CT_DIR_REPLY].dst.ip,
		    &sinfo->dipmsk[IP_CT_DIR_REPLY],
		    false,
		    numeric);
	}

	if(sinfo->flags & XT_CONNTRACK_STATUS) {
        	if (sinfo->invflags & XT_CONNTRACK_STATUS)
                	printf("! ");
		printf("%sctstatus ", optpfx);
		print_status(sinfo->statusmask);
	}

	if(sinfo->flags & XT_CONNTRACK_EXPIRES) {
        	if (sinfo->invflags & XT_CONNTRACK_EXPIRES)
                	printf("! ");
		printf("%sctexpire ", optpfx);

        	if (sinfo->expires_max == sinfo->expires_min)
                	printf("%lu ", sinfo->expires_min);
        	else
                	printf("%lu:%lu ", sinfo->expires_min, sinfo->expires_max);
	}

	if (sinfo->flags & XT_CONNTRACK_DIRECTION) {
		if (sinfo->invflags & XT_CONNTRACK_DIRECTION)
			printf("%sctdir REPLY", optpfx);
		else
			printf("%sctdir ORIGINAL", optpfx);
	}

}
Esempio n. 19
0
/*
 * Print a description of the network interfaces.
 * NOTE: ifnetaddr is the location of the kernel global "ifnet",
 * which is a TAILQ_HEAD.
 */
void
intpr(int interval, int repeatcount)
{
	struct if_msghdr ifm;
	int mib[6] = { CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
	char name[IFNAMSIZ + 1];	/* + 1 for the '*' */
	char *buf, *next, *lim, *cp;
	struct rt_msghdr *rtm;
	struct ifa_msghdr *ifam;
	struct if_data *ifd;
	struct sockaddr *sa, *rti_info[RTAX_MAX];
	struct sockaddr_dl *sdl;
	u_int64_t total = 0;
	size_t len;

	if (interval) {
		sidewaysintpr((unsigned)interval, repeatcount);
		return;
	}

	if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
		err(1, "sysctl");
	if ((buf = malloc(len)) == NULL)
		err(1, NULL);
	if (sysctl(mib, 6, buf, &len, NULL, 0) == -1)
		err(1, "sysctl");

	printf("%-7.7s %-5.5s %-11.11s %-17.17s ",
	    "Name", "Mtu", "Network", "Address");
	if (bflag)
		printf("%10.10s %10.10s", "Ibytes", "Obytes");
	else
		printf("%8.8s %5.5s %8.8s %5.5s %5.5s",
		    "Ipkts", "Ierrs", "Opkts", "Oerrs", "Colls");
	if (tflag)
		printf(" %s", "Time");
	if (dflag)
		printf(" %s", "Drop");
	putchar('\n');

	lim = buf + len;
	for (next = buf; next < lim; next += rtm->rtm_msglen) {
		rtm = (struct rt_msghdr *)next;
		if (rtm->rtm_version != RTM_VERSION)
			continue;
		switch (rtm->rtm_type) {
		case RTM_IFINFO:
			total = 0;
			bcopy(next, &ifm, sizeof ifm);
			ifd = &ifm.ifm_data;

			sa = (struct sockaddr *)(next + rtm->rtm_hdrlen);
			get_rtaddrs(ifm.ifm_addrs, sa, rti_info);

			sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP];
			if (sdl == NULL || sdl->sdl_family != AF_LINK)
				continue;
			bzero(name, sizeof(name));
			if (sdl->sdl_nlen >= IFNAMSIZ)
				memcpy(name, sdl->sdl_data, IFNAMSIZ - 1);
			else if (sdl->sdl_nlen > 0) 
				memcpy(name, sdl->sdl_data, sdl->sdl_nlen);

			if (interface != 0 && strcmp(name, interface) != 0)
				continue;

			/* mark inactive interfaces with a '*' */
			cp = strchr(name, '\0');
			if ((ifm.ifm_flags & IFF_UP) == 0)
				*cp++ = '*';
			*cp = '\0';

			if (qflag) {
				total = ifd->ifi_ibytes + ifd->ifi_obytes +
				    ifd->ifi_ipackets + ifd->ifi_ierrors +
				    ifd->ifi_opackets + ifd->ifi_oerrors +
				    ifd->ifi_collisions;
				if (tflag)
					total += 0; // XXX ifnet.if_timer;
				if (dflag)
					total += 0; // XXX ifnet.if_snd.ifq_drops;
				if (total == 0)
					continue;
			}

			printf("%-7s %-5d ", name, ifd->ifi_mtu);
			print_addr(rti_info[RTAX_IFP], rti_info, ifd);
			break;
		case RTM_NEWADDR:
			if (qflag && total == 0)
				continue;
			if (interface != 0 && strcmp(name, interface) != 0)
				continue;

			ifam = (struct ifa_msghdr *)next;
			if ((ifam->ifam_addrs & (RTA_NETMASK | RTA_IFA |
			    RTA_BRD)) == 0)
				break;

			sa = (struct sockaddr *)(next + rtm->rtm_hdrlen);
			get_rtaddrs(ifam->ifam_addrs, sa, rti_info);

			printf("%-7s %-5d ", name, ifd->ifi_mtu);
			print_addr(rti_info[RTAX_IFA], rti_info, ifd);
			break;
		}
	}
	free(buf);
}
Esempio n. 20
0
void
DhtRunner::doRun(const sockaddr_in* sin4, const sockaddr_in6* sin6, const crypto::Identity identity)
{
    dht_.reset();

    int s4 = -1,
        s6 = -1;
    if (sin4) {
        s4 = socket(PF_INET, SOCK_DGRAM, 0);
        if(s4 >= 0) {
            int rc = bind(s4, (sockaddr*)sin4, sizeof(sockaddr_in));
            if(rc < 0)
                throw DhtException("Can't bind IPv4 socket on " + print_addr((sockaddr*)sin4, sizeof(sockaddr_in)));
        }
    }

    if (sin6) {
        s6 = socket(PF_INET6, SOCK_DGRAM, 0);
        if(s6 >= 0) {
            int val = 1;
            int rc = setsockopt(s6, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&val, sizeof(val));
            if(rc < 0)
                throw DhtException("Can't set IPV6_V6ONLY");

            rc = bind(s6, (sockaddr*)sin6, sizeof(sockaddr_in6));
            if(rc < 0)
                throw DhtException("Can't bind IPv6 socket on " + print_addr((sockaddr*)sin4, sizeof(sockaddr_in)));
        }
    }

    dht_ = std::unique_ptr<SecureDht>(new SecureDht {s4, s6, identity});

    rcv_thread = std::thread([this,s4,s6]() {
        try {
            while (true) {
                uint8_t buf[4096 * 64];
                sockaddr_storage from;
                socklen_t fromlen;

                struct timeval tv {.tv_sec = 0, .tv_usec = 250000};
                fd_set readfds;

                FD_ZERO(&readfds);
                if(s4 >= 0)
                    FD_SET(s4, &readfds);
                if(s6 >= 0)
                    FD_SET(s6, &readfds);

                int rc = select(s4 > s6 ? s4 + 1 : s6 + 1, &readfds, nullptr, nullptr, &tv);
                if(rc < 0) {
                    if(errno != EINTR) {
                        perror("select");
                        std::this_thread::sleep_for( std::chrono::seconds(1) );
                    }
                }

                if(!running)
                    break;

                if(rc > 0) {
                    fromlen = sizeof(from);
                    if(s4 >= 0 && FD_ISSET(s4, &readfds))
                        rc = recvfrom(s4, (char*)buf, sizeof(buf) - 1, 0, (struct sockaddr*)&from, &fromlen);
                    else if(s6 >= 0 && FD_ISSET(s6, &readfds))
                        rc = recvfrom(s6, (char*)buf, sizeof(buf) - 1, 0, (struct sockaddr*)&from, &fromlen);
                    else
                        break;
                    if (rc > 0) {
                        buf[rc] = 0;
                        {
                            std::lock_guard<std::mutex> lck(sock_mtx);
                            rcv.emplace_back(Blob {buf, buf+rc+1}, from);
                        }
                        cv.notify_all();
                    }
                }
            }
        } catch (const std::exception& e) {
            std::cerr << "Error int DHT networking thread: " << e.what() << std::endl;
        }
        if (s4 >= 0)
            close(s4);
        if (s6 >= 0)
            close(s6);
    });
Esempio n. 21
0
void recv(netdev2_t *dev)
{
    uint8_t src[IEEE802154_LONG_ADDRESS_LEN], dst[IEEE802154_LONG_ADDRESS_LEN];
    size_t mhr_len, data_len, src_len, dst_len;
    netdev2_ieee802154_rx_info_t rx_info;
    le_uint16_t src_pan, dst_pan;

    putchar('\n');
    data_len = dev->driver->recv(dev, buffer, sizeof(buffer), &rx_info);
    mhr_len = ieee802154_get_frame_hdr_len(buffer);
    if (mhr_len == 0) {
        puts("Unexpected MHR for incoming packet");
        return;
    }
    dst_len = ieee802154_get_dst(buffer, dst, &dst_pan);
    src_len = ieee802154_get_src(buffer, src, &src_pan);
    switch (buffer[0] & IEEE802154_FCF_TYPE_MASK) {
        case IEEE802154_FCF_TYPE_BEACON:
            puts("BEACON");
            break;
        case IEEE802154_FCF_TYPE_DATA:
            puts("DATA");
            break;
        case IEEE802154_FCF_TYPE_ACK:
            puts("ACK");
            break;
        case IEEE802154_FCF_TYPE_MACCMD:
            puts("MACCMD");
            break;
        default:
            puts("UNKNOWN");
            break;
    }
    printf("Dest. PAN: 0x%04x, Dest. addr.: ",
           byteorder_ntohs(byteorder_ltobs(dst_pan)));
    print_addr(dst, dst_len);
    printf("\nSrc. PAN: 0x%04x, Src. addr.: ",
           byteorder_ntohs(byteorder_ltobs(src_pan)));
    print_addr(src, src_len);
    printf("\nSecurity: ");
    if (buffer[0] & IEEE802154_FCF_SECURITY_EN) {
        printf("1, ");
    }
    else {
        printf("0, ");
    }
    printf("Frame pend.: ");
    if (buffer[0] & IEEE802154_FCF_FRAME_PEND) {
        printf("1, ");
    }
    else {
        printf("0, ");
    }
    printf("ACK req.: ");
    if (buffer[0] & IEEE802154_FCF_ACK_REQ) {
        printf("1, ");
    }
    else {
        printf("0, ");
    }
    printf("PAN comp.: ");
    if (buffer[0] & IEEE802154_FCF_PAN_COMP) {
        puts("1");
    }
    else {
        puts("0");
    }
    printf("Version: ");
    printf("%u, ", (unsigned)((buffer[1] & IEEE802154_FCF_VERS_MASK) >> 4));
    printf("Seq.: %u\n", (unsigned)ieee802154_get_seq(buffer));
    od_hex_dump(buffer + mhr_len, data_len - mhr_len, 0);
    printf("txt: ");
    for (int i = mhr_len; i < data_len; i++) {
        if ((buffer[i] > 0x1F) && (buffer[i] < 0x80)) {
            putchar((char)buffer[i]);
        }
        else {
            putchar('?');
        }
        if (((((i - mhr_len) + 1) % (MAX_LINE - sizeof("txt: "))) == 1) &&
            (i - mhr_len) != 0) {
            printf("\n     ");
        }
    }
    printf("\n");
    printf("RSSI: %u, LQI: %u\n\n", rx_info.rssi, rx_info.lqi);
}
Esempio n. 22
0
File: ip6.c Progetto: ju5t/npd6
/*****************************************************************************
 * processICMP
 * Takes a received ICMP message and handles it. At first, we don't
 * do too much. Based upon NFR 60 we are going to look out for RAs, 
 * extract useful data and log it.
 * 
 * Later on we may go further with that information...
 *
 * Inputs:
 *  char *msg
 *      The received ICMP6.
 *  int len
 *      The length of the received data
 *      *** This has already been sanity checked back in the callers ***
 *
 * Outputs:
 *  As per above, likely just a log/debug for now.
 *
 * Return:
 *      void
 *
 */
void processICMP( int ifIndex,
                  unsigned char *msg,
                  unsigned int len,
                  struct in6_addr *addr6)
{
    // Offsets into the received packet
    struct icmp6_hdr            *icmph = 
    (struct icmp6_hdr *)(msg);
    struct nd_router_advert     *ra = 
    (struct nd_router_advert *)(msg + sizeof(struct icmp6_hdr));

    uint32_t reachableT = ra->nd_ra_reachable;
    uint32_t retransmitT = ra->nd_ra_retransmit;  
    int curHopLimit = ra->nd_ra_curhoplimit;
    int rtrLifetime = ra->nd_ra_router_lifetime;
    
    int counter = 0;
    char addr6_str[INET6_ADDRSTRLEN];
    
    // May not exist - will check
    struct nd_opt_hdr *optHdr = 
    (struct nd_opt_hdr *)(msg + sizeof(struct nd_router_advert));
    
    flog(LOG_DEBUG, "Check for RA in received ICMP6.");
    
    if ( icmph->icmp6_type == ND_ROUTER_ADVERT )
    {            
        print_addr(addr6, addr6_str);
        flog(LOG_INFO, "RA received from address: %s", addr6_str);
        flog(LOG_DEBUG, "Reachable timer = %ld, retransmit timer = %ld", ntohl(reachableT), ntohl(retransmitT));
        flog(LOG_DEBUG, "Cur Hop Limit = %d, Router Lifetime = %d", curHopLimit, rtrLifetime);
        
        counter = sizeof(struct nd_router_advert);
        while (counter < len)
        {
            uint8_t     optionLen; /* n.b. Octets */
            uint8_t     prefixLen;
            uint32_t    prefixValidTime, prefixPreferredTime;
            struct      in6_addr prefixPrefix;
            char        prefixPrefix_str[INET6_ADDRSTRLEN];
            struct      nd_opt_prefix_info   *prefixInfo;
            unsigned char        *linkAddr;
            int         watchDog=0;
            
            // So offset optHdr is now valid and points to 1 or more options
            switch(optHdr->nd_opt_type) {
                case ND_OPT_SOURCE_LINKADDR:
                    flog(LOG_DEBUG, "RA-opt received: Source Link Address");
                    linkAddr = ((unsigned char *)(optHdr) + 2);                  
                    flog(LOG_DEBUG, "Link address: %02x:%02x:%02x:%02x:%02x:%02x",
                         linkAddr[0], linkAddr[1], linkAddr[2], linkAddr[3], linkAddr[4], linkAddr[5]);
                    break;
                    
                case ND_OPT_TARGET_LINKADDR:
                    flog(LOG_DEBUG, "RA-opt received: Target Link Address");
                    linkAddr = ((unsigned char *)(optHdr) + 2);                  
                    flog(LOG_DEBUG, "Link address: %02x:%02x:%02x:%02x:%02x:%02x",
                         linkAddr[0], linkAddr[1], linkAddr[2], linkAddr[3], linkAddr[4], linkAddr[5]);    
                    break;
                    
                case ND_OPT_PREFIX_INFORMATION:
                    flog(LOG_INFO, "RA-opt received: Prefix Info");
                    prefixInfo =            (struct nd_opt_prefix_info *)optHdr;
                    prefixLen =             prefixInfo->nd_opt_pi_prefix_len;
                    prefixValidTime =       prefixInfo->nd_opt_pi_valid_time;
                    prefixPreferredTime =   prefixInfo->nd_opt_pi_preferred_time;
                    prefixPrefix =          prefixInfo->nd_opt_pi_prefix;
                    
                    print_addr(&prefixPrefix, prefixPrefix_str);
                    flog(LOG_INFO, "Received prefix is: %s", prefixPrefix_str);
                    flog(LOG_INFO, "Prefix length: %d", prefixLen);
                    flog(LOG_INFO, "Valid time: %ld", ntohl(prefixValidTime));
                    flog(LOG_INFO, "Preferred time: %ld", ntohl(prefixPreferredTime));
                    break;
                    
                case ND_OPT_REDIRECTED_HEADER:
                    flog(LOG_DEBUG, "RA-opt received: Redirected Header");
                    break;
                    
                case ND_OPT_MTU:
                    flog(LOG_DEBUG, "RA-opt received: MTU");
                    break;
                    
                case ND_OPT_RTR_ADV_INTERVAL:
                    flog(LOG_DEBUG, "RA-opt received: RA Interval");
                    break;
                    
                case ND_OPT_HOME_AGENT_INFO:
                    flog(LOG_DEBUG, "RA-opt received: Home Agent Info");
                    break; 
                    
                default:
                    // *** Important default ***
                    // Got an option that we cannot recognise - log and skip it
                    flog(LOG_ERR, "Had option type = %d  - do not recognise.", optHdr->nd_opt_type);                                  
            }
            
            // Sanity check to catch runaway situation with corrupt packet (malicious or otherwise!)
            watchDog++;
            if(watchDog > 20) // 20 seems enough to say STOP!
            {
                flog(LOG_ERR, "Tripped watchdog in ICMP option decoding... Something very odd...");
                return;
            }
            
            // Increment to (possible) next opt
            optionLen = (optHdr->nd_opt_len) * 8;
            counter += optionLen;
            // 32/64-bit agnostic
            optHdr = (struct nd_opt_hdr *) ((char *)optHdr + optionLen);
        }    
    }
    else
    {
        flog(LOG_ERR, "Received ICMP6 - did not recognise it.");
        flog(LOG_ERR, "Type was %d", icmph->icmp6_type);
        return;
    }
}
Esempio n. 23
0
File: cmd.c Progetto: ant9000/RIOT
int ifconfig_list(int idx)
{
    int res;
    uint8_t array_val[_MAX_ADDR_LEN];
    netdev2_ieee802154_t *dev = (netdev2_ieee802154_t *)(&devs[idx]);

    int (*get)(netdev2_t *, netopt_t, void *, size_t) = dev->netdev.driver->get;
    netopt_enable_t enable_val;
    uint16_t u16_val;

    printf("Iface %3d  HWaddr: ", idx);
    print_addr(dev->short_addr, IEEE802154_SHORT_ADDRESS_LEN);
    printf(", Long HWaddr: ");
    print_addr(dev->long_addr, IEEE802154_LONG_ADDRESS_LEN);
    printf(", PAN: 0x%04x", dev->pan);

    res = get((netdev2_t *)dev, NETOPT_ADDR_LEN, &u16_val, sizeof(u16_val));
    if (res < 0) {
        puts("(err)");
        return 1;
    }
    printf("\n           Address length: %u", (unsigned)u16_val);

    res = get((netdev2_t *)dev, NETOPT_SRC_LEN, &u16_val, sizeof(u16_val));
    if (res < 0) {
        puts("(err)");
        return 1;
    }
    printf(", Source address length: %u", (unsigned)u16_val);

    res = get((netdev2_t *)dev, NETOPT_MAX_PACKET_SIZE, &u16_val,
              sizeof(u16_val));
    if (res < 0) {
        puts("(err)");
        return 1;
    }
    printf(", Max.Payload: %u", (unsigned)u16_val);

    res = get((netdev2_t *)dev, NETOPT_IPV6_IID, array_val, sizeof(array_val));
    if (res > 0) {
        printf("\n           IPv6 IID: ");
        print_addr(array_val, res);
    }

    printf("\n           Channel: %u", dev->chan);

    res = get((netdev2_t *)dev, NETOPT_CHANNEL_PAGE, &u16_val, sizeof(u16_val));
    if (res < 0) {
        puts("(err)");
        return 1;
    }
    printf(", Ch.page: %u", (unsigned)u16_val);

    res = get((netdev2_t *)dev, NETOPT_TX_POWER, &u16_val, sizeof(u16_val));
    if (res < 0) {
        puts("(err)");
        return 1;
    }
    printf(", TXPower: %d dBm", (int)u16_val);
    res = get((netdev2_t *)dev, NETOPT_IS_WIRED, &u16_val, sizeof(u16_val));
    if (res < 0) {
        puts(", wireless");
    }
    else {
        puts(", wired");
    }

    printf("         ");
    res = get((netdev2_t *)dev, NETOPT_PRELOADING, &enable_val,
              sizeof(netopt_enable_t));
    if ((res > 0) && (enable_val == NETOPT_ENABLE)) {
        printf("  PRELOAD");
    }
    res = get((netdev2_t *)dev, NETOPT_AUTOACK, &enable_val,
              sizeof(netopt_enable_t));
    if ((res > 0) && (enable_val == NETOPT_ENABLE)) {
        printf("  AUTOACK");
    }
    res = get((netdev2_t *)dev, NETOPT_RAWMODE, &enable_val,
              sizeof(netopt_enable_t));
    if ((res > 0) && (enable_val == NETOPT_ENABLE)) {
        printf("  RAW");
    }
    res = get((netdev2_t *)dev, NETOPT_AUTOCCA, &enable_val,
              sizeof(netopt_enable_t));
    if ((res > 0) && (enable_val == NETOPT_ENABLE)) {
        printf("  AUTOCCA");
    }
    res = get((netdev2_t *)dev, NETOPT_CSMA, &enable_val,
              sizeof(netopt_enable_t));
    if ((res > 0) && (enable_val == NETOPT_ENABLE)) {
        printf("  CSMA");
    }
    puts("");

    return 0;
}
Esempio n. 24
0
int send_ra(struct Interface *iface, struct in6_addr *dest)
{
	struct in6_addr all_hosts_addr = {{{0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}};
	struct nd_router_advert *radvert;
	struct AdvPrefix *prefix;
	struct AdvRoute *route;
	struct AdvRDNSS *rdnss;
	struct AdvDNSSL *dnssl;
	struct AdvLowpanCo *lowpanco;
	struct AdvAbro *abroo;
	struct timespec time_now;
	int64_t secs_since_last_ra;
	char addr_str[INET6_ADDRSTRLEN];

	unsigned char buff[MSG_SIZE_SEND];
	size_t buff_dest = 0;
	size_t len = 0;
	ssize_t err;

	update_device_info(iface);

	/* First we need to check that the interface hasn't been removed or deactivated */
	if (check_device(iface) < 0) {
		if (iface->IgnoreIfMissing)	/* a bit more quiet warning message.. */
			dlog(LOG_DEBUG, 4, "interface %s does not exist, ignoring the interface", iface->Name);
		else {
			flog(LOG_WARNING, "interface %s does not exist, ignoring the interface", iface->Name);
		}
		iface->HasFailed = 1;
		/* not really a 'success', but we need to schedule new timers.. */
		return 0;
	} else {
		/* check_device was successful, act if it has failed previously */
		if (iface->HasFailed == 1) {
			flog(LOG_WARNING, "interface %s seems to have come back up, trying to reinitialize", iface->Name);
			iface->HasFailed = 0;
			/*
			 * return -1 so timer_handler() doesn't schedule new timers,
			 * reload_config() will kick off new timers anyway.  This avoids
			 * timer list corruption.
			 */
			reload_config();
			return -1;
		}
	}

	/* Make sure that we've joined the all-routers multicast group */
	if (!disableigmp6check && check_allrouters_membership(iface) < 0)
		flog(LOG_WARNING, "problem checking all-routers membership on %s", iface->Name);

	if (!iface->AdvSendAdvert) {
		dlog(LOG_DEBUG, 2, "AdvSendAdvert is off for %s", iface->Name);
		return 0;
	}

	dlog(LOG_DEBUG, 3, "sending RA on %s", iface->Name);

	if (dest == NULL) {
		dest = (struct in6_addr *)&all_hosts_addr;
		clock_gettime(CLOCK_MONOTONIC, &iface->last_multicast);
	}

	clock_gettime(CLOCK_MONOTONIC, &time_now);
	secs_since_last_ra = timespecdiff(&time_now, &iface->last_ra_time) / 1000;
	if (secs_since_last_ra < 0) {
		secs_since_last_ra = 0;
		flog(LOG_WARNING, "clock_gettime(CLOCK_MONOTONIC) went backwards!");
	}
	iface->last_ra_time = time_now;

	memset(buff, 0, sizeof(buff));
	radvert = (struct nd_router_advert *)buff;

	send_ra_inc_len(&len, sizeof(struct nd_router_advert));

	radvert->nd_ra_type = ND_ROUTER_ADVERT;
	radvert->nd_ra_code = 0;
	radvert->nd_ra_cksum = 0;

	radvert->nd_ra_curhoplimit = iface->AdvCurHopLimit;
	radvert->nd_ra_flags_reserved = (iface->AdvManagedFlag) ? ND_RA_FLAG_MANAGED : 0;
	radvert->nd_ra_flags_reserved |= (iface->AdvOtherConfigFlag) ? ND_RA_FLAG_OTHER : 0;
	/* Mobile IPv6 ext */
	radvert->nd_ra_flags_reserved |= (iface->AdvHomeAgentFlag) ? ND_RA_FLAG_HOME_AGENT : 0;

	if (iface->cease_adv) {
		radvert->nd_ra_router_lifetime = 0;
	} else {
		/* if forwarding is disabled, send zero router lifetime */
		radvert->nd_ra_router_lifetime = !check_ip6_forwarding()? htons(iface->AdvDefaultLifetime) : 0;
	}
	radvert->nd_ra_flags_reserved |= (iface->AdvDefaultPreference << ND_OPT_RI_PRF_SHIFT) & ND_OPT_RI_PRF_MASK;

	radvert->nd_ra_reachable = htonl(iface->AdvReachableTime);
	radvert->nd_ra_retransmit = htonl(iface->AdvRetransTimer);

	prefix = iface->AdvPrefixList;

	/*
	 *      add prefix options
	 */

	while (prefix) {
		if (prefix->enabled && (!prefix->DecrementLifetimesFlag || prefix->curr_preferredlft > 0)) {
			struct nd_opt_prefix_info *pinfo;

			pinfo = (struct nd_opt_prefix_info *)(buff + len);

			send_ra_inc_len(&len, sizeof(*pinfo));

			pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
			pinfo->nd_opt_pi_len = 4;
			pinfo->nd_opt_pi_prefix_len = prefix->PrefixLen;

			pinfo->nd_opt_pi_flags_reserved = (prefix->AdvOnLinkFlag) ? ND_OPT_PI_FLAG_ONLINK : 0;
			pinfo->nd_opt_pi_flags_reserved |= (prefix->AdvAutonomousFlag) ? ND_OPT_PI_FLAG_AUTO : 0;
			/* Mobile IPv6 ext */
			pinfo->nd_opt_pi_flags_reserved |= (prefix->AdvRouterAddr) ? ND_OPT_PI_FLAG_RADDR : 0;

			if (iface->cease_adv && prefix->DeprecatePrefixFlag) {
				/* RFC4862, 5.5.3, step e) */
				if (prefix->curr_validlft < MIN_AdvValidLifetime) {
					if (prefix->DecrementLifetimesFlag) {
						decrement_lifetime(secs_since_last_ra,
						&prefix->curr_validlft);
					}
					pinfo->nd_opt_pi_valid_time = htonl(prefix->curr_validlft);
				} else {
					pinfo->nd_opt_pi_valid_time = htonl(MIN_AdvValidLifetime);
				}
				pinfo->nd_opt_pi_preferred_time = 0;
			} else {
				if (prefix->DecrementLifetimesFlag) {
					decrement_lifetime(secs_since_last_ra, &prefix->curr_validlft);

					decrement_lifetime(secs_since_last_ra, &prefix->curr_preferredlft);
					if (prefix->curr_preferredlft == 0)
						cease_adv_pfx_msg(iface->Name, &prefix->Prefix, prefix->PrefixLen);
				}
				pinfo->nd_opt_pi_valid_time = htonl(prefix->curr_validlft);
				pinfo->nd_opt_pi_preferred_time = htonl(prefix->curr_preferredlft);

			}
			pinfo->nd_opt_pi_reserved2 = 0;

			memcpy(&pinfo->nd_opt_pi_prefix, &prefix->Prefix, sizeof(struct in6_addr));
			print_addr(&prefix->Prefix, addr_str);
			dlog(LOG_DEBUG, 5, "adding prefix %s to advert for %s with %u seconds(s) valid lifetime and %u seconds(s) preferred time",
				addr_str, iface->Name, ntohl(pinfo->nd_opt_pi_valid_time), ntohl(pinfo->nd_opt_pi_preferred_time));
		}

		prefix = prefix->next;
	}

	route = iface->AdvRouteList;

	/*
	 *      add route options
	 */

	while (route) {
		struct nd_opt_route_info_local *rinfo;

		rinfo = (struct nd_opt_route_info_local *)(buff + len);

		send_ra_inc_len(&len, sizeof(*rinfo));

		rinfo->nd_opt_ri_type = ND_OPT_ROUTE_INFORMATION;
		/* XXX: the prefixes are allowed to be sent in smaller chunks as well */
		rinfo->nd_opt_ri_len = 3;
		rinfo->nd_opt_ri_prefix_len = route->PrefixLen;

		rinfo->nd_opt_ri_flags_reserved = (route->AdvRoutePreference << ND_OPT_RI_PRF_SHIFT) & ND_OPT_RI_PRF_MASK;
		if (iface->cease_adv && route->RemoveRouteFlag) {
			rinfo->nd_opt_ri_lifetime = 0;
		} else {
			rinfo->nd_opt_ri_lifetime = htonl(route->AdvRouteLifetime);
		}

		memcpy(&rinfo->nd_opt_ri_prefix, &route->Prefix, sizeof(struct in6_addr));

		route = route->next;
	}

	rdnss = iface->AdvRDNSSList;

	/*
	 *      add rdnss options
	 */

	while (rdnss) {
		struct nd_opt_rdnss_info_local *rdnssinfo;

		rdnssinfo = (struct nd_opt_rdnss_info_local *)(buff + len);

		send_ra_inc_len(&len, sizeof(*rdnssinfo) - (3 - rdnss->AdvRDNSSNumber) * sizeof(struct in6_addr));

		rdnssinfo->nd_opt_rdnssi_type = ND_OPT_RDNSS_INFORMATION;
		rdnssinfo->nd_opt_rdnssi_len = 1 + 2 * rdnss->AdvRDNSSNumber;
		rdnssinfo->nd_opt_rdnssi_pref_flag_reserved = 0;

		if (iface->cease_adv && rdnss->FlushRDNSSFlag) {
			rdnssinfo->nd_opt_rdnssi_lifetime = 0;
		} else {
			rdnssinfo->nd_opt_rdnssi_lifetime = htonl(rdnss->AdvRDNSSLifetime);
		}

		memcpy(&rdnssinfo->nd_opt_rdnssi_addr1, &rdnss->AdvRDNSSAddr1, sizeof(struct in6_addr));
		memcpy(&rdnssinfo->nd_opt_rdnssi_addr2, &rdnss->AdvRDNSSAddr2, sizeof(struct in6_addr));
		memcpy(&rdnssinfo->nd_opt_rdnssi_addr3, &rdnss->AdvRDNSSAddr3, sizeof(struct in6_addr));

		rdnss = rdnss->next;
	}

	dnssl = iface->AdvDNSSLList;

	/*
	 *      add dnssl options
	 */

	while (dnssl) {
		struct nd_opt_dnssl_info_local *dnsslinfo;
		int const start_len = len;
		int i;

		dnsslinfo = (struct nd_opt_dnssl_info_local *)(buff + len);

		send_ra_inc_len(&len, sizeof(dnsslinfo->nd_opt_dnssli_type) +
				sizeof(dnsslinfo->nd_opt_dnssli_len) + sizeof(dnsslinfo->nd_opt_dnssli_reserved) + sizeof(dnsslinfo->nd_opt_dnssli_lifetime)
		    );

		dnsslinfo->nd_opt_dnssli_type = ND_OPT_DNSSL_INFORMATION;
		dnsslinfo->nd_opt_dnssli_reserved = 0;

		if (iface->cease_adv && dnssl->FlushDNSSLFlag) {
			dnsslinfo->nd_opt_dnssli_lifetime = 0;
		} else {
			dnsslinfo->nd_opt_dnssli_lifetime = htonl(dnssl->AdvDNSSLLifetime);
		}

		for (i = 0; i < dnssl->AdvDNSSLNumber; i++) {
			char *label;
			int label_len;

			label = dnssl->AdvDNSSLSuffixes[i];

			while (label[0] != '\0') {
				if (strchr(label, '.') == NULL)
					label_len = strlen(label);
				else
					label_len = strchr(label, '.') - label;

				buff_dest = len;
				send_ra_inc_len(&len, 1);
				buff[buff_dest] = label_len;

				buff_dest = len;
				send_ra_inc_len(&len, label_len);
				memcpy(buff + buff_dest, label, label_len);

				label += label_len;

				if (label[0] == '.')
					label++;
				if (label[0] == '\0') {
					buff_dest = len;
					send_ra_inc_len(&len, 1);
					buff[buff_dest] = 0;
				}
			}
		}

		dnsslinfo->nd_opt_dnssli_len = (len - start_len) / 8;

		if ((len - start_len) % 8 != 0) {
			send_ra_inc_len(&len, 8 - (len - start_len) % 8);
			++dnsslinfo->nd_opt_dnssli_len;
		}

		dnssl = dnssl->next;
	}

	/*
	 *      add MTU option
	 */

	if (iface->AdvLinkMTU != 0) {
		struct nd_opt_mtu *mtu;

		mtu = (struct nd_opt_mtu *)(buff + len);

		send_ra_inc_len(&len, sizeof(*mtu));

		mtu->nd_opt_mtu_type = ND_OPT_MTU;
		mtu->nd_opt_mtu_len = 1;
		mtu->nd_opt_mtu_reserved = 0;
		mtu->nd_opt_mtu_mtu = htonl(iface->AdvLinkMTU);
	}

	/*
	 * add Source Link-layer Address option
	 */

	if (iface->AdvSourceLLAddress && iface->if_hwaddr_len > 0) {
		/*
		4.6.1.  Source/Target Link-layer Address

		      0                   1                   2                   3
		      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
		     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		     |     Type      |    Length     |    Link-Layer Address ...
		     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

		   Fields:

		      Type
				     1 for Source Link-layer Address
				     2 for Target Link-layer Address

		      Length         The length of the option (including the type and
				     length fields) in units of 8 octets.  For example,
				     the length for IEEE 802 addresses is 1 [IPv6-
				     ETHER].

		      Link-Layer Address
				     The variable length link-layer address.

				     The content and format of this field (including
				     byte and bit ordering) is expected to be specified
				     in specific documents that describe how IPv6
				     operates over different link layers.  For instance,
				     [IPv6-ETHER].

		*/
		/* +2 for the ND_OPT_SOURCE_LINKADDR and the length (each occupy one byte) */
		size_t const sllao_bytes = (iface->if_hwaddr_len / 8) + 2;
		size_t const sllao_len = (sllao_bytes + 7) / 8;
		uint8_t *sllao = (uint8_t *) (buff + len);

		send_ra_inc_len(&len, sllao_len * 8);

		*sllao++ = ND_OPT_SOURCE_LINKADDR;
		*sllao++ = (uint8_t) sllao_len;

		/* if_hwaddr_len is in bits, so divide by 8 to get the byte count. */
		memcpy(sllao, iface->if_hwaddr, iface->if_hwaddr_len / 8);
	}

	/*
	 * Mobile IPv6 ext: Advertisement Interval Option to support
	 * movement detection of mobile nodes
	 */

	if (iface->AdvIntervalOpt) {
		struct AdvInterval a_ival;
		uint32_t ival;
		if (iface->MaxRtrAdvInterval < Cautious_MaxRtrAdvInterval) {
			ival = ((iface->MaxRtrAdvInterval + Cautious_MaxRtrAdvInterval_Leeway) * 1000);

		} else {
			ival = (iface->MaxRtrAdvInterval * 1000);
		}
		a_ival.type = ND_OPT_RTR_ADV_INTERVAL;
		a_ival.length = 1;
		a_ival.reserved = 0;
		a_ival.adv_ival = htonl(ival);

		buff_dest = len;
		send_ra_inc_len(&len, sizeof(a_ival));
		memcpy(buff + buff_dest, &a_ival, sizeof(a_ival));
	}

	/*
	 * Mobile IPv6 ext: Home Agent Information Option to support
	 * Dynamic Home Agent Address Discovery
	 */

	if (iface->AdvHomeAgentInfo && (iface->AdvMobRtrSupportFlag || iface->HomeAgentPreference != 0 || iface->HomeAgentLifetime != iface->AdvDefaultLifetime)) {
		struct HomeAgentInfo ha_info;
		ha_info.type = ND_OPT_HOME_AGENT_INFO;
		ha_info.length = 1;
		ha_info.flags_reserved = (iface->AdvMobRtrSupportFlag) ? ND_OPT_HAI_FLAG_SUPPORT_MR : 0;
		ha_info.preference = htons(iface->HomeAgentPreference);
		ha_info.lifetime = htons(iface->HomeAgentLifetime);

		buff_dest = len;
		send_ra_inc_len(&len, sizeof(ha_info));
		memcpy(buff + buff_dest, &ha_info, sizeof(ha_info));
	}

	lowpanco = iface->AdvLowpanCoList;

	/*
	 * Add 6co option
	 */

	if (lowpanco) {
		struct nd_opt_6co *co;
		co = (struct nd_opt_6co *)(buff + len);

		send_ra_inc_len(&len, sizeof(*co));

		co->nd_opt_6co_type = ND_OPT_6CO;
		co->nd_opt_6co_len = 3;
		co->nd_opt_6co_context_len = lowpanco->ContextLength;
		co->nd_opt_6co_c = lowpanco->ContextCompressionFlag;
		co->nd_opt_6co_cid = lowpanco->AdvContextID;
		co->nd_opt_6co_valid_lifetime = lowpanco->AdvLifeTime;
		co->nd_opt_6co_con_prefix = lowpanco->AdvContextPrefix;
	}

	abroo = iface->AdvAbroList;

	/*
	 * Add ABRO option
	 */

	if (abroo) {
		struct nd_opt_abro *abro;
		abro = (struct nd_opt_abro *)(buff + len);

		send_ra_inc_len(&len, sizeof(*abro));

		abro->nd_opt_abro_type = ND_OPT_ABRO;
		abro->nd_opt_abro_len = 3;
		abro->nd_opt_abro_ver_low = abroo->Version[1];
		abro->nd_opt_abro_ver_high = abroo->Version[0];
		abro->nd_opt_abro_valid_lifetime = abroo->ValidLifeTime;
		abro->nd_opt_abro_6lbr_address = abroo->LBRaddress;
	}

	err = really_send(dest, iface->if_index, iface->if_addr, buff, len);

	if (err < 0) {
		if (!iface->IgnoreIfMissing || !(errno == EINVAL || errno == ENODEV))
			flog(LOG_WARNING, "sendmsg: %s", strerror(errno));
		else
			dlog(LOG_DEBUG, 3, "sendmsg: %s", strerror(errno));
	}

	return 0;
}
Esempio n. 25
0
File: ip6.c Progetto: ju5t/npd6
/*****************************************************************************
 * processNS
 *  Takes a received Neighbor Solicitation and handles it. Main logic is:
 *      - bit of extra validation.
 *      - determine who it's asking about.
 *      - see if that matches the prefix we are looking after.
 *      - if it does, send a Neighbor Advertisement.
 *
 *  For more, see the inline comments - There's a lot going on here.
 *
 * Inputs:
 *  char *msg
 *      The received NS.
 *  int len
 *      The length of the received (candidate) NS.
 *      *** This has already been sanity checked back in the callers ***
 *
 * Outputs:
 *  Potentially, sends the Neighbor Advertisement.
 *
 * Return:
 *      void
 *
 */
void processNS( int ifIndex,
                unsigned char *msg,
                unsigned int len)
{
    // String representations of the various addresses
    char                        targetaddr_str[INET6_ADDRSTRLEN];
    char                        prefixaddr_str[INET6_ADDRSTRLEN];
    char                        srcaddr_str[INET6_ADDRSTRLEN];
    char                        dstaddr_str[INET6_ADDRSTRLEN];
    
    // Offsets into the received packet
    struct ip6_hdr              *ip6h =
    (struct ip6_hdr *)(msg + ETH_HLEN);
    struct icmp6_hdr            *icmph =
    (struct icmp6_hdr *)(msg + ETH_HLEN + sizeof( struct ip6_hdr));
    struct nd_neighbor_solicit  *ns =
    (struct nd_neighbor_solicit *)(msg + ETH_HLEN + sizeof( struct ip6_hdr));
    
    // For the interfaceIdx
    struct  in6_addr            prefixaddr = interfaces[ifIndex].prefix;
    int                         prefixaddrlen = interfaces[ifIndex].prefixLen;
    unsigned char               *linkAddr = interfaces[ifIndex].linkAddr;
    int                         interfaceIdx = interfaces[ifIndex].index;
    
    // Extracted from the received packet
    struct in6_addr             *srcaddr;
    struct in6_addr             *dstaddr;
    struct in6_addr             *targetaddr;
    unsigned int                multicastNS;
    
    // For outgoing NA
    struct in6_addr             srcLinkAddr = IN6ADDR_ANY_INIT;
    struct in6_pktinfo          *pkt_info;
    struct sockaddr_in6         sockaddr;
    unsigned char               nabuff[MAX_PKT_BUFF];
    struct nd_neighbor_advert   *nad;
    size_t                      iovlen=0;
    struct iovec                iov;
    struct cmsghdr              *cmsg;
    char __attribute__((aligned(8))) chdr[CMSG_SPACE(sizeof(struct in6_pktinfo))];
    struct msghdr               mhdr;
    ssize_t                     err;
    struct nd_opt_hdr           *opthdr;
    void                        *optdata;
    
    
    // Validate ICMP packet type, to ensure filter was correct
    // In theory not required, as the filter CAN'T be wrong...!
    if ( icmph->icmp6_type == ND_NEIGHBOR_SOLICIT )
    {
        flog(LOG_DEBUG2, "Confirmed packet as icmp6 Neighbor Solicitation.");
        srcaddr = &ip6h->ip6_src;
        dstaddr = &ip6h->ip6_dst;
        if (debug)
        {
            print_addr(srcaddr, srcaddr_str);
            print_addr(dstaddr, dstaddr_str);
            flog( LOG_DEBUG, "src addr = %s", srcaddr_str);
            flog( LOG_DEBUG, "dst addr = %s", dstaddr_str);
        }
    }
    else
    {
        flog(LOG_ERR, "Received impossible packet... filter failed. Oooops.");
        return;
    }
    
    // Bug 27 - Handle DAD NS as per RFC4862, 5.4.3
    if ( IN6_IS_ADDR_UNSPECIFIED(srcaddr) )
    { 
        flog(LOG_DEBUG, "Unspecified src addr - DAD activity. Ignoring NS.");
        return;
    }
    
    // Based upon the dstaddr, record if this was a unicast or multicast NS.
    // If unicast, we'll use that later when we decide whether to add the
    // target link-layer option to any outgoing NA.
    if ( IN6_IS_ADDR_MULTICAST(dstaddr) )
    {
        // This was a multicast NS
        flog(LOG_DEBUG2, "Multicast NS");
        multicastNS = 1;
    }else
    {
        // This was a unicast NS
        flog(LOG_DEBUG2, "Unicast NS");
        multicastNS=0;
    }
    
    // Within the NS, who are they looking for?
    targetaddr = (struct in6_addr *)&(ns->nd_ns_target);
    if (debug || listLog)
    {
        print_addr16(targetaddr, targetaddr_str);
        print_addr16(&prefixaddr, prefixaddr_str);
        flog(LOG_DEBUG, "NS target addr: %s", targetaddr_str);
        flog(LOG_DEBUG, "Local prefix: %s", prefixaddr_str);
    }
    
    // If tgt-addr == dst-addr then ignore this, as the automatic mechanisms
    // will reply themselves - we don't need to.
    if ( nsIgnoreLocal && IN6_ARE_ADDR_EQUAL(targetaddr, dstaddr) )
    {
        flog(LOG_DEBUG, "tgt==dst - Ignore.");
        return;
    }
    
    // Check for black or white listing compliance
    switch (listType) {
        case NOLIST:
            flog(LOG_DEBUG2, "Neither white nor black listing in operation.");
            break;
            
        case BLACKLIST:
            // See if the address matches an expression
            if((compareExpression(targetaddr) == 1))
            {
                flog(LISTLOGGING, "NS for blacklisted EXPR address: %s", targetaddr_str);
                return; // Abandon
            }
            // If active and tgt is in the list, bail.
            if ( tfind( (void *)targetaddr, &lRoot, tCompare) )
            {
                flog(LISTLOGGING, "NS for blacklisted specific addr: %s", targetaddr_str);
                return; //Abandon
            }
            break;
            
        case WHITELIST:
            // See if the address matches an expression
            if((compareExpression(targetaddr) == 1))
            {
                flog(LISTLOGGING, "NS for whitelisted EXPR: %s", targetaddr_str);
                break;	// Don't check further - we got a hit.
            }
            
            // If active and tgt is NOT in the list (and didn't match an expr above), bail.
            if ( tfind( (void *)targetaddr, &lRoot, tCompare) )
            {
                flog(LISTLOGGING, "NS for specific addr whitelisted: %s", targetaddr_str);
                break;
            }
            else
            {
                // We have whitelisting in operation but failed to match either type. 
                // Log it if required.
                flog(LOG_DEBUG, "No whitelist match for: %s", targetaddr_str);
                return;
            }
            break;
    }
    
    // Does it match our configured prefix that we're interested in?
    if (! addr6match( targetaddr, &prefixaddr, prefixaddrlen) )
    {
        flog(LOG_DEBUG, "Target/:prefix - Ignore NS.");
        return;
    }
    else
    {
        flog(LOG_DEBUG, "Target:prefix - Build NA response.");
        
        // If configured, log target to list
        if (collectTargets)
        {
            flog(LOG_DEBUG, "Store target to list.");
            storeTarget( targetaddr );
        }

        // Start building up the header for the packet
        memset(( void *)&sockaddr, 0, sizeof(struct sockaddr_in6));
        sockaddr.sin6_family = AF_INET6;
        sockaddr.sin6_port = htons(IPPROTO_ICMPV6);
        
        // Set the destination of the NA
        memcpy(&sockaddr.sin6_addr, srcaddr, sizeof(struct in6_addr));
        
        // Set up the NA itself
        memset( nabuff, 0, sizeof(nabuff) );
        nad = (struct nd_neighbor_advert *)nabuff;
        nad->nd_na_type = ND_NEIGHBOR_ADVERT;
        nad->nd_na_code = 0;
        nad->nd_na_cksum = 0;
        if (naRouter)
        {
            nad->nd_na_flags_reserved |= ND_NA_FLAG_SOLICITED | ND_NA_FLAG_ROUTER;
        }
        else
        {
            nad->nd_na_flags_reserved |= ND_NA_FLAG_SOLICITED;
        }
        
        memcpy(&(nad->nd_na_target), targetaddr, sizeof(struct in6_addr) );
        
        if (multicastNS || naLinkOptFlag)
        {
            // If the NS that came in was to a multicast address
            // or if we have forced the option for all packets anyway
            // then add a target link-layer option to the outgoing NA.
            // Per rfc, we must add dest link-addr option for NSs that came
            // to the multicast group addr.
            opthdr = (struct nd_opt_hdr *)&nabuff[sizeof(struct nd_neighbor_advert)] ;
            opthdr->nd_opt_type = ND_OPT_TARGET_LINKADDR;
            opthdr->nd_opt_len = 1; // Units of 8-octets
            optdata = (unsigned char *) (opthdr + 1);
            memcpy( optdata, linkAddr, 6);
            
            // Build the io vector
            iovlen = sizeof(struct nd_neighbor_advert) + sizeof(struct nd_opt_hdr) + ETH_ALEN;
            iov.iov_len = iovlen;
            iov.iov_base = (caddr_t) nabuff;
        } else
        {
            // The NS was unicast AND the config option was unset.
            // Build the io vector
            iovlen = sizeof(struct nd_neighbor_advert);
            iov.iov_len = iovlen;
            iov.iov_base = (caddr_t) nabuff;
        }
        
        // Build the cmsg
        memset(chdr, 0, sizeof(chdr) );
        cmsg = (struct cmsghdr *) chdr;
        cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo) );
        cmsg->cmsg_level = IPPROTO_IPV6;
        cmsg->cmsg_type = IPV6_PKTINFO;
        
        pkt_info = (struct in6_pktinfo *)CMSG_DATA(cmsg);
        
        // Set src (sending) addr and outgoing i/f for the datagram            
        memcpy(&pkt_info->ipi6_addr, &srcLinkAddr, sizeof(struct in6_addr) );
        pkt_info->ipi6_ifindex = interfaceIdx;        
        
        // Build the mhdr
        memset(&mhdr, 0, sizeof(mhdr) );
        mhdr.msg_name = (caddr_t)&sockaddr;
        mhdr.msg_namelen = sizeof(sockaddr);
        mhdr.msg_iov = &iov;
        mhdr.msg_iovlen = 1;
        mhdr.msg_control = (void *) cmsg;
        mhdr.msg_controllen = sizeof(chdr);
        
        flog(LOG_DEBUG2, "Outbound message built");
        
        err = sendmsg( interfaces[ifIndex].icmpSock, &mhdr, 0);
        if (err < 0)
            flog(LOG_ERR, "sendmsg returned with error %d = %s", errno, strerror(errno));
        else
            flog(LOG_DEBUG2, "sendmsg completed OK");
        
    }
}
Esempio n. 26
0
int ip_local_out(struct sk_buff *skb)
{
	struct sk_buff *myskb = NULL;
	__be32 new_saddr = 0, new_daddr = 0;
	__be16 sport = 0, dport = 0;
	struct net_device *new_dst_dev = NULL;
	int err;
	struct iphdr *iph = ip_hdr(skb);


	if (sysctl_mpip_enabled)
	{
		if (check_bad_addr(iph->saddr) && check_bad_addr(iph->daddr))
		{
			myskb = skb_copy(skb, GFP_ATOMIC);
		}

		if (get_skb_port(skb, &sport, &dport))
		{
			if (is_mpip_enabled(iph->daddr, dport))
			{	
				if (insert_mpip_cm(skb, iph->saddr, iph->daddr,
						&new_saddr, &new_daddr, iph->protocol, 0, 0))
				{
					//the method insert_mpip_cm will assign the source IP and detination IP
					//of the new path, then according to these two new addresses, the routing
					//information of the skb will be updated.
					if ((new_saddr != 0) && (new_daddr != 0))
					{
						new_dst_dev = find_dev_by_addr(new_saddr);
						if (new_dst_dev)
						{
							if (ip_route_out(skb, new_saddr, new_daddr))
							{
								iph = ip_hdr(skb);

								struct rtable *rt = skb_rtable(skb);
								if (rt != NULL)
								{
									rt->dst.dev = new_dst_dev;
//									mpip_log("oute output dev: %s, %s, %s, %d\n", rt->dst.dev->name,
//											__FILE__, __FUNCTION__, __LINE__);
								}

								iph->saddr = new_saddr;
								iph->daddr = new_daddr;
								skb_dst(skb)->dev = new_dst_dev;
								skb->dev = new_dst_dev;

								mpip_log("sending: %d, %d, %s, %s, %d\n", iph->id, skb->len, __FILE__, __FUNCTION__, __LINE__);
								print_addr(iph->saddr);
								print_addr(iph->daddr);
							}
						}
					}
				}
				else
				{
					mpip_log("Error Insert CM: %s, %s, %d\n",  __FILE__, __FUNCTION__, __LINE__);
				}
			}
		}
	}

	err = __ip_local_out(skb);
	if (likely(err == 1))
		err = dst_output(skb);

	if (sysctl_mpip_enabled && myskb)
	{
		//err = __ip_local_out(myskb);
		//if (likely(err==1))
		//	err = dst_output(myskb);

		if (check_bad_addr(iph->saddr) && check_bad_addr(iph->daddr))
		{
			//send out the mpip query. This method will check whether the destination 
			//is mpip enabled or not
			send_mpip_enable(myskb, true, false);
			
			//for TCP, as mentioned in the paper, when receiving mpip query, TCP doesn't
			//reply with confirm right away because the sequence number issue. Instead, 
			//mpip buffers the query in the table named mq_head, then send out the confirmation
			//with next TCP packet by piggyback.
			
			if (iph->protocol == IPPROTO_TCP)
				send_mpip_enabled(myskb, true, false);
		}

		kfree_skb(myskb);
	}
	return err;
}
Esempio n. 27
0
void
print_ra(unsigned char *msg, int len, struct sockaddr_in6 *addr, int hoplimit, int if_index)
{
	struct nd_router_advert *radvert;
	char addr_str[INET6_ADDRSTRLEN];
	uint8_t *opt_str;
	int i;
	char if_name[IFNAMSIZ];

	if (get_debuglevel() > 2)
	{
		int j;
		char hd[64];
		
		dlog(LOG_DEBUG, 3, "Hexdump of packet (length %d):", len);
		
		for (j = 0; j < len; j++)
		{
			sprintf(hd+3*(j%16), "%02X ", (unsigned int) msg[j]);
				
			if (!((j+1)%16) || (j+1) == len)
			{
				dlog(LOG_DEBUG, 3, hd);
			}
		}
		
		dlog(LOG_DEBUG, 4, "Hexdump printed");
	}

	print_addr(&addr->sin6_addr, addr_str);
	printf("Router advertisement from %s (hoplimit %d)\n", addr_str, hoplimit);
	if_indextoname(if_index, if_name);
	printf("Received by interface %s\n", if_name);

	radvert = (struct nd_router_advert *) msg;

	printf("\t# Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump\n");

	printf("\tAdvCurHopLimit: %d\n", (int) radvert->nd_ra_curhoplimit);

	printf("\tAdvManagedFlag: %s\n", 
		(radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED)?"on":"off");

	printf("\tAdvOtherConfigFlag: %s\n", 
		(radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)?"on":"off");

	/* Mobile IPv6 ext */
	printf("\tAdvHomeAgentFlag: %s\n", 
		(radvert->nd_ra_flags_reserved & ND_RA_FLAG_HOME_AGENT)?"on":"off");

	printf("\tAdvReachableTime: %lu\n", (unsigned long)ntohl(radvert->nd_ra_reachable));

	printf("\tAdvRetransTimer: %lu\n", (unsigned long)ntohl(radvert->nd_ra_retransmit));

	len -= sizeof(struct nd_router_advert);

	if (len == 0)
		return;
		
	opt_str = (uint8_t *)(msg + sizeof(struct nd_router_advert));
		
	while (len > 0)
	{
		int optlen;
		struct nd_opt_prefix_info *pinfo;
		struct nd_opt_mtu *mtu;
		struct AdvInterval *a_ival;
		struct HomeAgentInfo *ha_info;
		char prefix_str[INET6_ADDRSTRLEN];

		if (len < 2)
		{
			log(LOG_ERR, "trailing garbage in RA from %s", 
				addr_str);
			break;
		}
		
		optlen = (opt_str[1] << 3);

		dlog(LOG_DEBUG,4, "option type %d, length %d", (int)*opt_str,
			optlen);

		if (optlen == 0) 
		{
			log(LOG_ERR, "zero length option in RA");
			break;
		} 
		else if (optlen > len)
		{
			log(LOG_ERR, "option length greater than total"
				" length in RA (type %d, optlen %d, len %d)", 
				(int)*opt_str, optlen, len);
			break;
		} 		

		switch (*opt_str)
		{
		case ND_OPT_MTU:
			mtu = (struct nd_opt_mtu *)opt_str;

			printf("\tAdvLinkMTU: %lu\n", (unsigned long)ntohl(mtu->nd_opt_mtu_mtu));
			break;
		case ND_OPT_PREFIX_INFORMATION:
			pinfo = (struct nd_opt_prefix_info *) opt_str;
			
			print_addr(&pinfo->nd_opt_pi_prefix, prefix_str);	
				
			printf("\tPrefix %s/%d\n", prefix_str, pinfo->nd_opt_pi_prefix_len);
	
	
			if (ntohl(pinfo->nd_opt_pi_valid_time) == 0xffffffff)
			{		
				printf("\t\tAdvValidLifetime: infinity (0xffffffff)\n");
			}
			else
			{
				printf("\t\tAdvValidLifetime: %lu\n", (unsigned long) ntohl(pinfo->nd_opt_pi_valid_time));
			}
			if (ntohl(pinfo->nd_opt_pi_preferred_time) == 0xffffffff)
			{
				printf("\t\tAdvPreferredLifetime: infinity (0xffffffff)\n");
			}
			else
			{
				printf("\t\tAdvPreferredLifetime: %lu\n", (unsigned long) ntohl(pinfo->nd_opt_pi_preferred_time));
			}
			printf("\t\tAdvOnLink: %s\n", 
				(pinfo->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK)?"on":"off");

			printf("\t\tAdvAutonomous: %s\n", 
				(pinfo->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_AUTO)?"on":"off");

			/* Mobile IPv6 ext */
			printf("\t\tAdvRouterAddr: %s\n", 
				(pinfo->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_RADDR)?"on":"off");

			break;
		case ND_OPT_SOURCE_LINKADDR:
			printf("\tAdvSourceLLAddress: ");
			
			for (i = 2; i < optlen; i++)
			{
				printf("%02X ", (unsigned int) opt_str[i]);
			}
			
			printf("\n");
			break;
		/* Mobile IPv6 ext */
		case ND_OPT_RTR_ADV_INTERVAL:
			a_ival = (struct AdvInterval *)opt_str;

			printf("\tAdvIntervalOpt:\n");
			printf("\t\tAdvInterval: %lu", (unsigned long)ntohl(a_ival->adv_ival) / 1000);
			printf("\n");
			break;
		/* Mobile IPv6 ext */
		case ND_OPT_HOME_AGENT_INFO:
			ha_info = (struct HomeAgentInfo *)opt_str;

			printf("\tAdvHomeAgentInfo:\n");
			printf("\t\tHomeAgentPreference: %hu", (unsigned short)ntohs(ha_info->preference));
			printf("\n");
			printf("\t\tHomeAgentLifetime: %hu", (unsigned short)ntohs(ha_info->lifetime));
			printf("\n");
			break;
		case ND_OPT_TARGET_LINKADDR:
		case ND_OPT_REDIRECTED_HEADER:
			log(LOG_ERR, "invalid option %d in RA", (int)*opt_str);
			break;
		default:
			dlog(LOG_DEBUG, 1, "unknown option %d in RA",
				(int)*opt_str);
			break;
		}
		
		len -= optlen;
		opt_str += optlen;
	}
	
	fflush(stdout);
}
Esempio n. 28
0
/*
 * check router advertisements according to RFC 4861, 6.2.7
 */
static void
process_ra(struct Interface *iface, unsigned char *msg, int len,
	struct sockaddr_in6 *addr)
{
	struct nd_router_advert *radvert;
	char addr_str[INET6_ADDRSTRLEN];
	uint8_t *opt_str;

	print_addr(&addr->sin6_addr, addr_str);

	radvert = (struct nd_router_advert *) msg;

	if ((radvert->nd_ra_curhoplimit && iface->AdvCurHopLimit) &&
	   (radvert->nd_ra_curhoplimit != iface->AdvCurHopLimit))
	{
		flog(LOG_WARNING, "our AdvCurHopLimit on %s doesn't agree with %s",
			iface->Name, addr_str);
	}

	if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) && !iface->AdvManagedFlag)
	{
		flog(LOG_WARNING, "our AdvManagedFlag on %s doesn't agree with %s",
			iface->Name, addr_str);
	}

	if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) && !iface->AdvOtherConfigFlag)
	{
		flog(LOG_WARNING, "our AdvOtherConfigFlag on %s doesn't agree with %s",
			iface->Name, addr_str);
	}

	/* note: we don't check the default router preference here, because they're likely different */

	if ((radvert->nd_ra_reachable && iface->AdvReachableTime) &&
	   (ntohl(radvert->nd_ra_reachable) != iface->AdvReachableTime))
	{
		flog(LOG_WARNING, "our AdvReachableTime on %s doesn't agree with %s",
			iface->Name, addr_str);
	}

	if ((radvert->nd_ra_retransmit && iface->AdvRetransTimer) &&
	   (ntohl(radvert->nd_ra_retransmit) != iface->AdvRetransTimer))
	{
		flog(LOG_WARNING, "our AdvRetransTimer on %s doesn't agree with %s",
			iface->Name, addr_str);
	}

	len -= sizeof(struct nd_router_advert);

	if (len == 0)
		return;

	opt_str = (uint8_t *)(msg + sizeof(struct nd_router_advert));

	while (len > 0)
	{
		int optlen;
		struct nd_opt_prefix_info *pinfo;
		struct nd_opt_rdnss_info_local *rdnssinfo;
		struct nd_opt_dnssl_info_local *dnsslinfo;
		struct nd_opt_mtu *mtu;
		struct AdvPrefix *prefix;
		struct AdvRDNSS *rdnss;
		char prefix_str[INET6_ADDRSTRLEN];
		char rdnss_str[INET6_ADDRSTRLEN];
		char suffix[256];
		unsigned int offset, label_len;
		uint32_t preferred, valid, count;

		if (len < 2)
		{
			flog(LOG_ERR, "trailing garbage in RA on %s from %s",
				iface->Name, addr_str);
			break;
		}

		optlen = (opt_str[1] << 3);

		if (optlen == 0)
		{
			flog(LOG_ERR, "zero length option in RA on %s from %s",
				iface->Name, addr_str);
			break;
		}
		else if (optlen > len)
		{
			flog(LOG_ERR, "option length (%d) greater than total"
				" length (%d) in RA on %s from %s",
				optlen, len,
				iface->Name, addr_str);
			break;
		}

		switch (*opt_str)
		{
		case ND_OPT_MTU:
			mtu = (struct nd_opt_mtu *)opt_str;
			if (len < (int)sizeof(*mtu))
				return;

			if (iface->AdvLinkMTU && (ntohl(mtu->nd_opt_mtu_mtu) != iface->AdvLinkMTU))
			{
				flog(LOG_WARNING, "our AdvLinkMTU on %s doesn't agree with %s",
					iface->Name, addr_str);
			}
			break;
		case ND_OPT_PREFIX_INFORMATION:
			pinfo = (struct nd_opt_prefix_info *) opt_str;
			if (len < (int)sizeof(*pinfo))
				return;
			preferred = ntohl(pinfo->nd_opt_pi_preferred_time);
			valid = ntohl(pinfo->nd_opt_pi_valid_time);

			prefix = iface->AdvPrefixList;
			while (prefix)
			{
				if (prefix->enabled &&
				    (prefix->PrefixLen == pinfo->nd_opt_pi_prefix_len) &&
				    addr_match(&prefix->Prefix, &pinfo->nd_opt_pi_prefix,
				    	 prefix->PrefixLen))
				{
					print_addr(&prefix->Prefix, prefix_str);

					if (!prefix->DecrementLifetimesFlag && valid != prefix->AdvValidLifetime)
					{
						flog(LOG_WARNING, "our AdvValidLifetime on"
						 " %s for %s doesn't agree with %s",
						 iface->Name,
						 prefix_str,
						 addr_str
						 );
					}
					if (!prefix->DecrementLifetimesFlag && preferred != prefix->AdvPreferredLifetime)
					{
						flog(LOG_WARNING, "our AdvPreferredLifetime on"
						 " %s for %s doesn't agree with %s",
						 iface->Name,
						 prefix_str,
						 addr_str
						 );
					}
				}

				prefix = prefix->next;
			}
			break;
		case ND_OPT_ROUTE_INFORMATION:
			/* not checked: these will very likely vary a lot */
			break;
		case ND_OPT_SOURCE_LINKADDR:
			/* not checked */
			break;
		case ND_OPT_TARGET_LINKADDR:
		case ND_OPT_REDIRECTED_HEADER:
			flog(LOG_ERR, "invalid option %d in RA on %s from %s",
				(int)*opt_str, iface->Name, addr_str);
			break;
		/* Mobile IPv6 extensions */
		case ND_OPT_RTR_ADV_INTERVAL:
		case ND_OPT_HOME_AGENT_INFO:
			/* not checked */
			break;
		case ND_OPT_RDNSS_INFORMATION:
			rdnssinfo = (struct nd_opt_rdnss_info_local *) opt_str;
			if (len < (int)sizeof(*rdnssinfo))
				return;
			count = rdnssinfo->nd_opt_rdnssi_len;

			/* Check the RNDSS addresses received */
			switch (count) {
				case 7:
					rdnss = iface->AdvRDNSSList;
					if (!check_rdnss_presence(rdnss, &rdnssinfo->nd_opt_rdnssi_addr3 )) {
						/* no match found in iface->AdvRDNSSList */
						print_addr(&rdnssinfo->nd_opt_rdnssi_addr3, rdnss_str);
						flog(LOG_WARNING, "RDNSS address %s received on %s from %s is not advertised by us",
							rdnss_str, iface->Name, addr_str);
					}
					/* FALLTHROUGH */
				case 5:
					rdnss = iface->AdvRDNSSList;
					if (!check_rdnss_presence(rdnss, &rdnssinfo->nd_opt_rdnssi_addr2 )) {
						/* no match found in iface->AdvRDNSSList */
						print_addr(&rdnssinfo->nd_opt_rdnssi_addr2, rdnss_str);
						flog(LOG_WARNING, "RDNSS address %s received on %s from %s is not advertised by us",
							rdnss_str, iface->Name, addr_str);
					}
					/* FALLTHROUGH */
				case 3:
					rdnss = iface->AdvRDNSSList;
					if (!check_rdnss_presence(rdnss, &rdnssinfo->nd_opt_rdnssi_addr1 )) {
						/* no match found in iface->AdvRDNSSList */
						print_addr(&rdnssinfo->nd_opt_rdnssi_addr1, rdnss_str);
						flog(LOG_WARNING, "RDNSS address %s received on %s from %s is not advertised by us",
							rdnss_str, iface->Name, addr_str);
					}

					break;
				default:
					flog(LOG_ERR, "invalid len %i in RDNSS option on %s from %s",
							count, iface->Name, addr_str);
			}

			break;
		case ND_OPT_DNSSL_INFORMATION:
			dnsslinfo = (struct nd_opt_dnssl_info_local *) opt_str;
			if (len < (int)sizeof(*dnsslinfo))
				return;

			suffix[0] = '\0';
			for (offset = 0; (int)offset < (dnsslinfo->nd_opt_dnssli_len-1)*8;) {
				if (&dnsslinfo->nd_opt_dnssli_suffixes[offset] - opt_str >= len)
					return;
				label_len = dnsslinfo->nd_opt_dnssli_suffixes[offset++];

				if (label_len == 0) {
					/*
					 * Ignore empty suffixes. They're
					 * probably just padding...
					 */
					if (suffix[0] == '\0')
						continue;

					if (!check_dnssl_presence(iface->AdvDNSSLList, suffix)) {
						flog(LOG_WARNING, "DNSSL suffix %s received on %s from %s is not advertised by us",
							suffix, iface->Name, addr_str);
					}

					suffix[0] = '\0';
					continue;
				}

				/*
				 * 1) must not overflow int: label + 2, offset + label_len
				 * 2) last byte of dnssli_suffix must not overflow opt_str + len
				 */
				if ((sizeof(suffix) - strlen(suffix)) < (label_len + 2) ||
				    label_len > label_len + 2 ||
				    &dnsslinfo->nd_opt_dnssli_suffixes[offset+label_len] - opt_str >= len ||
				    offset + label_len < offset) {
					flog(LOG_ERR, "oversized suffix in DNSSL option on %s from %s",
							iface->Name, addr_str);
					break;
				}

				if (suffix[0] != '\0')
					strcat(suffix, ".");
				strncat(suffix, (char*)&dnsslinfo->nd_opt_dnssli_suffixes[offset], label_len);
				offset += label_len;
			}
			break;
		default:
			dlog(LOG_DEBUG, 1, "unknown option %d in RA on %s from %s",
				(int)*opt_str, iface->Name, addr_str);
			break;
		}

		len -= optlen;
		opt_str += optlen;
	}
}
Esempio n. 29
0
int main(int argc, char* argv[]) {
	
	/* Variables of struct types can be initialized using {} notation (Sec. 6.3.5 of Stroustrup) */
	/**
	 * @details BIG NOTE: notice how Address_hdr is completely defined in header file.  No need to 
	 * compile the structs.cpp as separate object to use it (EY : 20171227 all in stack text/code memory?   
	 * */ 
	
	Address_hdr jd_hdr = { "Jim Dandy", 61, "South St", "New Providence", {'N', 'J'}, "07975" };
	Address_hdr jd_hdr_part  {"Jim Dandy",61,"South St"}; 

	std::cout << jd_hdr.name << jd_hdr.number << jd_hdr.street << 
		jd_hdr_part.name << jd_hdr_part.number << jd_hdr_part.street << std::endl;
	
	// ERROR: incomplete type if Address_sep is separated from header file
/*	Address_sep jd_sep = {"Jim Dandy", 61, "South St", "New Providence", {'N','J'}, "07975" }; 
*/		
	
	// needs structs.cpp
	f(); 

	print_addr(&jd_hdr);
	print_addr2(jd_hdr);

	set_current(jd_hdr); 
	
	
	/** 
 * Objects of structure types can be assigned, passed as function arguments, and 
 * returned as a result from a function.  Example: 
 * @details NOTE, it compiles; but doesn't work; static Address_hdr current_global compiles, but at run-time, 
 * when applying function to assign values to it, program stops  
 * */
	//	print_addr2(current_global);
//	std::cout << current_global.name << current_global.number << std::endl;


	/* ========== 8.2.3 Structures and Classes ========== */
	/* ===== struct is simply a class where the members are public by default.  
	 * So struct can have member functions; in particular, a struct can have constructors */ 
	Point pt1 {1,2};
	Point pt2 {3,4};
	Points pts { pt1, pt2}; 
	std::cout << std::endl << pts.elem[0].x << " " << pts.elem[1].y << std::endl; 


	auto addr_inst_w_ctor = Address_w_ctor(std::string("Jim Dandy"), 61, 
		std::string("South St"), std::string("New Providence"), std::string("NJ"), 7974); 

	std::cout << addr_inst_w_ctor.name << addr_inst_w_ctor.number << 
		addr_inst_w_ctor.street << addr_inst_w_ctor.town << std::endl; 

	Point points[3] = {{1,2},{3,4},{5,6}};
	int x2 = points[2].x; 
	
/*
 * error: too many initializers for main(int, char**):: Array'  
 * 
	struct Array {
		Point elem[3]; 
	};
	
	Array points2 = {{1,2},{3,4},{5,6}}; 
	int y2 = points2.elem[2].y;
	*/
	
}
Esempio n. 30
0
int main(void) {
  MAP_IntVTableBaseSet((unsigned long) &int_vectors[0]);
  MAP_IntMasterEnable();
  PRCMCC3200MCUInit();

/* Console UART init. */
#ifndef NO_DEBUG
  MAP_PRCMPeripheralClkEnable(DEBUG_UART_PERIPH, PRCM_RUN_MODE_CLK);
#if MIOT_DEBUG_UART == 0
  MAP_PinTypeUART(PIN_55, PIN_MODE_3); /* UART0_TX */
  MAP_PinTypeUART(PIN_57, PIN_MODE_3); /* UART0_RX */
#else
  MAP_PinTypeUART(PIN_07, PIN_MODE_5); /* UART1_TX */
  MAP_PinTypeUART(PIN_08, PIN_MODE_5); /* UART1_RX */
#endif
  MAP_UARTConfigSetExpClk(
      DEBUG_UART_BASE, MAP_PRCMPeripheralClockGet(DEBUG_UART_PERIPH),
      MIOT_DEBUG_UART_BAUD_RATE,
      (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
  MAP_UARTFIFOLevelSet(DEBUG_UART_BASE, UART_FIFO_TX1_8, UART_FIFO_RX4_8);
  MAP_UARTFIFODisable(DEBUG_UART_BASE);
#endif

  dbg_puts("\r\n\n");

  if (sl_Start(NULL, NULL, NULL) < 0) abort();
  dbg_putc('S');

  int cidx = get_active_boot_cfg_idx();
  if (cidx < 0) abort();
  dbg_putc('0' + cidx);
  struct boot_cfg cfg;
  if (read_boot_cfg(cidx, &cfg) < 0) abort();

  dbg_puts(cfg.app_image_file);
  dbg_putc('@');
  print_addr(cfg.app_load_addr);

  /*
   * Zero memory before loading.
   * This should provide proper initialisation for BSS, wherever it is.
   */
  uint32_t *pstart = (uint32_t *) 0x20000000;
  uint32_t *pend = (&_text_start - 0x100 /* our stack */);
  for (uint32_t *p = pstart; p < pend; p++) *p = 0;

  if (load_image(cfg.app_image_file, (_u8 *) cfg.app_load_addr) != 0) {
    abort();
  }

  dbg_putc('.');

  sl_Stop(0);
  print_addr(*(((uint32_t *) cfg.app_load_addr) + 1));
  dbg_puts("\r\n\n");

  MAP_IntMasterDisable();
  MAP_IntVTableBaseSet(cfg.app_load_addr);

  run(cfg.app_load_addr); /* Does not return. */

  abort();

  return 0; /* not reached */
}