miniupnpd/portinuse.c: add FreeBSD support for CHECK_PORTINUSE
This commit is contained in:
parent
1576c07058
commit
90cc5ad3e7
|
@ -4,10 +4,12 @@
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||||
* This software is subject to the conditions detailed
|
* This software is subject to the conditions detailed
|
||||||
* in the LICENCE file provided within the distribution */
|
* in the LICENCE file provided within the distribution */
|
||||||
#if defined(__DragonFly__)
|
|
||||||
|
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -18,6 +20,7 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#if defined(__OpenBSD__)
|
#if defined(__OpenBSD__)
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
#include <kvm.h>
|
#include <kvm.h>
|
||||||
|
@ -30,7 +33,7 @@
|
||||||
#include <netinet/in_pcb.h>
|
#include <netinet/in_pcb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__DragonFly__)
|
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||||
#include <sys/socketvar.h>
|
#include <sys/socketvar.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
/* sys/socketvar.h must be included above the following headers */
|
/* sys/socketvar.h must be included above the following headers */
|
||||||
|
@ -265,9 +268,106 @@ static struct nlist list[] = {
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
}
|
}
|
||||||
/* #elif __NetBSD__ */
|
/* #elif __NetBSD__ */
|
||||||
/* #elif __FreeBSD__ */
|
#elif defined(__FreeBSD__)
|
||||||
/* TODO : FreeBSD / NetBSD / Darwin (OS X) / Solaris code */
|
const char *varname;
|
||||||
|
struct xinpgen *xig, *exig;
|
||||||
|
struct xinpcb *xip;
|
||||||
|
struct xtcpcb *xtp;
|
||||||
|
struct inpcb *inp;
|
||||||
|
void *buf = NULL;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
switch (proto) {
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
varname = "net.inet.tcp.pcblist";
|
||||||
|
break;
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
varname = "net.inet.udp.pcblist";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
syslog(LOG_ERR, "port_in_use() unknown proto=%d", proto);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sysctlbyname(varname, NULL, &len, NULL, 0) < 0) {
|
||||||
|
syslog(LOG_ERR, "sysctlbyname(%s, NULL, ...): %m", varname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
buf = malloc(len);
|
||||||
|
if (buf == NULL) {
|
||||||
|
syslog(LOG_ERR, "malloc(%u) failed", (unsigned)len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (sysctlbyname(varname, buf, &len, NULL, 0) < 0) {
|
||||||
|
syslog(LOG_ERR, "sysctlbyname(%s, buf, ...): %m", varname);
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
xig = (struct xinpgen *)buf;
|
||||||
|
exig = (struct xinpgen *)(void *)((char *)buf + len - sizeof *exig);
|
||||||
|
if (xig->xig_len != sizeof *xig) {
|
||||||
|
syslog(LOG_WARNING, "struct xinpgen size mismatch; %ld vs %ld",
|
||||||
|
(long)xig->xig_len, sizeof *xig);
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (exig->xig_len != sizeof *exig) {
|
||||||
|
syslog(LOG_WARNING, "struct xinpgen size mismatch; %ld vs %ld",
|
||||||
|
(long)exig->xig_len, sizeof *exig);
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
|
||||||
|
if (xig >= exig)
|
||||||
|
break;
|
||||||
|
switch (proto) {
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
xtp = (struct xtcpcb *)xig;
|
||||||
|
if (xtp->xt_len != sizeof *xtp) {
|
||||||
|
syslog(LOG_WARNING, "struct xtcpcb size mismatch; %ld vs %ld",
|
||||||
|
(long)xtp->xt_len, sizeof *xtp);
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
inp = &xtp->xt_inp;
|
||||||
|
break;
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
xip = (struct xinpcb *)xig;
|
||||||
|
if (xip->xi_len != sizeof *xip) {
|
||||||
|
syslog(LOG_WARNING, "struct xinpcb size mismatch : %ld vs %ld",
|
||||||
|
(long)xip->xi_len, sizeof *xip);
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
inp = &xip->xi_inp;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
/* no support for IPv6 */
|
||||||
|
if ((inp->inp_vflag & INP_IPV6) != 0)
|
||||||
|
continue;
|
||||||
|
syslog(LOG_DEBUG, "%08lx:%hu %08lx:%hu <=> %hu %08lx:%hu",
|
||||||
|
(u_long)inp->inp_laddr.s_addr, ntohs(inp->inp_lport),
|
||||||
|
(u_long)inp->inp_faddr.s_addr, ntohs(inp->inp_fport),
|
||||||
|
eport, (u_long)ip_addr.s_addr, iport
|
||||||
|
);
|
||||||
|
if (eport == (unsigned)ntohs(inp->inp_lport)) {
|
||||||
|
if (inp->inp_laddr.s_addr == INADDR_ANY || inp->inp_laddr.s_addr == ip_addr.s_addr) {
|
||||||
|
found++;
|
||||||
|
break; /* don't care how many, just that we found at least one */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(buf) {
|
||||||
|
free(buf);
|
||||||
|
buf = NULL;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
|
/* TODO : NetBSD / Darwin (OS X) / Solaris code */
|
||||||
#error "No port_in_use() implementation available for this OS"
|
#error "No port_in_use() implementation available for this OS"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue