00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config/compiler.h"
00027 #include "core/include/global.h"
00028 #include <linux/version.h>
00029 #include <linux/proc_fs.h>
00030 #include <linux/module.h>
00031 #include <linux/kernel.h>
00032 #include <asm/uaccess.h>
00033 #include "conf.h"
00034
00035 static struct proc_dir_entry *directory;
00036
00037
00038 int conf_init_proc(void) {
00039 printk(KERN_ERR "Initializing /proc files (net device)...");
00040 directory = get_proc_root();
00041 directory = proc_mkdir("port", directory);
00042 if (!directory) {
00043 remove_proc_entry("port");
00044 return -ENOMEM;
00045 }
00046 return 1;
00047 }
00048
00049
00050 int conf_close_proc(tpConfig *conf) {
00051 int i;
00052 for (i = 0; i < conf->udp_in.count; i++) {
00053 remove_proc_entry(conf->udp_in.port[i].proc_entry->name, directory);
00054 };
00055
00056 for (i = 0; i < conf->tcp_out.count; i++) {
00057 remove_proc_entry(conf->tcp_out.port[i].proc_entry->name, directory);
00058 };
00059
00060 for (i = 0; i < conf->udp_out.count; i++) {
00061 remove_proc_entry(conf->udp_out.port[i].proc_entry->name, directory);
00062 };
00063
00064 for (i = 0; i < conf->tcp_in.count; i++) {
00065 remove_proc_entry(conf->tcp_in.port[i].proc_entry->name, directory);
00066 };
00067 remove_proc_entry(directory->name, directory->parent);
00068 return 1;
00069 }
00070
00071 int f_port_read(char *page, char **start, off_t off, int count, int *eof,
00072 void *data) {
00073 if (off > 0) {
00074 *eof = 1;
00075 return 0;
00076 } else {
00077 tpPort * tp = (tpPort*) data;
00078 return sprintf(page, "%u\n", tp->priority);
00079 }
00080 }
00081
00082
00083
00084 int f_port_write(struct file *f, const char __user *buff, unsigned long len, void *data ){
00085 char aux[32];
00086 tpPort * tp;
00087 int val, size = (len>32?32:len);
00088
00089 if (copy_from_user(aux, buff, size)) {
00090 return -EFAULT;
00091 }
00092 aux[size-1]='\0';
00093
00094 val = atoi(aux);
00095 tp = (tpPort*) data;
00096 tp->priority = val;
00097
00098 return len;
00099 }
00100
00101
00102
00108 void asign_port (tpPortConf* portConf, u16 number, signed char priority, tpTraffic traffic, int type) {
00109 if (number == 0) {
00110 portConf->count = -1;
00111 portConf->port[0].number = number;
00112 portConf->port[0].priority = priority;
00113 portConf->port[0].traffic = traffic;
00114 } else {
00115
00116
00117 if(portConf->count != -1 && portConf->count < NUM_PORTS) {
00118 portConf->port[portConf->count].number = number;
00119 portConf->port[portConf->count].priority = priority;
00120 portConf->port[portConf->count].traffic = traffic;
00121
00122 {
00123 char txt[64];
00124 if (type == 1){
00125 sprintf(txt,"udp_in_%d",number);
00126 }else if (type == 2){
00127 sprintf(txt,"udp_out_%d",number);
00128 } if (type == 3){
00129 sprintf(txt,"tcp_in_%d",number);
00130 } if (type == 4){
00131 sprintf(txt,"tcp_out_%d",number);
00132 }
00133
00134 portConf->port[portConf->count].proc_entry = create_proc_entry(txt, 0666, directory);
00135 if(!portConf->port[portConf->count].proc_entry){
00136
00137 }
00138 portConf->port[portConf->count].proc_entry->read_proc = f_port_read;
00139 portConf->port[portConf->count].proc_entry->write_proc = f_port_write;
00140
00141 portConf->port[portConf->count].proc_entry->data = (void*) &(portConf->port[portConf->count]);
00142
00143 }
00144 portConf->count++;
00145 }
00146 }
00147 }
00148
00152 void asignConfICMP (tpPortConfICMP* portConf, signed char priority, tpTraffic traffic) {
00153 if (portConf->count == 0) {
00154 portConf->count++;
00155 portConf->priority = priority;
00156 portConf->traffic = traffic;
00157 } else {
00158 printk(KERN_INFO "ICMP already has a configuration.");
00159 }
00160 }
00161
00162 int readConfig(tpConfig *conf) {
00163 struct file *f;
00164 char proto[6], dir[5], traf[10], line[256];
00165 tpTraffic traffic;
00166 int port, priority;
00167 int exists, ret = 0;
00168
00169
00170 conf->udp_in.count=0;
00171 conf->udp_out.count=0;
00172 conf->tcp_in.count=0;
00173 conf->tcp_out.count=0;
00174 conf->icmp.count=0;
00175
00176
00177 f = filp_open("/etc/rt-wmp/interface.cfg", O_RDONLY, 0);
00178 if (IS_ERR(f)) {
00179 printk(KERN_INFO "File /etc/rt-wmp/interface.cfg not found...\n");
00180 return 0;
00181 }
00182
00183
00184 printk(KERN_INFO "Reading /etc/rt-wmp/interface.cfg...\n");
00185 while (fgets(line,256,f) != NULL) {
00186 if (line[0]<65 || line[0]>90){
00187 continue;
00188 }
00189
00190 if(sscanf(line,"%s %s %d %d %s",proto,dir, &port, &priority, traf) != 5){
00191 printk(KERN_INFO "MALFORMED: %s\n",line);
00192 continue;
00193 }
00194
00195 if (strcmp(traf, "NORMAL") == 0) {
00196 traffic = OTHER;
00197 } else if (strcmp(traf, "QoS") == 0) {
00198 traffic = QoS;
00199 } else {
00200 printk(KERN_INFO "Wrong type of traffic: %s\n",traf);
00201 continue;
00202 }
00203
00204 exists = 0;
00205 if (strcmp(proto, "UDP") == 0) {
00206 if (strcmp(dir, "FROM") == 0) {
00207 asign_port(&conf->udp_in, port, priority, traffic, 1);
00208 exists = 1;
00209 } else if (strcmp(dir, "TO") == 0) {
00210 asign_port(&conf->udp_out, port, priority, traffic, 2);
00211 exists = 1;
00212 } else if (strcmp(dir, "BOTH") == 0) {
00213 asign_port(&conf->udp_in, port, priority, traffic, 1);
00214 asign_port(&conf->udp_out, port, priority, traffic, 2);
00215 exists = 1;
00216 } else {
00217 printk(KERN_INFO "*** UNKNOWN DIRECTION %s\n", dir);
00218 }
00219 } else if (strcmp(proto, "TCP") == 0) {
00220 if (strcmp(dir, "FROM") == 0) {
00221 asign_port(&conf->tcp_in, port, priority, traffic, 3);
00222 exists = 1;
00223 } else if (strcmp(dir, "TO") == 0) {
00224 asign_port(&conf->tcp_out, port, priority, traffic, 4);
00225 exists = 1;
00226 } else if (strcmp(dir, "BOTH") == 0) {
00227 asign_port(&conf->tcp_in, port, priority, traffic, 3);
00228 asign_port(&conf->tcp_out, port, priority, traffic, 4);
00229 exists = 1;
00230 } else {
00231 printk(KERN_INFO "*** UNKNOWN DIRECTION %s\n", dir);
00232 }
00233 } else if (strcmp(proto, "ICMP") == 0) {
00234 asignConfICMP(&conf->icmp, priority, traffic);
00235 exists = 1;
00236 } else {
00237 printk(KERN_INFO "*** UNKNOWN PROTOCOL %s\n", proto);
00238 }
00239
00240 if (exists) {
00241 printk(KERN_INFO "READ: %s %s %d %d %s\n", proto, dir, port, priority, traf);
00242 }
00243 ret = (ret || exists);
00244 }
00245 printk(KERN_INFO "Done.\n");
00246
00247
00248 filp_close(f,0);
00249
00250
00251
00252 return ret;
00253 }
00254
00255 int __getPortConf (tpPortConf* portConf, u16 port, signed char *priority, tpTraffic *traffic) {
00256 int i, ret = 0;
00257 if(portConf->count == -1) {
00258 *priority = portConf->port[0].priority;
00259 *traffic = portConf->port[0].traffic;
00260 ret = 1;
00261 } else {
00262 for(i=0; i<portConf->count && !ret; i++){
00263 ret = (port == portConf->port[i].number);
00264 if(ret) {
00265 *priority = portConf->port[i].priority;
00266 *traffic = portConf->port[i].traffic;
00267 }
00268 }
00269 }
00270 return ret;
00271 }
00272
00273 int getPortConf (tpConfig *conf, tpProto proto, tpDir dir, u16 port, signed char *priority, tpTraffic *traffic){
00274 int ret = 0;
00275
00276 switch(proto){
00277 case UDP:
00278 if (dir == FROM) {
00279 ret = __getPortConf(&conf->udp_in, port, priority, traffic);
00280 } else {
00281 ret = __getPortConf(&conf->udp_out, port, priority, traffic);
00282 }
00283 break;
00284 case TCP:
00285 if (dir == FROM) {
00286 ret = __getPortConf(&conf->tcp_in, port, priority, traffic);
00287 } else {
00288 ret = __getPortConf(&conf->tcp_out, port, priority, traffic);
00289 }
00290 break;
00291 }
00292
00293 return ret;
00294 }
00295
00296 int getConfICMP (tpConfig* conf, signed char *priority, tpTraffic *traffic) {
00297 int ret = 0;
00298 if(conf->icmp.count > 0) {
00299 *priority = conf->icmp.priority;
00300 *traffic = conf->icmp.traffic;
00301 ret = 1;
00302 }
00303 return ret;
00304 }