📄 rsvp_socks.c
字号:
ntohs(NET_GET_ADDR_UDP_IPv4(addr).sin_port)); return(buffer);#ifdef USE_IPV6 case NET_ADDR_IPv6: return(inet_ntop(AF_INET6,&NET_GET_ADDR_IPv6(addr), buffer,sizeof(buffer))); case NET_ADDR_UDP_IPv6: sprintf(buffer,"%s/%hu",inet_ntop(AF_INET6, &NET_GET_ADDR_UDP_IPv6(addr).sin6_addr, buffer2,sizeof(buffer2)), ntohs(NET_GET_ADDR_UDP_IPv6(addr).sin6_port)); return(buffer);#endif /* USE_IPV6 */ default: return(NULL); }}/* Map net_addr into host[/port] character string using inverse * DNS lookup. */const char *net_addr_host(const net_addr *addr){ static char buffer[MAX_HOSTPORTSTRLEN]; struct hostent *hp; switch(NET_GET_TYPE(addr)) { case NET_ADDR_IPv4: hp = gethostbyaddr((char *) &NET_GET_ADDR_IPv4(addr), sizeof(NET_GET_ADDR_IPv4(addr)),AF_INET); if (hp == NULL) return(net_addr_print(addr)); return(hp->h_name); case NET_ADDR_UDP_IPv4: hp = gethostbyaddr( (char *) &NET_GET_ADDR_UDP_IPv4(addr).sin_addr, sizeof(NET_GET_ADDR_UDP_IPv4(addr).sin_addr), AF_INET); if (hp == NULL) return(net_addr_print(addr)); sprintf(buffer,"%s/%hu",hp->h_name, ntohs(NET_GET_ADDR_UDP_IPv4(addr).sin_port)); return(buffer);#ifdef USE_IPV6 case NET_ADDR_IPv6: hp = gethostbyaddr((char *) &NET_GET_ADDR_IPv6(addr), sizeof(NET_GET_ADDR_IPv6(addr)),AF_INET6); if (hp == NULL) return(net_addr_print(addr)); return(hp->h_name); case NET_ADDR_UDP_IPv6: hp = gethostbyaddr( (char *) &NET_GET_ADDR_UDP_IPv6(addr).sin6_addr, sizeof(NET_GET_ADDR_UDP_IPv6(addr).sin6_addr), AF_INET6); if (hp == NULL) return(net_addr_print(addr)); sprintf(buffer,"%s/%hu",hp->h_name, ntohs(NET_GET_ADDR_UDP_IPv6(addr).sin6_port)); return(buffer);#endif /* USE_IPV6 */ default: return(NULL); }}intnet_if_equal(const net_if *x,const net_if *y){ if (NET_UNEQUAL_TYPE(x,y)) return(FALSE); switch (NET_GET_TYPE(x)) { case NET_IF_UNKNOWN: return(TRUE); case NET_IF_ID: return(NET_GET_IF_ID(x) == NET_GET_IF_ID(y)); case NET_IF_STRING: return(strcmp(NET_GET_IF_STRING(x), NET_GET_IF_STRING(y)) == 0); case NET_IF_PHY: return((NET_GET_IF_PHY_ID(x) == NET_GET_IF_PHY_ID(y)) && net_addr_equal(&NET_GET_IF_PHY_ADDR(x), &NET_GET_IF_PHY_ADDR(y))); case NET_IF_VIF: return((NET_GET_IF_VIF_ID(x) == NET_GET_IF_VIF_ID(y)) && net_addr_equal(&NET_GET_IF_VIF_ADDR(x), &NET_GET_IF_VIF_ADDR(y))); default: return(FALSE); }}const char *net_if_print(const net_if *inf){ static char buffer[MAX_ADDRSTRLEN]; switch(NET_GET_TYPE(inf)) { case NET_IF_UNKNOWN: return("unknown"); case NET_IF_ID: sprintf(buffer,"%d",NET_GET_IF_ID(inf)); return(buffer); case NET_IF_STRING: return(NET_GET_IF_STRING(inf)); case NET_IF_PHY: return(net_addr_print(&NET_GET_IF_PHY_ADDR(inf))); case NET_IF_VIF: sprintf(buffer,"%s vif %d", net_addr_print(&NET_GET_IF_VIF_ADDR(inf)), NET_GET_IF_VIF_ID(inf)); return(buffer); default: return(NULL); }}/* Determine default interface by doing inverse DNS lookup on * my host name. */net_addr *net_get_default_interface(){ char name[MAXHOSTNAMELEN]; static net_addr addr; if (FAILED(gethostname(name,MAXHOSTNAMELEN))) return(NULL); if (!net_addr_ascii(&addr,name)) return(NULL); return(&addr);}#ifdef linux/* * libnetlink.c * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> * */#define MSG_TRUNC 0x20#define MSG_DONTWAIT 0x40 /* Nonblocking io */int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions){ int addr_len; memset(rth, 0, sizeof(rth)); rth->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (rth->fd < 0) { fprintf(stderr,"cannot open netlink socket: %m"); return -1; } memset(&rth->local, 0, sizeof(rth->local)); rth->local.nl_family = AF_NETLINK; rth->local.nl_groups = subscriptions; if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) { fprintf(stderr,"cannot bind netlink socket: %m"); goto failure; } addr_len = sizeof(rth->local); if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) { fprintf(stderr,"cannot getsockname: %m"); goto failure; } if (addr_len != sizeof(rth->local)) { fprintf(stderr,"wrong address length %d", addr_len); goto failure; } if (rth->local.nl_family != AF_NETLINK) { fprintf(stderr,"wrong address family %d", rth->local.nl_family); goto failure; } rth->seq = 1; return 0;failure: rth->fd = -1; return -1;}void rtnl_close(struct rtnl_handle *rth){ close(rth->fd); rth->fd = -1;}void rtnl_set_junkfilter(struct rtnl_handle *rth, int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n), int (**o_junk)(struct sockaddr_nl *,struct nlmsghdr *n)){ if (o_junk) *o_junk = rth->junk; rth->junk = junk;}int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len){ int err; struct nlmsghdr nlh; struct sockaddr_nl nladdr; struct iovec iov[2] = { { &nlh, sizeof(nlh) }, { req, len } }; struct msghdr msg = { (void*)&nladdr, sizeof(nladdr), iov, 2, NULL, 0, 0 }; memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; nlh.nlmsg_len = NLMSG_LENGTH(len); nlh.nlmsg_type = type; nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_REQUEST; nlh.nlmsg_pid = 0; nlh.nlmsg_seq = rth->dump = ++rth->seq; err = sendmsg(rth->fd, &msg, 0); if (err == nlh.nlmsg_len) return 0; return -1;}int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type){ struct rtgenmsg g; memset(&g, 0, sizeof(g)); g.rtgen_family = family; return rtnl_dump_request(rth, type, (void*)&g, sizeof(g));}/* As fast as possible flush queue. A part of information is lost in any case, so that the best that we can make now is to ignore burst and try to recover. */void rtnl_flush(struct rtnl_handle *rth){ char buf[8]; while (recv(rth->fd, buf, sizeof(buf), MSG_DONTWAIT) >= 0 || errno != EAGAIN) /* NOTHING */; sleep(1); while (recv(rth->fd, buf, sizeof(buf), MSG_DONTWAIT) >= 0 || errno != EAGAIN) /* NOTHING */;}int rtnl_dump_filter(struct rtnl_handle *rth, int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *), void *arg1){ char buf[8192]; struct sockaddr_nl nladdr; struct iovec iov = { buf, sizeof(buf) }; while (1) { int status; struct nlmsghdr *h; struct msghdr msg = { (void*)&nladdr, sizeof(nladdr), &iov, 1, NULL, 0, 0 }; status = recvmsg(rth->fd, &msg, 0); if (status < 0) { int s_errno = errno; if (errno == EINTR) continue; rtnl_flush(rth); errno = s_errno; return -1; } if (status == 0) { fprintf(stderr,"EOF on netlink"); errno = EINVAL; return -1; } if (msg.msg_namelen != sizeof(nladdr)) { fprintf(stderr,"sender address length == %d", msg.msg_namelen); errno = EINVAL; return -1; } if (nladdr.nl_pid) { fprintf(stderr,"message from %d", nladdr.nl_pid); continue; } h = (struct nlmsghdr*)buf; while (NLMSG_OK(h, status)) { int err; if (h->nlmsg_pid != rth->local.nl_pid || h->nlmsg_seq != rth->dump) { if (rth->junk) rth->junk(&nladdr, h); goto skip_it; } if (h->nlmsg_type == NLMSG_DONE) return 0; if (h->nlmsg_type == NLMSG_ERROR) { struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { fprintf(stderr,"ERROR truncated"); errno = EMSGSIZE; } else { if (err->error == 0) return 0; fprintf(stderr,"not OK\n"); errno = -err->error; } return -1; } err = filter(&nladdr, h, arg1); if (err < 0) return err;skip_it: h = NLMSG_NEXT(h, status); } if (msg.msg_flags & MSG_TRUNC) { errno = EMSGSIZE; return -1; } if (status) fprintf(stderr,"!!!Remnant of size %d", status); }}int rtnl_ask(struct rtnl_handle *rtnl, struct iovec *iov, int iovlen, struct rtnl_dialog *d, char *buf, int len){ int i; struct nlmsghdr *n = iov[0].iov_base; struct sockaddr_nl nladdr; struct msghdr msg = { (void*)&nladdr, sizeof(nladdr), iov, iovlen, NULL, 0, 0 }; memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; n->nlmsg_seq = d->seq = ++rtnl->seq; n->nlmsg_flags |= NLM_F_ACK|NLM_F_REQUEST; n->nlmsg_len = 0; for (i=0; i<iovlen-1; i++) { iov[i].iov_len = NLMSG_ALIGN(iov[i].iov_len); n->nlmsg_len += iov[i].iov_len; } n->nlmsg_len += iov[iovlen-1].iov_len; d->buf = d->ptr = buf; d->buflen = len; d->curlen = 0; i = sendmsg(rtnl->fd, &msg, 0); if (i == n->nlmsg_len) return 0; return -1;}struct nlmsghdr * rtnl_wait(struct rtnl_handle *rth, struct rtnl_dialog *d, int *err){ int status; struct nlmsghdr *n; while (1) { if (d->curlen == 0) { struct iovec iov = { (void*)d->buf, d->buflen }; struct msghdr msg = { (void*)&d->peer, sizeof(d->peer), &iov, 1, NULL, 0, 0 }; status = recvmsg(rth->fd, &msg, 0); if (status < 0) { int s_errno = errno; if (errno == EINTR) continue; rtnl_flush(rth); errno = s_errno; *err = -1; return NULL; } if (status == 0) { fprintf(stderr,"EOF on netlink"); *err = -1; errno = EINVAL; return NULL; } if (msg.msg_namelen != sizeof(d->peer)) { fprintf(stderr,"sender address length == %d\n", msg.msg_namelen); *err = -1; errno = EINVAL; return NULL; } if (d->peer.nl_pid) { fprintf(stderr,"message from %d", d->peer.nl_pid); continue; } d->curlen = status; d->ptr = d->buf; } n = (struct nlmsghdr*)d->ptr; status = d->curlen; while (NLMSG_OK(n, status)) { d->curlen -= NLMSG_ALIGN(n->nlmsg_len); d->ptr += NLMSG_ALIGN(n->nlmsg_len); if (n->nlmsg_pid != rth->local.nl_pid || n->nlmsg_seq != d->seq) { if (rth->junk) rth->junk(&d->peer, n); goto skip_it; } if (n->nlmsg_type == NLMSG_DONE) { *err = 0; return NULL; } if (n->nlmsg_type == NLMSG_ERROR) { struct nlmsgerr *e = (struct nlmsgerr*)NLMSG_DATA(n); if (n->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { fprintf(stderr,"ERROR truncated"); errno = EINVAL; } else if (e->error == 0) { *err = 0; return NULL; } else { errno = -e->error; fprintf(stderr,"RTNETLINK error: %m"); errno = -e->error; } *err = -1; return NULL; } return n;skip_it: n = NLMSG_NEXT(n, status); } d->curlen = 0; d->ptr = d->buf; }}int rtnl_tell_iov(struct rtnl_handle *rth, struct iovec *iov, int iovlen){ int err; char buf[4096]; struct rtnl_dialog d; err = rtnl_ask(rth, iov, iovlen, &d, buf, sizeof(buf)); if (err) return err; while (rtnl_wait(rth, &d, &err) != NULL) /* NOTHING */; return err;}int rtnl_tell(struct rtnl_handle *rth, struct nlmsghdr *n){ struct iovec iov = { (void*)n, n->nlmsg_len }; return rtnl_tell_iov(rth, &iov, 1);}int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data){ int len = RTA_LENGTH(4); struct rtattr *rta; if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) return -1; rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len)); rta->rta_type = type; rta->rta_len = len; memcpy(RTA_DATA(rta), &data, 4); n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len; return 0;}int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen){ int len = RTA_LENGTH(alen); struct rtattr *rta; if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) return -1; rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len)); rta->rta_type = type; rta->rta_len = len; memcpy(RTA_DATA(rta), data, alen); n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len; return 0;}int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen){ struct rtattr *subrta; int len = RTA_LENGTH(alen); if (RTA_ALIGN(rta->rta_len) + len > maxlen) return -1; subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len)); subrta->rta_type = type; subrta->rta_len = len; memcpy(RTA_DATA(subrta), data, alen); rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len; return 0;}int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len){ memset(tb, 0, sizeof(struct rtattr*)*(max+1)); while (RTA_OK(rta, len)) { if (rta->rta_type <= max) tb[rta->rta_type] = rta; rta = RTA_NEXT(rta,len); } if (len) { fprintf(stderr,"!!!Deficit %d: type=%d len=%d\n", len, rta->rta_type, rta->rta_len); return -EINVAL; } return 0;}#endif /* linux */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -