Ejemplo n.º 1
0
int tc_qdisc_list(int argc, char **argv)
{
	struct tcmsg t;
	struct rtnl_handle rth;
	char d[16];

	memset(&t, 0, sizeof(t));
	t.tcm_family = AF_UNSPEC;
	memset(&d, 0, sizeof(d));
	
	while (argc > 0) {
		if (strcmp(*argv, "dev") == 0) {
			NEXT_ARG();
			strncpy(d, *argv, sizeof(d)-1);
#ifdef TC_H_INGRESS
                } else if (strcmp(*argv, "ingress") == 0) {
                             if (t.tcm_parent) {
                                     fprintf(stderr, "Duplicate parent ID\n");
                                     usage();
                             }
                             t.tcm_parent = TC_H_INGRESS;
#endif
		} else if (matches(*argv, "help") == 0) {
			usage();
		} else {
			fprintf(stderr, "What is \"%s\"? Try \"tc qdisc help\".\n", *argv);
			return -1;
		}

		argc--; argv++;
	}

	if (rtnl_open(&rth, 0) < 0) {
		fprintf(stderr, "Cannot open rtnetlink\n");
		exit(1);
	}

	ll_init_map(&rth);

	if (d[0]) {
		if ((t.tcm_ifindex = ll_name_to_index(d)) == 0) {
			fprintf(stderr, "Cannot find device \"%s\"\n", d);
			exit(1);
		}
		filter_ifindex = t.tcm_ifindex;
	}

	if (rtnl_dump_request(&rth, RTM_GETQDISC, &t, sizeof(t)) < 0) {
		perror("Cannot send dump request");
		exit(1);
	}

	if (rtnl_dump_filter(&rth, print_qdisc, stdout, NULL, NULL) < 0) {
		fprintf(stderr, "Dump terminated\n");
		exit(1);
	}

	rtnl_close(&rth);
	return 0;
}
Ejemplo n.º 2
0
void add_classes() {
// call dump of classes, these needs to be dumped on per device basis
	struct tcmsg t;
	struct rtnl_handle rth;
	char d[16];

	char line[1024];
	FILE *dev;
	char *p;

	memset(&rth,0,sizeof(struct rtnl_handle));
	memset(&t, 0, sizeof(t));

	t.tcm_family = AF_UNSPEC;
	memset(&d, 0, sizeof(d));
	
	if (rtnl_open(&rth, 0) < 0) {
		snmp_log(LOG_NOTICE, "Cannot open rtnetlink");
		return;
	}


	dev=fopen("/proc/net/dev","r");
	if(dev==NULL) {
	    snmp_log(LOG_WARNING,"qos-ext: cannot open /proc/net/dev for reading, class stats won't be avaiable");
	    return;
	}    
	while(fscanf(dev,"%s",line)!=EOF) {
	//find existing devices
	    p=index(line,':'); if(p==NULL) continue;
	    *p='\0';
	    // line contains device_name.... need to translate name into index
	    t.tcm_ifindex = ll_name_to_index(line);
	
	    if (rtnl_dump_request(&rth, RTM_GETTCLASS, &t, sizeof(t)) < 0) {
		//dump all classes on device with index t.tcm_ifindex
	    	snmp_log(LOG_WARNING,"qos-ext: add_new_entries to table: cannot send dump request");
		fclose(dev);
		return;
	    }
	    if (rtnl_dump_filter(&rth, insert_entry, NULL, NULL, NULL) < 0) {
		//append all classes entris into the internal table
		snmp_log(LOG_WARNING, "qos-ext: add_new entries to table: class dump terminated");
		fclose(dev);
		return;
	    }
	}
	fclose(dev);
	rtnl_close(&rth);
}
Ejemplo n.º 3
0
static PyObject* pyrtnl_dump_request(PyObject* obj, PyObject* args)
{
  PyRtnlObject* self = (PyRtnlObject*)obj;
  int type;
  char* req;
  int len;

  if (!PyArg_ParseTuple(args, "is#", &type, &req, &len))
    return NULL;

  if (rtnl_dump_request(&self->rth, type, req, len) < 0) {
    PyErr_SetString(PyExc_IOError, "could not send dump request");
    return NULL;
  }

  Py_INCREF(Py_None);
  return Py_None;
}
Ejemplo n.º 4
0
void add_new_entries_to_table() {
// call dump of netlink qos layer in kernel and adds received object into qos_table 
//(specifically their statistics values & some parts of configuration (htb))
	struct tcmsg t;
	struct rtnl_handle rth;
	extern int rth_initialized;
	char d[16];

	memset(&rth,0,sizeof(struct rtnl_handle));
	memset(&t, 0, sizeof(t));
	t.tcm_family = AF_UNSPEC;
	memset(&d, 0, sizeof(d));
	
	if (rtnl_open(&rth, 0) < 0) {
		snmp_log(LOG_NOTICE, "Cannot open rtnetlink");
		return;
	}

//	if(rth_initialized==0) {
	    ll_init_map(&rth);
//	    rth_initialized=1;
//	}

	if (rtnl_dump_request(&rth, RTM_GETQDISC, &t, sizeof(t)) < 0) {
		snmp_log(LOG_WARNING,"qos-ext: add_new_entries to table: cannot send dump request");
		return;
	}


	if (rtnl_dump_filter(&rth, insert_entry, NULL, NULL, NULL) < 0) {
		snmp_log(LOG_WARNING, "qos-ext: add_new entries to table: qdisc dump terminated");
		return;
	}

	rtnl_close(&rth);

	add_classes();		
}
Ejemplo n.º 5
0
int do_vrf_show(void)
{
	struct rtnl_handle rth;
	struct vrfmsg r;

	memset(&r, 0, sizeof(r));

	r.va_family = PF_INET;

	xrtnl_open(&rth);

	if (rtnl_dump_request(&rth, RTM_GETVRF, &r, sizeof(r)) < 0) {
		perror("Cannot send dump request");
		exit(1);
		}

	if (xrtnl_dump_filter(&rth, print_vrf, stdout) < 0) {
		fprintf(stderr, "Dump terminated\n");
		exit(1);
	}

	return (0);
}
Ejemplo n.º 6
0
static int do_show_or_flush(int argc, char **argv, int flush)
{
	char *filter_dev = NULL;
	int state_given = 0;
	struct ndmsg ndm = { 0 };

	ipneigh_reset_filter();

	if (!filter.family)
		filter.family = preferred_family;

	if (flush) {
		if (argc <= 0) {
			fprintf(stderr, "Flush requires arguments.\n");
			return -1;
		}
		filter.state = ~(NUD_PERMANENT|NUD_NOARP);
	} else
		filter.state = 0xFF & ~NUD_NOARP;

	while (argc > 0) {
		if (strcmp(*argv, "dev") == 0) {
			NEXT_ARG();
			if (filter_dev)
				duparg("dev", *argv);
			filter_dev = *argv;
		} else if (strcmp(*argv, "unused") == 0) {
			filter.unused_only = 1;
		} else if (strcmp(*argv, "nud") == 0) {
			unsigned state;
			NEXT_ARG();
			if (!state_given) {
				state_given = 1;
				filter.state = 0;
			}
			if (nud_state_a2n(&state, *argv)) {
				if (strcmp(*argv, "all") != 0)
					invarg("nud state is bad", *argv);
				state = ~0;
				if (flush)
					state &= ~NUD_NOARP;
			}
			if (state == 0)
				state = 0x100;
			filter.state |= state;
		} else if (strcmp(*argv, "proxy") == 0)
			ndm.ndm_flags = NTF_PROXY;
		else {
			if (strcmp(*argv, "to") == 0) {
				NEXT_ARG();
			}
			if (matches(*argv, "help") == 0)
				usage();
			get_prefix(&filter.pfx, *argv, filter.family);
			if (filter.family == AF_UNSPEC)
				filter.family = filter.pfx.family;
		}
		argc--; argv++;
	}

	ll_init_map(&rth);

	if (filter_dev) {
		if ((filter.index = ll_name_to_index(filter_dev)) == 0) {
			fprintf(stderr, "Cannot find device \"%s\"\n", filter_dev);
			return -1;
		}
	}

	if (flush) {
		int round = 0;
		char flushb[4096-512];

		filter.flushb = flushb;
		filter.flushp = 0;
		filter.flushe = sizeof(flushb);
		filter.state &= ~NUD_FAILED;

		while (round < MAX_ROUNDS) {
			if (rtnl_wilddump_request(&rth, filter.family, RTM_GETNEIGH) < 0) {
				perror("Cannot send dump request");
				exit(1);
			}
			filter.flushed = 0;
			if (rtnl_dump_filter(&rth, print_neigh, stdout) < 0) {
				fprintf(stderr, "Flush terminated\n");
				exit(1);
			}
			if (filter.flushed == 0) {
				if (show_stats) {
					if (round == 0)
						printf("Nothing to flush.\n");
					else
						printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":"");
				}
				fflush(stdout);
				return 0;
			}
			round++;
			if (flush_update() < 0)
				exit(1);
			if (show_stats) {
				printf("\n*** Round %d, deleting %d entries ***\n", round, filter.flushed);
				fflush(stdout);
			}
		}
		printf("*** Flush not complete bailing out after %d rounds\n",
			MAX_ROUNDS);
		return 1;
	}

	ndm.ndm_family = filter.family;

	if (rtnl_dump_request(&rth, RTM_GETNEIGH, &ndm, sizeof(struct ndmsg)) < 0) {
		perror("Cannot send dump request");
		exit(1);
	}

	if (rtnl_dump_filter(&rth, print_neigh, stdout) < 0) {
		fprintf(stderr, "Dump terminated\n");
		exit(1);
	}

	return 0;
}
Ejemplo n.º 7
0
int tc_act_list_or_flush(int argc, char **argv, int event)
{
	int ret = 0, prio = 0, msg_size = 0;
	char k[16];
	struct rtattr *tail,*tail2;
	struct action_util *a = NULL;
	struct {
		struct nlmsghdr         n;
		struct tcamsg           t;
		char                    buf[MAX_MSG];
	} req;

	req.t.tca_family = AF_UNSPEC;

	memset(&req, 0, sizeof(req));

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcamsg));

	tail = NLMSG_TAIL(&req.n);
	addattr_l(&req.n, MAX_MSG, TCA_ACT_TAB, NULL, 0);
	tail2 = NLMSG_TAIL(&req.n);

	strncpy(k, *argv, sizeof (k) - 1);
