| 1 | /* $Id: igd_desc_parse.c,v 1.17 2015/09/15 13:30:04 nanard Exp $ */ |
| 2 | /* Project : miniupnp |
| 3 | * http://miniupnp.free.fr/ |
| 4 | * Author : Thomas Bernard |
| 5 | * Copyright (c) 2005-2015 Thomas Bernard |
| 6 | * This software is subject to the conditions detailed in the |
| 7 | * LICENCE file provided in this distribution. */ |
| 8 | |
| 9 | #include "igd_desc_parse.h" |
| 10 | #include <stdio.h> |
| 11 | #include <string.h> |
| 12 | |
| 13 | /* Start element handler : |
| 14 | * update nesting level counter and copy element name */ |
| 15 | void IGDstartelt(void * d, const char * name, int l) |
| 16 | { |
| 17 | struct IGDdatas * datas = (struct IGDdatas *)d; |
| 18 | if(l >= MINIUPNPC_URL_MAXSIZE) |
| 19 | l = MINIUPNPC_URL_MAXSIZE-1; |
| 20 | memcpy(datas->cureltname, name, l); |
| 21 | datas->cureltname[l] = '\0'; |
| 22 | datas->level++; |
| 23 | if( (l==7) && !memcmp(name, "service" , l) ) { |
| 24 | datas->tmp.controlurl[0] = '\0'; |
| 25 | datas->tmp.eventsuburl[0] = '\0'; |
| 26 | datas->tmp.scpdurl[0] = '\0'; |
| 27 | datas->tmp.servicetype[0] = '\0'; |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | #define COMPARE(str, cstr) (0==memcmp(str, cstr, sizeof(cstr) - 1)) |
| 32 | |
| 33 | /* End element handler : |
| 34 | * update nesting level counter and update parser state if |
| 35 | * service element is parsed */ |
| 36 | void IGDendelt(void * d, const char * name, int l) |
| 37 | { |
| 38 | struct IGDdatas * datas = (struct IGDdatas *)d; |
| 39 | datas->level--; |
| 40 | /*printf("endelt %2d %.*s\n", datas->level, l, name);*/ |
| 41 | if( (l==7) && !memcmp(name, "service" , l) ) |
| 42 | { |
| 43 | if(COMPARE(datas->tmp.servicetype, |
| 44 | "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:" )) { |
| 45 | memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service)); |
| 46 | } else if(COMPARE(datas->tmp.servicetype, |
| 47 | "urn:schemas-upnp-org:service:WANIPv6FirewallControl:" )) { |
| 48 | memcpy(&datas->IPv6FC, &datas->tmp, sizeof(struct IGDdatas_service)); |
| 49 | } else if(COMPARE(datas->tmp.servicetype, |
| 50 | "urn:schemas-upnp-org:service:WANIPConnection:" ) |
| 51 | || COMPARE(datas->tmp.servicetype, |
| 52 | "urn:schemas-upnp-org:service:WANPPPConnection:" ) ) { |
| 53 | if(datas->first.servicetype[0] == '\0') { |
| 54 | memcpy(&datas->first, &datas->tmp, sizeof(struct IGDdatas_service)); |
| 55 | } else { |
| 56 | memcpy(&datas->second, &datas->tmp, sizeof(struct IGDdatas_service)); |
| 57 | } |
| 58 | } |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | /* Data handler : |
| 63 | * copy data depending on the current element name and state */ |
| 64 | void IGDdata(void * d, const char * data, int l) |
| 65 | { |
| 66 | struct IGDdatas * datas = (struct IGDdatas *)d; |
| 67 | char * dstmember = 0; |
| 68 | /*printf("%2d %s : %.*s\n", |
| 69 | datas->level, datas->cureltname, l, data); */ |
| 70 | if( !strcmp(datas->cureltname, "URLBase" ) ) |
| 71 | dstmember = datas->urlbase; |
| 72 | else if( !strcmp(datas->cureltname, "presentationURL" ) ) |
| 73 | dstmember = datas->presentationurl; |
| 74 | else if( !strcmp(datas->cureltname, "serviceType" ) ) |
| 75 | dstmember = datas->tmp.servicetype; |
| 76 | else if( !strcmp(datas->cureltname, "controlURL" ) ) |
| 77 | dstmember = datas->tmp.controlurl; |
| 78 | else if( !strcmp(datas->cureltname, "eventSubURL" ) ) |
| 79 | dstmember = datas->tmp.eventsuburl; |
| 80 | else if( !strcmp(datas->cureltname, "SCPDURL" ) ) |
| 81 | dstmember = datas->tmp.scpdurl; |
| 82 | /* else if( !strcmp(datas->cureltname, "deviceType") ) |
| 83 | dstmember = datas->devicetype_tmp;*/ |
| 84 | if(dstmember) |
| 85 | { |
| 86 | if(l>=MINIUPNPC_URL_MAXSIZE) |
| 87 | l = MINIUPNPC_URL_MAXSIZE-1; |
| 88 | memcpy(dstmember, data, l); |
| 89 | dstmember[l] = '\0'; |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | #ifdef DEBUG |
| 94 | void printIGD(struct IGDdatas * d) |
| 95 | { |
| 96 | printf("urlbase = '%s'\n" , d->urlbase); |
| 97 | printf("WAN Device (Common interface config) :\n" ); |
| 98 | /*printf(" deviceType = '%s'\n", d->CIF.devicetype);*/ |
| 99 | printf(" serviceType = '%s'\n" , d->CIF.servicetype); |
| 100 | printf(" controlURL = '%s'\n" , d->CIF.controlurl); |
| 101 | printf(" eventSubURL = '%s'\n" , d->CIF.eventsuburl); |
| 102 | printf(" SCPDURL = '%s'\n" , d->CIF.scpdurl); |
| 103 | printf("primary WAN Connection Device (IP or PPP Connection):\n" ); |
| 104 | /*printf(" deviceType = '%s'\n", d->first.devicetype);*/ |
| 105 | printf(" servicetype = '%s'\n" , d->first.servicetype); |
| 106 | printf(" controlURL = '%s'\n" , d->first.controlurl); |
| 107 | printf(" eventSubURL = '%s'\n" , d->first.eventsuburl); |
| 108 | printf(" SCPDURL = '%s'\n" , d->first.scpdurl); |
| 109 | printf("secondary WAN Connection Device (IP or PPP Connection):\n" ); |
| 110 | /*printf(" deviceType = '%s'\n", d->second.devicetype);*/ |
| 111 | printf(" servicetype = '%s'\n" , d->second.servicetype); |
| 112 | printf(" controlURL = '%s'\n" , d->second.controlurl); |
| 113 | printf(" eventSubURL = '%s'\n" , d->second.eventsuburl); |
| 114 | printf(" SCPDURL = '%s'\n" , d->second.scpdurl); |
| 115 | printf("WAN IPv6 Firewall Control :\n" ); |
| 116 | /*printf(" deviceType = '%s'\n", d->IPv6FC.devicetype);*/ |
| 117 | printf(" servicetype = '%s'\n" , d->IPv6FC.servicetype); |
| 118 | printf(" controlURL = '%s'\n" , d->IPv6FC.controlurl); |
| 119 | printf(" eventSubURL = '%s'\n" , d->IPv6FC.eventsuburl); |
| 120 | printf(" SCPDURL = '%s'\n" , d->IPv6FC.scpdurl); |
| 121 | } |
| 122 | #endif /* DEBUG */ |
| 123 | |
| 124 | |