Implementing UPnP Nat Traversal

When creating a end-user network application, a number of problems arise such as, for instance, connectivity through firewalls and/or routers. Luckily, there is a number of standards and/or Windows API that deal with these problems, and the only thing we have to do to ensure a state-of-art support of networking technologies is to implement standards or stubs for API.

For instance, in order to make a network-aware application available through an IGD (Internet Gateway Device), The UPnP forum defines a standard for configuring IGD using UPnP: this is called NAT Traversal (where NAT stands for Network Address Translation). Microsoft exposes an API that implement NAT Traversal. The scope of this post is to use it in C#.

The NAT Traversal API is a COM Type Library. The first step is to add a stub for this component:

  • First, add a reference to the CustomMarshalers assembly (in the Solution Explorer, right-click on the project's References node, Add References..., .NET tab),
  • Then, create a file containing the following COM Interop code:
Code Copy HideScrollFull
using System.Collections;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.CustomMarshalers;

namespace NatTraversal.Interop {
[ComImport, Guid("624BD588-9060-4109-B0B0-1ADBBCAC32DF"), TypeLibType(4160)]
internal interface INATEventManager {
[DispId(1)]
object ExternalIPAddressCallback { [param: In, MarshalAs(UnmanagedType.IUnknown)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(1)] set; }
[DispId(2)]
object NumberOfEntriesCallback { [param: In, MarshalAs(UnmanagedType.IUnknown)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(2)] set; }
}

[ComImport, TypeLibType(4160), Guid("6F10711F-729B-41E5-93B8-F21D0F818DF1")]
internal interface IStaticPortMapping {
[DispId(1)]
string ExternalIPAddress { [return: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(1)] get; }
[DispId(2)]
int ExternalPort { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(2)] get; }
[DispId(3)]
int InternalPort { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(3)] get; }
[DispId(4)]
string Protocol { [return: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(4)] get; }
[DispId(5)]
string InternalClient { [return: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(5)] get; }
[DispId(6)]
bool Enabled { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(6)] get; }
[DispId(7)]
string Description { [return: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(7)] get; }
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(8)]
void EditInternalClient([In, MarshalAs(UnmanagedType.BStr)] string bstrInternalClient);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(9)]
void Enable([In] bool vb);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(10)]
void EditDescription([In, MarshalAs(UnmanagedType.BStr)] string bstrDescription);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(11)]
void EditInternalPort([In] int lInternalPort);
}

[ComImport, Guid("CD1F3E77-66D6-4664-82C7-36DBB641D0F1"), TypeLibType(4160)]
internal interface IStaticPortMappingCollection /*: IEnumerable*/ {
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(EnumeratorToEnumVariantMarshaler))]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(-4), TypeLibFunc(0x41)]
IEnumerator GetEnumerator();
[DispId(0)]
IStaticPortMapping this[int lExternalPort, string bstrProtocol] { [return: MarshalAs(UnmanagedType.Interface)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0)] get; }
[DispId(1)]
int Count { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(1)] get; }
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(2)]
void Remove([In] int lExternalPort, [In, MarshalAs(UnmanagedType.BStr)] string bstrProtocol);
[return: MarshalAs(UnmanagedType.Interface)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(3)]
IStaticPortMapping Add([In] int lExternalPort, [In, MarshalAs(UnmanagedType.BStr)] string bstrProtocol, [In] int lInternalPort, [In, MarshalAs(UnmanagedType.BStr)] string bstrInternalClient, [In] bool bEnabled, [In, MarshalAs(UnmanagedType.BStr)] string bstrDescription);
}

[ComImport, Guid("B171C812-CC76-485A-94D8-B6B3A2794E99"), TypeLibType(4160)]
internal interface IUPnPNAT {
[DispId(1)]
IStaticPortMappingCollection StaticPortMappingCollection { [return: MarshalAs(UnmanagedType.Interface)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(1)] get; }
[DispId(2)]
object /*IDynamicPortMappingCollection*/ DynamicPortMappingCollection { [return: MarshalAs(UnmanagedType.Interface)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(2)] get; }
[DispId(3)]
INATEventManager NATEventManager { [return: MarshalAs(UnmanagedType.Interface)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(3)] get; }
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("9C416740-A34E-446F-BA06-ABD04C3149AE")]
internal interface INATExternalIPAddressCallback {
void NewExternalIPAddress([MarshalAs(UnmanagedType.BStr)]string newExternalIPAddress);
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("C83A0A74-91EE-41B6-B67A-67E0F00BBD78")]
internal interface INATNumberOfEntriesCallback {
void NewNumberOfEntries(int newNumberOfEntries);
}

[ComImport, Guid("B171C812-CC76-485A-94D8-B6B3A2794E99"), CoClass(typeof(UPnPNATCreator))]
internal interface UPnPNAT : IUPnPNAT {}

[ComImport, TypeLibType(2), Guid("AE1E00AA-3FD5-403C-8A27-2BBDC30CD0E1"), ClassInterface(ClassInterfaceType.None)]
internal class UPnPNATCreator {}
}
. . .

According to the documentation, the IUPnPNAT.DynamicPortMappingCollection property is not implemented: I removed the definition of IDynamicPortMappingCollection and replaced it with a simple object in the interface definition.

Now we can work with the API. First, create a simple object that will represents the UPnP-compatible IGD, if present. The object initializer will create the COM object and check for availability of the StaticPortMappingCollection property:

Code Copy HideScrollFull
#region References

using System;
using System.Collections;
using System.Net;
using NatTraversal.Interop;

#endregion

namespace
NatTraversal {
public class UPnPNat {
#region Fields
private UPnPNAT uPnpNat;
#endregion

#region
Instance Management

public UPnPNat() {
try {
UPnPNAT nat = new UPnPNAT();
if (nat.NATEventManager != null && nat.StaticPortMappingCollection != null)
uPnpNat = nat;
}
catch { }

// No configurable UPNP NAT is available.
if (uPnpNat == null)
throw new NotSupportedException();
}

#endregion
}
}
. . .

In order to enumerate port mappings, we have to represent each mapping by a single object instead of a set of variables : the PortMappingInfo class is a helper that contains all the settings of a port mapping :

Code Copy HideScrollFull
#region References

using System.Net;

#endregion

namespace
NatTraversal {
public class PortMappingInfo {
#region Fields

private bool enabled;
private string description;
private string internalHostName;
private int internalPort;
private IPAddress externalIPAddress;
private int externalPort;
private string protocol;

#endregion

#region
Instance Management

public PortMappingInfo(
string description,
string protocol,
string internalHostName,
int internalPort,
IPAddress externalIPAddress,
int externalPort,
bool enabled){

// Initializes fields
this.enabled = enabled;
this.description = description;
this.internalHostName = internalHostName;
this.internalPort = internalPort;
this.externalIPAddress = externalIPAddress;
this.externalPort = externalPort;
this.protocol = protocol;
}

#endregion

#region
Properties

public string InternalHostName {
get {
return internalHostName;
}
}

public int InternalPort {
get {
return internalPort;
}
}

public IPAddress ExternalIPAddress {
get {
return externalIPAddress;
}
}

public int ExternalPort {
get {
return externalPort;
}
}

public string Protocol {
get {
return protocol;
}
}

public bool Enabled {
get {
return enabled;
}
}

public string Description {
get {
return description;
}
}

#endregion
}
}
. . .

Now, we can enumerate the existing port mappings. Since the StaticPortMappingCollection is an enumerator we should use the foreach statement, but unfortunately it does not work and throw an exception. That's why we enumerate the items using IEnumerator.MoveNext:

Code Copy HideScrollFull
public PortMappingInfo[] PortMappings {
get {
// Builds port mappings list
ArrayList portMappings = new ArrayList();

// Enumerates the ports without using the foreach statement (causes the interop to fail).
int count = uPnpNat.StaticPortMappingCollection.Count;
IEnumerator enumerator = uPnpNat.StaticPortMappingCollection.GetEnumerator();
enumerator.Reset();

for (int i = 0; i <= count; i++) {
IStaticPortMapping mapping = null;
try {
if (enumerator.MoveNext())
mapping = (IStaticPortMapping)enumerator.Current;
}
catch { }

if (mapping != null) {
portMappings.Add(new PortMappingInfo(
mapping.Description,
mapping.Protocol.ToUpper(),
mapping.InternalClient,
mapping.InternalPort,
IPAddress.Parse(mapping.ExternalIPAddress),
mapping.ExternalPort,
mapping.Enabled));
}
}

// Now copies the ArrayList to an array of PortMappingInfo.
PortMappingInfo[] portMappingInfos = new PortMappingInfo[portMappings.Count];
portMappings.CopyTo(portMappingInfos);

return portMappingInfos;
}
}
. . .

