Giter VIP home page Giter VIP logo

miniupnp's Introduction

 -= MiniUPnP project =-

Main author : Thomas BERNARD

Web site : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
Gitlab : https://framagit.org/miniupnp/miniupnp/
GitHub : https://github.com/miniupnp/miniupnp/
Appveyor : https://ci.appveyor.com/project/miniupnp/miniupnp

miniupnpc/ : MiniUPnP client - an UPnP IGD control point
miniupnpd/ : MiniUPnP daemon - an implementation of a UPnP IGD
                               + NAT-PMP / PCP gateway
minissdpd/ : SSDP managing daemon. Designed to work with miniupnpc,
             miniupnpd, ReadyMedia (formerly MiniDLNA), etc.
miniupnpc-async/    : Proof of concept for a UPnP IGD control point using
                      asynchronous (non blocking) sockets.
miniupnpc-libevent/ : UPnP IGD control point using libevent2
                      http://libevent.org/

Thanks to :
    * Ryan Wagoner
    * João Paulo Barraca
    * Craig Kadziolka
    * Seth Mos
    * Rick Richard
    * Michael van Tellingen
    * Julien Wajsberg
    * Jeremy Collake
    * Matthew Sporleder
    * Greg Hazel
    * Rico Huber
    * Jelle Huitema
    * Xavier Martin
    * Thomas Goirand
    * Darren Reed
    * Robbie Hanson
    * Nikos Mavrogiannopoulos
    * Elsö András
    * Justin Maggard
    * David Wu
    * Michael Trebilcock
    * Soren Dreijer
    * Colin McFarlane
    * Daniel Dickinson
    * Guillaume Habault
    * Alexey Osipov
    * Alexey Kuznetsov
    * Chiaki Ishikawa
    * David Kerr
    * Jardel Weyrich
    * Leah X. Schmidt
    * Peter Tatrai
    * Leo Moll
    * Daniel Becker
    * Yonetani Tomokazu
    * Markus Stenberg
    * Tomofumi Hayashi
    * Konstantin Tokarev
    * Mike Tzou
    * Nevo Hed
    * Salva Peiró
    * Stephan Zeisberg
    * Ben Barnea of VDOO
    * Sven Auhagen
    * Paul Chambers
    * Pali Rohár
    * Brian John

miniupnp's People

Contributors

altendky avatar arr2036 avatar axet avatar chocobo1 avatar edrikk avatar fanquake avatar fingon avatar irwir avatar jweyrich avatar leahxschmidt avatar mgorny avatar miniupnp avatar nathanrichard avatar niamster avatar pali avatar past-due avatar paul-chambers avatar ptpt52 avatar razzfazz avatar rbgarga avatar reddwarf69 avatar rofl0r avatar s1061123 avatar sanderjo avatar sbyx avatar scribam avatar self-hosting-group avatar svenauhagen avatar tedshroyer avatar yangfl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

miniupnp's Issues

PCP MAP requests will hang miniupnpd if it was compiled without IPv6 support

Experimenting with enabling PCP support in miniupnpd for my router firmware. I'm compiling miniupnpd without IPv6 support enabled.

When sending a PCP MAP requests to it, it will get stuck in pcpserver.c/ParsePCPOptions() on this section of code:

                if(getifaddr_in6(ext_if_name, &external_addr) < 0) {
                        pcp_msg_info->result_code = PCP_ERR_NETWORK_FAILURE;
                        return -1;
                }

If I comment out this piece of code, the MAP request is successfully completed and will appear in the UPNP chain.

I suspect this section of code should only be compiled if IPv6 support is enabled at build time (assuming that IPv6 support isn't mandatory for PCP - I don't think it is).

sys/queue.h not found

on sabotage linux [1] using musl libc there is no sys/queue.h

instead of blacklisting systems that are known not to have this header, you should follow the opposite approach and whitelist systems that are known to have it, i.e. GLIBC , BSD etc.

the current approach is broken, because it will fail on any system that was not yet tested by the authors.

the best solution is if you simply always include the copy that you deliver.

[1] https://github.com/rofl0r/sabotage

miniupnpc: add NewRemoteHost arg in GetSpecificPortMappingEntry

UPNP_GetSpecificPortMappingEntry() should have a way to add NewRemoteHost argument

GetPortMappingArgs[0].elt = "NewRemoteHost";
/* TODO : add remote host ? */
GetPortMappingArgs[1].elt = "NewExternalPort";
GetPortMappingArgs[1].val = extPort;
GetPortMappingArgs[2].elt = "NewProtocol";
GetPortMappingArgs[2].val = proto;

Lease file not created

The lease file is not automatically created on service startup , in debug mode " miniupnpd: could not open lease file: /var/log/upnp.leases" shows up , if the service is stooped the file is automatically deleted , as a workaround you can pre-touch /var/log/upnp.leases before service start .

Build fails on Solaris (miniupnp 1.7)

The bittorrent client Transmission (v. 2.52) makes use of miniupnp and the upgrade to v.1.7 broke on Solaris, see the following:

https://trac.transmissionbt.com/ticket/4891

A successful patch for miniupnpc.c was put forward and tested:

https://trac.transmissionbt.com/attachment/ticket/4891/miniupnpc.c.patch

I cross-posted the issue here as well as the miniupnp forum. I hope that is ok. I didn't see the source was on github before I posted on the forum.

http://miniupnp.tuxfamily.org/forum/viewtopic.php?t=1156&highlight=solaris

Makefile does not differentiate PREFIX and DESTDIR

the usual way of installing things on unix is that you have

  1. a prefix (this is were things ultimately end up, i.e. this is what hardcoded path references must use).

  2. a DESTDIR. this is where things get installed to. this is basically a mechanism for packagers so that the installed files dont clutter the machine they build on.

the usual formula to install things goes like this:

libdir=$(prefix)/lib

