Example #1
0
static void dissect_igmp_v2(struct pkt_buff *pkt)
{
	char     addr[INET_ADDRSTRLEN];
	uint16_t csum;

	struct igmp_v2_msg *msg =
		(struct igmp_v2_msg *) pkt_pull(pkt, sizeof(*msg));

	if (msg == NULL)
		return;

	switch (msg->type) {
	case RGMP_HELLO:
	case RGMP_BYE:
	case RGMP_JOIN_GROUP:
	case RGMP_LEAVE_GROUP:
		tprintf(" [ IGMPv2 (RGMP)");
		break;
	default:
		tprintf(" [ IGMPv2");
		break;
	}

	PRINT_FRIENDLY_NAMED_MSG_TYPE(msg->type);
	tprintf(", Max Resp Time (%u)", msg->max_resp_time);
	csum = calc_csum(msg, sizeof(*msg) + pkt_len(pkt), 0);
	tprintf(", CSum (0x%.4x) is %s", ntohs(msg->checksum), csum ?
		colorize_start_full(black, red) "bogus (!)" colorize_end() : "ok");
	if (csum)
		tprintf(" - %s should be %x%s", colorize_start_full(black, red),
			csum_expected(msg->checksum, csum), colorize_end());
	inet_ntop(AF_INET, &msg->group_address, addr, sizeof(addr));
	tprintf(", Group Addr (%s)", addr);
	tprintf(" ]\n");
}
Example #2
0
static void nlmsg_print(uint16_t family, struct nlmsghdr *hdr)
{
	u16 nlmsg_flags = hdr->nlmsg_flags;
	char type[32];
	char flags[128];
	char procname[PATH_MAX];

	/* Look up the process name if message is not coming from the kernel.
	 *
	 * Note that the port id is not necessarily equal to the PID of the
	 * receiving process (e.g. if the application is multithreaded or using
	 * multiple sockets). In these cases we're not able to find a matching
	 * PID and the information will not be printed.
	 */
	if (hdr->nlmsg_pid != 0) {
		if (proc_get_cmdline(hdr->nlmsg_pid, procname, sizeof(procname)) < 0)
			snprintf(procname, sizeof(procname), "unknown process");
	} else
		snprintf(procname, sizeof(procname), "kernel");

	tprintf(" [ NLMSG ");
	tprintf("Family %d (%s%s%s), ", family,
		colorize_start(bold),
		nlmsg_family2str(family),
		colorize_end());
	tprintf("Len %u, ", hdr->nlmsg_len);
	tprintf("Type 0x%.4x (%s%s%s), ", hdr->nlmsg_type,
		colorize_start(bold),
		nlmsg_type2str(family, hdr->nlmsg_type, type, sizeof(type)),
		colorize_end());
	tprintf("Flags 0x%.4x (%s%s%s), ", nlmsg_flags,
		colorize_start(bold),
		nlmsg_flags ? nl_nlmsg_flags2str(nlmsg_flags, flags, sizeof(flags)) : "none",
		colorize_end());
	tprintf("Seq-Nr %u, ", hdr->nlmsg_seq);
	tprintf("PID %u", hdr->nlmsg_pid);
	if (procname[0])
		tprintf(" (%s%s%s)", colorize_start(bold), basename(procname),
			colorize_end());
	tprintf(" ]\n");

	switch (family) {
	case NETLINK_ROUTE:
		rtnl_msg_print(hdr);
		break;
	case NETLINK_GENERIC:
		genl_msg_print(hdr);
		break;
	default:
		nlmsg_print_raw(hdr);
	}
}
Example #3
0
static void dissect_igmp_v3_membership_query(struct pkt_buff *pkt)
{
	char      addr[INET_ADDRSTRLEN];
	size_t    n;
	uint16_t  csum;
	uint32_t *src_addr;

	struct igmp_v3_membership_query *msg =
		(struct igmp_v3_membership_query *) pkt_pull(pkt, sizeof(*msg));

	if (msg == NULL)
		return;

	tprintf(" [ IGMPv3");
	PRINT_FRIENDLY_NAMED_MSG_TYPE(msg->type);
	tprintf(", Max Resp Code (0x%.2x => %u)", msg->max_resp_code,
		DECODE_MAX_RESP_CODE(msg->max_resp_code));
	csum = calc_csum(msg, sizeof(*msg) + pkt_len(pkt), 0);
	tprintf(", CSum (0x%.4x) is %s", ntohs(msg->checksum), csum ?
		colorize_start_full(black, red) "bogus (!)" colorize_end() : "ok");
	if (csum)
		tprintf(" - %s should be %x%s", colorize_start_full(black, red),
			csum_expected(msg->checksum, csum), colorize_end());
	inet_ntop(AF_INET, &msg->group_address, addr, sizeof(addr));
	/* S Flag (Suppress Router-Side Processing) */
	tprintf(", Suppress (%u)", msg->s_flag ? 1 : 0);
	/* QRV (Querier's Robustness Variable) */
	tprintf(", QRV (%u)", msg->qrv);
	/* QQIC (Querier's Query Interval Code) */
	tprintf(", QQIC (0x%.2x => %u)", msg->qqic, DECODE_QQIC(msg->qqic));
	tprintf(", Group Addr (%s)", addr);
	n = ntohs(msg->number_of_sources);
	tprintf(", Num Src (%zu)", n);

	if (n--) {
		src_addr = (uint32_t *) pkt_pull(pkt, sizeof(*src_addr));
		if (src_addr != NULL) {
			inet_ntop(AF_INET, src_addr, addr, sizeof(addr));
			tprintf(", Src Addr (%s", addr);
			while (n--) {
				src_addr = (uint32_t *)
					pkt_pull(pkt, sizeof(*src_addr));
				if (src_addr == NULL)
					break;
				inet_ntop(AF_INET, src_addr, addr, sizeof(addr));
				tprintf(", %s", addr);
			}
			tprintf(")");
		}
	}
	tprintf(" ]\n");
}
Example #4
0
static void tcp(struct pkt_buff *pkt)
{
    struct tcphdr *tcp = (struct tcphdr *) pkt_pull(pkt, sizeof(*tcp));
    uint16_t src, dest;
    char *src_name, *dest_name;

    if (tcp == NULL)
        return;

    src = ntohs(tcp->source);
    dest = ntohs(tcp->dest);

    src_name = lookup_port_tcp(src);
    dest_name = lookup_port_tcp(dest);

    tprintf(" [ TCP ");
    tprintf("Port (%u", src);
    if (src_name)
        tprintf(" (%s%s%s)", colorize_start(bold), src_name,
                colorize_end());
    tprintf(" => %u", dest);
    if (dest_name)
        tprintf(" (%s%s%s)", colorize_start(bold), dest_name,
                colorize_end());
    tprintf("), ");
    tprintf("SN (0x%x), ", ntohl(tcp->seq));
    tprintf("AN (0x%x), ", ntohl(tcp->ack_seq));
    tprintf("DataOff (%u), ", tcp->doff);
    tprintf("Res (%u), ", tcp->res1);
    tprintf("Flags (");
    if (tcp->fin)
        tprintf("FIN ");
    if (tcp->syn)
        tprintf("SYN ");
    if (tcp->rst)
        tprintf("RST ");
    if (tcp->psh)
        tprintf("PSH ");
    if (tcp->ack)
        tprintf("ACK ");
    if (tcp->urg)
        tprintf("URG ");
    if (tcp->ece)
        tprintf("ECE ");
    if (tcp->cwr)
        tprintf("CWR ");
    tprintf("), ");
    tprintf("Window (%u), ", ntohs(tcp->window));
    tprintf("CSum (0x%.4x), ", ntohs(tcp->check));
    tprintf("UrgPtr (%u)", ntohs(tcp->urg_ptr));
    tprintf(" ]\n");
}
static void auth_hdr(struct pkt_buff *pkt)
{
	ssize_t hdr_len;
	struct auth_hdr *auth_ops;

	auth_ops = (struct auth_hdr *) pkt_pull(pkt, sizeof(*auth_ops));
	if (auth_ops == NULL)
		return;
	
	hdr_len = (auth_ops->h_payload_len * 4) + 8;

	tprintf(" [ Authentication Header ");
	tprintf("NextHdr (%u), ", auth_ops->h_next_header);
	if (hdr_len > pkt_len(pkt) || hdr_len < 0){
		tprintf("HdrLen (%u, %zd Bytes %s), ",
		      auth_ops->h_payload_len, hdr_len,
		      colorize_start_full(black, red)
		      "invalid" colorize_end());
		      return;
	}
	tprintf("HdrLen (%u, %zd Bytes), ",auth_ops->h_payload_len, hdr_len);
	tprintf("Reserved (0x%x), ", ntohs(auth_ops->h_reserved));
	/* TODO
	 * Upgrade for Extended (64-bit) Sequence Number
	 * http://tools.ietf.org/html/rfc4302#section-2.5.1
	 */
	tprintf("SPI (0x%x), ", ntohl(auth_ops->h_spi));
	tprintf("SNF (0x%x), ", ntohl(auth_ops->h_snf));
	tprintf("ICV 0x");
	for (size_t i = sizeof(struct auth_hdr); i < hdr_len; i++)
		tprintf("%02x", *pkt_pull(pkt, 1));
	tprintf(" ]\n");

	pkt_set_proto(pkt, &eth_lay3, auth_ops->h_next_header);
}
static void hop_by_hop(struct pkt_buff *pkt)
{
	uint16_t hdr_ext_len;
	ssize_t opt_len;
	struct hop_by_hophdr *hop_ops;

	hop_ops = (struct hop_by_hophdr *) pkt_pull(pkt, sizeof(*hop_ops));
	if (hop_ops == NULL)
		return;

	/* Total Header Length in Bytes */
	hdr_ext_len = (hop_ops->hdr_len + 1) * 8;
	/* Options length in Bytes */
	opt_len = hdr_ext_len - sizeof(*hop_ops);

	tprintf("\t [ Hop-by-Hop Options ");
	tprintf("NextHdr (%u), ", hop_ops->h_next_header);
	if (opt_len > pkt_len(pkt) || opt_len < 0){
		tprintf("HdrExtLen (%u, %u Bytes, %s)", hop_ops->hdr_len,
		      hdr_ext_len, colorize_start_full(black, red)
		      "invalid" colorize_end());
		      return;
	}
	tprintf("HdrExtLen (%u, %u Bytes)", hop_ops->hdr_len,
		hdr_ext_len);

	dissect_opt_hop(pkt, &opt_len);

	tprintf(" ]\n");

	pkt_pull(pkt, opt_len);
	pkt_set_proto(pkt, &eth_lay3, hop_ops->h_next_header);
}
Example #7
0
static void nlmsg_less(struct pkt_buff *pkt)
{
	struct nlmsghdr *hdr = (struct nlmsghdr *) pkt_pull(pkt, NLMSG_HDRLEN);
	uint16_t family = ntohs(pkt->sll->sll_protocol);
	char type[32];

	if (hdr == NULL)
		return;

	tprintf(" NLMSG Family %d (%s%s%s), ", family,
		colorize_start(bold),
		nlmsg_family2str(family),
		colorize_end());
	tprintf("Type %u (%s%s%s)", hdr->nlmsg_type,
		colorize_start(bold),
		nlmsg_type2str(family, hdr->nlmsg_type, type, sizeof(type)),
		colorize_end());
}
Example #8
0
static void tcp_less(struct pkt_buff *pkt)
{
    struct tcphdr *tcp = (struct tcphdr *) pkt_pull(pkt, sizeof(*tcp));
    uint16_t src, dest;
    char *src_name, *dest_name;

    if (tcp == NULL)
        return;

    src = ntohs(tcp->source);
    dest = ntohs(tcp->dest);

    src_name = lookup_port_tcp(src);
    dest_name = lookup_port_tcp(dest);

    tprintf(" TCP %u", src);
    if(src_name)
        tprintf("(%s%s%s)", colorize_start(bold), src_name,
                colorize_end());
    tprintf("/%u", dest);
    if(dest_name)
        tprintf("(%s%s%s)", colorize_start(bold), dest_name,
                colorize_end());
    tprintf(" F%s",colorize_start(bold));
    if (tcp->fin)
        tprintf(" FIN");
    if (tcp->syn)
        tprintf(" SYN");
    if (tcp->rst)
        tprintf(" RST");
    if (tcp->psh)
        tprintf(" PSH");
    if (tcp->ack)
        tprintf(" ACK");
    if (tcp->urg)
        tprintf(" URG");
    if (tcp->ece)
        tprintf(" ECE");
    if (tcp->cwr)
        tprintf(" CWR");
    tprintf("%s Win %u S/A 0x%x/0x%x", colorize_end(),
            ntohs(tcp->window), ntohl(tcp->seq), ntohl(tcp->ack_seq));
}
Example #9
0
static void dissect_igmp_v1(struct pkt_buff *pkt)
{
	char     addr[INET_ADDRSTRLEN];
	uint16_t csum;

	struct igmp_v1_msg *msg =
		(struct igmp_v1_msg *) pkt_pull(pkt, sizeof(*msg));

	if (msg == NULL)
		return;

	tprintf(" [ IGMPv1");
	PRINT_FRIENDLY_NAMED_MSG_TYPE(msg->version__type);
	csum = calc_csum(msg, sizeof(*msg) + pkt_len(pkt), 0);
	tprintf(", CSum (0x%.4x) is %s", ntohs(msg->checksum), csum ?
		colorize_start_full(black, red) "bogus (!)" colorize_end() : "ok");
	if (csum)
		tprintf(" - %s should be %x%s", colorize_start_full(black, red),
			csum_expected(msg->checksum, csum), colorize_end());
	inet_ntop(AF_INET, &msg->group_address, addr, sizeof(addr));
	tprintf(", Group Addr (%s)", addr);
	tprintf(" ]\n");
}
Example #10
0
static void udp(struct pkt_buff *pkt)
{
	struct udphdr *udp = (struct udphdr *) pkt_pull(pkt, sizeof(*udp));
	ssize_t len;
	uint16_t src, dest;
	char *src_name, *dest_name;

	if (udp == NULL)
		return;

	len = ntohs(udp->len) - sizeof(*udp);
	src = ntohs(udp->source);
	dest = ntohs(udp->dest);

	src_name = lookup_port_udp(src);
	dest_name = lookup_port_udp(dest);

	tprintf(" [ UDP ");
	tprintf("Port (%u", src);
	if (src_name)
		tprintf(" (%s%s%s)", colorize_start(bold), src_name,
			colorize_end());
	tprintf(" => %u", dest);
	if (dest_name)
		tprintf(" (%s%s%s)", colorize_start(bold), dest_name,
			colorize_end());
	tprintf("), ");
	if(len > pkt_len(pkt) || len < 0){
		tprintf("Len (%u) %s, ", ntohs(udp->len),
			colorize_start_full(black, red)
			"invalid" colorize_end());
	}
	tprintf("Len (%u Bytes, %zd Bytes Data), ", ntohs(udp->len), len);
	tprintf("CSum (0x%.4x)", ntohs(udp->check));
	tprintf(" ]\n");
}
Example #11
0
static void udp_less(struct pkt_buff *pkt)
{
	struct udphdr *udp = (struct udphdr *) pkt_pull(pkt, sizeof(*udp));
	uint16_t src, dest;
	char *src_name, *dest_name;

	if (udp == NULL)
		return;

	src = ntohs(udp->source);
	dest = ntohs(udp->dest);

	src_name = lookup_port_udp(src);
	dest_name = lookup_port_udp(dest);

	tprintf(" UDP %u", src);
	if(src_name)
		tprintf("(%s%s%s)", colorize_start(bold), src_name,
			colorize_end());
	tprintf("/%u", dest);
	if (dest_name)
		tprintf("(%s%s%s)", colorize_start(bold), dest_name,
			colorize_end());
}
Example #12
0
static void routing(struct pkt_buff *pkt)
{
	uint16_t hdr_ext_len;
	ssize_t data_len;
	struct routinghdr *routing;

	routing = (struct routinghdr *) pkt_pull(pkt, sizeof(*routing));
	if (routing == NULL)
		return;

	/* Total Header Length in Bytes */
	hdr_ext_len = (routing->h_hdr_ext_len + 1) * 8;
	/* Data length in Bytes */
	data_len = hdr_ext_len - sizeof(*routing);

	tprintf("\t [ Routing ");
	tprintf("NextHdr (%u), ", routing->h_next_header);
	if (data_len > pkt_len(pkt) || data_len < 0){
		tprintf("HdrExtLen (%u, %u Bytes %s), ", routing->h_hdr_ext_len,
		      hdr_ext_len, colorize_start_full(black, red)
		      "invalid" colorize_end());
		      return;
	}
	tprintf("HdrExtLen (%u, %u Bytes), ", routing->h_hdr_ext_len,
		hdr_ext_len);
	tprintf("Type (%u), ", routing->h_routing_type);
	tprintf("Left (%u), ", routing->h_segments_left);

	switch (routing->h_routing_type) {
	case ROUTING_HEADER_TYPE_0:
		dissect_routinghdr_type_0_norm(pkt, &data_len);
		break;
	default:
		tprintf("Type %u is unknown", routing->h_routing_type);
	}

	tprintf(" ]\n");

	if (data_len > pkt_len(pkt) || data_len < 0)
		return;

	pkt_pull(pkt, data_len);
	pkt_set_proto(pkt, &eth_lay3, routing->h_next_header);
}
Example #13
0
static void genl_msg_print(struct nlmsghdr *hdr)
{
	struct genlmsghdr *genl;

	if (hdr->nlmsg_type != GENL_ID_CTRL) {
		nlmsg_print_raw(hdr);
		return;
	}

	genl = NLMSG_DATA(hdr);

	tprintf(" [ Cmd %u (%s%s%s)", genl->cmd,
		colorize_start(bold), genl_cmd2str(genl->cmd), colorize_end());
	tprintf(", Version %u", genl->version);
	tprintf(", Reserved %u", genl->reserved);
	tprintf(" ]\n");

	genl_print_ctrl(hdr);
}
Example #14
0
static void ethernet_less(struct pkt_buff *pkt)
{
	uint8_t *src_mac, *dst_mac;
	struct ethhdr *eth = (struct ethhdr *) pkt_pull(pkt, sizeof(*eth));

	if (eth == NULL)
		return;

	src_mac = eth->h_source;
	dst_mac = eth->h_dest;
	tprintf(" %s => %s ", 
		lookup_vendor((src_mac[0] << 16) | (src_mac[1] << 8) |
			      src_mac[2]),
		lookup_vendor((dst_mac[0] << 16) | (dst_mac[1] << 8) |
			      dst_mac[2]));
	tprintf("%s%s%s", colorize_start(bold), 
		lookup_ether_type(ntohs(eth->h_proto)), colorize_end());

	pkt_set_proto(pkt, &eth_lay2, ntohs(eth->h_proto));
}
static void mobility(struct pkt_buff *pkt)
{
	uint16_t hdr_ext_len;
	ssize_t message_data_len;
	struct mobilityhdr *mobility;

	mobility = (struct mobilityhdr *) pkt_pull(pkt, sizeof(*mobility));
	if (mobility == NULL)
		return;

	/* Total Header Length in Bytes */
	hdr_ext_len = (mobility->hdr_len + 1) * 8;
	/* Total Message Data length in Bytes*/
	message_data_len = (hdr_ext_len - sizeof(*mobility));

	tprintf("\t [ Mobility ");
	tprintf("NextHdr (%u), ", mobility->payload_proto);
	if (message_data_len > pkt_len(pkt) || message_data_len < 0){
		tprintf("HdrExtLen (%u, %u Bytes %s), ", mobility->hdr_len,
				hdr_ext_len, colorize_start_full(black, red)
				"invalid" colorize_end());
		return;
	}
	tprintf("HdrExtLen (%u, %u Bytes), ", mobility->hdr_len,
		hdr_ext_len);
	tprintf("MH Type (%u), ", mobility->MH_type);
	tprintf("Res (0x%x), ", mobility->reserved);
	tprintf("Chks (0x%x), ", ntohs(mobility->chksum));
	tprintf("MH Data ");

	get_mh_type(pkt, &message_data_len, &mobility->MH_type);

	tprintf(" ]\n");

	if (message_data_len > pkt_len(pkt) || message_data_len < 0)
		return;
	pkt_pull(pkt, message_data_len);
	pkt_set_proto(pkt, &eth_lay3, mobility->payload_proto);
}
Example #16
0
static void ethernet(struct pkt_buff *pkt)
{
	char *type;
	uint8_t *src_mac, *dst_mac;
	struct ethhdr *eth = (struct ethhdr *) pkt_pull(pkt, sizeof(*eth));

	if (eth == NULL)
		return;

	src_mac = eth->h_source;
	dst_mac = eth->h_dest;

	tprintf(" [ Eth ");
	tprintf("MAC (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x => ",
		src_mac[0], src_mac[1], src_mac[2],
		src_mac[3], src_mac[4], src_mac[5]);
	tprintf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x), ",
		dst_mac[0], dst_mac[1], dst_mac[2],
		dst_mac[3], dst_mac[4], dst_mac[5]);
	tprintf("Proto (0x%.4x", ntohs(eth->h_proto));

	type = lookup_ether_type(ntohs(eth->h_proto));
	if (type)
		tprintf(", %s%s%s", colorize_start(bold), type, colorize_end());

	tprintf(") ]\n");
	tprintf(" [ Vendor ");
	tprintf("(%s => %s)",
		lookup_vendor((src_mac[0] << 16) | (src_mac[1] << 8) |
			      src_mac[2]),
		lookup_vendor((dst_mac[0] << 16) | (dst_mac[1] << 8) |
			      dst_mac[2]));
	tprintf(" ]\n");

	pkt_set_proto(pkt, &eth_lay2, ntohs(eth->h_proto));
}
Example #17
0
static void header(void)
{
	printf("%s%s%s\n", colorize_start(bold), PROGNAME_STRING " " 
	       VERSION_STRING, colorize_end());
}
Example #18
0
static void xmit_slowpath_or_die(struct ctx *ctx, unsigned int cpu, unsigned long orig_num)
{
	int ret, icmp_sock = -1;
	unsigned long num = 1, i = 0;
	struct timeval start, end, diff;
	unsigned long long tx_bytes = 0, tx_packets = 0;
	struct packet_dyn *pktd;
	struct sockaddr_ll saddr = {
		.sll_family = PF_PACKET,
		.sll_halen = ETH_ALEN,
		.sll_ifindex = device_ifindex(ctx->device),
	};

	if (ctx->num > 0)
		num = ctx->num;
	if (ctx->num == 0 && orig_num > 0)
		num = 0;

	if (ctx->smoke_test)
		icmp_sock = xmit_smoke_setup(ctx);

	drop_privileges(ctx->enforce, ctx->uid, ctx->gid);

	bug_on(gettimeofday(&start, NULL));

	while (likely(sigint == 0 && num > 0 && plen > 0)) {
		pktd = &packet_dyn[i];
		if (pktd->clen + pktd->rlen + pktd->slen) {
			apply_counter(i);
			apply_randomizer(i);
			apply_csum16(i);
		}
retry:
		ret = sendto(sock, packets[i].payload, packets[i].len, 0,
			     (struct sockaddr *) &saddr, sizeof(saddr));
		if (unlikely(ret < 0)) {
			if (errno == ENOBUFS) {
				sched_yield();
				goto retry;
			}
			if (ctx->smoke_test)
				panic("Sendto error: %s!\n", strerror(errno));
		}

		tx_bytes += packets[i].len;
		tx_packets++;

		if (ctx->smoke_test) {
			ret = xmit_smoke_probe(icmp_sock, ctx);
			if (unlikely(ret < 0)) {
				printf("%sSmoke test alert:%s\n", colorize_start(bold), colorize_end());
				printf("  Remote host seems to be unresponsive to ICMP probes!\n");
				printf("  Last instance was packet%lu, seed:%u, trafgen snippet:\n\n",
				       i, seed);

				dump_trafgen_snippet(packets[i].payload, packets[i].len);
				break;
			}
		}

		if (!ctx->rand) {
			i++;
			if (i >= plen)
				i = 0;
		} else
			i = rand() % plen;

		if (ctx->num > 0)
			num--;

		if ((ctx->gap.tv_sec | ctx->gap.tv_nsec) > 0)
			nanosleep(&ctx->gap, NULL);
	}

	bug_on(gettimeofday(&end, NULL));
	timersub(&end, &start, &diff);

	if (ctx->smoke_test)
		close(icmp_sock);

	stats[cpu].tx_packets = tx_packets;
	stats[cpu].tx_bytes = tx_bytes;
	stats[cpu].tv_sec = diff.tv_sec;
	stats[cpu].tv_usec = diff.tv_usec;

	stats[cpu].state |= CPU_STATS_STATE_RES;
}