Invoking this property is done this way:

Code Copy
UPnPNat nat = new UPnPNat();

foreach (PortMappingInfo info in nat.PortMappings)
Console.WriteLine("{0} : {1} -> {2}:{3} ({4})", info.Description, info.ExternalPort, info.InternalHostName, info.InternalPort, info.Protocol);

In order to use UPnP to configure the IGD, we have to implement stubs for adding and removing port mappings :

Code Copy
public void AddPortMapping(PortMappingInfo portMapping) {
uPnpNat.StaticPortMappingCollection.Add(portMapping.ExternalPort, portMapping.Protocol, portMapping.InternalPort, portMapping.InternalHostName, portMapping.Enabled, portMapping.Description);
}

public void RemovePortMapping(PortMappingInfo portMapping) {
uPnpNat.StaticPortMappingCollection.Remove(portMapping.ExternalPort, portMapping.Protocol);
}

Now, last but not least, you have to configure both your IGD and Windows box to use UPnP !

posted on Thursday, March 31, 2005 10:29 AM

Feedback

# re: Implementing UPnP Nat Traversal 9/6/2005 8:46 AM ShadowDrakken

How would this be done in VB.NET?

# re: Implementing UPnP Nat Traversal 2/25/2006 1:10 AM Krys

Is there a way to develop a "UPnP & IGD" installation, automatically !