install:
             install -D -m 644 libexample.so $(DESTDIR)$(libdir)

note the missing slash. this makes it possible to concatenate paths without getting double slashes in the path name.

in my case, prefix="" (empty) and DESTDIR=/opt/packagename
that makes libdir=/lib and things get installed to /opt/packagename/lib

alternatively with prefix=/usr/local:
libdir=/usr/local/lib
destination: /opt/packagename/usr/local/lib.

i don't see any good reason why packages lacking autoconf (it is basically a good thing to supply only a simple makefile) start to introduce their own variable names like INSTALLPREFIX and don't follow best practices used by 98% of open source packages.

Router isn't being discovered with both upnpc and minissdpd

Hello,
I tried upnpc on my network but it says
"No IGD UPnP Device found on the network !"

My router is a Livebox Play from French ISP Orange, Model Description : Sagemcom.fr,SG30-sip-fr.4.28.35.1

The gupnp-universal control point was able to discover it.
Its description url is http://192.168.1.1:60001/96999fec/gatedesc.xml
Using the -u option in upnpc I was able to get my external ip and add port redirection.

I pasted the gatedesc.xml here : http://pastie.org/private/qkek1rsfpg0fgjp0yf3ka

I tried the -m option, but it was already selecting the good interface without it, finding other UPnP device on my network, like the Orange Décodeur set-top box.

Errors in syslog when shutting down miniupnpd

When miniupnpd is compiled with IPv6 support and there is no IPv6 address yet when it is started, IPv6 stays disabled, even when an address is obtained later on. Since there is no signal that can tell miniupnpd to retry it again, I tried restarting miniupnpd as soon as an IPv6 address was assigned.

This results in several repeated messages to the syslog: sendto(udp_shutdown=-1): Bad file descriptor

I think that SendSSDPGoodbye should skip ipv6 addresses when GETFLAG(IPV6DISABLEDMASK) returns a non-zero value.
Or perhaps SendSSDPbyebye should not be called at all when socket[j] is -1, if it is possible to have 0 open sockets while shutting down?

upnpc fails to list mapping (new router)

Hello,

I recently purchased the new french livebox 3fr-ed2 (sagem), and enabled upnp igd (of course).

My upnpc client (v1.9) no longer working on it, I get this error:

upnpc : miniupnpc library test client. (c) 2005-2013 Thomas Bernard
Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
for more information.
List of UPNP devices found on the network :
desc: http://192.168.1.1:60000/87895a19/gatedesc.xml
st: upnp:rootdevice

desc: http://192.168.1.1:49152/wps_device.xml
st: upnp:rootdevice

Found a (not connected?) IGD : http://192.168.1.1:60000/
Trying to continue anyway
Local LAN ip address : 192.168.1.26
GetConnectionTypeInfo failed.
GetStatusInfo failed.
Time started : Mon Jun 30 19:56:08 2014
GetLinkLayerMaxBitRates failed.
GetExternalIPAddress failed. (errorcode=-1)
i protocol exPort->inAddr:inPort description remoteHost leaseTime
GetGenericPortMappingEntry() returned -1 (Miniupnpc Unknown Error)

What may be causing this bug ?

Redirect outside port X to port Y on 'this' IP address

I want to redirect outside port X to port Y on 'this' IP address (with X not the same as Y), so command "-d" does not do the trick.

As far as I know, there is no direct command for that as you first have find out the RFC1918 address on the host you're on. I now use:

upnpc -a $(ip route get 8.8.8.8 | head -1 | awk '{ print $NF }') 22 22000 tcp

to redirect outside port 22000 to port 22 on the system issueing the command.

If the above assumption is correct, I suggest an extra option "-m" (for: "me"):

./upnpc-static [options] -m port external_port protocol [duration]

With that implemented, the usage would be:

upnpc -m 22 22000 tcp

Implementing should be feasible as upnpc already knows it's own RFC1918 IP address

java binding error on linux x64

Hi ,when I start to test the java binding on my pc,an error raise,and then after an period try,it finally comes out no error with the later output

kerr@DearPanda:~/miniupnp/miniupnpc/java$ ./testjava.sh 
List of UPNP devices found on the network :
desc: http://192.168.20.1:1900/igd.xml st: urn:schemas-upnp-org:device:InternetGatewayDevice:1
Found valid IGD : http://192.168.20.1:1900/ipc
Local LAN ip address : 192.168.20.111
ExternalIPAddress = 172.31.70.28
InternalIP:Port = 192.168.20.111:12345 (added via miniupnpc/JAVA !)
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f53fd208314, pid=16837, tid=139999026202368
#
# JRE version: 7.0_17-b02
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.7-b01 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [jna1884787305357561782.tmp+0x9314]  Java_com_sun_jna_Native__1getPointer+0xd4
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/kerr/miniupnp/miniupnpc/java/hs_err_pid16837.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
./testjava.sh: 行 8: 16837 已放弃               (核心已转储) $JAVA -cp $CP JavaBridgeTest 12345 UDP

later output

kerr@DearPanda:~/miniupnp/miniupnpc/java$ ./testjava.sh 
List of UPNP devices found on the network :
desc: http://192.168.20.1:1900/igd.xml st: urn:schemas-upnp-org:device:InternetGatewayDevice:1
Found valid IGD : http://192.168.20.1:1900/ipc
Local LAN ip address : 192.168.20.111
ExternalIPAddress = 172.31.70.28
InternalIP:Port = 192.168.20.111:12345 (added via miniupnpc/JAVA !)

Unknown error, GetSpecificPortMappingEntry() failed

UPNPC isn't working with my router for some reason... I've updated to the latest build..

This is what it's saying. Any ideas? Thanks!

List of UPNP devices found on the network :
 desc: http://192.168.1.64:80/description.xml
 st: urn:schemas-upnp-org:device:basic:1

 desc: http://192.168.1.64:80/description.xml
 st: uuid:2f402f80-da50-11e1-9b23-00178814ba4e

 desc: http://192.168.1.64:80/description.xml
 st: upnp:rootdevice