#ifdef CONFIG_GACT
	if (!gact_ld) {
		get_action_kind("gact");
	}
#endif
	a = get_action_kind(k);
	if (NULL == a) {
		fprintf(stderr,"bad action %s\n",k);
		goto bad_val;
	}
	if (strcmp(a->id, k) != 0) {
		fprintf(stderr,"bad action %s\n",k);
		goto bad_val;
	}
	strncpy(k, *argv, sizeof (k) - 1);

	addattr_l(&req.n, MAX_MSG, ++prio, NULL, 0);
	addattr_l(&req.n, MAX_MSG, TCA_ACT_KIND, k, strlen(k) + 1);
	tail2->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail2;
	tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail;

	msg_size = NLMSG_ALIGN(req.n.nlmsg_len) - NLMSG_ALIGN(sizeof(struct nlmsghdr));

	if (event == RTM_GETACTION) {
		if (rtnl_dump_request(&rth, event, (void *)&req.t, msg_size) < 0) {
			perror("Cannot send dump request");
			return 1;
		}
		ret = rtnl_dump_filter(&rth, print_action, stdout);
	}

	if (event == RTM_DELACTION) {
		req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len);
		req.n.nlmsg_type = RTM_DELACTION;
		req.n.nlmsg_flags |= NLM_F_ROOT;
		req.n.nlmsg_flags |= NLM_F_REQUEST;
		if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) {
			fprintf(stderr, "We have an error flushing\n");
			return 1;
		}

	}

