X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=lib%2Fsrc%2Fsession.c;h=a0357f3ba4a2d356a6639df90222ed937098c49f;hb=a0ae34fef838b8b5a8d937c14be6016a3d825c31;hp=c36c772d899a05587f58dd9fd15cf0e8a4cab2ec;hpb=25149569297f5d9e2b4eee51e93f696c54756d08;p=ngadmin diff --git a/lib/src/session.c b/lib/src/session.c index c36c772..a0357f3 100644 --- a/lib/src/session.c +++ b/lib/src/session.c @@ -3,8 +3,8 @@ #include -#include -#include +#include +#include #include "lib.h" #include "network.h" @@ -15,23 +15,28 @@ int ngadmin_scan (struct ngadmin *nga) int i; List *attr, *swiList; struct swi_attr *sa; - /* - sent by official win client: - ATTR_PRODUCT, - ATTR_UNK2, - ATTR_NAME, - ATTR_MAC, - ATTR_UNK5, - ATTR_IP, - ATTR_NETMASK, - ATTR_GATEWAY, - ATTR_DHCP, - ATTR_UNK12, - ATTR_FIRM_VER, - ATTR_UNK14, - ATTR_UNK15, - ATTR_END - */ + struct nsdp_cmd nc; + /* sent by official win client: + * ATTR_PRODUCT + * ATTR_UNK2 + * ATTR_NAME + * ATTR_MAC + * ATTR_UNK5 + * ATTR_IP + * ATTR_NETMASK + * ATTR_GATEWAY + * ATTR_DHCP + * ATTR_UNK12 + * ATTR_FIRM_VER + * ATTR_UNK14 + * ATTR_UNK15 + * ATTR_END + * + * one may be tempted to add ATTR_ENCPASS so we can now early if the + * switch uses password encryption, but this would cause (at least) + * switches that do not support this feature not to reply to the + * discovery request at all + */ static const unsigned short hello[] = { ATTR_PRODUCT, ATTR_NAME, @@ -64,7 +69,8 @@ int ngadmin_scan (struct ngadmin *nga) } /* send request to all potential switches */ - i = sendNsdpPacket(nga, CODE_READ_REQ, attr); + prepareSend(nga, &nc, CODE_READ_REQ); + i = sendNsdpPacket(nga->sock, &nc, attr); clearList(attr, (void(*)(void*))freeAttr); if (i == -EINVAL) return ERR_INVARG; @@ -74,13 +80,19 @@ int ngadmin_scan (struct ngadmin *nga) /* try to receive any packets until timeout */ swiList = createEmptyList(); /* FIXME: end after timeout whatever received packet is good or not */ - while (recvNsdpPacket(nga, CODE_READ_REP, NULL, NULL, attr) >= 0) { + while (1) { + prepareRecv(nga, &nc, CODE_READ_REP); + if (recvNsdpPacket(nga->sock, &nc, attr, &nga->timeout) < 0) + break; + sa = malloc(sizeof(struct swi_attr)); if (sa == NULL) return ERR_MEM; - extractSwitchAttributes(sa, attr); + + if (extractSwitchAttributes(sa, attr) == 0) + pushBackList(swiList, sa); + clearList(attr, (void(*)(void*))freeAttr); - pushBackList(swiList, sa); } nga->swi_count = swiList->count; @@ -130,6 +142,10 @@ int ngadmin_login (struct ngadmin *nga, int id) nga->current = sa; nga->encrypt_pass = false; + /* determine if the switch uses password encryption + * as explained in ngadmin_scan, it cannot be done at discovery + * stage + */ attr = createEmptyList(); pushBackList(attr, newEmptyAttr(ATTR_ENCPASS)); ret = readRequest(nga, attr); @@ -139,19 +155,30 @@ int ngadmin_login (struct ngadmin *nga, int id) filterAttributes(attr, ATTR_ENCPASS, ATTR_END); if (attr->first != NULL) { at = attr->first->data; - nga->encrypt_pass = (at->size == 4 && ntohl(*(unsigned int*)at->data) == 1); + nga->encrypt_pass = (at->size == 4 && *(unsigned int*)at->data == 1); } clearList(attr, (void(*)(void*))freeAttr); - /* Strangely, passwords must never be encrypted inside a read request, - * or it will be rejected. Seems more to be a firmware bug. */ + /* strangely, passwords must never be encrypted inside a read request, + * or it will be rejected. Seems more to be a firmware bug + */ pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password))); ret = readRequest(nga, attr); + + if (ret == ERR_INVOP) { + /* it seems some switches do not support login with read request + * fallback to write request, even if it has the drawback of + * the password being broadcasted back by the switch + */ + ret = writeRequest(nga, NULL); + } + if (ret == ERR_OK ) { /* login succeeded */ - /* TODO: if keep broadcasting is disabled, connect() the UDP - socket so icmp errors messages (port unreachable, TTL exceeded - in transit, ...) can be received */ + /* TODO: if keep broadcasting is disabled, connect() the UDP + * socket so icmp errors messages (port unreachable, TTL exceeded + * in transit, ...) can be received + */ } else { /* login failed */ nga->current = NULL;