UPnP device found. Is it an IGD ? : http://192.168.1.64:80/
Trying to continue anyway
Local LAN ip address : 192.168.1.76
GetExternalIPAddress failed.
GetSpecificPortMappingEntry() failed with code -1 (Miniupnpc Unknown Error)

get_lan_for_peer in upnputils.c doesn't return NULL for non-LAN IPv6 addresses

In case of IPv6, get_lan_for_peer uses get_src_for_route_to to compute the interface index. The index returned is the one used as the next hop to the peer.
Except when there is no IPv6 connectivity, any IPv6 address will be accepted and the interface that routes ::/0 will be returned for non LAN addresses. (This can also be seen by running testgetroute with any non-LAN IPv6 address, like the documentation prefix 2001:db8::).

One possible way to solve this would be something like this:
In upnputils.c replace

#include "getroute.h"

by

#include <ifaddrs.h>
#include <netinet/in.h>

Then replace the call to get_src_for_route_to by:

struct ifaddrs *ifaddr, *ifa;
struct sockaddr_in6 *addr, *netmask;
int i;
if (getifaddrs(&ifaddr) < 0) return NULL;

for (lan_addr = lan_addrs.lh_first;
     lan_addr != NULL;
     lan_addr = lan_addr->list.le_next)
{
    // Loop through all interfaces.
    for (ifa = ifaddr;
         ifa != NULL;
         ifa = ifa->ifa_next)
    {
        // Skip non IPv6 interfaces and interfaces where the name differs.
        if (ifa->ifa_addr == NULL ||
            ifa->ifa_addr->sa_family != AF_INET6 ||
            strcmp(ifa->ifa_name, lan_addr->ifname)) continue;

            addr = (struct sockaddr_in6 *)ifa->ifa_addr;
            netmask = (struct sockaddr_in6 *)ifa->ifa_netmask;
            // Check that the prefix is the same.
            for (i = 0; i < 16; i++)
            {
                if ((addr->sin6_addr.s6_addr[i] & netmask->sin6_addr.s6_addr[i])
                    != (peer6->sin6_addr.s6_addr[i] & netmask->sin6_addr.s6_addr[i])) break;
            }
            // If no early break, it means the prefix matched.
            if (i == 16) return lan_addr;
    }
}
freeifaddrs(ifaddr);
return NULL;

IPv6: AddPortMapping(4567, 4567, 2001:470:AAA5:100c::100) failed with code 402 (Invalid Args)

I'm not sure this is a real issue, or a misunderstandig from my side:

A upnpc -6 -r 4567 tcp (so: ipv6) results in an error message:

AddPortMapping(4567, 4567, 2001:470:AAA5:100c::100) failed with code 402 (Invalid Args)

My upnpc client is talking to a router running openwrt with miniupnpd running on it. Port 4567 is not used on the router.

Am I doing something wrong? Can't '-6' be used this way? Or is it indeed a bug, on the client or the router side?

$ ./upnpc-static -6 -r 4567 tcp
upnpc : miniupnpc library test client, version 1.9.
 (c) 2005-2014 Thomas Bernard.
Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
for more information.
List of UPNP devices found on the network :
 desc: http://[2001:470:AAA4:100c::2]:5000/rootDesc.xml
 st: urn:schemas-upnp-org:device:InternetGatewayDevice:1

Found valid IGD : http://[2001:470:AAA4:100c::2]:5000/ctl/IPConn
Local LAN ip address : 2001:470:AAA5:100c::100
ExternalIPAddress = 83.128.233.31
AddPortMapping(4567, 4567, 2001:470:AAA5:100c::100) failed with code 402 (Invalid Args)
GetSpecificPortMappingEntry() failed with code 714 (NoSuchEntryInArray)

FYI: "AAA" is the replacement for my real ipv6 address.

getportmappingnumberofentries

the function getportmappingnumberofentries() doesn't works in the python module:

log =
p = upnp.getportmappingnumberofentries()
Exception: Invalid Action

thanks

Using interface name for listening_ip assumes /24 mask

parselanaddr in miniupnpd.c assumes a 24-bit subnet mask unless explicitly stated even given named interfaces. Users won't expect this behavior, as they will assume the interface subnet mask will be used for the given named interface by default.

how do you know the version of the installed library?

now do not have any definition in the header of library or as a separate file, in case of changes in the api calls (eg 1.5 -> 1.6) it is necessary to determine the compatibility of code based on the library to use its features.

AddPortMapping() failed with code 402 (Invalid Args)

I try to add redirection with upnpc for ipcamera, but I got the following error : AddPortMapping() failed with code 402. That a bit strange, because I added some redirections for my raspberry pi without any problem.

$ upnpc -a 192.168.1.4 4001 4001 TCP
upnpc : miniupnpc library test client. (c) 2006-2010 Thomas Bernard
Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
for more information.
List of UPNP devices found on the network :
desc: http://192.168.1.254:5678/desc/root
st: urn:schemas-upnp-org:device:InternetGatewayDevice:1

Found valid IGD : http://192.168.1.254:5678/control/wan_ip_connection
Local LAN ip address : 192.168.1.6
ExternalIPAddress = x.x.x.x
AddPortMapping(4001, 4001, 192.168.1.4) failed with code 402 (Invalid Args)
GetSpecificPortMappingEntry() failed with code 714 (NoSuchEntryInArray)

Service anouncement messages only being sent out once

So per the UPnP guidlines:

In UPnP Device Architecture 1.0, Section 1.1.2,
Due to the unreliable nature of UDP, devices should send each of the above discovery messages more than once, although to avoid network congestion discovery messages should not be sent more than three times.

NAT-PMP implementation violates RFC 6886.

