Branch oldpackages for 14.07
[14.07/packages.git] / net / chillispot / patches / 150-chillispot-rmtctrl.patch
1 --- a/src/chilli.c
2 +++ b/src/chilli.c
3 @@ -102,6 +102,7 @@
4  #include "dhcp.h"
5  #include "cmdline.h"
6  #include "chilli.h"
7 +#include "remotectrl.h"
8  
9  struct options_t options;
10  
11 @@ -127,6 +128,12 @@ static int do_sighup = 0;
12  /* Forward declarations */
13  int static acct_req(struct app_conn_t *conn, int status_type);
14  int static config_radius();
15 +void admin_disconnect(struct app_conn_t *appconn, int terminateCause);
16 +void admin_authorize(struct app_conn_t *appconn);
17 +int send_acct_head( struct rmt_socket_t *client, struct app_conn_t *appconn);
18 +int send_Connection( struct rmt_socket_t *client, struct app_conn_t *appconn );
19 +int send_Acct_Setting ( struct rmt_socket_t *client, struct app_conn_t *appconn );
20 +int send_Accounting( struct rmt_socket_t *client, struct app_conn_t *appconn );
21  
22  /* Fireman catches falling childs and eliminates zombies */
23  void static fireman(int signum) { 
24 @@ -180,19 +187,18 @@ int static leaky_bucket(struct app_conn_
25    struct timeval timenow;
26    uint64_t timediff; /* In microseconds */
27    int result = 0;
28 -
29   
30    gettimeofday(&timenow, NULL);
31  
32    timediff = (timenow.tv_sec - conn->last_time.tv_sec) * ((uint64_t) 1000000);
33    timediff += (timenow.tv_usec - conn->last_time.tv_usec);
34  
35 -  /*  if (options.debug) printf("Leaky bucket timediff: %lld, bucketup: %d, bucketdown: %d %d %d\n", 
36 -                           timediff, conn->bucketup, conn->bucketdown, 
37 -                           octetsup, octetsdown);*/
38 -
39 -  if (conn->bandwidthmaxup) {
40 +/*    if (options.debug) 
41 +                       printf("Leaky bucket timediff: %lld, bucketup: %d, bucketdown: %d %d %d\n",
42 +                                       timediff, conn->bucketup, conn->bucketdown, octetsup, octetsdown);
43 +*/
44  
45 +       if (conn->bandwidthmaxup) {
46      /* Subtract what the leak since last time we visited */
47      if (conn->bucketup > ((timediff * conn->bandwidthmaxup)/8000000)) {
48        conn->bucketup -= (timediff * conn->bandwidthmaxup) / 8000000;
49 @@ -200,9 +206,9 @@ int static leaky_bucket(struct app_conn_
50      else {
51        conn->bucketup = 0;
52      }
53 -    
54 +//    printf("octetsup: %d -> conn->bucketup+octetsup: %d > conn->bucketupsize: %d \n", octetsup, conn->bucketup + octetsup, conn->bucketupsize);
55      if ((conn->bucketup + octetsup) > conn->bucketupsize) {
56 -      /*if (options.debug) printf("Leaky bucket deleting uplink packet\n");*/
57 +      if (options.debug) printf("Leaky bucket deleting uplink packet\n");
58        result = -1;
59      }
60      else {
61 @@ -217,9 +223,10 @@ int static leaky_bucket(struct app_conn_
62      else {
63        conn->bucketdown = 0;
64      }
65 +//    printf("octetsdown: %d -> conn->bucketdown+octetsdown: %d > conn->bucketdownsize: %d \n", octetsdown, conn->bucketdown + octetsdown, conn->bucketdownsize);
66      
67      if ((conn->bucketdown + octetsdown) > conn->bucketdownsize) {
68 -      /*if (options.debug) printf("Leaky bucket deleting downlink packet\n");*/
69 +      if (options.debug) printf("Leaky bucket deleting downlink packet\n");
70        result = -1;
71      }
72      else {
73 @@ -233,6 +240,7 @@ int static leaky_bucket(struct app_conn_
74  }
75  #endif /* ifndef NO_LEAKY_BUCKET */
76  
77 +
78  /* Run external script */
79  
80  int set_env(char *name, char *value, int len, struct in_addr *addr,
81 @@ -550,7 +558,7 @@ int static process_options(int argc, cha
82      return -1;
83    }
84  
85 -  if (cmdline_parser_configfile (args_info.conf_arg, &args_info, 0, 0, 0)) {
86 +       if (cmdline_parser_configfile (args_info.conf_arg, &args_info, 0, 0, 0)) {
87      sys_err(LOG_ERR, __FILE__, __LINE__, 0,
88             "Failed to parse configuration file: %s!", 
89             args_info.conf_arg);
90 @@ -1056,7 +1064,21 @@ int static process_options(int argc, cha
91                        strlen(args_info.macallowed_arg[numargs]))) 
92        return -1;
93    }
94 -
95 +  /* remote monitor                                                    */
96 +  /* Defaults to net plus 1                                       */
97 +  if (!args_info.rmtlisten_arg)
98 +    options.rmtlisten.s_addr = options.uamlisten.s_addr;
99 +  else 
100 +               if (!inet_aton(args_info.rmtlisten_arg, &options.rmtlisten)){
101 +                       sys_err(LOG_ERR, __FILE__, __LINE__, 0,
102 +           "Invalid Remote monitor IP address: %s!", args_info.rmtlisten_arg);
103 +                       return -1;
104 +               }
105 +  /* rmtport                                                      */
106 +  options.rmtport = args_info.rmtport_arg;
107 +  options.rmtpasswd = args_info.rmtpasswd_arg;
108 +  options.bandwidthmaxup = args_info.bandwidthmaxup_arg;
109 +  options.bandwidthmaxdown = args_info.bandwidthmaxdown_arg;
110  
111    /* foreground                                                   */
112    /* If flag not given run as a daemon                            */
113 @@ -1095,7 +1117,6 @@ void static reprocess_options(int argc, 
114      memcpy(&options, &options2, sizeof(options));
115      return;
116    }
117 -
118    /* Options which we do not allow to be affected */
119    /* fg, conf and statedir are not stored in options */
120    options.net = options2.net; /* net */
121 @@ -1123,6 +1144,13 @@ void static reprocess_options(int argc, 
122    options.eapolenable = options2.eapolenable; /* eapolenable */
123    options.pidfile = options2.pidfile; /* pidfile */
124  
125 +  options.rmtlisten = options2.rmtlisten; /* remote listen */
126 +  options.rmtport = options2.rmtport; /* remote port */
127 +  options.rmtpasswd = options2.rmtpasswd; /* remote password */
128 +
129 +//  options.bandwidthmaxup = options2.bandwidthmaxup; /* remote password */
130 +//  options.bandwidthmaxdown = options2.bandwidthmaxdown; /* remote password */
131 +
132    /* Reinit DHCP parameters */
133    (void) dhcp_set(dhcp, (options.debug & DEBUG_DHCP),
134                   options.uamserver, options.uamserverlen, options.uamanydns,
135 @@ -3099,9 +3127,8 @@ int cb_radius_auth_conf(struct radius_t 
136        appconn->bucketupsize = BUCKET_SIZE_MIN;
137  #endif
138    }
139 -  else {
140 +  else
141      appconn->bandwidthmaxup = 0;
142 -  }
143    
144    /* Bandwidth down */
145    if (!radius_getattr(pack, &attr, RADIUS_ATTR_VENDOR_SPECIFIC,
146 @@ -3116,9 +3143,8 @@ int cb_radius_auth_conf(struct radius_t 
147        appconn->bucketdownsize = BUCKET_SIZE_MIN;
148  #endif
149    }
150 -  else {
151 +  else
152      appconn->bandwidthmaxdown = 0;
153 -  }
154  
155  #ifdef RADIUS_ATTR_CHILLISPOT_BANDWIDTH_MAX_UP
156    /* Bandwidth up */
157 @@ -3623,7 +3649,7 @@ int cb_dhcp_data_ind(struct dhcp_conn_t 
158      appconn->input_octets +=len;
159  #ifndef NO_LEAKY_BUCKET
160  #ifdef COUNT_UPLINK_DROP
161 -    if (leaky_bucket(appconn, len, 0)) return 0;
162 +    if (leaky_bucket(appconn, len, 0)==-1) return 0;
163  #endif /* ifdef COUNT_UPLINK_DROP */
164  #endif /* ifndef NO_LEAKY_BUCKET */
165    }
166 @@ -3889,6 +3915,10 @@ int main(int argc, char **argv)
167    struct sigaction act;
168    struct itimerval itval;
169  
170 +       struct rmt_socket_t srv;
171 +       struct rmt_socket_t client[MAX_CLIENTS];
172 +       int activeClients = 0;                  /* NĂºmero clientes conectados */
173 +
174    /* open a connection to the syslog daemon */
175    /*openlog(PACKAGE, LOG_PID, LOG_DAEMON);*/
176    openlog(PACKAGE, (LOG_PID | LOG_PERROR), LOG_DAEMON);
177 @@ -4046,6 +4076,8 @@ int main(int argc, char **argv)
178    if (options.debug) 
179      printf("Waiting for client request...\n");
180  
181 +       
182 +       srv = rmtctrl_initSrv(options.rmtlisten, options.rmtport);
183  
184    /******************************************************************/
185    /* Main select loop                                               */
186 @@ -4053,6 +4085,8 @@ int main(int argc, char **argv)
187  
188    while (keep_going) {
189  
190 +               rmtctrl_srv(srv,client,&activeClients);
191 +
192      if (do_timeouts) {
193        /*if (options.debug) printf("Do timeouts!\n");*/
194        (void) radius_timeout(radius);
195 @@ -4178,3 +4212,487 @@ int main(int argc, char **argv)
196    return 0;
197    
198  }
199 +
200 +void rmtctrl_msg_proccess(struct rmt_socket_t *client)
201 +{
202 +       msg_head_t header;
203 +       char *msg=NULL;
204 +       char *reg=NULL;
205 +       struct app_conn_t *appconn;
206 +       struct dhcp_conn_t *dhcpconn;
207 +       char str[2048];
208 +       int found=0;
209 +       int rslt=0;
210 +       int n;
211 +       uint64_t l;
212 +       rslt = rmtctrl_read_msg(client,&header,&msg);
213 +       if (rslt > 0)
214 +       {
215 +               switch (header.id)
216 +               {
217 +                       case QRY_CONNECTED_LIST:
218 +                               rslt += send_srvData(client);
219 +                               rslt += rmtctrl_write_msg(client,MSG_START,0, "\n" );
220 +                               rslt += rmtctrl_write_msg(client,MSG_PART,0, "Ord ---------- User Name ----------- -- MAC Address -- -- IP Address - -- Input - - Output - Sta\n" );
221 +                               for (n=0; n<APP_NUM_CONN; n++) {
222 +                                       appconn = &connection[n];
223 +                                       if ((appconn->inuse != 0)){
224 +                                               dhcpconn = (struct dhcp_conn_t*) appconn->dnlink;
225 +                                               found++;
226 +                                               l = found;
227 +                                               rslt += send_number(client, MSG_PART, 0, "%3s ", l);
228 +                                               rslt += send_line(client,MSG_PART,0, "%-32s ",appconn->proxyuser);
229 +                                               rslt += send_mac(client,MSG_PART,0, "%17s ",appconn->hismac);
230 +                                               rslt += send_line(client,MSG_PART,0, "%15s ",inet_ntoa(appconn->hisip));
231 +                                               rslt += send_number(client,MSG_PART,0, "%10s ",appconn->input_octets);
232 +                                               rslt += send_number(client,MSG_PART,0, "%10s ",appconn->output_octets);
233 +                                               rslt += send_number(client, MSG_PART, 0, " %s ",appconn->authenticated);
234 +                                               rslt += send_number(client, MSG_PART, 0, " %s \n",dhcpconn->authstate);
235 +                                       }
236 +                               }
237 +                               rslt += send_number(client,MSG_END,found, "Total of connected device(s) %s\n",found);
238 +                       break;
239 +                       case QRY_CONNECTED_FULL_LIST:
240 +                               rslt += send_srvData(client);
241 +                               rslt += rmtctrl_write_msg(client,MSG_START,0, "\n" );
242 +                               for (n=0; n<APP_NUM_CONN; n++) {
243 +                                       appconn = &connection[n];
244 +                                       if ((appconn->inuse != 0)){
245 +                                               found++;
246 +                                               l = found;
247 +                                               rslt += send_number(client, MSG_PART, 0, "Connection : %s\n{\n", l);
248 +                                               rslt += send_acct_head( client, appconn);
249 +                                               rslt += send_line(client, MSG_PART, 0, "%s\n", "}");
250 +                                       }
251 +                               }
252 +                               rslt += send_number(client, MSG_END, found, "Total of connected device(s) %s\n",found);
253 +                       break;
254 +                       case QRY_STATUS:
255 +                               ///
256 +                               rslt += send_Status(client, appconn);
257 +                       break;
258 +                       case CMD_AUTHORIZE:
259 +                               for (n=0; n<APP_NUM_CONN; n++)
260 +                               {
261 +                                       l = 0;
262 +                                       appconn = &connection[n];
263 +                                       if ((appconn->inuse != 0) && (appconn->authenticated == 0))
264 +                                       {
265 +                                               switch (header.extra)
266 +                                               {
267 +                                                       case EXTRA_MAC_OP:
268 +                                                               if ( strcmp(msg,mac2str(appconn->hismac)) == 0)
269 +                                                               {
270 +                                                                       found++;
271 +                                                                       l=1;
272 +                                                                       break;
273 +                                                               }
274 +                                                       break;
275 +                                                       case EXTRA_IP_OP:
276 +                                                               if ( strcmp(msg,inet_ntoa(appconn->hisip)) == 0)
277 +                                                               {
278 +                                                                       found++;
279 +                                                                       l=1;
280 +                                                                       break;
281 +                                                               }
282 +                                                       break;
283 +                                                       case EXTRA_USER_OP:
284 +                                                               if ( strcmp(msg,appconn->proxyuser) == 0)
285 +                                                               {
286 +                                                                       found++;
287 +                                                                       l=1;
288 +                                                                       break;
289 +                                                               }
290 +                                                       break;
291 +                                                       default:
292 +                                                               found++;
293 +                                                               l=1;
294 +                                                       break;
295 +                                               }
296 +                                               if ( l == 1 ){
297 +                                                       admin_authorize(appconn);
298 +                                                       rslt += send_srvData( client );
299 +                                                       rslt += rmtctrl_write_msg(client,MSG_PART,0, " \n" );
300 +                                                       rslt += send_acct_head( client, appconn);
301 +                                                       sys_err(LOG_NOTICE, __FILE__, __LINE__, 0,
302 +                                                               "Admin Authorize MAC=%s IP=%s",
303 +                                                               mac2str(appconn->hismac), inet_ntoa(appconn->hisip));
304 +                                               }
305 +                                       }
306 +                               }
307 +                               if (found == 0)
308 +                                       rslt += rmtctrl_write_msg(client,MSG_END,0, "Not device found to Authorze\n" );
309 +                               else 
310 +                               {
311 +                                       rslt += send_number(client, MSG_END, found, "Autorized %s device(s)\n",found);
312 +                               }
313 +                       break;
314 +                       case CMD_DISCONNECT:
315 +                               for (n=0; n<APP_NUM_CONN; n++)
316 +                               {
317 +                                       l = 0;
318 +                                       appconn = &connection[n];
319 +                                       if ((appconn->inuse != 0) && (appconn->authenticated == 1))
320 +                                       {
321 +                                               if (dhcpconn = (struct dhcp_conn_t*) appconn->dnlink) {
322 +                                                       switch (header.extra)
323 +                                                       {
324 +                                                               case EXTRA_MAC_OP:
325 +                                                                       if ( strcmp(msg,mac2str(appconn->hismac)) == 0)
326 +                                                                       {
327 +                                                                               found++;
328 +                                                                               l=1;
329 +                                                                               break;
330 +                                                                       }
331 +                                                               break;
332 +                                                               case EXTRA_IP_OP:
333 +                                                                       if ( strcmp(msg,inet_ntoa(appconn->hisip)) == 0)
334 +                                                                       {
335 +                                                                               found++;
336 +                                                                               l=1;
337 +                                                                               break;
338 +                                                                       }
339 +                                                               break;
340 +                                                               case EXTRA_USER_OP:
341 +                                                                       if ( strcmp(msg,appconn->proxyuser) == 0)
342 +                                                                       {
343 +                                                                               found++;
344 +                                                                               l=1;
345 +                                                                               break;
346 +                                                                       }
347 +                                                               break;
348 +                                                               default:
349 +                                                                       found++;
350 +                                                                       l=1;
351 +                                                               break;
352 +                                                       }
353 +                                                       if ( l == 1 ) {
354 +                                                               rslt += send_srvData( client );
355 +                                                               rslt += rmtctrl_write_msg(client,MSG_PART,0, " \n" );
356 +                                                               rslt += send_acct_head( client, appconn);
357 +                                                               admin_disconnect(appconn, RADIUS_TERMINATE_CAUSE_ADMIN_RESET);
358 +                                                               sys_err(LOG_NOTICE, __FILE__, __LINE__, 0,
359 +                                                                       "Admin Disconnect username=%s IP=%s",
360 +                                                                       appconn->user, inet_ntoa(appconn->hisip));
361 +                                                       }
362 +                                               }
363 +                                       }
364 +                               }
365 +                               if (found == 0)
366 +                                       rslt += rmtctrl_write_msg(client,MSG_END,0, "Not decice found to Disconnect\n" );
367 +                               else 
368 +                               {
369 +                                       rslt += send_number(client, MSG_END, found, "Disconnect %s device(s)\n",found);
370 +                               }
371 +                       break;
372 +                       default:
373 +                                       rslt += rmtctrl_write_msg(client,MSG_END,0, "Unknow command.\n" );
374 +                       break;
375 +               }
376 +       }
377 +       else
378 +       {
379 +               printf("Desde %s se recibieron %d bytes y se enviaron %d bytes\n",inet_ntoa(client->addr.sin_addr),client->Rx,client->Tx);
380 +               close(client->fd); /* cierra fd_rmt_client */
381 +               printf("Client cerro conexiĂ³n desde %s\n",inet_ntoa(client->addr.sin_addr) ); 
382 +               client->fd = -1;
383 +       }
384 +       if(msg)
385 +               free(msg);
386 +}
387 +
388 +void admin_authorize(struct app_conn_t *appconn)
389 +{
390 +  struct radius_packet_t radius_pack;
391 +       strcpy(appconn->user,"Admin-Authorize");
392 +       strcpy(appconn->proxyuser,"Admin-Authorize");
393 +       appconn->proxyuserlen = strlen(appconn->proxyuser);
394 +       appconn->interim_interval = 600;
395 +       appconn->terminate_cause = 0;
396 +       appconn->idletimeout = 300;
397 +
398 +       radius_default_pack(radius, &radius_pack, RADIUS_CODE_ACCESS_REQUEST);
399 +  radius_pack.code = RADIUS_CODE_ACCESS_REQUEST;
400 +//  (void) radius_addattr(radius, &radius_pack, RADIUS_ATTR_USER_NAME, 0, 0, 0,
401 +//                     (uint8_t*) appconn->proxyuser, appconn->proxyuserlen);
402 +
403 +       if ( options.bandwidthmaxup > 0 ){
404 +               appconn->bandwidthmaxup = options.bandwidthmaxup * 1024;
405 +    appconn->bucketupsize = BUCKET_TIME * appconn->bandwidthmaxup / 8000;
406 +    if (appconn->bucketupsize < BUCKET_SIZE_MIN) 
407 +      appconn->bucketupsize = BUCKET_SIZE_MIN;
408 +       }
409 +       if ( options.bandwidthmaxdown > 0 ){
410 +               appconn->bandwidthmaxdown = options.bandwidthmaxdown * 1024;
411 +    appconn->bucketdownsize = BUCKET_TIME * appconn->bandwidthmaxdown / 8000;
412 +    if (appconn->bucketdownsize < BUCKET_SIZE_MIN) 
413 +      appconn->bucketdownsize = BUCKET_SIZE_MIN;
414 +       }
415 +       dnprot_accept(appconn);
416 +}
417 +
418 +void admin_disconnect(struct app_conn_t *appconn, int terminateCause)
419 +{
420 +       dnprot_terminate(appconn);
421 +       (void) acct_req(appconn, RADIUS_STATUS_TYPE_STOP);
422 +       set_sessionid(appconn);
423 +}
424 +
425 +int send_acct_head( struct rmt_socket_t *client, struct app_conn_t *appconn)
426 +{
427 +       int rslt;
428 +       rslt += send_Connection( client, appconn );
429 +       rslt += send_Acct_Setting( client, appconn );
430 +       rslt += send_Accounting( client, appconn );
431 +       return rslt;
432 +}
433 +
434 +int send_Connection( struct rmt_socket_t *client, struct app_conn_t *appconn )
435 +{
436 +       int rslt;
437 +       uint64_t l;
438 +       rslt += send_line(client, MSG_PART, 0, "\tSession-Id = %s\n",appconn->sessionid);
439 +       rslt += send_line(client, MSG_PART, 0, "\tUser-Name = %s\n",appconn->user);
440 +//     rslt = send_line(client, MSG_PART, 0, "\tnasip=%s\n",appconn->nasip);
441 +       rslt += send_mac(client, MSG_PART, 0, "\tClient-Mac-Address = %s\n",appconn->hismac);
442 +       rslt += send_mac(client, MSG_PART, 0, "\tNas-Mac-Address = %s\n",appconn->ourmac);
443 +//     rslt += send_line(client, MSG_PART, 0, "\tourip=%s\n",inet_ntoa(appconn->ourip));
444 +       rslt += send_line(client, MSG_PART, 0, "\tClient-Ip = %s\n",inet_ntoa(appconn->hisip));
445 +       rslt += send_line(client, MSG_PART, 0, "\tClient-Require-Ip = %s\n",inet_ntoa(appconn->reqip));
446 +       rslt += send_number(client, MSG_PART, 0, "\tAutheticated = %s\n",appconn->authenticated);
447 +       l = appconn->uamtime;
448 +       if (l > 0)
449 +               rslt += send_number(client, MSG_PART, 0, "\tUAM-Time = %s\n",l);
450 +       if (strlen(appconn->userurl)>0)
451 +               rslt = send_line(client, MSG_PART, 0, "\tUser-URL = %s\n",appconn->userurl);
452 +       return rslt;
453 +}
454 +
455 +int send_Acct_Setting ( struct rmt_socket_t *client, struct app_conn_t *appconn )
456 +{
457 +       int rslt = 0;
458 +       uint64_t l;
459 +       if (appconn->authenticated == 0 ) return 0;
460 +       /* Account Settings */
461 +       l = appconn->sessionterminatetime;
462 +       if (l > 0)
463 +               rslt += send_number(client, MSG_PART, 0, "\tSession-Terminate-Time = %s\n",l);
464 +       l = appconn->sessiontimeout;
465 +       if (l > 0)
466 +               rslt += send_number(client, MSG_PART, 0, "\tSession-Timeout = %s\n",l);
467 +       l = appconn->idletimeout;
468 +       if (l > 0)
469 +               rslt += send_number(client, MSG_PART, 0, "\tIdle-Timeout = %s\n",l);
470 +       l = appconn->bandwidthmaxup;
471 +       if (l > 0)
472 +               rslt += send_number(client, MSG_PART, 0, "\tBandwidth-Max-Up = %s\n",l);
473 +       l = appconn->bandwidthmaxdown;
474 +       if (l > 0)
475 +               rslt += send_number(client, MSG_PART, 0, "\tBandwidth-Max-Down = %s\n",l);
476 +       l = appconn->maxinputoctets;
477 +       if (l > 0)
478 +               rslt += send_number(client, MSG_PART, 0, "\tMax-Input-Octets = %s\n",l);
479 +       l = appconn->maxoutputoctets;
480 +       if (l > 0)
481 +               rslt += send_number(client, MSG_PART, 0, "\tMax-Output-Octets = %s\n",l);
482 +       l = appconn->maxtotaloctets;
483 +       if (l > 0)
484 +               rslt += send_number(client, MSG_PART, 0, "\tMax-Total-Octets = %s\n",l);
485 +       return rslt;
486 +}
487 +
488 +int send_Accounting( struct rmt_socket_t *client, struct app_conn_t *appconn )
489 +{
490 +       if (appconn->authenticated == 0 ) return 0;
491 +       int rslt = 0;
492 +       uint64_t l;
493 +       l = appconn->start_time.tv_sec;
494 +       if (l > 0)
495 +               rslt += send_number(client, MSG_PART, 0, "\tStart-Time = %s\n",l);
496 +       l = appconn->interim_time.tv_sec;
497 +       if (l > 0)
498 +               rslt += send_number(client, MSG_PART, 0, "\tInterim-Time = %s\n",l);
499 +       l = appconn->interim_interval;
500 +       if (l > 0)
501 +               rslt += send_number(client, MSG_PART, 0, "\tInterim-Interval = %s\n",l);
502 +       l = appconn->last_time.tv_sec;
503 +       if (l > 0)
504 +               rslt += send_number(client, MSG_PART, 0, "\tLast-Time = %s\n",l);
505 +       l = appconn->input_packets;
506 +       if (l > 0)
507 +               rslt += send_number(client, MSG_PART, 0, "\tInput-Packets = %s\n",l);
508 +       l = appconn->output_packets;
509 +       if (l > 0)
510 +               rslt += send_number(client, MSG_PART, 0, "\tOutput-Packets = %s\n",l);
511 +       l = appconn->input_octets;
512 +       if (l > 0)
513 +               rslt += send_number(client, MSG_PART, 0, "\tInput-Octets = %s\n",l);
514 +       l = appconn->output_octets;
515 +       if (l > 0)
516 +               rslt += send_number(client, MSG_PART, 0, "\tOutput-Octets = %s\n",l);
517 +       l = appconn->terminate_cause;
518 +       if (l > 0)
519 +               rslt += send_number(client, MSG_PART, 0, "\tTerminate-Cause = %s\n",l);
520 +       l = appconn->bucketup;
521 +       if (l > 0)
522 +               rslt += send_number(client, MSG_PART, 0, "\tBucket-Up = %s\n",l);
523 +       l = appconn->bucketdown;
524 +       if (l > 0)
525 +               rslt += send_number(client, MSG_PART, 0, "\tBucket-Down = %s\n",l);
526 +       l = appconn->bucketupsize;
527 +       if (l > 0)
528 +               rslt += send_number(client, MSG_PART, 0, "\tBucket-Up-Size = %s\n",l);
529 +       l = appconn->bucketdownsize;
530 +       if (l > 0)
531 +               rslt += send_number(client, MSG_PART, 0, "\tBucket-Down-Size = %s\n",l);
532 +       return rslt;
533 +}
534 +
535 +int send_srvData( struct rmt_socket_t *client)
536 +{
537 +       int rslt=0;
538 +       rslt += send_line(client, MSG_PART, 0, "%s\n",options.radiusnasid);
539 +       if (options.radiuslocationid)
540 +               rslt += send_line(client, MSG_PART, 0, "\tLOCATION ID:%s\n",options.radiuslocationid);
541 +       if (options.radiuslocationname)
542 +               rslt += send_line(client, MSG_PART, 0, "\tLOCATION NAME:%s\n",options.radiuslocationname);
543 +//     rslt += send_line(client, MSG_PART, 0, "\tDEVICE: %s ",tun->devname);
544 +//     rslt += send_line(client, MSG_PART, 0, "INTERFACE: %s\n",options.dhcpif);
545 +//     rslt += send_line(client, MSG_PART, 0, "\tIP ADDR: %s ",inet_ntoa(options.dhcplisten));
546 +//     rslt += send_line(client, MSG_PART, 0, "NETWORK: %s ",inet_ntoa(options.net));
547 +//     rslt += send_line(client, MSG_PART, 0, "MASK: %s\n",inet_ntoa(options.mask));
548 +       if (options.dns1.s_addr)
549 +               rslt += send_line(client, MSG_PART, 0, "\tDNS SERVERS: %s - ",inet_ntoa(options.dns1));
550 +       if (options.dns2.s_addr)
551 +               rslt += send_line(client, MSG_PART, 0, "%s\n",inet_ntoa(options.dns2));
552 +       rslt += send_line(client, MSG_PART, 0, "\tRADIUS SERVERS: %s - ",inet_ntoa(options.radiusserver1));
553 +       rslt += send_line(client, MSG_PART, 0, "%s\n",inet_ntoa(options.radiusserver2));
554 +       return rslt;
555 +}
556 +
557 +int send_Status( struct rmt_socket_t *client, struct app_conn_t *appconn )
558 +{
559 +       int rslt = 0;
560 +       int n;
561 +       uint64_t l;
562 +       l = options.debug;
563 +       rslt += send_number(client, MSG_PART, 0, "\tdebug=%s\n",l);
564 +       /* conf */
565 +       l = options.interval;
566 +       rslt += send_number(client, MSG_PART, 0, "\tinterval=%s\n",l);
567 +       rslt += send_line(client, MSG_PART, 0, "\tpidfile=%s\n",options.pidfile);
568 +       /* TUN parameters */
569 +       rslt += send_line(client, MSG_PART, 0, "\tnet=%s\n",inet_ntoa(options.net)); /* Network IP address */
570 +       rslt += send_line(client, MSG_PART, 0, "\tmask=%s\n",inet_ntoa(options.mask)); /* Network mask */
571 +       rslt += send_line(client, MSG_PART, 0, "\tnetc=%s\n",options.netc);
572 +       rslt += send_line(client, MSG_PART, 0, "\tmaskc=%s\n",options.maskc);
573 +       l = options.allowdyn;
574 +       rslt += send_number(client, MSG_PART, 0, "\tallowdyn=%s\n",l); /* Allow dynamic address allocation */
575 +       rslt += send_line(client, MSG_PART, 0, "\tdynip=%s\n",options.dynip); /* Dynamic IP address pool */
576 +
577 +       l = options.allowstat;
578 +       rslt += send_number(client, MSG_PART, 0, "\tallowstat=%s\n",l); /* Allow static address allocation */
579 +       rslt += send_line(client, MSG_PART, 0, "\tstatip=%s\n",options.statip); /* Static IP address pool */
580 +
581 +       rslt += send_line(client, MSG_PART, 0, "\tdns1=%s\n",inet_ntoa(options.dns1)); /* Primary DNS server IP address */
582 +       rslt += send_line(client, MSG_PART, 0, "\tdns2=%s\n",inet_ntoa(options.dns2)); /* Secondary DNS server IP address */
583 +       rslt += send_line(client, MSG_PART, 0, "\tdomain=%s\n",options.domain); /* Domain to use for DNS lookups */
584 +       rslt += send_line(client, MSG_PART, 0, "\tipup=%s\n",options.ipup); /* Script to run after link-up */
585 +       rslt += send_line(client, MSG_PART, 0, "\tipdown=%s\n",options.ipdown); /* Script to run after link-down */
586 +       rslt += send_line(client, MSG_PART, 0, "\tconup=%s\n",options.conup); /* Script to run after user logon */
587 +       rslt += send_line(client, MSG_PART, 0, "\tcondown=%s\n",options.condown); /* Script to run after user logoff */
588 +       /* Radius parameters */
589 +       rslt += send_line(client, MSG_PART, 0, "\tradiuslisten=%s\n",inet_ntoa(options.radiuslisten)); /* IP address to listen to */
590 +       rslt += send_line(client, MSG_PART, 0, "\tradiusserver1=%s\n",inet_ntoa(options.radiusserver1)); /* IP address of radius server 1 */
591 +       rslt += send_line(client, MSG_PART, 0, "\tradiusserver2=%s\n",inet_ntoa(options.radiusserver2)); /* IP address of radius server 2 */
592 +       l = options.radiusauthport;
593 +       rslt += send_number(client, MSG_PART, 0, "\tradiusauthport=%s\n",l); /* Authentication UDP port */
594 +       l = options.radiusacctport;
595 +       rslt += send_number(client, MSG_PART, 0, "\tradiusacctport=%s\n",l); /* Accounting UDP port */
596 +       rslt += send_line(client, MSG_PART, 0, "\tradiussecret=%s\n",options.radiussecret); /* Radius shared secret */
597 +       rslt += send_line(client, MSG_PART, 0, "\tradiusnasid=%s\n",options.radiusnasid); /* Radius NAS-Identifier */
598 +       rslt += send_line(client, MSG_PART, 0, "\tradiuscalled=%s\n",options.radiuscalled); /* Radius Called-Station-ID */
599 +       rslt += send_line(client, MSG_PART, 0, "\tradiusnasip=%s\n",inet_ntoa(options.radiusnasip)); /* Radius NAS-IP-Address */
600 +       rslt += send_line(client, MSG_PART, 0, "\tradiuslocationid=%s\n",options.radiuslocationid); /* WISPr location ID */
601 +       rslt += send_line(client, MSG_PART, 0, "\tradiuslocationname=%s\n",options.radiuslocationname); /* WISPr location name */
602 +       l = options.radiusnasporttype;
603 +       rslt += send_number(client, MSG_PART, 0, "\tradiusnasporttype=%s\n",l); /* NAS-Port-Type */
604 +       l = options.coaport;
605 +       rslt += send_number(client, MSG_PART, 0, "\tcoaport=%s\n",l); /* UDP port to listen to */
606 +       l = options.coanoipcheck;
607 +       rslt += send_number(client, MSG_PART, 0, "\tcoaipcheck=%s\n",l); /* Allow disconnect from any IP */
608 +       /* Radius proxy parameters */
609 +       rslt += send_line(client, MSG_PART, 0, "\tproxylisten=%s\n",inet_ntoa(options.proxylisten)); /* IP address to listen to */
610 +       l = options.proxyport;
611 +       rslt += send_number(client, MSG_PART, 0, "\tproxyport=%s\n",l); /* UDP port to listen to */
612 +       rslt += send_line(client, MSG_PART, 0, "\tproxyaddr=%s\n",inet_ntoa(options.proxyaddr)); /* IP address of proxy client(s) */
613 +       rslt += send_line(client, MSG_PART, 0, "\tproxymask=%s\n",inet_ntoa(options.proxymask)); /* IP mask of proxy client(s) */
614 +       rslt += send_line(client, MSG_PART, 0, "\tproxysecret=%s\n",options.proxysecret); /* Proxy shared secret */
615 +       /* Radius configuration management parameters */
616 +       rslt += send_line(client, MSG_PART, 0, "\tconfusername=%s\n",options.confusername); /* Username for remote config */
617 +       rslt += send_line(client, MSG_PART, 0, "\tconfpassword=%s\n",options.confpassword); /* Password for remote config */
618 +       /* DHCP parameters */
619 +       l = options.nodhcp;
620 +       rslt += send_number(client, MSG_PART, 0, "\tnodhcp=%s\n",l); /* Do not use DHCP */
621 +       rslt += send_line(client, MSG_PART, 0, "\tdhcpif=%s\n",options.dhcpif); /* Interface: eth0 */
622 +       rslt += send_mac(client, MSG_PART, 0, "\tdhcpmac=%s\n",options.dhcpmac); /* Interface MAC address */
623 +       l = options.dhcpusemac;
624 +       rslt += send_number(client, MSG_PART, 0, "\tdhcpusemac=%s\n",l); /* Use given MAC or interface default */
625 +       rslt += send_line(client, MSG_PART, 0, "\tdhcplisten=%s\n",inet_ntoa(options.dhcplisten)); /* IP address to listen to */
626 +       l = options.lease;
627 +       rslt += send_number(client, MSG_PART, 0, "\tlease=%s\n",l); /* DHCP lease time */
628 +       /* EAPOL parameters */
629 +       l = options.eapolenable;
630 +       rslt += send_number(client, MSG_PART, 0, "\teapolenable=%s\n",l); /* Use eapol */
631 +       /* UAM parameters */
632 +       l = options.uamserverlen;
633 +       rslt += send_number(client, MSG_PART, 0, "\tuamserverlen=%s\n",l); /* Number of UAM servers */
634 +       for (n = 0; n < options.uamserverlen; n++){
635 +               rslt += send_number(client, MSG_PART, 0, "\tuamokip[%s]=",n);
636 +               rslt += send_line(client, MSG_PART, 0, "%s\n",inet_ntoa(options.uamserver[n])); /* IP address of UAM server */
637 +       }
638 +       l = options.uamserverport;
639 +       rslt += send_number(client, MSG_PART, 0, "\tuamserverport=%s\n",l); /* Port of UAM server */
640 +       rslt += send_line(client, MSG_PART, 0, "\tuamsecret=%s\n",options.uamsecret); /* Shared secret */
641 +       rslt += send_line(client, MSG_PART, 0, "\tuamurl=%s\n",options.uamurl); /* URL of authentication server */
642 +       rslt += send_line(client, MSG_PART, 0, "\tuamhomepage=%s\n",options.uamhomepage); /* URL of redirection homepage */
643 +       l = options.uamhomepageport;
644 +       rslt += send_number(client, MSG_PART, 0, "\tuamhomepageport=%s\n",l); /* Port of redirection homepage */
645 +       rslt += send_line(client, MSG_PART, 0, "\tuamlisten=%s\n",inet_ntoa(options.uamlisten)); /* IP address of local authentication */
646 +       l = options.uamport;
647 +       rslt += send_number(client, MSG_PART, 0, "\tuamport=%s\n",l); /* TCP port to listen to */
648 +       l = options.uamokiplen;
649 +       rslt += send_number(client, MSG_PART, 0, "\tuamokiplen=%s\n",l); /* Number of allowed IP addresses */
650 +       for (n=0; n < options.uamokiplen; n++){
651 +               rslt += send_number(client, MSG_PART, 0, "\tuamokip[%s]=",n);
652 +               rslt = send_line(client, MSG_PART, 0, "%s\n",inet_ntoa(options.uamokip[n])); /* List of allowed IP addresses */
653 +       }
654 +       l = options.uamoknetlen;
655 +       rslt += send_number(client, MSG_PART, 0, "\tuamoknetlen=%s\n",l); /* Number of networks */
656 +       for (n=0; n < options.uamoknetlen; n++){
657 +               rslt += send_number(client, MSG_PART, 0, "\tuamoknet[%s]=",n);
658 +               rslt += send_line(client, MSG_PART, 0, "%s/",inet_ntoa(options.uamokaddr[n])); /* List of allowed network IP */
659 +               rslt += send_line(client, MSG_PART, 0, "%s\n",inet_ntoa(options.uamokmask[n])); /* List of allowed network mask */
660 +       }
661 +       l = options.uamanydns;
662 +       rslt += send_number(client, MSG_PART, 0, "\tuamanydns=%s\n",l); /* Allow client to use any DNS server */
663 +       /* MAC Authentication */
664 +       l = options.macauth;
665 +       rslt += send_number(client, MSG_PART, 0, "\tmacauth=%s\n",l); /* Use MAC authentication */
666 +       l = options.macoklen; 
667 +       rslt += send_number(client, MSG_PART, 0, "\tmacoklen=%s\n",l); /* Number of MAC addresses */
668 +       for (n=0; n < options.macoklen; n++){
669 +               rslt += send_number(client, MSG_PART, 0, "\tmacok[%s]=",n);
670 +               rslt += send_mac(client, MSG_PART, 0, "\%s\n",options.macok[n]); /* Allowed MACs */
671 +       }
672 +       rslt += send_line(client, MSG_PART, 0, "\tmacsuffix=%s\n",options.macsuffix);
673 +       rslt += send_line(client, MSG_PART, 0, "\tmacpasswd=%s\n",options.macpasswd);
674 +
675 +       rslt += send_line(client, MSG_PART, 0, "\trmtlisten=%s\n",inet_ntoa(options.rmtlisten));
676 +       l = options.rmtport; 
677 +       rslt += send_number(client, MSG_PART, 0, "\trmtport=%s\n",l); /* Number of MAC addresses */
678 +       rslt += send_line(client, MSG_PART, 0, "\trmtpasswd=%s\n",options.rmtpasswd);
679 +       rslt += send_number(client, MSG_PART, 0, "\tbandwidthmaxup=%s\n",options.bandwidthmaxup);
680 +       rslt += send_number(client, MSG_PART, 0, "\tbandwidthmaxdown=%s\n",options.bandwidthmaxdown);
681 +       rslt += rmtctrl_write_msg(client,MSG_END,0, "End of configuration\n");
682 +}
683 --- a/src/chilli.h
684 +++ b/src/chilli.h
685 @@ -50,8 +50,8 @@
686  /* If the constants below are defined packets which have been dropped
687     by the traffic shaper will be counted towards accounting and
688     volume limitation */
689 -/* #define COUNT_DOWNLINK_DROP 1 */
690 -/* #define COUNT_UPLINK_DROP 1 */
691 +#define COUNT_DOWNLINK_DROP 1 
692 +#define COUNT_UPLINK_DROP 1 
693  
694  #define APP_NUM_CONN 128
695  #define EAP_LEN 2048            /* TODO: Rather large */
696 @@ -68,7 +68,7 @@
697  #define CHALLENGESIZE 24 /* From chap.h MAX_CHALLENGE_LENGTH */
698  #define USERURLSIZE 256  /* Max length of URL requested by user */
699  
700 -#define BUCKET_SIZE  300000 /* Size of leaky bucket (~200 packets) */
701 +//#define BUCKET_SIZE  300000 /* Size of leaky bucket (~200 packets) */
702  
703  /* Time length of leaky bucket in milliseconds */
704  /* Bucket size = BUCKET_TIME * Bandwidth-Max radius attribute */
705 @@ -194,12 +194,14 @@ struct app_conn_t {
706    struct in_addr dns1;
707    struct in_addr dns2;
708    struct timeval last_time; /* Last time a packet was received or sent */
709 +  struct timeval last_up_time; /* Last time a packet was received or sent */
710 +  struct timeval last_down_time; /* Last time a packet was received or sent */
711  
712    /* Leaky bucket */
713 -  uint32_t bucketup;
714 -  uint32_t bucketdown;
715 -  uint32_t bucketupsize;
716 -  uint32_t bucketdownsize;
717 +  uint64_t bucketup;
718 +  uint64_t bucketdown;
719 +  uint64_t bucketupsize;
720 +  uint64_t bucketdownsize;
721  
722    /* UAM information */
723    uint8_t uamchal[REDIR_MD5LEN];
724 @@ -305,6 +307,11 @@ struct options_t {
725    int macoklen;                   /* Number of MAC addresses */
726    char* macsuffix;               /* Suffix to add to MAC address */
727    char* macpasswd;               /* Password to use for MAC authentication */  
728 +  struct in_addr rmtlisten;      /* IP address of remote monitor and config */
729 +  int rmtport;                   /* TCP port to listen to monitor and config*/
730 +  char* rmtpasswd;               /* Password to use for MAC authentication */  
731 +       int bandwidthmaxup;            /* Default Max Up Bandwith setting */
732 +       int bandwidthmaxdown;          /* Default Max Up Bandwith setting */
733  };
734  
735  extern struct app_conn_t connection[APP_NUM_CONN];
736 --- a/src/cmdline.c
737 +++ b/src/cmdline.c
738 @@ -113,6 +113,11 @@ void clear_given (struct gengetopt_args_
739    args_info->macallowed_given = 0 ;
740    args_info->macsuffix_given = 0 ;
741    args_info->macpasswd_given = 0 ;
742 +  args_info->rmtlisten_given = 0 ;
743 +  args_info->rmtport_given = 0 ;
744 +  args_info->rmtpasswd_given = 0 ;
745 +  args_info->bandwidthmaxup_given = 0 ;
746 +  args_info->bandwidthmaxdown_given = 0 ;
747  }
748  
749  static
750 @@ -216,7 +221,19 @@ void clear_args (struct gengetopt_args_i
751    args_info->macsuffix_orig = NULL;
752    args_info->macpasswd_arg = gengetopt_strdup ("password");
753    args_info->macpasswd_orig = NULL;
754 -  
755 +  args_info->rmtport_arg = 3991;
756 +  args_info->rmtport_orig = NULL;
757 +  args_info->rmtlisten_arg = gengetopt_strdup("127.0.0.1");
758 +       args_info->rmtlisten_orig = NULL;
759 +  args_info->rmtport_orig = NULL;
760 +  args_info->rmtpasswd_arg = NULL;
761 +  args_info->rmtpasswd_orig = NULL;
762 +
763 +  args_info->bandwidthmaxup_arg = 0;
764 +  args_info->bandwidthmaxup_orig = NULL;
765 +  args_info->bandwidthmaxdown_arg = 0;
766 +  args_info->bandwidthmaxdown_orig = NULL;
767 +       
768  }
769  
770  void
771 @@ -284,7 +301,12 @@ cmdline_parser_print_help (void)
772    printf("%s\n","      --macauth                 Authenticate based on MAC address  \n                                  (default=off)");
773    printf("%s\n","      --macallowed=STRING       List of allowed MAC addresses");
774    printf("%s\n","      --macsuffix=STRING        Suffix to add to the MAC address");
775 -  printf("%s\n","      --macpasswd=STRING        Password used when performing MAC \n                                  authentication  (default=`password')");
776 +  printf("%s\n","      --macpasswd=STRING        Password used when performing MAC       \n                                  authentication  (default='password')");
777 +  printf("%s\n","      --rmtlisten=STRING        IP address to listen to for monitor and \n                                  configuration (default=`127.0.0.1')");
778 +  printf("%s\n","      --rmtport=INT             TCP port to bind to for monitor and     \n                                  configuration (default=`3991')");
779 +  printf("%s\n","      --rmtpasswd=STRING        Password used for remote monitor and    \n                                  configuration\n");
780 +  printf("%s\n","      --bandwidthmaxup=INT      Deafaul Max Up Setting in Kilobits\n");
781 +  printf("%s\n","      --bandwidthmaxdown=INT    Deafaul Max Down Setting in Kilobits\n");
782    
783  }
784  
785 @@ -675,6 +697,11 @@ cmdline_parser_release (struct gengetopt
786        free (args_info->uamport_orig); /* free previous argument */
787        args_info->uamport_orig = 0;
788      }
789 +  if (args_info->macpasswd_orig)
790 +    {
791 +      free (args_info->macpasswd_orig); /* free previous argument */
792 +      args_info->macpasswd_orig = 0;
793 +    }
794    if (args_info->uamallowed_arg)
795      {
796        for (i = 0; i < args_info->uamallowed_given; ++i)
797 @@ -739,6 +766,34 @@ cmdline_parser_release (struct gengetopt
798        free (args_info->macpasswd_orig); /* free previous argument */
799        args_info->macpasswd_orig = 0;
800      }
801 +  if (args_info->rmtlisten_orig)
802 +    {
803 +      free (args_info->rmtlisten_orig); /* free previous argument */
804 +      args_info->rmtlisten_orig = 0;
805 +    }
806 +  if (args_info->rmtport_orig)
807 +    {
808 +      free (args_info->rmtport_orig); /* free previous argument */
809 +      args_info->rmtport_orig = 0;
810 +    }
811 +
812 +  if (args_info->rmtpasswd_orig)
813 +    {
814 +      free (args_info->rmtpasswd_orig); // free previous argument 
815 +      args_info->rmtpasswd_orig = 0;
816 +    }
817 +  
818 +  if (args_info->bandwidthmaxup_orig)
819 +    {
820 +      free (args_info->bandwidthmaxup_orig); // free previous argument 
821 +      args_info->bandwidthmaxup_orig = 0;
822 +    }
823 +  
824 +  if (args_info->bandwidthmaxdown_orig)
825 +    {
826 +      free (args_info->bandwidthmaxdown_orig); // free previous argument 
827 +      args_info->bandwidthmaxdown_orig = 0;
828 +    }
829    
830    clear_given (args_info);
831  }
832 @@ -1109,7 +1164,41 @@ cmdline_parser_file_save(const char *fil
833        fprintf(outfile, "%s\n", "macpasswd");
834      }
835    }
836 -  
837 +  if (args_info->rmtlisten_given) {
838 +    if (args_info->rmtlisten_orig) {
839 +      fprintf(outfile, "%s=\"%s\"\n", "rmtlisten", args_info->rmtlisten_orig);
840 +    } else {
841 +      fprintf(outfile, "%s\n", "rmtlisten");
842 +    }
843 +  }
844 +  if (args_info->rmtport_given) {
845 +    if (args_info->rmtport_orig) {
846 +      fprintf(outfile, "%s=\"%s\"\n", "rmtport", args_info->rmtport_orig);
847 +    } else {
848 +      fprintf(outfile, "%s\n", "rmtport");
849 +    }
850 +  }
851 +  if (args_info->rmtpasswd_given) {
852 +    if (args_info->rmtpasswd_orig) {
853 +      fprintf(outfile, "%s=\"%s\"\n", "rmtpasswd", args_info->rmtpasswd_orig);
854 +    } else {
855 +      fprintf(outfile, "%s\n", "rmtpasswd");
856 +    }
857 +  }
858 +  if (args_info->bandwidthmaxup_given) {
859 +    if (args_info->bandwidthmaxup_orig) {
860 +      fprintf(outfile, "%s=\"%s\"\n", "bandwidthmaxup", args_info->bandwidthmaxup_orig);
861 +    } else {
862 +      fprintf(outfile, "%s\n", "bandwidthmaxup");
863 +    }
864 +  }
865 +  if (args_info->bandwidthmaxdown_given) {
866 +    if (args_info->bandwidthmaxdown_orig) {
867 +      fprintf(outfile, "%s=\"%s\"\n", "bandwidthmaxdown", args_info->bandwidthmaxdown_orig);
868 +    } else {
869 +      fprintf(outfile, "%s\n", "bandwidthmaxdown");
870 +    }
871 +  }
872    fclose (outfile);
873  
874    i = EXIT_SUCCESS;
875 @@ -1221,6 +1310,7 @@ cmdline_parser_internal (int argc, char 
876  {
877    int c;       /* Character of the parsed option.  */
878    char *multi_token, *multi_next; /* for multiple options */
879 +       char quehace[100];
880  
881    int i;        /* Counter */
882  
883 @@ -1299,6 +1389,11 @@ cmdline_parser_internal (int argc, char 
884          { "macallowed",        1, NULL, 0 },
885          { "macsuffix", 1, NULL, 0 },
886          { "macpasswd", 1, NULL, 0 },
887 +        { "rmtport",   1, NULL, 0 },
888 +        { "rmtlisten", 1, NULL, 0 },
889 +        { "rmtpasswd", 1, NULL, 0 },
890 +        { "bandwidthmaxup",    1, NULL, 0 },
891 +        { "bandwidthmaxdown",  1, NULL, 0 },
892          { NULL,        0, NULL, 0 }
893        };
894  
895 @@ -1380,8 +1475,6 @@ cmdline_parser_internal (int argc, char 
896              free (args_info->net_orig); /* free previous string */
897            args_info->net_orig = gengetopt_strdup (optarg);
898            break;
899 -
900 -
901          case 0:        /* Long option with no short option */
902            /* Which modules to print debug messages for.  */
903            if (strcmp (long_options[option_index].name, "debugfacility") == 0)
904 @@ -2273,7 +2366,93 @@ cmdline_parser_internal (int argc, char 
905                free (args_info->macpasswd_orig); /* free previous string */
906              args_info->macpasswd_orig = gengetopt_strdup (optarg);
907            }
908 -          
909 +          /* IP address to listen to for remote monitor and config.  */
910 +          else if (strcmp (long_options[option_index].name, "rmtlisten") == 0)
911 +          {
912 +            if (local_args_info.rmtlisten_given)
913 +              {
914 +                fprintf (stderr, "%s: `--rmtlisten' option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
915 +                goto failure;
916 +              }
917 +            if (args_info->rmtlisten_given && ! override)
918 +              continue;
919 +            local_args_info.rmtlisten_given = 1;
920 +            args_info->rmtlisten_given = 1;
921 +            if (args_info->rmtlisten_arg)
922 +              free (args_info->rmtlisten_arg); /* free previous string */
923 +            args_info->rmtlisten_arg = gengetopt_strdup (optarg);
924 +            if (args_info->rmtlisten_orig)
925 +              free (args_info->rmtlisten_orig); /* free previous string */
926 +            args_info->rmtlisten_orig = gengetopt_strdup (optarg);
927 +          }
928 +          /* TCP port to bind to for authentication requests.  */
929 +          else if (strcmp (long_options[option_index].name, "rmtport") == 0)
930 +          {
931 +            if (local_args_info.rmtport_given)
932 +              {
933 +                fprintf (stderr, "%s: `--rmtport' option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
934 +                goto failure;
935 +              }
936 +            if (args_info->rmtport_given && ! override)
937 +              continue;
938 +            local_args_info.rmtport_given = 1;
939 +            args_info->rmtport_given = 1;
940 +            args_info->rmtport_arg = strtol (optarg,&stop_char,0);
941 +            if (args_info->rmtport_orig)
942 +              free (args_info->rmtport_orig); /* free previous string */
943 +            args_info->rmtport_orig = gengetopt_strdup (optarg);
944 +          }
945 +          /* Password used when performing remote config.  */
946 +          else if (strcmp (long_options[option_index].name, "rmtpasswd") == 0)
947 +          {
948 +            if (local_args_info.rmtpasswd_given)
949 +              {
950 +                fprintf (stderr, "%s: `--rmtpasswd' option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
951 +                goto failure;
952 +              }
953 +            if (args_info->rmtpasswd_given && ! override)
954 +              continue;
955 +            local_args_info.rmtpasswd_given = 1;
956 +            args_info->rmtpasswd_given = 1;
957 +            if (args_info->rmtpasswd_arg)
958 +              free (args_info->rmtpasswd_arg); // free previous string 
959 +            args_info->rmtpasswd_arg = gengetopt_strdup (optarg);
960 +            if (args_info->rmtpasswd_orig)
961 +              free (args_info->rmtpasswd_orig); // free previous string 
962 +            args_info->rmtpasswd_orig = gengetopt_strdup (optarg);
963 +          }
964 +          else if (strcmp (long_options[option_index].name, "bandwidthmaxup") == 0)
965 +          {
966 +            if (local_args_info.bandwidthmaxup_given)
967 +              {
968 +                fprintf (stderr, "%s: `--bandwidthmaxup' option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
969 +                goto failure;
970 +              }
971 +            if (args_info->bandwidthmaxup_given && ! override)
972 +              continue;
973 +            local_args_info.bandwidthmaxup_given = 1;
974 +            args_info->bandwidthmaxup_given = 1;
975 +            args_info->bandwidthmaxup_arg = strtol (optarg,&stop_char,0);
976 +            if (args_info->bandwidthmaxup_orig)
977 +              free (args_info->bandwidthmaxup_orig); /* free previous string */
978 +            args_info->bandwidthmaxup_orig = gengetopt_strdup (optarg);
979 +          }
980 +          else if (strcmp (long_options[option_index].name, "bandwidthmaxdown") == 0)
981 +          {
982 +            if (local_args_info.bandwidthmaxdown_given)
983 +              {
984 +                fprintf (stderr, "%s: `--bandwidthmaxdown' option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
985 +                goto failure;
986 +              }
987 +            if (args_info->bandwidthmaxdown_given && ! override)
988 +              continue;
989 +            local_args_info.bandwidthmaxdown_given = 1;
990 +            args_info->bandwidthmaxdown_given = 1;
991 +            args_info->bandwidthmaxdown_arg = strtol (optarg,&stop_char,0);
992 +            if (args_info->bandwidthmaxdown_orig)
993 +              free (args_info->bandwidthmaxdown_orig); /* free previous string */
994 +            args_info->bandwidthmaxdown_orig = gengetopt_strdup (optarg);
995 +          }
996            break;
997          case '?':      /* Invalid option.  */
998            /* `getopt_long' already printed an error message.  */
999 --- a/src/cmdline.ggo
1000 +++ b/src/cmdline.ggo
1001 @@ -119,3 +119,12 @@ option "macallowed"  - "List of allowed 
1002  option "macsuffix"   - "Suffix to add to the MAC address" string no
1003  option "macpasswd"   - "Password used when performing MAC authentication" string default="password" no
1004  
1005 +# Remote Monitor and Config
1006 +option "rmtlisten"   - "IP address to listen to for authentication requests" string default="127.0.0.1" no
1007 +option "rmtport"     - "TCP port to bind to for authentication requests" int default="3991" no
1008 +option "rmtpasswd"   - "Password used when performing MAC authentication" string no
1009 +
1010 +# Extra settings
1011 +option "bandwidthmaxup" - "Default bandwidth control to apply when account don't have setting" int no
1012 +option "bandwidthmaxdown" - "Default bandwidth control to apply when account don't have setting" int no
1013 +
1014 --- a/src/cmdline.h
1015 +++ b/src/cmdline.h
1016 @@ -122,6 +122,17 @@ struct gengetopt_args_info
1017    char * macsuffix_orig;       /* Suffix to add to the MAC address original value given at command line.  */
1018    char * macpasswd_arg;        /* Password used when performing MAC authentication (default='password').  */
1019    char * macpasswd_orig;       /* Password used when performing MAC authentication original value given at command line.  */
1020 +  int rmtport_arg;     /* TCP port to bind to for remote monitor and config (default='3991').  */
1021 +  char * rmtport_orig; /* TCP port to bind to for remote monitor and config original value given at command line.  */
1022 +  char * rmtlisten_arg;        /* IP address to listen to for remote monitor and config.  */
1023 +  char * rmtlisten_orig;       /* IP address to listen to for remote monitor and config original value given at command line.  */
1024 +  char * rmtpasswd_arg;        /* Password for remote monitor and config.  */
1025 +  char * rmtpasswd_orig;       /* Password for remote monitor and config original value given at command line.  */
1026 +  int bandwidthmaxup_arg;      /* Default Bandwidth Max Up.  */
1027 +  char *bandwidthmaxup_orig;   /* Default Bandwidth Max Up value given at command line.  */
1028 +  int bandwidthmaxdown_arg;    /* Default Bandwidth Max Down.  */
1029 +  char *bandwidthmaxdown_orig; /* Default Bandwidth Max Down value given at command line.  */
1030 +
1031    
1032    int help_given ;     /* Whether help was given.  */
1033    int version_given ;  /* Whether version was given.  */
1034 @@ -177,7 +188,11 @@ struct gengetopt_args_info
1035    unsigned int macallowed_given ;      /* Whether macallowed was given.  */
1036    int macsuffix_given ;        /* Whether macsuffix was given.  */
1037    int macpasswd_given ;        /* Whether macpasswd was given.  */
1038 -
1039 +  int rmtport_given ;  /* Whether uamport was given.  */
1040 +  int rmtlisten_given ;        /* Whether uamlisten was given.  */
1041 +  int rmtpasswd_given ;        /* Whether confpassword was given.  */
1042 +       int bandwidthmaxup_given ;
1043 +       int bandwidthmaxdown_given ;
1044  } ;
1045  
1046  int cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info);
1047 --- a/src/Makefile
1048 +++ b/src/Makefile
1049 @@ -54,7 +54,7 @@ PROGRAMS = $(sbin_PROGRAMS)
1050  am_chilli_OBJECTS = chilli.$(OBJEXT) tun.$(OBJEXT) cmdline.$(OBJEXT) \
1051         ippool.$(OBJEXT) radius.$(OBJEXT) md5.$(OBJEXT) \
1052         redir.$(OBJEXT) dhcp.$(OBJEXT) syserr.$(OBJEXT) \
1053 -       iphash.$(OBJEXT) lookup.$(OBJEXT)
1054 +       iphash.$(OBJEXT) lookup.$(OBJEXT)  remotectrl.$(OBJEXT)
1055  chilli_OBJECTS = $(am_chilli_OBJECTS)
1056  chilli_LDADD = $(LDADD)
1057  DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
1058 @@ -172,7 +172,7 @@ target_alias = 
1059  
1060  # add -pg to enable gprof
1061  AM_CFLAGS = -D_GNU_SOURCE -fno-builtin -DSBINDIR='"$(sbindir)"' 
1062 -chilli_SOURCES = chilli.c defs.h tun.c tun.h cmdline.c cmdline.h ippool.c ippool.h radius.h radius.c md5.c md5.h redir.h redir.c dhcp.c dhcp.h syserr.c syserr.h iphash.c iphash.h lookup.c lookup.h
1063 +chilli_SOURCES = chilli.c defs.h tun.c tun.h cmdline.c cmdline.h ippool.c ippool.h radius.h radius.c md5.c md5.h redir.h redir.c dhcp.c dhcp.h syserr.c syserr.h iphash.c iphash.h lookup.c lookup.h remotectrl.c remotectrl.h
1064  all: all-am
1065  
1066  .SUFFIXES:
1067 --- a/src/Makefile.in
1068 +++ b/src/Makefile.in
1069 @@ -54,7 +54,7 @@ PROGRAMS = $(sbin_PROGRAMS)
1070  am_chilli_OBJECTS = chilli.$(OBJEXT) tun.$(OBJEXT) cmdline.$(OBJEXT) \
1071         ippool.$(OBJEXT) radius.$(OBJEXT) md5.$(OBJEXT) \
1072         redir.$(OBJEXT) dhcp.$(OBJEXT) syserr.$(OBJEXT) \
1073 -       iphash.$(OBJEXT) lookup.$(OBJEXT)
1074 +       iphash.$(OBJEXT) lookup.$(OBJEXT)  remotectrl.$(OBJEXT)
1075  chilli_OBJECTS = $(am_chilli_OBJECTS)
1076  chilli_LDADD = $(LDADD)
1077  DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
1078 @@ -172,7 +172,7 @@ target_alias = @target_alias@
1079  
1080  # add -pg to enable gprof
1081  AM_CFLAGS = -D_GNU_SOURCE -fno-builtin -DSBINDIR='"$(sbindir)"' 
1082 -chilli_SOURCES = chilli.c defs.h tun.c tun.h cmdline.c cmdline.h ippool.c ippool.h radius.h radius.c md5.c md5.h redir.h redir.c dhcp.c dhcp.h syserr.c syserr.h iphash.c iphash.h lookup.c lookup.h
1083 +chilli_SOURCES = chilli.c defs.h tun.c tun.h cmdline.c cmdline.h ippool.c ippool.h radius.h radius.c md5.c md5.h redir.h redir.c dhcp.c dhcp.h syserr.c syserr.h iphash.c iphash.h lookup.c lookup.h remotectrl.c remotectrl.h
1084  all: all-am
1085  
1086  .SUFFIXES:
1087 --- /dev/null
1088 +++ b/src/remotectrl.c
1089 @@ -0,0 +1,340 @@
1090 +#include <stdio.h>          
1091 +#include <sys/types.h>
1092 +#include <sys/socket.h>
1093 +#include <netinet/in.h>
1094 +#include <errno.h>
1095 +
1096 +#include "remotectrl.h"
1097 +
1098 +/*
1099 +char *vstrcat(char *first, ...)
1100 +{
1101 +       size_t len = 0;
1102 +       char *retbuf;
1103 +       va_list argp;
1104 +       char *p;
1105 +       char *tmp="";
1106 +       if(first == NULL)
1107 +               first=tmp;
1108 +//             return NULL;
1109 +       
1110 +       len = strlen(first);
1111 +               
1112 +       va_start(argp, first);
1113 +
1114 +       while((p = va_arg(argp, char *)) != NULL)
1115 +               len += strlen(p);
1116 +
1117 +       va_end(argp);
1118 +       retbuf = (char *)malloc(len + 1);       // +1 for trailing \0 
1119 +
1120 +       if(retbuf == NULL)
1121 +               return NULL;            // error 
1122 +
1123 +       (void)strcpy(retbuf, first);
1124 +
1125 +       va_start(argp, first);
1126 +
1127 +       while((p = va_arg(argp, char *)) != NULL)
1128 +               (void)strcat(retbuf, p);
1129 +
1130 +       va_end(argp);
1131 +
1132 +       return retbuf;
1133 +}
1134 +*/
1135 +
1136 +int rmtctrl_write_msg( struct rmt_socket_t *sckHnd, uint32_t id, uint32_t extra, char *message ){
1137 +       msg_head_t header;
1138 +       int rslt;
1139 +       header.id    = id;
1140 +       header.len   = strlen(message);
1141 +       header.extra = extra;
1142 +  rslt = send(sckHnd->fd,&header,sizeof(struct msg_head_t),0);
1143 +       if (rslt != -1 && header.len > 0) {
1144 +               sckHnd->Tx += rslt;
1145 +               rslt = send(sckHnd->fd, message, header.len, 0);
1146 +               if (rslt > 0)
1147 +               {
1148 +                       sckHnd->Tx += rslt;
1149 +                       rslt += sizeof(struct msg_head_t);
1150 +               }
1151 +       }
1152 +       return rslt;
1153 +}
1154 +
1155 +int rmtctrl_read_msg( struct rmt_socket_t *sckHnd, msg_head_t *head, char **message )
1156 +{
1157 +//     msg_head_t header;
1158 +       int rslt;
1159 +       char *buffer;
1160 +       int reading = 0;
1161 +       int aux = 0;
1162 +  rslt = recv(sckHnd->fd, head, sizeof(struct msg_head_t), 0);
1163 +       if (rslt == sizeof(struct msg_head_t) ) {
1164 +               sckHnd->Rx += rslt;
1165 +               *message = (char *)malloc(head->len+1);
1166 +               memset(*message,'\0', head->len+1);
1167 +               while ( reading < head->len ){
1168 +                       aux = recv(sckHnd->fd, *message, head->len, 0);
1169 +                       switch ( aux ) 
1170 +                       {
1171 +                               case -1:
1172 +                                       switch (errno)
1173 +                                       {
1174 +                                               case EINTR:
1175 +                                               case EAGAIN:
1176 +                                                       usleep (100);
1177 +                                                       break;
1178 +                                               default:
1179 +                                                       return -1;
1180 +                                       }
1181 +                               break;
1182 +                               case 0: // mean socket was closed
1183 +                                       sckHnd->Rx += reading;
1184 +                                       return reading;
1185 +                                       break;
1186 +                               break;
1187 +                               default:
1188 +                                       reading+=aux;
1189 +                               break;
1190 +                       }
1191 +               }
1192 +/*
1193 +               buffer = (char *)malloc(head->len+1);
1194 +               while ( reading < head->len ){
1195 +                       memset(buffer,'\0', head->len+1);
1196 +                       aux = recv(sckHnd->fd, buffer, head->len, 0);
1197 +                       switch ( aux ) {
1198 +                               case -1:
1199 +                                       switch (errno){
1200 +                                               case EINTR:
1201 +                                               case EAGAIN:
1202 +                                                       usleep (100);
1203 +                                                       break;
1204 +                                               default:
1205 +                                                       return -1;
1206 +                                       }
1207 +                               break;
1208 +                               case 0: // mean socket was closed
1209 +                                       sckHnd->Rx += reading;
1210 +                                       return reading;
1211 +                                       break;
1212 +                               break;
1213 +                               default:
1214 +                                       if (reading == 0) 
1215 +                                               *message=(char *)malloc(aux+1);
1216 +                                       else
1217 +                                               *message=(char*)realloc(*message,(reading+aux+1)*sizeof(char));
1218 +//                                             strcat(*message, buffer);
1219 +                                       memcpy(*message+reading, buffer, aux);
1220 +                                       reading += aux;
1221 +                                       *message[reading]=0;
1222 +                       }
1223 +               }
1224 +               free(buffer);
1225 +*/
1226 +               sckHnd->Rx += reading;
1227 +               reading += rslt;
1228 +               return reading;
1229 +       }
1230 +       return rslt;
1231 +}
1232 +
1233 +void rmtctrl_newClient(struct rmt_socket_t srv, struct rmt_socket_t *client, int *activeClients)
1234 +{
1235 +       int rslt;
1236 +       int cli = (*activeClients);
1237 +       rmtctrl_accept(srv,&client[cli]);
1238 +       if (client[(*activeClients)].fd != -1)
1239 +       {
1240 +               (*activeClients)++;
1241 +       }
1242 +       if ((*activeClients) >= MAX_CLIENTS)
1243 +       {
1244 +               (*activeClients)--;
1245 +               rslt = rmtctrl_write_msg(&client[(*activeClients)],MSG_END,0, "Sorry Server is too Busy\n       Try more late\n" );
1246 +               if (rslt > 0) client[(*activeClients)].Tx += rslt;
1247 +               rmtctrl_close(&client[(*activeClients)]);
1248 +       }
1249 +}
1250 +
1251 +void rmtctrl_close ( struct rmt_socket_t *client )
1252 +{
1253 +       printf("Desde %s se recibieron %d bytes y se enviaron %d bytes\n",inet_ntoa(client->addr.sin_addr),client->Rx,client->Tx);
1254 +       close(client->fd); /* cierra fd_rmt_client */
1255 +       printf("Se cerro conexiĂ³n desde %s\n",inet_ntoa(client->addr.sin_addr) ); 
1256 +       client->fd = -1;
1257 +}
1258 +
1259 +void rmtctrl_accept (struct rmt_socket_t srv, struct rmt_socket_t *client ) 
1260 +{
1261 +       int sin_size=sizeof(struct sockaddr_in);
1262 +       int int_Send;
1263 +       struct sockaddr_in addr;
1264 +       
1265 +       if ((client->fd = accept(srv.fd,(struct sockaddr *)&client->addr,&sin_size))!=-1) 
1266 +       {
1267 +               client->Rx = 0;
1268 +               client->Tx = 0;
1269 +               unsigned char c = sizeof(uint32_t);
1270 +               int_Send = send(client->fd, &c, 1, 0);
1271 +               if (int_Send > 0) client->Tx += int_Send;
1272 +               printf("Se abriĂ³ una conexiĂ³n desde %s\n", inet_ntoa(client->addr.sin_addr)); 
1273 +       }
1274 +}
1275 +
1276 +//void cleanClients (int *table, int *n)
1277 +void rmtctrl_cleanClients (struct rmt_socket_t *client, int *n)
1278 +{
1279 +       int i,j;
1280 +
1281 +       if ((client == NULL) || ((*n) == 0))
1282 +               return;
1283 +
1284 +       j=0;
1285 +       for (i=0; i<(*n); i++)
1286 +       {
1287 +               if (client[i].fd != -1)
1288 +               {
1289 +                       client[j].fd = client[i].fd;
1290 +                       client[j].addr = client[i].addr;
1291 +                       client[j].Rx = client[i].Rx;
1292 +                       client[j].Tx = client[i].Tx;
1293 +                       j++;
1294 +               }
1295 +       }
1296 +       
1297 +       *n = j;
1298 +}
1299 +
1300 +int rmtctrl_maxValue (struct rmt_socket_t *client, int n)
1301 +{
1302 +       int i;
1303 +       int max;
1304 +
1305 +       if ((client == NULL) || (n<1))
1306 +               return 0;
1307 +               
1308 +       max = client[0].fd;
1309 +       for (i=0; i<n; i++)
1310 +               if (client[i].fd > max)
1311 +                       max = client[i].fd;
1312 +
1313 +       return max;
1314 +}
1315 +
1316 +struct rmt_socket_t rmtctrl_initSrv(struct in_addr rmtlisten, int rmtport){
1317 +       struct rmt_socket_t srv;
1318 +       if ((srv.fd=socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {  
1319 +               printf("error en socket()\n");
1320 +               exit(1);
1321 +       }
1322 +       srv.addr.sin_family = AF_INET;
1323 +       srv.addr.sin_port = htons(rmtport); 
1324 +       srv.addr.sin_addr.s_addr = rmtlisten.s_addr;
1325 +       memset(&(srv.addr.sin_zero), 0, 8); 
1326 +
1327 +       if(bind(srv.fd,(struct sockaddr*)&srv.addr,sizeof(struct sockaddr))==-1) {
1328 +               printf("error en bind() \n");
1329 +               exit(-1);
1330 +       }     
1331 +
1332 +       if(listen(srv.fd,BACKLOG) == -1) {
1333 +               printf("error en listen()\n");
1334 +               exit(-1);
1335 +       }
1336 +       return srv;
1337 +}
1338 +
1339 +void rmtctrl_srv(struct rmt_socket_t srv, struct rmt_socket_t *client, int *activeClients)
1340 +{
1341 +       fd_set fdRead;
1342 +       int maxHnd;
1343 +       int i;
1344 +       struct timeval  nowait; 
1345 +       memset((char *)&nowait,0,sizeof(nowait)); 
1346 +
1347 +       rmtctrl_cleanClients(client, activeClients);
1348 +       FD_ZERO (&fdRead);
1349 +       FD_SET (srv.fd, &fdRead);
1350 +
1351 +       for (i=0; i<*activeClients; i++)
1352 +               FD_SET (client[i].fd, &fdRead);
1353 +
1354 +       maxHnd = rmtctrl_maxValue (client, *activeClients);
1355 +               
1356 +       if (maxHnd < srv.fd)
1357 +               maxHnd = srv.fd;
1358 +
1359 +       select (maxHnd + 1, &fdRead, NULL, NULL,&nowait);
1360 +       for (i=0; i<*activeClients; i++)
1361 +       {
1362 +               if (FD_ISSET (client[i].fd, &fdRead))
1363 +               {
1364 +                               rmtctrl_msg_proccess(&client[i]);
1365 +               }
1366 +       }
1367 +       if (FD_ISSET (srv.fd, &fdRead))
1368 +               rmtctrl_newClient(srv,client, &(*activeClients));
1369 +}
1370 +
1371 +int send_line( struct rmt_socket_t *client, int msg_type, int msg_extra, char *fmt, char *data)
1372 +{
1373 +       char str[2048];
1374 +       memset(str,'\0',2048);
1375 +       sprintf(str,fmt,data);
1376 +       return rmtctrl_write_msg(client,msg_type,msg_extra, str);
1377 +}
1378 +
1379 +int send_octets( struct rmt_socket_t *client, int msg_type, int msg_extra, char *fmt, uint64_t value)
1380 +{
1381 +       char *Buffer = (char *)octets2str(value);
1382 +       int ret = send_line( client, msg_type, msg_extra, fmt, Buffer);
1383 +       free(Buffer);
1384 +       return ret;
1385 +}
1386 +
1387 +int send_mac( struct rmt_socket_t *client, int msg_type, int msg_extra, char *fmt, uint8_t *value)
1388 +{
1389 +       char *Buffer = (char*)mac2str(value);
1390 +       int ret = send_line( client, msg_type, msg_extra, fmt, Buffer);
1391 +       free(Buffer);
1392 +       return ret;
1393 +}
1394 +
1395 +int send_number( struct rmt_socket_t *client, int msg_type, int msg_extra, char *fmt, uint64_t value)
1396 +{
1397 +       char Buffer[64];
1398 +       sprintf(Buffer,"%d", value);
1399 +       return send_line( client, msg_type, msg_extra, fmt, Buffer);
1400 +}
1401 +
1402 +const char * mac2str(uint8_t *mac)
1403 +{
1404 +       char *buffer;
1405 +       buffer=(char*)malloc(18*sizeof(char));
1406 +       memset(buffer,'\0',18);
1407 +       (void) sprintf(buffer,"%.2X-%.2X-%.2X-%.2X-%.2X-%.2X",
1408 +                   mac[0], mac[1],
1409 +                   mac[2], mac[3],
1410 +                   mac[4], mac[5]);
1411 +       return buffer;
1412 +}
1413 +
1414 +const char * octets2str(uint64_t value)
1415 +{
1416 +       char *buffer;
1417 +       buffer=(char*)malloc(13*sizeof(char));
1418 +       memset(buffer,'\0',13);
1419 +       if (value/8 > 1073741824){ // gigas
1420 +               sprintf(buffer,"%.1f(GiB)",((value/8.0)/1073741824.0));
1421 +       }else if (value/8 > 1048576){ // megas
1422 +               sprintf(buffer,"%.1f(MiB)",((value/8.0)/1048576.0));
1423 +       }else if (value/8 > 1024){ // KiloBytes
1424 +               sprintf(buffer,"%.1f(KiB)",((value/8.0)/1024.0));
1425 +       }else // Bytes
1426 +               sprintf(buffer,"%.1f(B)",(value/8));
1427 +       return buffer;
1428 +}
1429 +
1430 --- /dev/null
1431 +++ b/src/remotectrl.h
1432 @@ -0,0 +1,86 @@
1433 +#include <stdarg.h>
1434 +#ifndef _RMTCTRL_H
1435 +#define _RMTCTRL_H
1436 +
1437 +enum 
1438 +{
1439 +       MSG_OK              = 0,
1440 +       MSG_START           = 1,
1441 +       MSG_PART            = 2,
1442 +       MSG_END             = 3,
1443 +       QRY_STATUS          = 100,
1444 +       QRY_CONNECTED_LIST      = 101,
1445 +       QRY_CONNECTED_FULL_LIST = 102,
1446 +       QRY_MACADDR         = 103,
1447 +       QRY_IPADDR          = 104,
1448 +       QRY_USERNAME        = 105,
1449 +
1450 +       CMD_AUTHORIZE                           = 200,
1451 +       CMD_DISCONNECT                  = 201,
1452 +       
1453 +       EXTRA_ALL_OP                            = 300,
1454 +       EXTRA_MAC_OP                            = 301,
1455 +       EXTRA_IP_OP                                     = 302,
1456 +       EXTRA_USER_OP                           = 303,
1457 +};
1458 +
1459 +enum
1460 +{
1461 +       STRING,
1462 +       IP_ADDR,
1463 +       MAC_ADDR,
1464 +       NUMBER,
1465 +       OCTETS,
1466 +};
1467 +
1468 +#define PORT 15557 /* El puerto que ser? abierto */
1469 +#define BACKLOG 2 /* El n?mero de conexiones permitidas */
1470 +#define MAX_CLIENTS 10
1471 +static char CONVERT_BUFF[1024];
1472 +
1473 +typedef struct msg_head_t {
1474 +       uint32_t id;
1475 +       uint32_t extra;
1476 +       uint32_t len;
1477 +} msg_head_t;
1478 +
1479 +typedef struct rmt_socket_t {
1480 +       int fd;
1481 +       struct sockaddr_in addr;
1482 +       int Rx;
1483 +       int Tx;
1484 +} rmt_socket_t;
1485 +
1486 +//char *vstrcat(char *first, ...);
1487 +
1488 +       
1489 +int rmtctrl_write_msg( struct rmt_socket_t *sckHnd, uint32_t id, uint32_t extra, char *message );
1490 +int rmtctrl_read_msg( struct rmt_socket_t *sckHnd, msg_head_t *head, char **message );
1491 +void rmtctrl_newClient(struct rmt_socket_t srv, struct rmt_socket_t *client, int *activeClients);
1492 +void rmtctrl_close ( struct rmt_socket_t *client );
1493 +void rmtctrl_accept (struct rmt_socket_t srv, struct rmt_socket_t *client );
1494 +void rmtctrl_cleanClients (struct rmt_socket_t *client, int *n);
1495 +
1496 +//inicializa las variables y arranca el servidor
1497 +struct rmt_socket_t rmtctrl_initSrv(struct in_addr rmtlisten, int rmtport);
1498 +//esta funcion es la que va dentro del loop del programa que lo utiliza
1499 +void rmtctrl_srv(struct rmt_socket_t srv, struct rmt_socket_t *client, int *activeClients);
1500 +//En esta funcion es donde se define como se procesan los mensajes
1501 +void rmtctrl_msg_proccess(struct rmt_socket_t *client);
1502 +
1503 +//char * pepe(char *dest, char *sep, char *src);
1504 +
1505 +//char * send_value(char *name, char *value, int len, struct in_addr *addr,
1506 +//         uint8_t *mac, long int *integer);
1507 +//int addfield(char* reg, char *field, char sep);
1508 +//int addfield1(char** reg,int rlen, char *field, int flen, char sep);
1509 +//int sendConnectedInfo(struct app_conn_t *appconn, struct rmt_socket_t *client); 
1510 +//const char * value2str( int type, void *value);
1511 +const char * octets2str(uint64_t value);
1512 +const char * mac2str(uint8_t *mac);
1513 +int send_line( struct rmt_socket_t *client, int msg_type, int msg_extra, char *fmt, char *data);
1514 +int send_octets( struct rmt_socket_t *client, int msg_type, int msg_extra, char *fmt, uint64_t value);
1515 +int send_mac( struct rmt_socket_t *client, int msg_type, int msg_extra, char *fmt, uint8_t *value);
1516 +int send_number( struct rmt_socket_t *client, int msg_type, int msg_extra, char *fmt, uint64_t value);
1517 +
1518 +#endif /* !_RMTCTRL_H */
1519 --- a/src/Makefile.am
1520 +++ b/src/Makefile.am
1521 @@ -3,7 +3,7 @@ sbin_PROGRAMS = chilli
1522  # add -pg to enable gprof
1523  AM_CFLAGS = -D_GNU_SOURCE -fno-builtin -DSBINDIR='"$(sbindir)"' 
1524  
1525 -chilli_SOURCES = chilli.c defs.h tun.c tun.h cmdline.c cmdline.h ippool.c ippool.h radius.h radius.c md5.c md5.h redir.h redir.c dhcp.c dhcp.h syserr.c syserr.h iphash.c iphash.h lookup.c lookup.h
1526 +chilli_SOURCES = chilli.c defs.h tun.c tun.h cmdline.c cmdline.h ippool.c ippool.h radius.h radius.c md5.c md5.h redir.h redir.c dhcp.c dhcp.h syserr.c syserr.h iphash.c iphash.h lookup.c lookup.h remotectrl.c remotectrl.h
1527  
1528  # chilli_LDFLAGS = -lcrypt
1529