static void xmit_fastpath_or_die(struct ctx *ctx, unsigned int cpu, unsigned long orig_num)
{
	int ifindex = device_ifindex(ctx->device);
	uint8_t *out = NULL;
	unsigned int it = 0;
	unsigned long num = 1, i = 0;
	size_t size = ring_size(ctx->device, ctx->reserve_size);
	struct ring tx_ring;
	struct frame_map *hdr;
	struct timeval start, end, diff;
	struct packet_dyn *pktd;
	unsigned long long tx_bytes = 0, tx_packets = 0;

	set_sock_prio(sock, 512);

	ring_tx_setup(&tx_ring, sock, size, ifindex, ctx->jumbo_support, ctx->verbose);

	drop_privileges(ctx->enforce, ctx->uid, ctx->gid);

	if (ctx->num > 0)
		num = ctx->num;
	if (ctx->num == 0 && orig_num > 0)
		num = 0;

	bug_on(gettimeofday(&start, NULL));

	while (likely(sigint == 0 && num > 0 && plen > 0)) {
		if (!user_may_pull_from_tx(tx_ring.frames[it].iov_base)) {
			int ret = pull_and_flush_tx_ring(sock);
			if (unlikely(ret < 0)) {
				/* We could hit EBADF if the socket has been closed before
				 * the timer was triggered.
				 */
				if (errno != EBADF && errno != ENOBUFS)
					panic("Flushing TX_RING failed: %s!\n", strerror(errno));
			}

			continue;
		}

		hdr = tx_ring.frames[it].iov_base;
		out = ((uint8_t *) hdr) + TPACKET2_HDRLEN - sizeof(struct sockaddr_ll);

		hdr->tp_h.tp_snaplen = packets[i].len;
		hdr->tp_h.tp_len = packets[i].len;

		pktd = &packet_dyn[i];
		if (pktd->clen + pktd->rlen + pktd->slen) {
			apply_counter(i);
			apply_randomizer(i);
			apply_csum16(i);
		}

		fmemcpy(out, packets[i].payload, packets[i].len);

		tx_bytes += packets[i].len;
		tx_packets++;

		if (!ctx->rand) {
			i++;
			if (i >= plen)
				i = 0;
		} else
			i = rand() % plen;

		kernel_may_pull_from_tx(&hdr->tp_h);

		it++;
		if (it >= tx_ring.layout.tp_frame_nr)
			it = 0;

		if (ctx->num > 0)
			num--;
	}

	bug_on(gettimeofday(&end, NULL));
	timersub(&end, &start, &diff);

	pull_and_flush_tx_ring_wait(sock);
	destroy_tx_ring(sock, &tx_ring);

	stats[cpu].tx_packets = tx_packets;
	stats[cpu].tx_bytes = tx_bytes;
	stats[cpu].tv_sec = diff.tv_sec;
	stats[cpu].tv_usec = diff.tv_usec;

	stats[cpu].state |= CPU_STATS_STATE_RES;
}
Example #19
0
static void ipv4(struct pkt_buff *pkt)
{
	uint16_t csum, frag_off, h_tot_len;
	char src_ip[INET_ADDRSTRLEN];
	char dst_ip[INET_ADDRSTRLEN];
	struct ipv4hdr *ip = (struct ipv4hdr *) pkt_pull(pkt, sizeof(*ip));
	uint8_t *opt, *trailer;
	unsigned int trailer_len = 0;
	ssize_t opts_len, opt_len;
	struct sockaddr_in sas, sad;
	const char *city, *region, *country;

	if (!ip)
		return;

	frag_off = ntohs(ip->h_frag_off);
	h_tot_len = ntohs(ip->h_tot_len);
	csum = calc_csum(ip, ip->h_ihl * 4, 0);

	inet_ntop(AF_INET, &ip->h_saddr, src_ip, sizeof(src_ip));
	inet_ntop(AF_INET, &ip->h_daddr, dst_ip, sizeof(dst_ip));

	if ((pkt_len(pkt) + sizeof(*ip)) > h_tot_len) {
		trailer_len = pkt_len(pkt) + sizeof(*ip) - h_tot_len;
		trailer = pkt->data + h_tot_len + trailer_len;
	}

	if (trailer_len) {
		 tprintf(" [ Eth trailer ");
		 while (trailer_len--) {
			tprintf("%x", *(trailer - trailer_len));
		 }
		 tprintf(" ]\n");
	}

	tprintf(" [ IPv4 ");
	tprintf("Addr (%s => %s), ", src_ip, dst_ip);
	tprintf("Proto (%u), ", ip->h_protocol);
	tprintf("TTL (%u), ", ip->h_ttl);
	tprintf("TOS (%u), ", ip->h_tos);
	tprintf("Ver (%u), ", ip->h_version);
	tprintf("IHL (%u), ", ip->h_ihl);
	tprintf("Tlen (%u), ", ntohs(ip->h_tot_len));
	tprintf("ID (%u), ", ntohs(ip->h_id));
	tprintf("Res (%u), NoFrag (%u), MoreFrag (%u), FragOff (%u), ",
		FRAG_OFF_RESERVED_FLAG(frag_off) ? 1 : 0,
		FRAG_OFF_NO_FRAGMENT_FLAG(frag_off) ? 1 : 0,
		FRAG_OFF_MORE_FRAGMENT_FLAG(frag_off) ? 1 : 0,
		FRAG_OFF_FRAGMENT_OFFSET(frag_off));
	tprintf("CSum (0x%.4x) is %s", ntohs(ip->h_check),
		csum ? colorize_start_full(black, red) "bogus (!)"
		       colorize_end() : "ok");
	if (csum)
		tprintf("%s should be 0x%.4x%s", colorize_start_full(black, red),
			csum_expected(ip->h_check, csum), colorize_end());
	tprintf(" ]\n");

	memset(&sas, 0, sizeof(sas));
	sas.sin_family = PF_INET;
	sas.sin_addr.s_addr = ip->h_saddr;

	memset(&sad, 0, sizeof(sad));
	sad.sin_family = PF_INET;
	sad.sin_addr.s_addr = ip->h_daddr;

	if (geoip_working()) {
		tprintf("\t[ Geo (");
		if ((country = geoip4_country_name(sas))) {
			tprintf("%s", country);
			if ((region = geoip4_region_name(sas)))
				tprintf(" / %s", region);
			if ((city = geoip4_city_name(sas)))
				tprintf(" / %s", city);
		} else {
			tprintf("local");
		}
		tprintf(" => ");
		if ((country = geoip4_country_name(sad))) {
			tprintf("%s", country);
			if ((region = geoip4_region_name(sad)))
				tprintf(" / %s", region);
			if ((city = geoip4_city_name(sad)))
				tprintf(" / %s", city);
		} else {
			tprintf("local");
		}
		tprintf(") ]\n");
	}

	opts_len = max((uint8_t) ip->h_ihl, sizeof(*ip) / sizeof(uint32_t)) *
		   sizeof(uint32_t) - sizeof(*ip);

	for (opt = pkt_pull(pkt, opts_len); opt && opts_len > 0; opt++) {
		tprintf("   [ Option  Copied (%u), Class (%u), Number (%u)",
			IP_OPT_COPIED_FLAG(*opt) ? 1 : 0, IP_OPT_CLASS(*opt),
			IP_OPT_NUMBER(*opt));

		switch (*opt) {
		case IP_OPT_EOOL:
		case IP_OPT_NOP:
			tprintf(" ]\n");
			opts_len--;
			break;
		default:
			/*
			 * Assuming that EOOL and NOP are the only single-byte
			 * options, treat all other options as variable in
			 * length with a minimum of 2.
			 *
			 * TODO: option length might be incorrect in malformed packets,
			 *       check and handle that
			 */
			opt_len = *(++opt);
			if (opt_len > opts_len) {
				tprintf(", Len (%zd, invalid) ]\n", opt_len);
				goto out;
			} else
				tprintf(", Len (%zd) ]\n", opt_len);
			opts_len -= opt_len;
			tprintf("     [ Data hex ");
			for (opt_len -= 2; opt_len > 0; opt_len--)
				tprintf(" %.2x", *(++opt));
			tprintf(" ]\n");
			break;
		}
	}
out:
	/* cut off everything that is not part of IPv4 payload */
	/* XXX there could still be an Ethernet trailer included or others */

	pkt_trim(pkt, pkt_len(pkt) - min(pkt_len(pkt),
		 (ntohs(ip->h_tot_len) - ip->h_ihl * sizeof(uint32_t))));

	pkt_set_proto(pkt, &eth_lay3, ip->h_protocol);
}
Example #20
0
static void dissect_igmp_v3_membership_report(struct pkt_buff *pkt)
{
	char      addr[INET_ADDRSTRLEN];
	size_t    m, n;
	uint16_t  csum;
	uint32_t *src_addr;

	struct igmp_v3_group_record      *rec;
	struct igmp_v3_membership_report *msg =
		(struct igmp_v3_membership_report *) pkt_pull(pkt, sizeof(*msg));

	if (msg == NULL)
		return;

	tprintf(" [ IGMPv3");
	PRINT_FRIENDLY_NAMED_MSG_TYPE(msg->type);
	csum = calc_csum(msg, sizeof(*msg) + pkt_len(pkt), 0);
	tprintf(", CSum (0x%.4x) is %s", ntohs(msg->checksum), csum ?
		colorize_start_full(black, red) "bogus (!)" colorize_end() : "ok");
	if (csum)
		tprintf(" - %s should be %x%s", colorize_start_full(black, red),
			csum_expected(msg->checksum, csum), colorize_end());
	m = ntohs(msg->number_of_group_records);
	tprintf(", Num Group Rec (%zu)", m);
	tprintf(" ]\n");

	while (m--) {
		rec = (struct igmp_v3_group_record *) pkt_pull(pkt, sizeof(*rec));

		if (rec == NULL)
			break;

		tprintf("   [ Group Record");
		if (friendly_group_rec_type_name(rec->record_type))
			tprintf("  Type (%u, %s)", rec->record_type,
				friendly_group_rec_type_name(rec->record_type));
		else
			tprintf("  Type (%u)", rec->record_type);
		n = ntohs(rec->number_of_sources);
		tprintf(", Num Src (%zu)", n);
		inet_ntop(AF_INET, &rec->multicast_address, addr, sizeof(addr));
		tprintf(", Multicast Addr (%s)", addr);

		if (n--) {
			src_addr = (uint32_t *) pkt_pull(pkt, sizeof(*src_addr));
			if (src_addr != NULL) {
				inet_ntop(AF_INET, src_addr, addr, sizeof(addr));
				tprintf(", Src Addr (%s", addr);
				while (n--) {
					src_addr = (uint32_t *)
						pkt_pull(pkt, sizeof(*src_addr));
					if (src_addr == NULL)
						break;
					inet_ntop(AF_INET, src_addr, addr, sizeof(addr));
					tprintf(", %s", addr);
				}
				tprintf(")");
			}
		}

		tprintf(" ]\n");
	}
	tprintf("\n");
}
Example #21
0
static void header(void)
{
	printf("%s%s%s\n", colorize_start(bold), "curvetun "
	       VERSION_STRING, colorize_end());
}
Example #22
0
static void xmit_slowpath_or_die(struct ctx *ctx, int cpu, unsigned long orig_num)
{
	int ret, icmp_sock = -1;
	unsigned long num = 1, i = 0;
	struct timeval start, end, diff;
	unsigned long long tx_bytes = 0, tx_packets = 0;
	struct packet_dyn *pktd;
	struct sockaddr_ll saddr = {
		.sll_family = PF_PACKET,
		.sll_halen = ETH_ALEN,
		.sll_ifindex = device_ifindex(ctx->device),
	};

	if (ctx->num > 0)
		num = ctx->num;
	if (ctx->num == 0 && orig_num > 0)
		num = 0;

	if (ctx->smoke_test)
		icmp_sock = xmit_smoke_setup(ctx);

	drop_privileges(ctx->enforce, ctx->uid, ctx->gid);

	bug_on(gettimeofday(&start, NULL));

	while (likely(sigint == 0) && likely(num > 0) && likely(plen > 0)) {
		pktd = &packet_dyn[i];
		if (pktd->clen + pktd->rlen + pktd->slen) {
			apply_counter(i);
			apply_randomizer(i);
			apply_csum16(i);
		}
retry:
		ret = sendto(sock, packets[i].payload, packets[i].len, 0,
			     (struct sockaddr *) &saddr, sizeof(saddr));
		if (unlikely(ret < 0)) {
			if (errno == ENOBUFS) {
				sched_yield();
				goto retry;
			}

			panic("Sendto error: %s!\n", strerror(errno));
		}

		tx_bytes += packets[i].len;
		tx_packets++;

		if (ctx->smoke_test) {
			ret = xmit_smoke_probe(icmp_sock, ctx);
			if (unlikely(ret < 0)) {
				printf("%sSmoke test alert:%s\n", colorize_start(bold), colorize_end());
				printf("  Remote host seems to be unresponsive to ICMP probes!\n");
				printf("  Last instance was packet%lu, seed:%u, trafgen snippet:\n\n",
				       i, seed);

				dump_trafgen_snippet(packets[i].payload, packets[i].len);
				break;
			}
		}

		if (!ctx->rand) {
			i++;
			if (i >= plen)
				i = 0;
		} else
			i = rand() % plen;

		if (ctx->num > 0)
			num--;

		if (ctx->gap > 0)
			usleep(ctx->gap);
	}

	bug_on(gettimeofday(&end, NULL));
	timersub(&end, &start, &diff);

	if (ctx->smoke_test)
		close(icmp_sock);

	stats[cpu].tx_packets = tx_packets;
	stats[cpu].tx_bytes = tx_bytes;
	stats[cpu].tv_sec = diff.tv_sec;
	stats[cpu].tv_usec = diff.tv_usec;

	stats[cpu].state |= CPU_STATS_STATE_RES;
}

