static int rtnl_qdisc_get(struct nlmsghdr *h, int (*if_callback)(int, struct in_ifaddr *)) { struct rtattr *tb[IFA_MAX + 1]; struct tcmsg *tc; int len; struct in_qdisc qdisc; if (h->nlmsg_type != RTM_NEWQDISC) return 0; tc = NLMSG_DATA(h); len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct tcmsg)); if (len < 0) return -1; netlink_parse_rtattr(tb, TCA_MAX, TCA_RTA(tc), len); strcpy(qdisc.name, (char *)RTA_DATA(tb[TCA_KIND])); qdisc.stats = *(struct tc_stats *)RTA_DATA(tb[TCA_STATS]); return if_callback(tc->tcm_ifindex, &qdisc); }
static int rtnl_iface_get(struct nlmsghdr *h, int (*if_callback)(struct iface *)) { struct rtattr *tb[IFLA_MAX + 1]; struct ifinfomsg *ifi; int len; struct iface iface; if (h->nlmsg_type != RTM_NEWLINK) return 0; ifi = NLMSG_DATA(h); len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg)); if (len < 0) return -1; netlink_parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); if (!tb[IFLA_IFNAME] || !tb[IFLA_ADDRESS]) { DEBUGP("Error: getting interface info"); return -1; } iface.haddr_len = RTA_PAYLOAD(tb[IFLA_ADDRESS]); if (iface.haddr_len < MAX_ADDR_LEN) { memcpy(iface.haddr, RTA_DATA(tb[IFLA_ADDRESS]), iface.haddr_len); } else { DEBUGP("Warning: Hardware address is too large: %d", iface.haddr_len); return -1; } strcpy(iface.name, (char *)RTA_DATA(tb[IFLA_IFNAME])); strcpy(iface.qdisc, (char *)RTA_DATA(tb[IFLA_QDISC])); iface.index = ifi->ifi_index; iface.type = ifi->ifi_type; iface.flags = ifi->ifi_flags & 0x0000fffff; iface.mtu = (tb[IFLA_MTU]) ? *(int *)RTA_DATA(tb[IFLA_MTU]) : 0; iface.weight = (tb[IFLA_WEIGHT]) ? *(int *)RTA_DATA(tb[IFLA_WEIGHT]) : 0; iface.txqueuelen = *(int *)RTA_DATA(tb[IFLA_TXQLEN]); iface.stats = *(struct net_device_stats *)RTA_DATA(tb[IFLA_STATS]); return if_callback(&iface); }
static int rtnl_ifaddr_get(struct nlmsghdr *h, int (*if_callback)(int, struct in_ifaddr *)) { struct rtattr *tb[IFA_MAX + 1]; struct ifaddrmsg *ifaddr; int len; struct in_ifaddr in_ifaddr; if (h->nlmsg_type != RTM_NEWADDR) return 0; ifaddr = NLMSG_DATA(h); len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg)); if (len < 0) return -1; netlink_parse_rtattr(tb, IFA_MAX, IFA_RTA(ifaddr), len); strcpy(in_ifaddr.ifa_label, (char *)RTA_DATA(tb[IFA_LABEL])); in_ifaddr.ifa_address = *(uint32_t *)RTA_DATA(tb[IFA_ADDRESS]); in_ifaddr.ifa_local = *(uint32_t *)RTA_DATA(tb[IFA_LOCAL]); if (tb[IFA_BROADCAST]) in_ifaddr.ifa_broadcast = *(uint32_t *)RTA_DATA(tb[IFA_BROADCAST]); if (tb[IFA_ANYCAST]) in_ifaddr.ifa_anycast = *(uint32_t *)RTA_DATA(tb[IFA_ANYCAST]); in_ifaddr.ifa_family = ifaddr->ifa_family; in_ifaddr.ifa_prefixlen = ifaddr->ifa_prefixlen; in_ifaddr.ifa_flags = ifaddr->ifa_flags; in_ifaddr.ifa_scope = ifaddr->ifa_scope; return if_callback(ifaddr->ifa_index, &in_ifaddr); }
void _jn_recv_buflist_progress(jn_cb_entry * cb_entry) { void (*if_callback) (jn_cb_entry *); jn_pkt *pkt = cb_entry->pkt; //jn_conn* conn = (jn_conn*)cb_entry->conn; /* if(cb_entry->nbytes == 0L){ cb_entry->buf = NULL; } */ if ((cb_entry->nbytes == 0L) && (pkt->hdr.data_len == 0L)) { _wdeb(L"Expected Data!!!"); pkt->hdr.type = JNT_FAIL; if (!(pkt->hdr.flags & JNF_ERR)) { pkt->hdr.rs = (uint32_t) - JE_FORBID; pkt->hdr.flags |= JNF_ERR; } } if (pkt->hdr.type != JNT_OK) { /* if(pkt->hdr.data_len){ _wdeb(L"freeing data"); free(pkt->data); } _wdeb(L"freeing packet"); free(pkt); */ //_wdeb(L"recieved not-ok, type = %x", pkt->hdr.type); if (!(pkt->hdr.flags & JNF_ERR)) { if (pkt->hdr.rs != (uint32_t) - JE_FORBID) pkt->hdr.rs = (uint32_t) - JE_UNK; pkt->hdr.flags |= JNF_ERR; } cb_entry->jerr = (int)pkt->hdr.rs; if (cb_entry->if_callback) { if_callback = cb_entry->if_callback; if_callback(cb_entry); } return; } assert(pkt->hdr.data_len); cb_entry->nremain = pkt->hdr.rs; if ((cb_entry->nbytes == 0L) && (pkt->hdr.data_len)) { _wdeb2(L"allocating %u bytes", pkt->hdr.rs + pkt->hdr.data_len); cb_entry->buf = (char *)malloc(pkt->hdr.rs + pkt->hdr.data_len); } if (pkt->hdr.data_len) { _wdeb2(L"nbytes = %u, data_len = %u", cb_entry->nbytes, pkt->hdr.data_len); memcpy(cb_entry->buf + cb_entry->nbytes, pkt->data, pkt->hdr.data_len); cb_entry->nbytes += pkt->hdr.data_len; free(pkt->data); } if (!pkt->hdr.rs && cb_entry->if_callback) { //remove call back request on completion cb_entry->jerr = 0; if_callback = cb_entry->if_callback; if_callback(cb_entry); } free(pkt); }