I m currenctly trying to install UPnP... without Succes !!! It is to become crazy :-(

cdemez2@hotmail.com

# re: Implementing UPnP Nat Traversal 4/30/2006 1:24 AM Gene Jones

Is there a way to get the external IP of the IGD when there are no PortMapping(s) to read the ExternalIPAddress property of?

# re: Implementing UPnP Nat Traversal 5/13/2006 1:59 AM Stephen

I would also like to gain the external IP address. I would also love to know how to connect to a specific computer on a network using ip addresses and sockets.
For example say I have a client that wishes to connect up to a server app on a computer located on a network behind a router.
Let me know if you can here

omecron87@hotmail.com

# re: Implementing UPnP Nat Traversal 5/21/2006 11:23 PM Stephen

To get an external ip address you could use the shortcut--->


//**Getting the public ip address via a website***

System.Net.WebClient myWebClient = new System.Net.WebClient();
System.IO.Stream myStream = myWebClient.OpenRead("http://www.twistedchat.com/css/myip.cfm");
System.IO.StreamReader myStreamReader = new System.IO.StreamReader(myStream);
return myStreamReader.ReadToEnd();

//***********************************

Is there some way you can show people how to implement your code into their projects. For example how to use it and why. Thanks!!

Also come see www.twistedchat.com and give me some suggestions on making it better.

# re: Implementing UPnP Nat Traversal 5/22/2006 5:12 PM Buz

Hi all,

Thanks for your feedback. A long time have passed since I wrote this snippet, so I'm not sure I perfectly remember the underlying API...

I'll try to answer your question :

As Stephen notes, there is no way to get the external IP address of the IGD when no port mapping is configured.

There is a "INATExternalIPAddressCallback" interface that helps receiving notifications when the external IP address has changed, but it does not help having the address at startup...

Anyway, getting the external IP address from the IGD itself would not guarantee that you're getting the "real" public address. Here at work, we have a router configuration with two nat traversal; So the external IP address of the first router is only an address on the second router local network...

The best solution I've found is to get the IP address from a computer anywhere on the Internet. For instance, we at www.pixvillage.com are using our servers to determine the public IP addresses of our users.

This solution (the one Stephen finally used) is an elegant one, but the drawback is that you are dependant on the server availability.

Please note, Stephen, that you omit to dispose both the WebClient and StreamReader objects in your snippet.

# re: Implementing UPnP Nat Traversal 6/23/2006 4:59 PM Sumit

Can you please tell me what will be the class hierarchy of the codes that have been written.
Please mention the class names elaborately.
Contact me indianbill007@yahoo.co.in

# re: Implementing UPnP Nat Traversal 6/27/2006 10:16 AM Buz

Here is the class hierarchy :

The root namespace is NatTraversal : it contains the public classes, UPnPNat and PortMappingInfo

The interop types and classes (the first block of code above) are located in the NatTraversal.Interop namespace.

# re: Implementing UPnP Nat Traversal 6/29/2006 11:16 AM lapsy

I am kinda new to C# and I not able to find the implementation for the namespace NetTraversal.Interop. Can you please help me out
Thnx
Lapsy

# re: Implementing UPnP Nat Traversal 7/6/2006 3:43 PM Buz

The NatTraversal.Interop objects are given in the very first part of code :

Click the "Copy" link under the line "Then, create a file containing the following COM Interop code:", and it will be copied to your clipboard.

# re: Implementing UPnP Nat Traversal 7/9/2006 2:48 AM Robert

Thank you very much for the good article! I'm implementing a UPnP based control for changing enabled state for existing port mappings, on my router, via a ssl-reached form. However, after changing a few things back and forth I got the message :

"An exception of type 'System.Runtime.InteropServices.COMException' occurred in NatTraversal.UPnP.DLL but was not handled in user code

Additional information: The owner of the PerUser subscription is not logged on to the system specified (Exception from HRESULT: 0x80040210)"

The message is now shown every time I try to index the StaticPortMappingCollection. If I restart the web server I can access the StaticPortMappingCollection[21,"TCP"] once again, but on second attempt it gives me the same error message again. Is there any special release (dispose) I need to do, to avoid this?

Again, thank you very much for a very good article which has helped me quite a lot!

# re: Implementing UPnP Nat Traversal 7/10/2006 4:23 PM Buz

It seems to be an impersonation problem.

Did you try to modify the impersonation / authentication on your ASP.Net web application ?

The default user for ASP.Net applications may not have sufficient permissions for using the NatTraversal API

# re: Implementing UPnP Nat Traversal 7/14/2006 7:45 PM Robert

Well, that might have been the case, had it not been for the fact that it worked correctly a couple of times before that exception (and even now works the first attempt). I will try your tip at a later time, since I'm currently on vacation going to France. I don't think it will do the trick, but every possitility is worth an attempt.

# re: Implementing UPnP Nat Traversal 10/17/2006 4:52 PM Deepak Agarwal

hi. please provide the code for PortMappingInfo too..

# re: Implementing UPnP Nat Traversal 10/17/2006 4:56 PM Buz

The code is already provided in the third block of code (minimized by default, you just have to click the "scroll" or "full" radio button).

# re: Implementing UPnP Nat Traversal 10/17/2006 5:05 PM Deepak Agarwal

Nope. it is showing only three dots. and when i click on the radio buttons nothing is happening.
please guide me...

# re: Implementing UPnP Nat Traversal 10/17/2006 5:10 PM Buz

I suppose you're using Firefox... code snippets does not work under FF.

You can either use IE to display the page, or display the page source and search for the snippet inside.

Sorry for the inconvenience...

# re: Implementing UPnP Nat Traversal 10/17/2006 5:15 PM Deepak Agarawl

Thnx A Lot!! i was def using firefox :-). great work by the way on external ip as i couldnt find this anywhere on the web...

# re: Implementing UPnP Nat Traversal 10/17/2006 5:51 PM Deepak Agarwal

Actually i m new to c# , migrating from java to c#, just 1 week with the c#. please tell me how to use this as i want to bind my server with my external ip....

# re: Implementing UPnP Nat Traversal 10/18/2006 9:40 AM Deepak Agarawl

could u please do me a favor.. could you please zip the code in a zip with complete hirearchy and send to me ???

# re: Implementing UPnP Nat Traversal 10/18/2006 10:03 AM Deepak Agarwal

ok. i m on the rite path now i guess, but tell me how to setup IGD and Windows Box??

# re: Implementing UPnP Nat Traversal 10/18/2006 2:48 PM Deepak Agarawl

I have understood how the code work and implemented that but getting NotSupportedException...What to do..? i m on the LAN, which is connected to a switch and switch is connected to a ADSL modem ... Please guide me...

# re: Implementing UPnP Nat Traversal 10/18/2006 4:46 PM Buz

You have to enable uPnP both on Windows (start "SSDP Discovery Service" and "Universal Plug and Play Device Host Service") and on the IGD (depends on the IGD manufacturer and model; usually can enable uPnP using the IGD administration web tool).

