+ /* cmd == LIST */
+
+ while (1) {
+ len = recv(s, &rxbuf, sizeof(rxbuf), 0);
+ if (len < 0) {
+ perror("netlink recv");
+ return len;
+ }
+ nlh = (struct nlmsghdr *)rxbuf;
+ if (nlh->nlmsg_type == NLMSG_DONE)
+ break;
+
+ rtc = (struct rtcanmsg *)NLMSG_DATA(nlh);
+ if (rtc->can_family != AF_CAN) {
+ printf("received msg from unknown family %d\n", rtc->can_family);
+ return -EINVAL;
+ }
+
+ /*
+ * print list in a representation that
+ * can be used directly for start scripts
+ */
+
+ printf("%s -A ", basename(argv[0]));
+ printf("-s %s ", if_indextoname(rtc->src_ifindex, ifname));
+ printf("-d %s ", if_indextoname(rtc->dst_ifindex, ifname));
+
+ if (rtc->can_txflags & CAN_GW_TXFLAGS_ECHO)
+ printf("-e ");
+
+ if (rtc->can_txflags & CAN_GW_TXFLAGS_SRC_TSTAMP)
+ printf("-t ");
+
+ /* check for attributes */
+ rta = (struct rtattr *) RTM_RTA(rtc);
+ rtlen = RTM_PAYLOAD(nlh);
+ for(;RTA_OK(rta, rtlen);rta=RTA_NEXT(rta,rtlen))
+ {
+ switch(rta->rta_type) {
+
+ case CGW_FILTER:
+ printfilter(RTA_DATA(rta));
+ break;
+
+ case CGW_MOD_AND:
+ printmod("AND", RTA_DATA(rta));
+ break;
+
+ case CGW_MOD_OR:
+ printmod("OR", RTA_DATA(rta));
+ break;
+
+ case CGW_MOD_XOR:
+ printmod("XOR", RTA_DATA(rta));
+ break;
+
+ case CGW_MOD_SET:
+ printmod("SET", RTA_DATA(rta));
+ break;
+
+ case CGW_HANDLED:
+ handled = *(__u32 *)RTA_DATA(rta);
+ break;
+
+ case CGW_DROPPED:
+ dropped = *(__u32 *)RTA_DATA(rta);
+ break;
+
+ default:
+ printf("Unknown attribute %d!", rta->rta_type);
+ return -EINVAL;
+ break;
+ }
+ }
+
+ printf("# %d handled %d dropped\n", handled, dropped); /* end of entry */
+ }
+ }