static void xmit_fastpath_or_die(struct ctx *ctx, int cpu, unsigned long orig_num)
{
	int ifindex = device_ifindex(ctx->device);
	uint8_t *out = NULL;
	unsigned int it = 0;
	unsigned long num = 1, i = 0, size;
	struct ring tx_ring;
	struct frame_map *hdr;
	struct timeval start, end, diff;
	struct packet_dyn *pktd;
	unsigned long long tx_bytes = 0, tx_packets = 0;

	fmemset(&tx_ring, 0, sizeof(tx_ring));

	size = ring_size(ctx->device, ctx->reserve_size);

	set_sock_prio(sock, 512);
	set_packet_loss_discard(sock);

	setup_tx_ring_layout(sock, &tx_ring, size, ctx->jumbo_support);
	create_tx_ring(sock, &tx_ring, ctx->verbose);
	mmap_tx_ring(sock, &tx_ring);
	alloc_tx_ring_frames(sock, &tx_ring);
	bind_tx_ring(sock, &tx_ring, ifindex);

	drop_privileges(ctx->enforce, ctx->uid, ctx->gid);

	if (ctx->kpull)
		interval = ctx->kpull;
	if (ctx->num > 0)
		num = ctx->num;
	if (ctx->num == 0 && orig_num > 0)
		num = 0;

	set_itimer_interval_value(&itimer, 0, interval);
	setitimer(ITIMER_REAL, &itimer, NULL); 

	bug_on(gettimeofday(&start, NULL));

	while (likely(sigint == 0) && likely(num > 0) && likely(plen > 0)) {
		while (user_may_pull_from_tx(tx_ring.frames[it].iov_base) && likely(num > 0)) {
			hdr = tx_ring.frames[it].iov_base;
			out = ((uint8_t *) hdr) + TPACKET2_HDRLEN - sizeof(struct sockaddr_ll);

			hdr->tp_h.tp_snaplen = packets[i].len;
			hdr->tp_h.tp_len = packets[i].len;

			pktd = &packet_dyn[i];
			if (pktd->clen + pktd->rlen + pktd->slen) {
				apply_counter(i);
				apply_randomizer(i);
				apply_csum16(i);
			}

			fmemcpy(out, packets[i].payload, packets[i].len);

			tx_bytes += packets[i].len;
			tx_packets++;

			if (!ctx->rand) {
				i++;
				if (i >= plen)
					i = 0;
			} else
				i = rand() % plen;

			kernel_may_pull_from_tx(&hdr->tp_h);

			it++;
			if (it >= tx_ring.layout.tp_frame_nr)
				it = 0;

			if (ctx->num > 0)
				num--;

			if (unlikely(sigint == 1))
				break;
		}
	}

	bug_on(gettimeofday(&end, NULL));
	timersub(&end, &start, &diff);

	timer_purge();

	destroy_tx_ring(sock, &tx_ring);

	stats[cpu].tx_packets = tx_packets;
	stats[cpu].tx_bytes = tx_bytes;
	stats[cpu].tv_sec = diff.tv_sec;
	stats[cpu].tv_usec = diff.tv_usec;

	stats[cpu].state |= CPU_STATS_STATE_RES;
}
Example #23
0
static void rtnl_print_ifinfo(struct nlmsghdr *hdr)
{
	struct ifinfomsg *ifi = NLMSG_DATA(hdr);
	struct rtattr *attr = IFLA_RTA(ifi);
	uint32_t attrs_len = IFLA_PAYLOAD(hdr);
	char flags[256];
	char if_addr[64] = {};
	char *af_link = "unknown";

	if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*ifi)))
		return;

	if (ifi->ifi_family == AF_UNSPEC)
		af_link = "unspec";
	else if (ifi->ifi_family == AF_BRIDGE)
		af_link = "bridge";

	tprintf(" [ Link Family %d (%s%s%s)", ifi->ifi_family,
			colorize_start(bold), af_link, colorize_end());
	tprintf(", Type %d (%s%s%s)", ifi->ifi_type,
			colorize_start(bold),
			device_type2str(ifi->ifi_type),
			colorize_end());
	tprintf(", Index %d", ifi->ifi_index);
	tprintf(", Flags 0x%x (%s%s%s)", ifi->ifi_flags,
			colorize_start(bold),
			rtnl_link_flags2str(ifi->ifi_flags, flags,
				sizeof(flags)),
			colorize_end());
	tprintf(", Change 0x%x (%s%s%s) ]\n", ifi->ifi_change,
			colorize_start(bold),
			rtnl_link_flags2str(ifi->ifi_change, flags,
				sizeof(flags)),
			colorize_end());

	for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) {
		switch (attr->rta_type) {
		case IFLA_ADDRESS:
			rta_fmt(attr, "Address %s",
					device_addr2str(RTA_DATA(attr),
						RTA_LEN(attr), ifi->ifi_type,
						if_addr, sizeof(if_addr)));
			break;
		case IFLA_BROADCAST:
			rta_fmt(attr, "Broadcast %s",
					device_addr2str(RTA_DATA(attr),
						RTA_LEN(attr), ifi->ifi_type,
						if_addr, sizeof(if_addr)));
			break;
		case IFLA_IFNAME:
			rta_fmt(attr, "Name %s%s%s",
					colorize_start(bold), RTA_STR(attr),
					colorize_end());
			break;
		case IFLA_MTU:
			rta_fmt(attr, "MTU %d", RTA_INT(attr));
			break;
		case IFLA_LINK:
			rta_fmt(attr, "Link %d", RTA_INT(attr));
			break;
		case IFLA_QDISC:
			rta_fmt(attr, "QDisc %s", RTA_STR(attr));
			break;
		case IFLA_OPERSTATE:
			{
				uint8_t st = RTA_UINT8(attr);
				char states[256];

				rta_fmt(attr, "Operation state 0x%x (%s%s%s)",
						st,
						colorize_start(bold),
						rtnl_link_operstate2str(st,
							states, sizeof(states)),
						colorize_end());
			}
			break;
		case IFLA_LINKMODE:
			{
				uint8_t mode = RTA_UINT8(attr);
				char str[32];

				rta_fmt(attr, "Mode 0x%x (%s%s%s)", mode,
						colorize_start(bold),
						rtnl_link_mode2str(mode, str,
							sizeof(str)),
						colorize_end());
			}
			break;
		case IFLA_GROUP:
			rta_fmt(attr, "Group %d", RTA_INT(attr));
			break;
		case IFLA_TXQLEN:
			rta_fmt(attr, "Tx queue len %d", RTA_INT(attr));
			break;
		case IFLA_NET_NS_PID:
			rta_fmt(attr, "Network namespace pid %d",
					RTA_INT(attr));
			break;
		case IFLA_NET_NS_FD:
			rta_fmt(attr, "Network namespace fd %d", RTA_INT(attr));
			break;
		default:
			rta_fmt(attr, "0x%x", attr->rta_type);
			break;
		}
	}
}
Example #24
0
static void dissect_igmp_v0(struct pkt_buff *pkt)
{
	char     addr[INET_ADDRSTRLEN];
	uint16_t csum;

	static const char *reply_codes[] = {
		"Request Granted",
		"Request Denied, No Resources",
		"Request Denied, Invalid Code",
		"Request Denied, Invalid Group Address",
		"Request Denied, Invalid Access Key"
	};

	struct igmp_v0_msg *msg =
		(struct igmp_v0_msg *) pkt_pull(pkt, sizeof(*msg));

	if (msg == NULL)
		return;

	tprintf(" [ IGMPv0");
	PRINT_FRIENDLY_NAMED_MSG_TYPE(msg->type);

	switch (msg->type) {
	case IGMP_V0_CREATE_GROUP_REQUEST:
		switch (msg->code) {
		case 0:
			tprintf(", Code (%u, %s)", msg->code, "Public");
			break;
		case 1:
			tprintf(", Code (%u, %s)", msg->code, "Private");
			break;
		default:
			tprintf(", Code (%u)", msg->code);
		}
		break;
	case IGMP_V0_CREATE_GROUP_REPLY:
	case IGMP_V0_JOIN_GROUP_REPLY:
	case IGMP_V0_LEAVE_GROUP_REPLY:
	case IGMP_V0_CONFIRM_GROUP_REPLY:
		if (msg->code < 5)
			tprintf(", Code (%u, %s)", msg->code, reply_codes[msg->code]);
		else
			tprintf(", Code (%u, Request Pending, Retry In %u Seconds)",
				msg->code, msg->code);
		break;
	default:
		tprintf(", Code (%u)", msg->code);
	}

	csum = calc_csum(msg, sizeof(*msg) + pkt_len(pkt), 0);
	tprintf(", CSum (0x%.4x) is %s", ntohs(msg->checksum), csum ?
		colorize_start_full(black, red) "bogus (!)" colorize_end() : "ok");
	if (csum)
		tprintf(" - %s should be %x%s", colorize_start_full(black, red),
			csum_expected(msg->checksum, csum), colorize_end());
	tprintf(", Id (%u)", ntohs(msg->identifier));
	inet_ntop(AF_INET, &msg->group_address, addr, sizeof(addr));
	tprintf(", Group Addr (%s)", addr);
	tprintf(", Access Key (0x%.16lx)", msg->access_key);
	tprintf(" ]\n");
}
Example #25
0
static void rtnl_print_ifaddr(struct nlmsghdr *hdr)
{
	struct ifaddrmsg *ifa = NLMSG_DATA(hdr);
	uint32_t attrs_len = IFA_PAYLOAD(hdr);
	struct rtattr *attr = IFA_RTA(ifa);
	struct ifa_cacheinfo *ci;
	char addr_str[256];
	char flags[256];

	if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*ifa)))
		return;

	tprintf(" [ Address Family %d (%s%s%s)", ifa->ifa_family,
			colorize_start(bold),
			addr_family2str(ifa->ifa_family),
			colorize_end());
	tprintf(", Prefix Len %d", ifa->ifa_prefixlen);
	tprintf(", Flags %d (%s%s%s)", ifa->ifa_flags,
			colorize_start(bold),
			rtnl_addr_flags2str(ifa->ifa_flags, flags,
				sizeof(flags)),
			colorize_end());
	tprintf(", Scope %d (%s%s%s)", ifa->ifa_scope,
			colorize_start(bold),
			scope2str(ifa->ifa_scope),
			colorize_end());
	tprintf(", Link Index %d ]\n", ifa->ifa_index);

	for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) {
		switch (attr->rta_type) {
		case IFA_LOCAL:
			rta_fmt(attr, "Local %s", addr2str(ifa->ifa_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
		case IFA_ADDRESS:
			rta_fmt(attr, "Address %s", addr2str(ifa->ifa_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
		case IFA_BROADCAST:
			rta_fmt(attr, "Broadcast %s",
					addr2str(ifa->ifa_family,
						RTA_DATA(attr), addr_str,
						sizeof(addr_str)));
			break;
		case IFA_MULTICAST:
			rta_fmt(attr, "Multicast %s",
					addr2str(ifa->ifa_family,
						RTA_DATA(attr), addr_str,
						sizeof(addr_str)));
			break;
		case IFA_ANYCAST:
			rta_fmt(attr, "Anycast %s", addr2str(ifa->ifa_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
#ifdef IFA_FLAGS
		case IFA_FLAGS:
			rta_fmt(attr, "Flags %d (%s%s%s)", RTA_INT(attr),
				colorize_start(bold),
				rtnl_addr_flags2str(RTA_INT(attr),
					flags, sizeof(flags)),
				colorize_end());
			break;
#endif
		case IFA_LABEL:
			rta_fmt(attr, "Label %s", RTA_STR(attr));
			break;
		case IFA_CACHEINFO:
			ci = RTA_DATA(attr);
			tprintf("\tA: Cache (");

			if (ci->ifa_valid == INFINITY)
				tprintf("valid lft(forever)");
			else
				tprintf("valid lft(%us)", ci->ifa_valid);

			if (ci->ifa_prefered == INFINITY)
				tprintf(", prefrd lft(forever)");
			else
				tprintf(", prefrd lft(%us)", ci->ifa_prefered);

			tprintf(", created on(%.2fs)", (double)ci->cstamp / 100);
			tprintf(", updated on(%.2fs))", (double)ci->cstamp / 100);
			tprintf(", Len %d\n", RTA_LEN(attr));
			break;
		default:
			rta_fmt(attr, "0x%x", attr->rta_type);
			break;
		}
	}
}
Example #26
0
static void rtnl_print_route(struct nlmsghdr *hdr)
{
	struct rtmsg *rtm = NLMSG_DATA(hdr);
	uint32_t attrs_len = RTM_PAYLOAD(hdr);
	struct rtattr *attr = RTM_RTA(rtm);
	struct rta_cacheinfo *ci;
	int hz = get_user_hz();
	char addr_str[256];
	char flags[256];

	if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*rtm)))
		return;

	tprintf(" [ Route Family %d (%s%s%s)", rtm->rtm_family,
			colorize_start(bold),
			addr_family2str(rtm->rtm_family),
			colorize_end());
	tprintf(", Dst Len %d", rtm->rtm_dst_len);
	tprintf(", Src Len %d", rtm->rtm_src_len);
	tprintf(", ToS %d", rtm->rtm_tos);
	tprintf(", Table %d (%s%s%s)", rtm->rtm_table,
			colorize_start(bold),
			route_table2str(rtm->rtm_table),
			colorize_end());
	tprintf(", Proto %d (%s%s%s)", rtm->rtm_protocol,
			colorize_start(bold),
			route_proto2str(rtm->rtm_protocol),
			colorize_end());
	tprintf(", Scope %d (%s%s%s)", rtm->rtm_scope,
			colorize_start(bold),
			scope2str(rtm->rtm_scope),
			colorize_end());
	tprintf(", Type %d (%s%s%s)", rtm->rtm_type,
			colorize_start(bold),
			route_type2str(rtm->rtm_type),
			colorize_end());
	tprintf(", Flags 0x%x (%s%s%s) ]\n", rtm->rtm_flags,
			colorize_start(bold),
			flags2str(route_flags, rtm->rtm_flags, flags,
				sizeof(flags)),
			colorize_end());

	for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) {
		switch (attr->rta_type) {
		case RTA_DST:
			rta_fmt(attr, "Dst %s", addr2str(rtm->rtm_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
		case RTA_SRC:
			rta_fmt(attr, "Src %s", addr2str(rtm->rtm_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
		case RTA_IIF:
			rta_fmt(attr, "Iif %d", RTA_INT(attr));
			break;
		case RTA_OIF:
			rta_fmt(attr, "Oif %d", RTA_INT(attr));
			break;
		case RTA_GATEWAY:
			rta_fmt(attr, "Gateway %s", addr2str(rtm->rtm_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
		case RTA_PRIORITY:
			rta_fmt(attr, "Priority %u", RTA_UINT32(attr));
			break;
		case RTA_PREFSRC:
			rta_fmt(attr, "Pref Src %s", addr2str(rtm->rtm_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
		case RTA_MARK:
			rta_fmt(attr, "Mark 0x%x", RTA_UINT(attr));
			break;
		case RTA_FLOW:
			rta_fmt(attr, "Flow 0x%x", RTA_UINT(attr));
			break;
		case RTA_TABLE:
			rta_fmt(attr, "Table %d (%s%s%s)", RTA_UINT32(attr),
				colorize_start(bold),
				route_table2str(RTA_UINT32(attr)),
				colorize_end());
			break;
		case RTA_CACHEINFO:
			ci = RTA_DATA(attr);
			tprintf("\tA: Cache (");
			tprintf("expires(%ds)", ci->rta_expires / hz);
			tprintf(", error(%d)", ci->rta_error);
			tprintf(", users(%d)", ci->rta_clntref);
			tprintf(", used(%d)", ci->rta_used);
			tprintf(", last use(%ds)", ci->rta_lastuse / hz);
			tprintf(", id(%d)", ci->rta_id);
			tprintf(", ts(%d)", ci->rta_ts);
			tprintf(", ts age(%ds))", ci->rta_tsage);
			tprintf(", Len %d\n", RTA_LEN(attr));
			break;
		default:
			rta_fmt(attr, "0x%x", attr->rta_type);
			break;
		}
	}
}
Example #27
0
static void rtnl_print_neigh(struct nlmsghdr *hdr)
{
	struct ndmsg *ndm = NLMSG_DATA(hdr);
	uint32_t attrs_len = NDA_PAYLOAD(hdr);
	struct rtattr *attr = NDA_RTA(ndm);
	struct nda_cacheinfo *ci;
	int hz = get_user_hz();
	char addr_str[256];
	char hw_addr[30];
	char states[256];
	char flags[256];

	if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*ndm)))
		return;

	tprintf(" [ Neigh Family %d (%s%s%s)", ndm->ndm_family,
			colorize_start(bold),
			addr_family2str(ndm->ndm_family),
			colorize_end());
	tprintf(", Link Index %d", ndm->ndm_ifindex);
	tprintf(", State %d (%s%s%s)", ndm->ndm_state,
			colorize_start(bold),
			flags2str(neigh_states, ndm->ndm_state, states,
				sizeof(states)),
			colorize_end());
	tprintf(", Flags %d (%s%s%s)", ndm->ndm_flags,
			colorize_start(bold),
			flags2str(neigh_flags, ndm->ndm_flags, flags,
				sizeof(flags)),
			colorize_end());
	tprintf(", Type %d (%s%s%s)", ndm->ndm_type,
			colorize_start(bold),
			route_type2str(ndm->ndm_type),
			colorize_end());
	tprintf(" ]\n");

	for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) {
		switch (attr->rta_type) {
		case NDA_DST:
			rta_fmt(attr, "Address %s", addr2str(ndm->ndm_family,
						RTA_DATA(attr), addr_str,
						sizeof(addr_str)));
			break;
		case NDA_LLADDR:
			rta_fmt(attr, "HW Address %s",
					device_addr2str(RTA_DATA(attr),
						RTA_LEN(attr), 0, hw_addr,
						sizeof(hw_addr)));
			break;
		case NDA_PROBES:
			rta_fmt(attr, "Probes %d", RTA_UINT32(attr));
			break;
		case NDA_CACHEINFO:
			ci = RTA_DATA(attr);
			tprintf("\tA: Cache (");
			tprintf("confirmed(%ds)", ci->ndm_confirmed / hz);
			tprintf(", used(%ds)", ci->ndm_used / hz);
			tprintf(", updated(%ds)", ci->ndm_updated / hz);
			tprintf(", refcnt(%d))", ci->ndm_refcnt);
			tprintf(", Len %d\n", RTA_LEN(attr));
			break;
		default:
			rta_fmt(attr, "0x%x", attr->rta_type);
			break;
		}
	}
}