]> git.sur5r.net Git - ngadmin/blob - lib/src/session.c
Split lib code into several files
[ngadmin] / lib / src / session.c
1
2 #include <errno.h>
3
4 #include <ngadmin.h>
5
6 #include <attr.h>
7 #include <protocol.h>
8
9 #include "lib.h"
10 #include "network.h"
11
12
13 int ngadmin_scan (struct ngadmin *nga)
14 {
15         int i;
16         List *attr, *swiList;
17         struct swi_attr *sa;
18         /*
19         sent by official win client:
20         ATTR_PRODUCT,
21         ATTR_UNK2,
22         ATTR_NAME,
23         ATTR_MAC,
24         ATTR_UNK5,
25         ATTR_IP,
26         ATTR_NETMASK,
27         ATTR_GATEWAY,
28         ATTR_DHCP,
29         ATTR_UNK12,
30         ATTR_FIRM_VER,
31         ATTR_UNK14,
32         ATTR_UNK15,
33         ATTR_END
34         */
35         static const unsigned short hello[] = {
36                 ATTR_PRODUCT,
37                 ATTR_NAME,
38                 ATTR_MAC,
39                 ATTR_IP,
40                 ATTR_NETMASK,
41                 ATTR_GATEWAY,
42                 ATTR_DHCP,
43                 ATTR_FIRM_VER,
44                 ATTR_PORTS_COUNT,
45                 ATTR_END
46         };
47         
48         
49         if (nga == NULL)
50                 return ERR_INVARG;
51         
52         free(nga->swi_tab);
53         nga->swi_tab = NULL;
54         nga->swi_count = 0;
55         nga->current = NULL;
56         
57         
58         /* create attributes for an "hello" request */
59         attr = createEmptyList();
60         for (i = 0; ; i++) {
61                 pushBackList(attr, newEmptyAttr(hello[i]));
62                 if (hello[i] == ATTR_END)
63                         break;
64         }
65         
66         /* send request to all potential switches */
67         i = sendNgPacket(nga, CODE_READ_REQ, attr);
68         clearList(attr, (void(*)(void*))freeAttr);
69         if (i == -EINVAL)
70                 return ERR_INVARG;
71         else if (i < 0)
72                 return ERR_NET;
73         
74         /* try to receive any packets until timeout */
75         swiList = createEmptyList();
76         /* FIXME: end after timeout whatever received packet is good or not */
77         while (recvNgPacket(nga, CODE_READ_REP, NULL, NULL, attr) >= 0) {
78                 sa = malloc(sizeof(struct swi_attr));
79                 if (sa == NULL)
80                         return ERR_MEM;
81                 extractSwitchAttributes(sa, attr);
82                 clearList(attr, (void(*)(void*))freeAttr);
83                 pushBackList(swiList, sa);
84         }
85         
86         nga->swi_count = swiList->count;
87         nga->swi_tab = convertToArray(swiList, sizeof(struct swi_attr));
88         destroyList(swiList, free);
89         destroyList(attr, (void(*)(void*))freeAttr);
90         
91         
92         return ERR_OK;
93 }
94
95
96 const struct swi_attr* ngadmin_getSwitchTab (struct ngadmin *nga, int *nb)
97 {
98         if (nga == NULL || nb == NULL)
99                 return NULL;
100         
101         *nb = nga->swi_count;
102         
103         return nga->swi_tab;
104 }
105
106
107 const struct swi_attr* ngadmin_getCurrentSwitch (struct ngadmin *nga)
108 {
109         if (nga == NULL)
110                 return NULL;
111         
112         return nga->current;
113 }
114
115
116 int ngadmin_login (struct ngadmin *nga, int id)
117 {
118         List *attr;
119         struct attr *at;
120         int ret = ERR_OK;
121         struct swi_attr *sa;
122         
123         
124         if (nga == NULL)
125                 return ERR_INVARG;
126         else if (id < 0 || id >= nga->swi_count)
127                 return ERR_BADID;
128         
129         sa = &nga->swi_tab[id];
130         nga->current = sa;
131         nga->encrypt_pass = false;
132         
133         attr = createEmptyList();
134         pushBackList(attr, newEmptyAttr(ATTR_ENCPASS));
135         ret = readRequest(nga, attr);
136         if (ret != ERR_OK)
137                 goto end;
138         
139         filterAttributes(attr, ATTR_ENCPASS, ATTR_END);
140         if (attr->first != NULL) {
141                 at = attr->first->data;
142                 nga->encrypt_pass = (at->size == 4 && ntohl(*(unsigned int*)at->data) == 1);
143         }
144         clearList(attr, (void(*)(void*))freeAttr);
145         
146         /* Strangely, passwords must never be encrypted inside a read request,
147          * or it will be rejected. Seems more to be a firmware bug. */
148         pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
149         ret = readRequest(nga, attr);
150         if (ret == ERR_OK ) {
151                 /* login succeeded */
152                 /* TODO: if keep broadcasting is disabled, connect() the UDP 
153                 socket so icmp errors messages (port unreachable, TTL exceeded 
154                 in transit, ...) can be received */
155         } else {
156                 /* login failed */
157                 nga->current = NULL;
158         }
159         
160 end:
161         destroyList(attr, (void(*)(void*))freeAttr);
162         
163         
164         return ret;
165 }
166
167