Concerning your NotSupportedException, where does it happen ?

# re: Implementing UPnP Nat Traversal 10/18/2006 5:30 PM Deepak Agarwal

the exception is at this line :
if (uPnpNat == null)
throw new NotSupportedException();

actually i m using microsoft windows server 2003, and i dont have any router access, i just wrote one peer to peer program which is working fine on LAN, but not on internet as i cannt bind my server to the external IP... i heard that UPnP is not available in ms windows 2003, is taht true!!?











# re: Implementing UPnP Nat Traversal 10/18/2006 5:35 PM Deepak Agarwal

I m newbie on C#.
i just wrote this program.
http://rapidshare.de/files/37220472/PurePeerToPeer.rar.html

# re: Implementing UPnP Nat Traversal 10/18/2006 6:03 PM Buz

I tried your application and did not encounter any error (it successfully enumerates port mappings on the router).

Windows Server 2003 does not seem to have UPnP installed and, since you do not have access to you router, you have only few chances to make UPnP working with your infrastructure...

# re: Implementing UPnP Nat Traversal 11/16/2006 4:03 PM Philippe

Hello from France,

I've put the first block in a file called NatTraversal.Interop.cs
I've put the 2nd and 3rd block in a file called NatRaversal.cs

Where do I have to put the 4th, 5th, 6yh blocks of code : in my main form ?

Can you put a sample or email-me please ?
ordinoir at gmail.com

Thanks a lot. Best regards

# re: Implementing UPnP Nat Traversal 4/20/2007 3:27 PM Key

Hello

I am trying to follow your example.
But I get alway get into NotSupportedException.
I am using Microsoft Visual Studio 2005.
I created a project. In the project I have two namespaces, one called: NatTraversal.Interop and the other called: NatTraversal
In the first one I just added the first code (Interop)
and in the second one I added both classes: UPnPNat and PortMappingInfo.

But when I run it I I always get the exception.
I have a router with UPnP enable and also my win XP has the UPnP service enable. I used another application that shows all my UPnP devices available and it worked fine. But when I try to run this code I get the exception.
could you tell me what I could be ding wrong? or you could send me a running example to d_garcia_ch at hotmail.com.

Thanks for your time.

# re: Implementing UPnP Nat Traversal 7/9/2007 9:46 PM RobCube

Sweet piece of writing Buz. I noticed it didn't traverse through items with dual protocols set up, i.e. Both or TCP/UDP. Any way we can do this?

# re: Implementing UPnP Nat Traversal 7/20/2007 8:32 AM Flora

Hey:

I alway get into NotSupportedException..
is this because i run on windows vista??
is there a way i can go around about it?

You can add me to msn
lin_jialu@hotmail.com

cheers

# re: Implementing UPnP Nat Traversal 8/1/2008 10:47 AM Giuseppe

Hi Buz from Italy!

I have an issue with your code.
I alway get into NotSupportedException at this point:

if (uPnpNat == null)
throw new NotSupportedException();

I use Windows XP SP2 and uPnP is installed and enabled on service. But nat.NATEventManager and nat.StaticPortMappingCollection are NULL.

What is the problem in your opinion?
Thanks a lot in advance

# re: Implementing UPnP Nat Traversal 5/13/2009 11:29 PM eva

i'm sry to post such noob question but i success have this to work and its return all my forwarded port info.

but i miss something what is the code for add a port.
i mean
AddPortMapping(PortMappingInfo portMapping)
what kind of info i need put between () to open a port?

# re: Implementing UPnP Nat Traversal 10/13/2009 2:22 PM r4 nintendo

heya....how did you do that Code Copy Hide Scroll Full???? Do you have any specific control for it?

# imitation jewelry 10/19/2010 8:35 AM imitation jewelry

good

# bag 11/11/2011 7:28 AM Marc by Marc Jacobs Bags

As an influx of people, rather bare, better than the tasteless. <a href="http://www.marcjacobs-">http://www.marcjacobs-handbags.org/">Marc">http://www.marcjacobs-">http://www.marcjacobs-handbags.org/">Marc

Jacobs</a> designed the product, especially the main and sub-brand bag brand <a href="http://www.marcjacobs-">http://www.marcjacobs-

