Annotation of embedaddon/miniupnpc/src/portlistingparse.c, revision 1.1.1.1
1.1 misho 1: /* $Id: portlistingparse.c,v 1.11 2020/03/22 22:43:44 nanard Exp $ */
2: /* MiniUPnP project
3: * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4: * (c) 2011-2020 Thomas Bernard
5: * This software is subject to the conditions detailed
6: * in the LICENCE file provided within the distribution */
7: #include <string.h>
8: #include <stdlib.h>
9: #ifdef DEBUG
10: #include <stdio.h>
11: #endif /* DEBUG */
12: #include "portlistingparse.h"
13: #include "minixml.h"
14:
15: #if defined(__HAIKU__)
16: /* rename our private function because Haiku already defines a atoui() function */
17: #define atoui atoui2
18: #endif
19:
20: /* list of the elements */
21: static const struct {
22: const portMappingElt code;
23: const char * const str;
24: } elements[] = {
25: { PortMappingEntry, "PortMappingEntry"},
26: { NewRemoteHost, "NewRemoteHost"},
27: { NewExternalPort, "NewExternalPort"},
28: { NewProtocol, "NewProtocol"},
29: { NewInternalPort, "NewInternalPort"},
30: { NewInternalClient, "NewInternalClient"},
31: { NewEnabled, "NewEnabled"},
32: { NewDescription, "NewDescription"},
33: { NewLeaseTime, "NewLeaseTime"},
34: { PortMappingEltNone, NULL}
35: };
36:
37: /* Helper function */
38: static UNSIGNED_INTEGER
39: atoui(const char * p, int l)
40: {
41: UNSIGNED_INTEGER r = 0;
42: while(l > 0 && *p)
43: {
44: if(*p >= '0' && *p <= '9')
45: r = r*10 + (*p - '0');
46: else
47: break;
48: p++;
49: l--;
50: }
51: return r;
52: }
53:
54: /* Start element handler */
55: static void
56: startelt(void * d, const char * name, int l)
57: {
58: int i;
59: struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
60: pdata->curelt = PortMappingEltNone;
61: for(i = 0; elements[i].str; i++)
62: {
63: if(strlen(elements[i].str) == (size_t)l && memcmp(name, elements[i].str, l) == 0)
64: {
65: pdata->curelt = elements[i].code;
66: break;
67: }
68: }
69: if(pdata->curelt == PortMappingEntry)
70: {
71: struct PortMapping * pm;
72: pm = calloc(1, sizeof(struct PortMapping));
73: if(pm == NULL)
74: {
75: /* malloc error */
76: #ifdef DEBUG
77: fprintf(stderr, "%s: error allocating memory",
78: "startelt");
79: #endif /* DEBUG */
80: return;
81: }
82: pm->l_next = pdata->l_head; /* insert in list */
83: pdata->l_head = pm;
84: }
85: }
86:
87: /* End element handler */
88: static void
89: endelt(void * d, const char * name, int l)
90: {
91: struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
92: (void)name;
93: (void)l;
94: pdata->curelt = PortMappingEltNone;
95: }
96:
97: /* Data handler */
98: static void
99: data(void * d, const char * data, int l)
100: {
101: struct PortMapping * pm;
102: struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
103: pm = pdata->l_head;
104: if(!pm)
105: return;
106: if(l > 63)
107: l = 63;
108: switch(pdata->curelt)
109: {
110: case NewRemoteHost:
111: memcpy(pm->remoteHost, data, l);
112: pm->remoteHost[l] = '\0';
113: break;
114: case NewExternalPort:
115: pm->externalPort = (unsigned short)atoui(data, l);
116: break;
117: case NewProtocol:
118: if(l > 3)
119: l = 3;
120: memcpy(pm->protocol, data, l);
121: pm->protocol[l] = '\0';
122: break;
123: case NewInternalPort:
124: pm->internalPort = (unsigned short)atoui(data, l);
125: break;
126: case NewInternalClient:
127: memcpy(pm->internalClient, data, l);
128: pm->internalClient[l] = '\0';
129: break;
130: case NewEnabled:
131: pm->enabled = (unsigned char)atoui(data, l);
132: break;
133: case NewDescription:
134: memcpy(pm->description, data, l);
135: pm->description[l] = '\0';
136: break;
137: case NewLeaseTime:
138: pm->leaseTime = atoui(data, l);
139: break;
140: default:
141: break;
142: }
143: }
144:
145:
146: /* Parse the PortMappingList XML document for IGD version 2
147: */
148: void
149: ParsePortListing(const char * buffer, int bufsize,
150: struct PortMappingParserData * pdata)
151: {
152: struct xmlparser parser;
153:
154: memset(pdata, 0, sizeof(struct PortMappingParserData));
155: /* init xmlparser */
156: parser.xmlstart = buffer;
157: parser.xmlsize = bufsize;
158: parser.data = pdata;
159: parser.starteltfunc = startelt;
160: parser.endeltfunc = endelt;
161: parser.datafunc = data;
162: parser.attfunc = 0;
163: parsexml(&parser);
164: }
165:
166: void
167: FreePortListing(struct PortMappingParserData * pdata)
168: {
169: struct PortMapping * pm;
170: while((pm = pdata->l_head) != NULL)
171: {
172: /* remove from list */
173: pdata->l_head = pm->l_next;
174: free(pm);
175: }
176: }
177:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>