Results 1 to 28 of 28

Thread: [VB6] PortMapper - UPnP NAT Traversal Class

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Thumbs up [VB6] PortMapper - UPnP NAT Traversal Class

    Title

    PortMapper

    Description

    A VB6 class to allow a TCP/IP server to map ports through a UPnP NAT router without manual intervention and retrieve the router's external public IP address.

    Feature List

    Queries and returns the external public address of the router's public (Internet facing) interface. Can add and remove port mappings for TCP and UDP ports. Uses the Windows UPnP Control Point interface instead of the sometimes more problematic NATUPnP library.

    Packaged with a simple chat server and client to demonstrate basic use. PortMapper.cls contains comments documenting its properties, methods, and events.

    Author Name

    Bob Riemersma

    System Requirements

    Server OS:
    Windows XP or later. Must have SSDP components ("Network Discovery") enabled and the Windows Firewall or other software firewall must allow UPnP traffic through.
    NAT router:
    Must support some level of UPnP port mapping ("Virtual Servers" or "Forwarded Ports" defined via UPnP). UPnP must be enabled (may require reboot).

    License Info

    Unencumbered freeware. No guarantee of support. Use at your own risk. This software is offered AS IS.

    Testing

    PortMapper has been tested on Windows XP SP3, Vista SP2, and Windows 7 RC using a D-Link EBR-2310 wired router (Version B1 hardware, Version 2.01 firmware).


    Working With PortMapper

    Much more detail can be found by reading the comments in PortMapper.cls.

    To add PortMapper to your VB6 project copy PortMapper.cls and PortMapperCBs.cls from the SimpleServer folder to your project folder, then use Project|Add file... to add each of these two modules to your Project.

    To use the demo chat client and server compile each of the two programs, then run the server and click its Listen button, then run the client and fill in the server's external IP address and a "chat handle" name and click its Connect button.


    Be sure to scroll down for the latest version!
    Attached Files Attached Files
    Last edited by dilettante; Sep 8th, 2010 at 08:03 PM. Reason: Reposted attachment, added note re. Win7 testing

  2. #2

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Caution:

    The demo project now seems to be failing on XP SP3, even though it still works fine on Windows Vista (32-bit). I am looking for solutions.

    Update:

    Still no resolution on XP. Tested on Windows 7 Release Candidate and it works fine there though.
    Last edited by dilettante; Nov 22nd, 2009 at 11:42 AM.

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Good news:

    New version posted that seems to resolve the program crashes on XP SP3!


    Anyone who downloaded the previous version of the attachment might want to get the new copy. The new sources are marked as version 1.3 instead of the previous 1.2, if you want to check this.

  4. #4

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Interesting...

    I'm playing with trying to compile this under Windows XP SP3 and it fails. So far from what I see the upnp.dll in WinXP doesn't provide COM type information for some of the interfaces in this library. The symptom is that the program won't compile, with the compiler complaining about a "missing UDT" (the usual message when something is undefined).

    So at this point it looks like you have to compile under Vista or later.

    I'm looking into a workaround for this. These old OSs get harder to support every day!

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    New version 1.4 that by default uses the late-bound "VBScript" approach to get around the limitations of compiling under Windows XP.


    Version 1.3 must be compiled under Vista or later, but should run fine on any OS from XP forward.

    Version 1.4 by default can be compiled under XP or later, and should run on any OS from XP forward.

    Version 1.4 can be modified by changing two lines in PortMapperCBs.cls to compile the same way as Version 1.3 (using early binding). More details can be found in comments within PortMapperCBs.cls.


    Oops!

    Version 1.4 compiles but doesn't actually work properly on any OS. Right now compiling using 1.3 on Vista is the only absolutely known working configuration.
    Last edited by dilettante; Nov 23rd, 2009 at 01:38 PM. Reason: Removed 1.4

  6. #6

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Reposting a corrected 1.4 that handles early binding of the callback object correctly.

    Seems to compile on XP or later and run on XP or later. I hope this is it!
    Attached Files Attached Files

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    I have created a .TLB that extends the type information in the Win XP version of upnp.dll. It allows Version 1.3 to compile under XP if you add another reference (to the new UPnPExtXP.tlb) and make a one-line change to the Implements statement in PortMapperCBs.cls.

    If there is interest I can post it, but Version 1.4 may meet everyone's needs unless they want to make more use of upnp.dll's capabilities from VB6 when compiling under Windows XP.

  8. #8
    Junior Member Shadow-GK's Avatar
    Join Date
    Jul 2009
    Posts
    25

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    nice work

  9. #9
    New Member
    Join Date
    Feb 2010
    Posts
    1

    Exclamation Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Hi,
    Please help, I tested application but:

    Server:
    Checking for UPnP NAT router
    Found router, mapping port
    Port mapped
    Listening on port 8765

    Client:
    Connecting on port 8765
    Error 10061: Connection is forcefully rejected
    Closing connection

    If I use internal IP then I can connect to server.

    Any help would be so good.
    Cheers,
    Gabor

  10. #10
    Junior Member Shadow-GK's Avatar
    Join Date
    Jul 2009
    Posts
    25

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    You are probably using it from the same computer. You can't use external IP from the computer on which the server is running. You have to run the server on one computer, and client on the other.

    -Regards

  11. #11

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Quote Originally Posted by Shadow-GK View Post
    You are probably using it from the same computer. You can't use external IP from the computer on which the server is running. You have to run the server on one computer, and client on the other.
    Actually this works fine for me.

    The issues involved are probably:
    • Whether or not your router will turn connections addressed to its external port back into the private network.
    • Whether your PC's software firewall is allowing incoming connections on this port.

  12. #12
    Fanatic Member
    Join Date
    May 2005
    Posts
    528

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    I've been using this for a while now in a program I made on XP, and it works very well. But I've now moved to windows 7 and when I run it, I get: error: -2147220223 Automation error
    When I click debug it takes me to the sub: Private Sub PMCBs_DeviceAdded(ByVal Device As UPNPLib.IUPnPDevice)
    and highlights the line: For Each Service In .Services

    I've enabled network discovery, and the upnp service is running. So I don't know what this can be.

  13. #13

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    I just retested after recompiling the posted files and it is running fine on Windows 7 here.

    If you used the 1.4 version (the most recently posted above) I can only think of one possibility. Have you tried to deploy the upnp.dll from Windows XP? The version in Windows 7 is different and already part of Windows 7.

    However it sounds as if you are seeing this problem while testing within the IDE on Windows 7. Are you running the VB6 IDE elevated? If not this could be the problem. Ideally you are elevating the VB6.EXE IDE by using a manifest (and not simply using Run As Administrator or marking it to Run As Administrator via an application compatibility setting). This avoids a lot of registry virtualization issues. Be sure to test this elevated if you haven't though.


    It is possible that the version of upnp.dll in Windows 7 lacks type information the program requires. This would be similar to the problem encountered on Windows XP.

    I have not tried compiling this on a Windows 7 machine myself yet. But a version compiled under Vista seems to work on all three versions of Windows when I try it. I would expect the Windows 7 version of upnp.dll to be almost identical to the Vista version in terms of the type information provided.


    Until I get VB6 installed on a Windows 7 machine I'm not sure what else I can suggest. MSDN does not describe any changes in upnp.dll for Windows 7, but we're probably looking at a very fine point here.

  14. #14
    Fanatic Member
    Join Date
    May 2005
    Posts
    528

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    I was playing around with the portmappercbs module and I think I've fixed it.
    I uncommented the implements statement and set XPcompile to true, even though this is windows 7.
    I'll let you know if the error comes back.

  15. #15

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    That sounds odd. Are you by any chance using "XP Mode" to run VB6.EXE? If so, you aren't compiling on Windows 7 at all, so of course you'd have to fall back to the more limited XP approach to using upnp.dll. I really don't recommend using XP Mode for VB6.EXE. It severely handicaps your ability to do development for Windows-as-it-is and limits you to Windows-as-it-was.

    If you're running into this with VB6 fully installed in Windows 7 (not the XP VM) I'd like to know about it.


    I'm glad you found a solution though!

  16. #16
    Fanatic Member
    Join Date
    May 2005
    Posts
    528

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    No I'm not using vb6 in xp mode.
    But actually, now it has started to give me the same error on my xp machine. If I do the fix that I posted above, then it doesn't give me the error, but it says "No router, upnp disabled, or firewall blocking upnp" when I am definitely connected to the router and no firewall is blocking upnp. Although I can still communicate through two computers on the same network.
    EDIT: i have just tried downloading your original version from the first post and that still gives me the error. So it can't be anything that I've changed in the project.
    EDIT 2: I have now managed to fix the error. I recently changed the channel of my wireless router to 3 instead of 1 to improve the signal, I didn't think this would make any difference to the program, but obviously it did.
    So the program only works if the router is on channel 1. And I don't know why this would affect it at all. Is there any way that the program can be modified to work with the router on any channel?
    Last edited by killo; Sep 8th, 2010 at 04:13 AM.

  17. #17

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    The program doesn't know anything about wireless channels. Whether the router is wired or wireless makes no difference.

    Your error is &H80040501 "Event subscription timeout." It means your router has failed to reply to a UPnP query.

    The problem is at your router. Resetting/rebooting the router is the only known fix, assuming the router has UPnP enabled to begin with. Perhaps your efforts to hop channels caused a reset.


    Here: UPnP control point API unexpectedly subscribes to UPnP services, fails to find Xbox 360 & WMP 11 somebody else ran into the same thing. He complains about it being "not documented" however:

    IUPnPServices Interface
    When To Use

    Use this interface to enumerate the list of services associated with a device.

    Be aware that use of these properties cause the UPnP framework to contact the service across the network. If the service does not exist, the application is blocked until the connection request fails. It is recommended that applications use the Item property in most instances, and reserve the enumeration for instances when an application is starting up.
    This means the service requests can still fail, just that we might recode to trap them locally.

    By rewriting my code to use For X = 1 To .Services.Count and then .Services.Item(X) instead it would be easier to trap this error and produce some other result. But that "other result" can only be to raise another error or perhaps an error event. It doesn't cure anything.

    I suppose it could be friendlier though, and my code could raise Opened(False) which the main program could handle more easily.
    Last edited by dilettante; Sep 8th, 2010 at 07:59 PM.

  18. #18

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Ok, I hadn't realized that Device.Services was not a full-blown collection in the VB sense. It is more like collections returned by Shell32 methods: you can't use an index to access it, only the key value (string).

    The changes don't result in any "cure" for the problem described above. However the Opened event will be raised passing the value False to let the main program know that contact was not made with the UPnP router. That makes this a worthwhile if small improvement.
    Attached Files Attached Files

  19. #19

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Minor code cleanup. Should now catch cases that fail to find a UPnP router and raise Opened event with Success = False.
    Attached Files Attached Files

  20. #20
    New Member
    Join Date
    Dec 2010
    Posts
    1

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Hey nice job. Just a heads up. If using a port higher than 32767, the port sent to the router is invalid.
    I see you are using the CUint function. I have removed that function, and this resolved the issue. I don't know if this is just an XP issue (i wouldnt believe so).

    Thanks for the great work.

  21. #21

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Good catch, thanks!

    Yes, not only did CUInt() have a bug, it wasn't necessary because of the way a Variant is structured internally.

    Safest bet is to replace CUInt() by CLng() though, so that's what I did here.

    Slight overkill since the only places CUInt() was being used was on Long variables, but it helps me remember later what was going on. I just don't want to fall into a trap using:

    var = 123

    ... to replace

    var=CUInt(123)

    ... just to find that the VB compiler decided to put a Single into the Variant or something!


    I hope people who get confused using an earlier version drop back to find the fix.
    Attached Files Attached Files

  22. #22
    New Member
    Join Date
    Feb 2011
    Posts
    2

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Hello

    I can not understand one thing. If I import your class modules in my project everything works fine, but if I write the code by myself, or if I copy and paste your code, the method "IDispatchCallback"is never called.

    Thank you for your help.

    Sorry for my English, I hope I am clear

  23. #23

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    You may have missed this comment inside PortMapperCBs.cls:
    Code:
            'NOTE: Must be dispID = 0, i.e. the default method of the class.
    This means you must set IDispatchCallback as the default member of the Class. This is done via the Tools|Procedure attributes... dialog in the IDE.

    In that dialog select IDispatchCallback in the Name dropdown. Then click the Advanced >> button in that dialog, which will let you set Procedure ID to (default). Then click the Apply button.


    If this is unfamiliar to you it may be hazardous to edit these Classes and you might want to just use them as supplied. However Setting the Procedure Attributes may help understand this particular issue, and the article might also be available in your own language there as well.

  24. #24
    New Member
    Join Date
    Feb 2011
    Posts
    2

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Hello

    ok, thanks so much, it works !. Thank you for taking the time to detail how do, and also for the link. I know the visual basic, but not quite the IDE, I do a lot of vba excel and there are many features missing.


    i'm french, i just begun to learn the english, I hope I am sufficiently comprehensible.

  25. #25

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Your English is very good. My French is very limited grade school level and over 40 years old with little use, so I won't attempt any here!

  26. #26
    New Member
    Join Date
    Mar 2011
    Location
    FL
    Posts
    2

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    nice one!

  27. #27

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    This may be obsolete for most applications. I found an alternative: Easy UPnP NAT Traversal.

  28. #28
    Fanatic Member
    Join Date
    Jan 2015
    Posts
    596

    Re: [VB6] PortMapper - UPnP NAT Traversal Class

    Interesting also.
    To be investigated.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width