bad_val:

	return ret;
}
Ejemplo n.º 8
0
vector get_routes_by_table(int table,int family){

	vector routes;
	vector_init(&routes);

	struct{
		struct nlmsghdr n;
		struct rtmsg r;
		char buf[1024];
	}route_req;

	memset(&route_req, 0, sizeof(route_req));

	struct rtnl_handle rth;
    	if (rtnl_open(&rth, 0) < 0){
		printf("cannot open rtnetlink\n");
		return routes;
	}

	route_req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
	route_req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
	route_req.n.nlmsg_type = RTM_GETROUTE;

	route_req.r.rtm_family = family;
	route_req.r.rtm_table = table;
	route_req.r.rtm_dst_len = 0;
	route_req.r.rtm_src_len = 0;

	int nbytes=0,reply_len=0;//ret, count=0;
	ssize_t counter = 5000;
	char reply_ptr[5000];
	char* buf = reply_ptr;
	struct nlmsghdr *nlp;
	struct rtmsg *rtp;
	struct rtattr *rtap;
	int rtl;
	unsigned long bufsize ;

	nlp = malloc(sizeof(struct nlmsghdr));
	memset(nlp, 0, sizeof(struct nlmsghdr));
	
	int rbytes __attribute__((unused)) = rtnl_dump_request(&rth,RTM_GETROUTE,&route_req,sizeof(route_req));

	for(;;){
		if( counter < sizeof(struct nlmsghdr)){
			printf("Routing table is bigger than %lu\n", sizeof(reply_ptr));
			vector_free(&routes);
			return routes;
		}

		nbytes = recv(rth.fd, &reply_ptr[reply_len], counter, 0);

		if(nbytes < 0 ){
			printf("Error in recv\n");
			break;
		}
		
		if(nbytes == 0)
			printf("EOF in netlink\n");
	
		nlp = (struct nlmsghdr*)(&reply_ptr[reply_len]);
	
		if (nlp->nlmsg_type == NLMSG_DONE){
			// All data has been received.
			// Truncate the reply to exclude this message,
			// i.e. do not increase reply_len.
			break;
		}

		if (nlp->nlmsg_type == NLMSG_ERROR){
			printf("Error in msg\n");
			vector_free(&routes);
			return routes;
	}

		reply_len += nbytes;
		counter -= nbytes;
	}

	bufsize = reply_len;
	nlp = (struct nlmsghdr*)buf;
	
    	for (;NLMSG_OK(nlp, bufsize); nlp = NLMSG_NEXT(nlp, bufsize)){
		
		/* Get the route data */
        	rtp = (struct rtmsg *) NLMSG_DATA(nlp);

		/* We only need route from the specific protocol*/
		if (rtp->rtm_table != table)
			continue;
	
        	/* Get attributes of route_entry */
        	rtap = (struct rtattr *) RTM_RTA(rtp);

        	/* Get the route atttibutes len */
        	rtl = RTM_PAYLOAD(nlp);
        	/* Loop through all attributes */

		struct netlink_route *route = malloc(sizeof(struct netlink_route));
		route->proto = rtp->rtm_protocol;
		route->prefix = rtp->rtm_dst_len;

        	for ( ; RTA_OK(rtap, rtl);rtap = RTA_NEXT(rtap, rtl)){
			
			if(rtap->rta_type == RTA_DST){
				struct sockaddr_storage dest;
				if(family == AF_INET){
					((struct sockaddr_in*)&dest)->sin_addr.s_addr = (unsigned long) RTA_DATA(rtap);
					dest.ss_family = AF_INET;
				}else{
					memcpy(&((struct sockaddr_in6*)&dest)->sin6_addr.s6_addr,RTA_DATA(rtap),16);
					dest.ss_family = AF_INET6;
				}
				route->dest = dest;
			}
			if(rtap->rta_type == RTA_GATEWAY){
				struct sockaddr_storage dest;
				if(family == AF_INET){
					((struct sockaddr_in*)&dest)->sin_addr.s_addr = (unsigned long) RTA_DATA(rtap);
					dest.ss_family = AF_INET;
				}else{
					memcpy(&((struct sockaddr_in6*)&dest)->sin6_addr.s6_addr,RTA_DATA(rtap),16);
					dest.ss_family = AF_INET6;
				}
				route->gateway = dest;
			}
			if(rtap->rta_type == RTA_PRIORITY){
				route->metric = *(unsigned long *) RTA_DATA(rtap);
			}

        	}

		vector_add(&routes,route);

    	}

	rtnl_close(&rth);

	return routes;
}
Ejemplo n.º 9
0
// This function forms the netlink packet to add a route to the kernel routing
// table
bool check_if_status(int index){
	struct rtnl_handle rth;

	// structure of the netlink packet. 
	struct{
		struct nlmsghdr n;
		struct ifinfomsg r;
		char buf[1024];
	} req;

	memset(&req, 0, sizeof(req));

    	if (rtnl_open(&rth, 0) < 0){
		printf("cannot open rtnetlink\n");
		return false;
	}

	// Initialisation of a few parameters 
	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
	req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
	req.n.nlmsg_type = RTM_GETLINK;

	req.r.ifi_index = index;

	int nbytes=0,reply_len=0;//ret, count=0;
	ssize_t counter = 5000;
	char reply_ptr[5000];
	char* buf = reply_ptr;
	struct ifinfomsg *iface;
	struct nlmsghdr *nlp;
	unsigned long bufsize ;

	nlp = malloc(sizeof(struct nlmsghdr));
	struct nlmsghdr *original_pointer = nlp;
	memset(nlp, 0, sizeof(struct nlmsghdr));

	int rbytes __attribute__((unused)) = rtnl_dump_request(&rth,RTM_GETLINK,&req,sizeof(req));

	for(;;){
		if( counter < sizeof(struct nlmsghdr)){
			printf("Reply is bugger than %lu\n", sizeof(reply_ptr));
			free(original_pointer);
			return false;
		}

		nbytes = recv(rth.fd, &reply_ptr[reply_len], counter, 0);

		if(nbytes < 0 ){
			printf("Error in recv\n");
			break;
		}
		
		if(nbytes == 0)
			printf("EOF in netlink\n");

		nlp = (struct nlmsghdr*)(&reply_ptr[reply_len]);
	
		if (nlp->nlmsg_type == NLMSG_DONE){
			// All data has been received.
			// Truncate the reply to exclude this message,
			// i.e. do not increase reply_len.
			break;
		}

		if (nlp->nlmsg_type == NLMSG_ERROR){
			printf("Error in msg\n");
			free(original_pointer);
			return false;
	}

		reply_len += nbytes;
		counter -= nbytes;
	}

	bufsize = reply_len;
	nlp = (struct nlmsghdr*)buf;
	
    	for (;NLMSG_OK(nlp, bufsize); nlp = NLMSG_NEXT(nlp, bufsize)){
		
		/* Get the route data */
        	iface = (struct ifinfomsg *) NLMSG_DATA(nlp);

		/* We only need the link of the specific index*/
		if (iface->ifi_index != index)
			continue;
	
        	if(iface->ifi_flags & IFF_RUNNING){
			free(original_pointer);
			rtnl_close(&rth);
			return true;
		}else{
			free(original_pointer);
			rtnl_close(&rth);
			return false;
		}

    	}

	free(original_pointer);
	rtnl_close(&rth);
	return false;
}