handbags.org/">Marc by Marc Jacobs Bags</a>, is a unique mix of taste. <a href="http://www.marcjacobs-">http://www.marcjacobs-

handbags.org/">Marc Jacobs Handbag</a> used almost mature female, are to be highly it. Young people's favorite

handbag comes <a href="http://www.marcjacobs-">http://www.marcjacobs-handbags.org/">Marc">http://www.marcjacobs-">http://www.marcjacobs-handbags.org/">Marc by Marc Jacobs Handbag</a>. As long as you are

stylish, with a focus on people, then you have to have them.

# calvin klein underwear 11/24/2011 6:16 AM calvin klein steel

The main function of underwear is more conducive to live and work. For men is to live in the root and eggs stretched, so as not to walk or do something random shaking, affecting work and life. For women, the menstrual period comes in an easy to absorbent pads good things, to avoid the outflow of blood affect the life and work. Then choose a suitable underwear becomes very important. <a href="http://www.underwear-sale.org">Calvin Klein Underwear</a> can help you do so. <a href="http://www.underwear-sale.org/womens-calvin-klein-c-48.html">calvin klein steel</a> and <a href="http://www.underwear-sale.org/mens-underwear-calvin-klein-underwear-c-42_46.html">calvin klein 365</a> series is especially good. We have <a href="http://www.underwear-sale.org">underwear sale</a>. In addition to these, this site also <a href="http://www.underwear-sale.org/aussiebum-retro-swimwear-c-44.html">aussieBum Swimwear</a> and so on. Welcome to win your favor. Thank you!

# louis vuitton sale 2/1/2012 3:33 AM louis vuitton sale

Bags of many different models, materials and colors at the
louis vuitton sale

outlet can be significant along with ample, nevertheless quite trendy, fantastic requirement.Here is a world of
louis vuitton outlet

where you can find all kinds of new style and fashion Louis Vuitton bags. We really want to lead the trend and let our customer in the pursuit of luxury and fashion, satisfied the needs of customers.

# coach factory outlet 2/1/2012 4:51 AM coach factory outlet

If you do not know design can be the most fashionable this fall, consider a glance on
coach factory outlet

! This summer, you have a wide range of options, because there are numerous designs, you can find from.
coach factory online

is actually a stylish Coach online store to sell perfect quality and discount Coach handbags, Coach bags, Coach wallets and Cheap Coach Purse.If you love Coach,you will like to get the best price on it.

# christian louboutin uk 2/1/2012 4:52 AM christian louboutin uk

If you have enough leisure time, you may go to the mall or go to the christian franchised store to have a good look at varieties of
christian louboutin uk

the diverse styles and rich colors of the purses with low cost will surely impress you a lot!You will always get surprised by the beautiful colors and perfect details of
christian louboutin

.So come on, do not hesitate.

# coach bags 2/1/2012 10:06 AM coach bags

coach bags

with fashion style and top quality succeed. In any occasions they are very suitable and appropriate for its precise and rich design.
coach outlet store

vision system is a visual enjoy, is a visual art. The particular design has been integrated function and the element of elegancy, then show you an exquisite and excellent product.

# chanel uk 2/2/2012 1:51 AM chanel uk

Swarovski's Crystal is due to their commitment to consistency, precision and quality standards, and to the automatic cutting machine invented by the founder,
chanel bags

enjoy high reputation all over the world. They are designed for hand, elbow and shoulder carry thanks to comfortable flat leather handles.
http://www.chanel-outlet.org.uk

# coach outlet online 2/2/2012 1:51 AM coach outlet online

Becoming a regular member of
coach outlet online

, you can even buy wholesale purses, handbags, leather wallets at preferential prices. Why not have a try?
coach factory outlet

is famous for the discounts it offers. Latest coach purses and sunglasses can be purchased at discounted rates from this coach outlet store.
http://www.coachoutletonlinecoachdays.com

# coach outlet 2/2/2012 1:51 AM coach outle

coach outlet

sells products which are excellent in quality and reasonable in price. All customers can easily pick up their favorite Coach briefcase, wallets, shoes, hats, scarf, jewelry and sunglasses.If you need to acquire the focus, you need to sustain the
coach outlet store online

, which with stylish components that will immediately concoct you appreciably more attracting and outstanding.
http://www.coachoutletcoachstore.com