This is a moot point from my perspective (as a client implementer) since I can't rely on routers acutally updating, but for the sake of documentation, the mapping request processing in miniupnpd does not handle non-wildcard mapping removal correctly.

RFC 6886 states:

A client MAY also send an explicit packet to request deletion of a
mapping that is no longer needed. A client requests explicit
deletion of a mapping by sending a message to the NAT gateway
requesting the mapping, with the Requested Lifetime in Seconds set to
zero. The Suggested External Port MUST be set to zero by the client
on sending, and MUST be ignored by the gateway on reception.

So the correct layout of the UDP body for a single mapping removal (TCP) would be:

Vers: 00
OP: 01 Map TCP (Map UDP is equally broken)
Reserved: 00 00
Internal Port: <whatever>
Suggested External Port: 00 00
Requested Port Mapping Lifetime in Seconds: 00 00 00 00

natpmp.c:ProcessIncomingNATPMPPacket() will handle this like:

  • Look at eport and sets it to iport since eport is 0.
  • Remove the port forwarding entry based on proto (TCP) and eport, which is actually the client's internal (LAN side) port.

Assuming that eport == iport when handling mapping requests is flat out wrong, because there is no requirement anywhere that they must be equal. In the best case, the mapping removal fails with a Not Authorized/Refused status code. If another mapping that happens to use the client's iport as the eport exists, the incorrect mapping (possibly belonging to a different process on a different client host) will be removed.

The client side workaround, assuming every implementation of NAT-PMP is equally broken, would be to ignore the "The Suggested External Port MUST be set to zero by the client on sending" clause, but that's not an assumption I'm personally willing to make given that the clause has been present in the protocol specification from the initial IETF draft (Dating back to 2005).

The correct fix would be to remove the mapping based on the client address/iport pair, but I'm not sure how easy it would be to do (and I can't rely on that behavior).

Log Spam on OpenWRT from Windows7 SSDP from fe80::

Windows7 sends SSDP Messages from fe80:: Protocol was PNRP (Peer Name Resolution Protocol)

Apr 19 17:45:42 OpenWrt daemon.warn miniupnpd[1704]: SSDP packet sender [fe80::]:65424 not from a LAN, ignoring

with debug:
miniupnpd[7058]: Received UDP Packet (IPv6)
miniupnpd[7058]: get_src_for_route_to ([fe80::]:65424)
miniupnpd[7058]: get_lan_for_peer() looking for LAN interface index=2
miniupnpd[7058]: ifname= index=0 str=192.168.3.1 addr=c0a80301 mask=ffffff00
miniupnpd[7058]: get_lan_for_peer(): not found !
miniupnpd[7058]: SSDP packet sender [fe80::]:65424 not from a LAN, ignoring

error seems to be in upnputils.c with funktion: get_lan_for_peer

Need to work around iptables/conntrack multicast rigidity

Suppose I have a router that already has a UPnP daemon running, and suppose I want to periodically run a UPnP client on same router to see if an upstream router exists that supports UPnP.

  • UDP Multicast packets leave the box with an ephemeral source port and a multicast destination

    192.168.20.21:5555 -> 239.255.255.250:1900
  • UDP Unicast response packets are sent from the upstream router

    192.168.20.1:1900 -> 192.168.20.21:5555
  • These UDP packets are dropped by iptables as they do not match the outgoing traffic. To the best of my knowledge I don't think that there is a way to convince connection tracking to correlate unicast responses to multicast probes.

Things that won't work:

  • ❌ If I didn't have a UPnP daemon running I could simply set the sameport option and create an iptables rule to allow all traffic destined to port 1900. But as I have the daemon, I can't
  • ❌I could follow the advice at this post and create a rule to allow all traffic FROM port 1900, but that sounds like a very bad thing for a router to do, allowing any and all UDP traffic as long as the source port is 1900

✔️❓ Short of enhancing conntrack, the easiest solution that I can think of is let the user specify the local port (other than sameport), and then the user can construct iptables rules to match

I intend to implement this now and submit a PR. Please respond with any comments suggestions

GetConnectionTypeInfo failed after upnpc -D

Hi,
I was trying the -D command and after a

upnpc -D 67

if type

upnpc -l

I get this:

List of UPNP devices found on the network : 
desc: http://192.168.0.10:50000/rootDesc.xml 
st: upnp:rootdevice 

UPnP device found. Is it an IGD ? : http://192.168.0.10:50000/ 
Trying to continue anyway 
Local LAN ip address : 192.168.0.225 
GetConnectionTypeInfo failed. 
Status : Connected, uptime=1849296s, LastConnectionError : ERROR_NONE 
Time started : Sat Apr 18 10:37:54 2015 
GetLinkLayerMaxBitRates failed. 
GetExternalIPAddress failed. (errorcode=401) 
i protocol exPort->inAddr:inPort description remoteHost leaseTime 
GetGenericPortMappingEntry() returned 401 (Invalid Action)

my router (192.168.0.1) is a Netgear DG834 and terminal is a Mac OS.

What I wrong?
Thank you

genconfig.sh: freebsd: /etc/rc.conf.local

freebsd using not only /etc/rc.conf for configuration.
full list available at /etc/defaults/rc.conf:
rc_conf_files="/etc/rc.conf /etc/rc.conf.local"

best way to get all params:
. /etc/defaults/rc.conf
(its include all other confs)

pcpserver does not handle all-zeroes IPv4 external address correctly

I recently updated my home router to a firmware that uses miniupnpd 1.8.20140401. I immediately began seeing messages like this in the system log:

Apr 20 03:32:10 miniupnpd[474]: PCP: External IP in request didn't match interface IP

After recompiling miniupnpd with -DDEBUG, I got this information:

Apr 20 03:32:10 miniupnpd[474]: PCP request received from 192.168.1.224:5353 60bytes
Apr 20 03:32:10 miniupnpd[474]: PCP MAP: v2 Opcode specific information.
Apr 20 03:32:10 miniupnpd[474]: MAP nonce:      70ec7ba6133c3dda59e45bc2
Apr 20 03:32:10 miniupnpd[474]: MAP protocol:   17
Apr 20 03:32:10 miniupnpd[474]: MAP int port:   16402
Apr 20 03:32:10 miniupnpd[474]: MAP ext port:   55709
Apr 20 03:32:10 miniupnpd[474]: MAP Ext IP:     ::ffff:0.0.0.0
Apr 20 03:32:10 miniupnpd[474]: PCP: External IP in request didn't match interface IP 
Apr 20 03:32:10 miniupnpd[474]: Interface IP ::ffff:xx.xxx.xx.xx
Apr 20 03:32:10 miniupnpd[474]: IP in the PCP request ::ffff:0.0.0.0 

(where the x's are my public IPv4 address). So miniupnpd is complaining about a MAP request using the all-zeroes IPv4 suggested external address ::ffff:0.0.0.0 (see http://tools.ietf.org/html/rfc6887#section-5).

Looking at the code, it looks like CheckExternalAddress uses IN6_IS_ADDR_UNSPECIFIED to check for all-zeroes addresses. However, that macro only works for actual IPv6 addresses, not IPv6-mapped IPv4 addresses (it essentially just checks that all 16 bytes of the address are zero).

if LINUX has IPV6 disabled while miniupnpd is still trying to use [::1]

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 13.10
Release:        13.10
Codename:       saucy
$ sudo sysctl -a|grep disable_ipv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.ppp0.disable_ipv6 = 1
$ sudo /etc/init.d/miniupnpd restart;tail -f /var/log/syslog
 * Stopping UPnP devices daemon MiniUPnPd                                                                                                                                    [ OK ]
 * Starting UPnP devices daemon MiniUPnPd                                                                                                                                    [ OK ]
Feb  1 06:48:01 GEAR miniupnpd[4864]: HTTP listening on port 56969
Feb  1 06:48:01 GEAR miniupnpd[4864]: no HTTP IPv6 address
Feb  1 06:48:01 GEAR miniupnpd[4864]: setsockopt(udp, IPV6_ADD_MEMBERSHIP): No such device
Feb  1 06:48:01 GEAR miniupnpd[4864]: sendto(udp_notify=8, [::1]): Network is unreachable
Feb  1 06:49:25  miniupnpd[4864]: last message repeated 11 times
Feb  1 06:49:31 GEAR miniupnpd[4864]: sendto(udp_notify=8, [::1]): Network is unreachable
Feb  1 06:49:36  miniupnpd[4864]: last message repeated 11 times
F

Also no pnp-nat is not working so far.

syslog flooded with miniupnpd[xxxx]: SendSSDPResponse(): sendto(udp): Operation not permitted

When running the Plex DLNA server the syslog is flooded with the subject message (one entry every 1-2 minutes). Anecdotally, this is only occurring on the latest generation (fast) ARM-based routers.

When miniupnpd was restarted in debug mode, the message was no longer seen implying some type of timing issue. Using ASUSWRT-MERLIN builds for the RT-AC68U several patches were tested which eliminates this error/error log. Note that the Merlin builds do not enable STRICT mode for miniupnpd.

The following changes were tested to eliminate the error:
(1) Changing the gen to separately enable DELAY_MSEARCH_RESPONSE (there is some concern about side effects of enabling STRICT mode)
(2) Changing the default base delay from 0 to 100
(3) Changing the specific SSDP response call to hardcode a delay.

Additional history/problem reports can be found in the following forums:

http://forums.smallnetbuilder.com/showthread.php?t=17666 (lastest discussions)
https://forums.plex.tv/index.php/topic/104297-plex-taking-down-my-router/

miniupnpc-1.9.20150206.tar.gz does not have testportlistingparse.c

http://miniupnp.free.fr/files/miniupnpc-1.9.20150206.tar.gz does not have testportlistingparse.c

x86_64-pc-linux-gnu-gcc -Wl,--hash-style=gnu -Wl,-O1 -Wl,--as-needed  testportlistingparse.o minixml.o portlistingparse.o   -o testportlistingparse
x86_64-pc-linux-gnu-gcc: error: testportlistingparse.o: No such file or directory
<builtin>: recipe for target 'testportlistingparse' failed
make: *** [testportlistingparse] Error 1

P.S. Seems commit e280c3d is for miniupnpc-1.9.20150206 release, but why git tag is missing?

Problem while installing miniupnpd

When I am trying command, make -f Makefile.linux, I am getting this error:

linux/getroute.c:19:39: fatal error: libnfnetlink/libnfnetlink.h: No such file or directory
compilation terminated.
make: *** [linux/getroute.o] Error 1

Also, I am not able to find any folder named libfnetlink. Can you help?

upnpc doesn't support "-h" or "--help" options

This is a tiny thing, but I think it's somewhat important. :)

I was surprised when -h and --help made the program probe the network for UPNP devices. I tried looking for a manpage, upon finding none I looked for documentation on the website, upon finding none I looked at the source code in the github repository, and discovered that you just run it without any options to get information on how to use it.

Remove dependency on libnfnetlink

Would it be possible to remove the dependency on libnfnetlink?
My router's firmware does not include this library and it seems to be a bit wasteful to include an extra library when only a small part of it is used.

One way to remove the dependency would be doing something like this (and I believe similar changes apply to minissdpd):

diff --git a/miniupnpd/Makefile.linux b/miniupnpd/Makefile.linux
index 92fc49d..b270201 100644
--- a/miniupnpd/Makefile.linux
+++ b/miniupnpd/Makefile.linux
@@ -138,8 +138,6 @@ endif # ($(TEST), 1)
 endif # ifdef IPTABLESPATH
 endif # ifdef PCFILE_FOUND

-LDLIBS += -lnfnetlink
-
 TEST := $(shell $(PKG_CONFIG) --atleast-version=1.0.2 libnetfilter_conntrack && $(PKG_CONFIG) --atleast-version=1.0.3 libmnl && echo 1)
 ifeq ($(TEST),1)
 CPPFLAGS += -DUSE_NFCT
diff --git a/miniupnpd/linux/getroute.c b/miniupnpd/linux/getroute.c
index 40bcbb6..9761a67 100644
--- a/miniupnpd/linux/getroute.c
+++ b/miniupnpd/linux/getroute.c
@@ -16,7 +16,6 @@
 /*#include <linux/in_route.h>*/
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
-#include <libnfnetlink/libnfnetlink.h>

 #include "../getroute.h"
 #include "../upnputils.h"
@@ -46,6 +45,7 @@ get_src_for_route_to(const struct sockaddr * dst,
    };
    const struct sockaddr_in * dst4;
    const struct sockaddr_in6 * dst6;
+   struct rtattr * rta;

    memset(&req, 0, sizeof(req));
    req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
@@ -66,15 +66,20 @@ get_src_for_route_to(const struct sockaddr * dst,
        syslog(LOG_DEBUG, "get_src_for_route_to (%s)", dst_str);
    }
    /* add address */
+   rta = (struct rtattr *)(((char*)&req) + NLMSG_ALIGN(req.n.nlmsg_len));
+   rta->rta_type = RTA_DST;
    if(dst->sa_family == AF_INET) {
        dst4 = (const struct sockaddr_in *)dst;
-       nfnl_addattr_l(&req.n, sizeof(req), RTA_DST, &dst4->sin_addr, 4);
+       rta->rta_len = RTA_SPACE(sizeof(dst4->sin_addr));
+       memcpy(RTA_DATA(rta), &dst4->sin_addr, sizeof(dst4->sin_addr));
        req.r.rtm_dst_len = 32;
    } else {
        dst6 = (const struct sockaddr_in6 *)dst;
-       nfnl_addattr_l(&req.n, sizeof(req), RTA_DST, &dst6->sin6_addr, 16);
+       rta->rta_len = RTA_SPACE(sizeof(dst6->sin6_addr));
+       memcpy(RTA_DATA(rta), &dst6->sin6_addr, sizeof(dst6->sin6_addr));
        req.r.rtm_dst_len = 128;
    }
+   req.n.nlmsg_len += rta->rta_len;

    fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
    if (fd < 0) {

Version in upnpc output

I see no version in the output upnpc:

$ ./upnpc-static 
upnpc : miniupnpc library test client. (c) 2005-2014 Thomas Bernard
Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
for more information.

It would be helpful for me if upnpc would tell it's version to distinguish between the different versions I have on different system: built-in by Ubuntu, or self-compiled from github. To get an idea I played a bit with Makefile and upnpc.c.

Option 1: Just VERSION as already defined in Makefile:

$ ./upnpc-static 
upnpc : miniupnpc library test client, version 1.9. (c) 2005-2015 Thomas Bernard

Option 2: VERSION plus the date in Changelog (CHANGELOGVERSION, as Changelog is more granular than VERSION)

$ ./upnpc-static 
upnpc : miniupnpc library test client, version 1.9 (changelog: 2015/04/27). (c) 2005-2015 Thomas Bernard

Option 3 VERSION and CHANGELOGVERSION combined to one number:

$ ./upnpc-static 
upnpc : miniupnpc library test client, version 1.9-20150427. (c) 2005-2015 Thomas Bernard

FWIW: Snippet from Makefile

VERSION = $(shell cat VERSION)
CHANGELOGVERSION = $(shell awk 'NR==1 { print $$4 }' Changelog.txt)
# CHANGELOGVERSION = $(shell awk 'NR==1 { print $$4 }' Changelog.txt | tr -d '/')

So ... how about this? I can implement it and send a pull request.

Default external IP address

When creating a rule without specifying external IP address upnpc uses 0.0.0.0, this results in no matches in RouterOS since the dynamic rule on the router has a destination address of 0.0.0.0 .

Manually creating a rule with all the very same settings but an empty destination address (i.e. the external IP address) works as expected.

Is the 0.0.0.0 implicit parameter needed in UPnP?

Is this a MiniUPnP issue or a RouterOS's one?

size of ‘reqn’ isn’t known

[user@localhost build]$ cmake ../
-- The C compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/miniupnpc/BUILD/miniupnp/miniupnpc/build
[user@localhost build]$ make
Scanning dependencies of target minixmlvalid
[ 1%] Building C object CMakeFiles/minixmlvalid.dir/minixmlvalid.c.o
[ 3%] Building C object CMakeFiles/minixmlvalid.dir/minixml.c.o
Linking C executable minixmlvalid
[ 3%] Built target minixmlvalid
Scanning dependencies of target testigddescparse
[ 5%] Building C object CMakeFiles/testigddescparse.dir/testigddescparse.c.o
[ 7%] Building C object CMakeFiles/testigddescparse.dir/igd_desc_parse.c.o
[ 9%] Building C object CMakeFiles/testigddescparse.dir/minixml.c.o
[ 11%] Building C object CMakeFiles/testigddescparse.dir/miniupnpc.c.o
/home/user/miniupnpc/BUILD/miniupnp/miniupnpc/miniupnpc.c: In function ‘upnpDiscover’:
/home/user/miniupnpc/BUILD/miniupnp/miniupnpc/miniupnpc.c:515:21: error: storage size of ‘reqn’ isn’t known
/home/user/miniupnpc/BUILD/miniupnp/miniupnpc/miniupnpc.c:516:29: error: invalid application of ‘sizeof’ to incomplete type ‘struct ip_mreqn’

simplify java binding just as the upnpc console command

Hi,i want to using the miniupnpc's java binding just as the upnpc's cmd in the linux shell.
now I interactive with it via Runtime.exec();

I think this method is so nice,so sorry for my bad c++,I am starting to learn it.what I think is that could just provide an java binding via bridj and only contains the listed method ?

whit the using of bridj ,this upnp lib could be used on android and so on ,thanks ,I will take an try after I learned my c++.thanks for your great project.

Usage : upnpc [options] -a ip port external_port protocol [duration]
        Add port redirection
        upnpc [options] -d external_port protocol [port2 protocol2] [...]
        Delete port redirection
        upnpc [options] -s
        Get Connection status
        upnpc [options] -l
        List redirections
        upnpc [options] -L
        List redirections (using GetListOfPortMappings, IGD v2)
        upnpc [options] -r port1 protocol1 [port2 protocol2] [...]
        Add all redirections to the current host
        upnpc [options] -A remote_ip remote_port internal_ip internal_port protocol lease_time
        Add Pinhole (for IGD:2 only)
        upnpc [options] -U uniqueID new_lease_time
        Update Pinhole (for IGD:2 only)
        upnpc [options] -C uniqueID
        Check if Pinhole is Working (for IGD:2 only)
        upnpc [options] -K uniqueID
        Get Number of packets going through the rule (for IGD:2 only)
        upnpc [options] -D uniqueID
        Delete Pinhole (for IGD:2 only)
        upnpc [options] -S
        Get Firewall status (for IGD:2 only)
        upnpc [options] -G remote_ip remote_port internal_ip internal_port protocol
        Get Outbound Pinhole Timeout (for IGD:2 only)
        upnpc [options] -P
        Get Presentation url

miniupnpc and Virtual Machine

I'm currentrly trying to use miniupnpc into a kvm in proxmox with a bridge.
But whatever i try, upnpc -s always give me that :
No IGD UPnP Device found on the network !

Any idea?
thanks

miniupnpd25277: DIOCGETSTATUS: Operation not supported by device

uname -a
FreeBSD ghost.ittown 10.0-RELEASE FreeBSD 10.0-RELEASE #0 r260789: Fri Jan 17 01:46:25 UTC 2014

Mar 18 00:08:28 ghost miniupnpd25277: DIOCGETSTATUS: Operation not supported by device
Mar 18 00:08:28 ghost kernel: Mar 18 00:08:28 ghost miniupnpd25277: DIOCGETSTATUS: Operation not supported by device
Mar 18 00:08:28 ghost miniupnpd25277: Failed to init redirection engine. EXITING
Mar 18 00:08:28 ghost kernel: Mar 18 00:08:28 ghost miniupnpd25277: Failed to init redirection engine. EXITING

port forwarding from lan

Hello,
my upnp rules are working great outside (from wan)
but doesn't work inside (from lan)
is there something special to do?

miniupnpc native build warnings on fedora 21

Hello!

Thanks for this project. We've faced a small issue with miniupnpc native library. When we are compiling it on fedora 21 linux and gcc 4.9, we're getting a warning from 'features.h' header '_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE'. According to 'man feature_test_macros', _DEFAULT_SOURCE must be used instead of _BSD_SOURCE in glibc version 2.20 and higher, on earlier versions it has no effect. Portable application can use this options together. Can you please fix it? We are using this library in our application and it has '-Werror' flag set, so we are getting compile time errors.

If you want we can make a pull request which will fix this issue.

miniupnpd on OpenWRT, sometimes cause CPU High to 100%

HI,

I'm using miniupnpd-1.8.20130426 on OpenWRT, but sometimes it causes CPU High,
I don't know what happens to the miniupnpd. so I attached the strace log. please help me.

Seems github cannot post a attachment.

709 2014-03-12-19:55:49:gettimeofday({1394625350, 770857}, NULL) = 0
6710 2014-03-12-19:55:49:accept(3, {sa_family=AF_INET6, sin6_port=htons(53681), inet_pton(AF_INET6, "::ffff:192.168.31.242", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 14
6711 2014-03-12-19:55:49:fcntl64(14, F_GETFL) = 0x2 (flags O_RDWR)
6712 2014-03-12-19:55:49:fcntl64(14, F_SETFL, O_RDWR|O_NONBLOCK) = 0
6713 2014-03-12-19:55:49:gettimeofday({1394625350, 771519}, NULL) = 0
6714 2014-03-12-19:55:49:select(17, [3 5 6 12 13 14], [], NULL, {6, 247488}) = 1 (in [14], left {6, 247474})
6715 2014-03-12-19:55:49:gettimeofday({1394625350, 771883}, NULL) = 0
6716 2014-03-12-19:55:49:recv(14, "POST /ctl/CmnIfCfg HTTP/1.1\r\nCac"..., 2048, 0) = 630
6717 2014-03-12-19:55:49:open("/proc/net/dev", O_RDONLY) = 15
6718 2014-03-12-19:55:49:ioctl(15, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbe87d164) = -1 ENOTTY (Inappropriate ioctl for device)
6719 2014-03-12-19:55:49:read(15, "Inter-| Receive "..., 4096) = 1963
6720 2014-03-12-19:55:49:close(15) = 0
6721 2014-03-12-19:55:49:open("/sys/class/net/pppoe-wan/speed", O_RDONLY) = 15
6722 2014-03-12-19:55:49:ioctl(15, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbe87d164) = -1 ENOTTY (Inappropriate ioctl for device)
6723 2014-03-12-19:55:49:read(15, 0x24348, 4096) = -1 EINVAL (Invalid argument)
6724 2014-03-12-19:55:49:close(15) = 0
6725 2014-03-12-19:55:49:send(14, "HTTP/1.1 200 OK\r\nContent-Type: t"..., 516, 0) = 516
6726 2014-03-12-19:55:49:close(14) = 0
6727 2014-03-12-19:55:49:gettimeofday({1394625350, 774532}, NULL) = 0
6728 2014-03-12-19:55:50:select(17, [3 5 6 12 13], [], NULL, {6, 244475}) = 1 (in [3], left {5, 240542})
6729 2014-03-12-19:55:50:gettimeofday({1394625351, 778953}, NULL) = 0
6730 2014-03-12-19:55:50:accept(3, {sa_family=AF_INET6, sin6_port=htons(53682), inet_pton(AF_INET6, "::ffff:192.168.31.242", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 14
6731 2014-03-12-19:55:50:fcntl64(14, F_GETFL) = 0x2 (flags O_RDWR)
6732 2014-03-12-19:55:50:fcntl64(14, F_SETFL, O_RDWR|O_NONBLOCK) = 0
6733 2014-03-12-19:55:50:gettimeofday({1394625351, 779495}, NULL) = 0
6734 2014-03-12-19:55:50:select(17, [3 5 6 12 13 14], [], NULL, {5, 239512}) = 1 (in [14], left {5, 239499})
6735 2014-03-12-19:55:50:gettimeofday({1394625351, 779790}, NULL) = 0
6736 2014-03-12-19:55:50:recv(14, "POST /ctl/CmnIfCfg HTTP/1.1\r\nCac"..., 2048, 0) = 622
6737 2014-03-12-19:55:50:open("/proc/net/dev", O_RDONLY) = 15
6738 2014-03-12-19:55:50:ioctl(15, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbe87d164) = -1 ENOTTY (Inappropriate ioctl for device)
6739 2014-03-12-19:55:50:read(15, "Inter-| Receive "..., 4096) = 1963
6740 2014-03-12-19:55:50:close(15) = 0
6741 2014-03-12-19:55:50:open("/sys/class/net/pppoe-wan/speed", O_RDONLY) = 15
6742 2014-03-12-19:55:50:ioctl(15, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbe87d164) = -1 ENOTTY (Inappropriate ioctl for device)
6743 2014-03-12-19:55:50:read(15, 0x24348, 4096) = -1 EINVAL (Invalid argument)
6744 2014-03-12-19:55:50:close(15) = 0
6745 2014-03-12-19:55:50:send(14, "HTTP/1.1 200 OK\r\nContent-Type: t"..., 499, 0) = 499
6746 2014-03-12-19:55:50:close(14) = 0
6747 2014-03-12-19:55:50:gettimeofday({1394625351, 781863}, NULL) = 0
6748 2014-03-12-19:55:50:select(17, [3 5 6 12 13], [], NULL, {5, 237144}) = 1 (in [3], left {5, 235403})
6749 2014-03-12-19:55:50:gettimeofday({1394625351, 784003}, NULL) = 0
6750 2014-03-12-19:55:50:accept(3, {sa_family=AF_INET6, sin6_port=htons(53683), inet_pton(AF_INET6, "::ffff:192.168.31.242", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 14
6751 2014-03-12-19:55:50:fcntl64(14, F_GETFL) = 0x2 (flags O_RDWR)
6752 2014-03-12-19:55:50:fcntl64(14, F_SETFL, O_RDWR|O_NONBLOCK) = 0
6753 2014-03-12-19:55:50:gettimeofday({1394625351, 784494}, NULL) = 0
6754 2014-03-12-19:55:50:select(17, [3 5 6 12 13 14], [], NULL, {5, 234513}) = 1 (in [14], left {5, 234501})
6755 2014-03-12-19:55:50:gettimeofday({1394625351, 784767}, NULL) = 0
6756 2014-03-12-19:55:50:recv(14, "POST /ctl/CmnIfCfg HTTP/1.1\r\nCac"..., 2048, 0) = 630
6757 2014-03-12-19:55:50:open("/proc/net/dev", O_RDONLY) = 15
6758 2014-03-12-19:55:50:ioctl(15, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbe87d164) = -1 ENOTTY (Inappropriate ioctl for device)
6759 2014-03-12-19:55:50:read(15, "Inter-| Receive "..., 4096) = 1963
6760 2014-03-12-19:55:50:close(15) = 0
6761 2014-03-12-19:55:50:open("/sys/class/net/pppoe-wan/speed", O_RDONLY) = 15
6762 2014-03-12-19:55:50:ioctl(15, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbe87d164) = -1 ENOTTY (Inappropriate ioctl for device)
6763 2014-03-12-19:55:50:read(15, 0x24348, 4096) = -1 EINVAL (Invalid argument)

No convenient way to find out the internal IP of the local machine

In order to properly forward ports, you need the internal IP of the machine you want to forward to. A lot of people seem to use gethostname() and then gethostbyname() to find it. This will break horribly as soon as there is more than one network interface, and may even just resolve to localhost (on my machine, that resolves to an IP which points to one of my ISP's servers, blech).

A better way perhaps would be to use the result of getsockname() on the socket used to connect to the router to find out the IP, however, this is slightly inconvenient to do and easy to mess up since it requires the client to use the socket interface. It would be nice if miniupnpc could do this for you.

miniupnpc: Explicitly export symbols via LIBSPEC for GCC/Clang compilers

OS X 10.9.2
Compiler: Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)

Currently, the miniupnpc build will fail on OS X when using the Clang compiler from Apple LLVM, if the fvisibility=hidden flag is passed to the compiler (through e.g. CFLAGS). The linker fails to resolve the now hidden symbols from libminiupnpc.dylib, as when building the upnpc-shared tool. declspec.h exports symbols for win32 builds, but not yet GCC/Clang.

A solution which is often used in libraries and fixes the above error, is something like this:

--- declspec.h
+++ declspec.h
@@ -9,5 +9,9 @@
     #endif
 #else
-    #define LIBSPEC
+    #if defined(__GNUC__) && __GNUC__ >= 4
+        #define LIBSPEC __attribute__ ((visibility ("default")))
+    #else
+        #define LIBSPEC
+    #endif
 #endif

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.