1 /* $Id: portlistingparse.c,v 1.6 2012/05/29 10:26:51 nanard Exp $ */
3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4 * (c) 2011 Thomas Bernard
5 * This software is subject to the conditions detailed
6 * in the LICENCE file provided within the distribution */
9 #include "portlistingparse.h"
12 /* list of the elements */
14 const portMappingElt code
;
15 const char * const str
;
17 { PortMappingEntry
, "PortMappingEntry"},
18 { NewRemoteHost
, "NewRemoteHost"},
19 { NewExternalPort
, "NewExternalPort"},
20 { NewProtocol
, "NewProtocol"},
21 { NewInternalPort
, "NewInternalPort"},
22 { NewInternalClient
, "NewInternalClient"},
23 { NewEnabled
, "NewEnabled"},
24 { NewDescription
, "NewDescription"},
25 { NewLeaseTime
, "NewLeaseTime"},
26 { PortMappingEltNone
, NULL
}
30 static UNSIGNED_INTEGER
31 atoui(const char * p
, int l
)
33 UNSIGNED_INTEGER r
= 0;
36 if(*p
>= '0' && *p
<= '9')
37 r
= r
*10 + (*p
- '0');
46 /* Start element handler */
48 startelt(void * d
, const char * name
, int l
)
51 struct PortMappingParserData
* pdata
= (struct PortMappingParserData
*)d
;
52 pdata
->curelt
= PortMappingEltNone
;
53 for(i
= 0; elements
[i
].str
; i
++)
55 if(memcmp(name
, elements
[i
].str
, l
) == 0)
57 pdata
->curelt
= elements
[i
].code
;
61 if(pdata
->curelt
== PortMappingEntry
)
63 struct PortMapping
* pm
;
64 pm
= calloc(1, sizeof(struct PortMapping
));
65 LIST_INSERT_HEAD( &(pdata
->head
), pm
, entries
);
69 /* End element handler */
71 endelt(void * d
, const char * name
, int l
)
73 struct PortMappingParserData
* pdata
= (struct PortMappingParserData
*)d
;
76 pdata
->curelt
= PortMappingEltNone
;
81 data(void * d
, const char * data
, int l
)
83 struct PortMapping
* pm
;
84 struct PortMappingParserData
* pdata
= (struct PortMappingParserData
*)d
;
85 pm
= pdata
->head
.lh_first
;
93 memcpy(pm
->remoteHost
, data
, l
);
94 pm
->remoteHost
[l
] = '\0';
97 pm
->externalPort
= (unsigned short)atoui(data
, l
);
102 memcpy(pm
->protocol
, data
, l
);
103 pm
->protocol
[l
] = '\0';
105 case NewInternalPort
:
106 pm
->internalPort
= (unsigned short)atoui(data
, l
);
108 case NewInternalClient
:
109 memcpy(pm
->internalClient
, data
, l
);
110 pm
->internalClient
[l
] = '\0';
113 pm
->enabled
= (unsigned char)atoui(data
, l
);
116 memcpy(pm
->description
, data
, l
);
117 pm
->description
[l
] = '\0';
120 pm
->leaseTime
= atoui(data
, l
);
128 /* Parse the PortMappingList XML document for IGD version 2
131 ParsePortListing(const char * buffer
, int bufsize
,
132 struct PortMappingParserData
* pdata
)
134 struct xmlparser parser
;
136 memset(pdata
, 0, sizeof(struct PortMappingParserData
));
137 LIST_INIT(&(pdata
->head
));
139 parser
.xmlstart
= buffer
;
140 parser
.xmlsize
= bufsize
;
142 parser
.starteltfunc
= startelt
;
143 parser
.endeltfunc
= endelt
;
144 parser
.datafunc
= data
;
150 FreePortListing(struct PortMappingParserData
* pdata
)
152 struct PortMapping
* pm
;
153 while((pm
= pdata
->head
.lh_first
) != NULL
)
155 LIST_REMOVE(pm
, entries
);