123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- /* $Id: portlistingparse.c,v 1.9 2015/07/15 12:41:13 nanard Exp $ */
- /* MiniUPnP project
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2011-2016 Thomas Bernard
- * This software is subject to the conditions detailed
- * in the LICENCE file provided within the distribution */
- #include <string.h>
- #include <stdlib.h>
- #ifdef DEBUG
- #include <stdio.h>
- #endif /* DEBUG */
- #include "portlistingparse.h"
- #include "minixml.h"
- /* list of the elements */
- static const struct {
- const portMappingElt code;
- const char * const str;
- } elements[] = {
- { PortMappingEntry, "PortMappingEntry"},
- { NewRemoteHost, "NewRemoteHost"},
- { NewExternalPort, "NewExternalPort"},
- { NewProtocol, "NewProtocol"},
- { NewInternalPort, "NewInternalPort"},
- { NewInternalClient, "NewInternalClient"},
- { NewEnabled, "NewEnabled"},
- { NewDescription, "NewDescription"},
- { NewLeaseTime, "NewLeaseTime"},
- { PortMappingEltNone, NULL}
- };
- /* Helper function */
- static UNSIGNED_INTEGER
- atoui(const char * p, int l)
- {
- UNSIGNED_INTEGER r = 0;
- while(l > 0 && *p)
- {
- if(*p >= '0' && *p <= '9')
- r = r*10 + (*p - '0');
- else
- break;
- p++;
- l--;
- }
- return r;
- }
- /* Start element handler */
- static void
- startelt(void * d, const char * name, int l)
- {
- int i;
- struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
- pdata->curelt = PortMappingEltNone;
- for(i = 0; elements[i].str; i++)
- {
- if(strlen(elements[i].str) == (size_t)l && memcmp(name, elements[i].str, l) == 0)
- {
- pdata->curelt = elements[i].code;
- break;
- }
- }
- if(pdata->curelt == PortMappingEntry)
- {
- struct PortMapping * pm;
- pm = calloc(1, sizeof(struct PortMapping));
- if(pm == NULL)
- {
- /* malloc error */
- #ifdef DEBUG
- fprintf(stderr, "%s: error allocating memory",
- "startelt");
- #endif /* DEBUG */
- return;
- }
- pm->l_next = pdata->l_head; /* insert in list */
- pdata->l_head = pm;
- }
- }
- /* End element handler */
- static void
- endelt(void * d, const char * name, int l)
- {
- struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
- (void)name;
- (void)l;
- pdata->curelt = PortMappingEltNone;
- }
- /* Data handler */
- static void
- data(void * d, const char * data, int l)
- {
- struct PortMapping * pm;
- struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
- pm = pdata->l_head;
- if(!pm)
- return;
- if(l > 63)
- l = 63;
- switch(pdata->curelt)
- {
- case NewRemoteHost:
- memcpy(pm->remoteHost, data, l);
- pm->remoteHost[l] = '\0';
- break;
- case NewExternalPort:
- pm->externalPort = (unsigned short)atoui(data, l);
- break;
- case NewProtocol:
- if(l > 3)
- l = 3;
- memcpy(pm->protocol, data, l);
- pm->protocol[l] = '\0';
- break;
- case NewInternalPort:
- pm->internalPort = (unsigned short)atoui(data, l);
- break;
- case NewInternalClient:
- memcpy(pm->internalClient, data, l);
- pm->internalClient[l] = '\0';
- break;
- case NewEnabled:
- pm->enabled = (unsigned char)atoui(data, l);
- break;
- case NewDescription:
- memcpy(pm->description, data, l);
- pm->description[l] = '\0';
- break;
- case NewLeaseTime:
- pm->leaseTime = atoui(data, l);
- break;
- default:
- break;
- }
- }
- /* Parse the PortMappingList XML document for IGD version 2
- */
- void
- ParsePortListing(const char * buffer, int bufsize,
- struct PortMappingParserData * pdata)
- {
- struct xmlparser parser;
- memset(pdata, 0, sizeof(struct PortMappingParserData));
- /* init xmlparser */
- parser.xmlstart = buffer;
- parser.xmlsize = bufsize;
- parser.data = pdata;
- parser.starteltfunc = startelt;
- parser.endeltfunc = endelt;
- parser.datafunc = data;
- parser.attfunc = 0;
- parsexml(&parser);
- }
- void
- FreePortListing(struct PortMappingParserData * pdata)
- {
- struct PortMapping * pm;
- while((pm = pdata->l_head) != NULL)
- {
- /* remove from list */
- pdata->l_head = pm->l_next;
- free(pm);
- }
- }
|