# coach outlet online 2/2/2012 1:52 AM coach outlet online

Becoming a regular member of
coach outlet online

, you can even buy wholesale purses, handbags, leather wallets at preferential prices. Why not have a try?
coach factory outlet

is famous for the discounts it offers. Latest coach purses and sunglasses can be purchased at discounted rates from this coach outlet store.
http://www.coachoutletonlinecoachdays.com

# coach factory outlet 2/2/2012 2:34 AM coach factory outlet

That experts claim coach factory outlet shopping is in the changes they are available in, which can make it well suited for benefit from to be a'luggage'bag. There are different kinds of crossbody bags within marketplace nowadays. Even so it is not possible to beat the timeless design jointly with traditional elegance of the Bags at the coach factory outlet online.
http://www.coachfactoryoutletonlinedays.com

# louis vuitton uk 2/2/2012 2:35 AM louis vuitton uk

More and more people can afford louis vuitton uk, not to say they are on sale. Price is not equivalent with value,they own classical style, fine materials, elaborate technique. If you want to catch up to the latest vogue, having Louis Vuitton Handbags of the latest styles can absolutely satisfy you.Just visit LV outlet webpage and select the most suitable products for yourself.
http://www.louisvuitton-full.org.uk

# christian louboutin 2/2/2012 2:36 AM christian louboutin

This elegant and discreet pair of rhodium-plated button christian louboutin will add sparkle to your outfit. They are covered in clear crystal pave and reflect the light in magical ways. christian Madison Handbags and christian Poppy Bags are viewed among probably the most newsworthy among the particular christian louboutin uk so far.
http://www.christian-louboutinshoes.co.uk

# coach outlet online 2/2/2012 2:41 AM coach outlet online

If you buy Coach items at the
coach outlet online

store, the goods will be sent out within 24 hours after confirming your payment and arrive to your door within 7 work days.
coach outlet

can provide the coach exactly the same is expected in a retail store. It can help you find bags of various colors, shapes and designs, which prove once again that the coach is actually a selection for the housekeeper.
http://www.coachoutletonlinecell.com

# chanel uk 2/2/2012 2:53 AM chanel uk

chanel uk have own characteristic designs. The beautiful crystals have added the magical finishing touch to countless bridal gowns. Just get some for yourself. I hope that I have helped you realize the potential for a breathtaking theme on your wedding day.Incorporating chanel handbags and pearls into your decor is a very fun and easy way to create a classic and warm setting.

http://www.chanel-bags.org.uk

# coach outlet store 2/2/2012 2:53 AM coach outlet store

Coach Outlet Store sells goods that are constructed to meet the highest standards of quality and functionality.You can trust it 100 percent. Wholesale coach outlet are even provided for VIP members. Haven't got your own Coach yet? Why not come to coach outlet store online outlet.

http://www.coachoutletstoreonlinegood.com

# coach outlet online 2/2/2012 2:54 AM coach outlet online

I got to know it from my elder sister who owns enviable luxury Coach bags. Coach Outlet Online Store is established to be your home shopping paradise. Coach New Signature BackPack Black Beige is a useful backpack for outdoors activities. It's convenient that you can freely take along with for travel,climbing and go for school.In our coach outlet,there are many graceful styles of Coach backpack for you.

http://www.coachoutletonlinefull.com

# louis vuitton uk 2/2/2012 3:55 AM louis vuitton uk

This
louis vuitton uk

for sale belongs to the sounding just what are termed as Louis Vuitton vintage best sellers, many other products and services for the reason that range appearing companies.I am so confused that I don,t even know where to buy the
louis vuitton

Handbags. Because I can prefer to chose the fashionable design, favorable price, top service .
http://www.louis-vuittonukoutlets.org.uk

# louboutin uk 2/2/2012 4:13 AM louboutin uk

Come by for dinner soon and check out the wine list for yourself. We are always here to help with selection. Cheers for the successful of christian
louboutin uk

.The christian Signature Hobo is from the latest release of
christian louboutin uk

. Its crisp, scribble material, leather handle, perfectly complements the relaxed shape of this stylish pouch.
http://www.christianlouboutinuk-sale.co.uk

Title
 
Name
 
Url
Comments   
Protected by Clearscreen.SharpHIPEnter the code you see: