/* Finds entry from REG_DB by comparing mac address */ Reg_t* regdb_find_mac(LaneDestination_t maddr) { Reg_t *tmp; tmp = reglist; while (tmp) { if((tmp->mac_address).tag == htons(LANE_DEST_MAC)) { if (memcmp((char *)&(tmp->mac_address).a_r.mac_address, (char *)&maddr.a_r.mac_address, 6) ==0) { Debug_unit(&conn_unit, "MAC found from database"); return tmp; } } else if ((tmp->mac_address).tag == htons(LANE_DEST_RD)) { if (memcmp((char *)&(tmp->mac_address.a_r.route), (char *)&maddr.a_r.route, 4 + sizeof(unsigned short)) == 0) { Debug_unit(&conn_unit, "MAC found from database"); return tmp; } else if (memcmp((char *)&(tmp->mac_address), (char *)&maddr, sizeof(LaneDestination_t)) == 0) { Debug_unit(&conn_unit, "MAC found from database"); return tmp; } } tmp = tmp->next; } Debug_unit(&conn_unit, "MAC address not found from database"); return NULL; }
/* Dump status, local data etc. */ static void mem_dump_all(void) { Debug_unit(&mem_unit, "Memory statistics:"); mem_dump(NULL); Debug_unit(&mem_unit, "%d allocs, %d frees", alloccount, freecount); }
ConnState_t call_state(EventType_t event, unsigned short opcode, Conn_t *conn) { State_t **tmp; unsigned int i = 0; int ret; Debug_unit(&conn_unit, "Call state"); assert(conn != NULL); assert(conn->state <= CS_MAX); tmp = transitions[conn->state]; for(; tmp[i] != NULL; i++) { if (tmp[i]->event == event && htons(tmp[i]->opcode) == opcode) { Debug_unit(&conn_unit, "Trying func %s", tmp[i]->descript); ret = tmp[i]->func(conn); if (ret != 0){ Debug_unit(&conn_unit, "Success"); return tmp[i]->nextstate; } else { Debug_unit(&conn_unit, "Failed"); } } else { Debug_unit(&conn_unit, "Skipping func %s", tmp[i]->descript); } } return conn->state; }
/* Release allocated memory, close files etc. */ static void mem_release(void) { MemList_t *tmp; Debug_unit(&mem_unit, "Releasing unit"); for (tmp = memlist; tmp != NULL; tmp = tmp->next) { Debug_unit(&mem_unit, "memory not released: unit %s size %u ptr 0x%x", tmp->unit->name, tmp->memsize, tmp->mem); mem_free(&mem_unit, tmp->mem); } }
/* Searches LECID-DB for entry */ Lecdb_t *leciddb_find(LecId_t to_find) { Lecdb_t *tmp; tmp = leclist; while(tmp) { if (to_find == tmp->lecid) { Debug_unit(&conn_unit, "Lecdb_t found"); return tmp; } tmp = tmp->next; } Debug_unit(&conn_unit,"Lecdb_t not found from database"); return NULL; }
Lecdb_t *leciddb_find_atm(AtmAddr_t to_find) { Lecdb_t *tmp; tmp = leclist; while (tmp) { if (memcmp(&to_find,&(tmp->address), sizeof(AtmAddr_t)) == 0) { Debug_unit(&conn_unit, "Lecdb_t found"); return tmp; } tmp= tmp->next; } Debug_unit(&conn_unit,"Lecid_t not found from database"); return NULL; }
/* Release allocated memory, close files etc. */ static void conn_release(void) { Conn_t *tmp; Reg_t *rtmp; Lecdb_t *ltmp; Proxy_t *ptmp; Debug_unit(&conn_unit, "Releasing unit"); for(tmp = connlist; tmp != NULL; tmp = tmp->next) { connlist = tmp->next; if (tmp->fd) close(tmp->fd); if (tmp->sfd) close(tmp->sfd); mem_free(&conn_unit, tmp); } for(rtmp = reglist; rtmp != NULL; rtmp = rtmp->next) { reglist = rtmp->next; mem_free(&conn_unit, rtmp); } for(ltmp = leclist; ltmp != NULL; ltmp = ltmp->next) { leclist = ltmp->next; mem_free(&conn_unit, ltmp); } for(ptmp = proxylist; ptmp != NULL; ptmp = ptmp->next) { proxylist = ptmp->next; mem_free(&conn_unit, ptmp); } }
int leciddb_remove(LecId_t to_remove) { Lecdb_t *tmp, *tmp2; Debug_unit(&conn_unit,"Leciddb_remove"); if (leclist == NULL) { return 0; } tmp = leclist; if (to_remove == tmp->lecid) { leclist =tmp->next; mem_free(&conn_unit, tmp); return 1; } tmp2 = tmp; tmp = tmp->next; while(tmp) { if (to_remove == tmp->lecid) { tmp2->next = tmp->next; mem_free(&conn_unit, tmp); return 1; } tmp = tmp->next; } dump_error(&conn_unit,"Trying to remove unexisting entry from LECID-DB"); return 0; }
Proxy_t* proxydb_find(LecId_t to_find) { Proxy_t *tmp; tmp = proxylist; while(tmp) { if (to_find == tmp->lecid) { Debug_unit(&conn_unit, "Proxy_t found"); return tmp; } tmp = tmp->next; } Debug_unit(&conn_unit,"Proxy_t not found from database"); return NULL; }
static void atm_init1(void) { set_var_str(&atm_unit, "version", rcsid); Debug_unit(&atm_unit,"Initialized"); }
/* Removes entry from PROXY-DB */ int proxydb_remove(const Conn_t *conn) { Proxy_t *tmp, *tmp2; Debug_unit(&conn_unit,"Proxydb_remove"); if (proxylist == NULL) { return 0; } tmp = proxylist; if (conn->lecid == tmp->lecid) { proxylist =tmp->next; mem_free(&conn_unit, tmp); return 1; } tmp2 = tmp; tmp = tmp->next; while(tmp) { if (conn->lecid == tmp->lecid) { tmp2->next = tmp->next; mem_free(&conn_unit, tmp); return 1; } tmp = tmp->next; } dump_error(&conn_unit,"Trying to remove unexisting entry from PROXY-DB"); return 0; }
/* Removes entry from REG-DB. Returns 0 if entry is not found. 1 otherwise. */ int regdb_remove(AtmAddr_t to_remove) { Reg_t *tmp, *tmp2; Debug_unit(&conn_unit,"Regdb_remove"); if (reglist == NULL) { return 0; } tmp = reglist; if (memcmp((char *)&to_remove, (char *)&tmp->atm_address, sizeof(AtmAddr_t)) == 0) { reglist =tmp->next; mem_free(&conn_unit, tmp); return 1; } tmp2 = tmp; tmp = tmp->next; while(tmp) { if (memcmp((char *)&to_remove, (char *)&tmp->atm_address, sizeof(AtmAddr_t)) == 0) { tmp2->next = tmp->next; mem_free(&conn_unit, tmp); return 1; } tmp = tmp->next; } dump_error(&conn_unit,"Trying to remove unexisting entry from REG-DB"); return 0; }
static int register_req(Conn_t *conn) { Reg_t *tmp; Lecdb_t *ltmp; Debug_unit(&conn_unit, "Register_req called"); dump_conn(conn); assert(control_packet != NULL); /* If trying to register a multicast or broadcast address, reject */ if (is_multicast(&control_packet->source)) { send_register_response(conn->sfd, control_packet, LE_STATUS_BAD_DEST, 1); return 1; } /* Check lecid */ ltmp = leciddb_find(control_packet->lecid); if (!ltmp) { send_register_response(conn->sfd, control_packet, LE_STATUS_BAD_LECID, 1); return 1; } tmp = regdb_find_mac(control_packet->source); if (tmp == NULL) { /* Unregistered MAC, registering... */ dump_addr(&control_packet->source); dump_printf(EL_CONT,"\n"); regdb_add(control_packet->source_addr, control_packet->source); send_register_response(conn->sfd, control_packet, LE_STATUS_SUCCESS, 1); } else { if (memcmp(&tmp->atm_address,&control_packet->source_addr, sizeof(AtmAddr_t)) != 0) { Debug_unit(&conn_unit, "MAC Address is bound to another ATM address"); send_register_response(conn->sfd, control_packet, LE_STATUS_DUPLICATE_REG, 1); } else { Debug_unit(&conn_unit,"Duplicate registeration"); send_register_response(conn->sfd, control_packet, LE_STATUS_SUCCESS, 1); } } return 1; }
static int idle_bad(Conn_t *conn) { Debug_unit(&conn_unit, "Idle bad called"); dump_conn(conn); conn_remove(conn); return 1; }
/* Initialization for data that needs other units */ static void conn_init1(void) { set_var_str(&conn_unit, "version", rcsid); conn_main(); add_event_handler(CE_DATA, &data_handler, "data_handler", NULL); add_event_handler(CE_TIMER, &timer_handler, "timer_handler", NULL); Debug_unit(&conn_unit, "Initialized."); }
static int join_expire(Conn_t *conn) { Debug_unit(&conn_unit, "Join_expire called"); dump_conn(conn); conn_remove(conn); return 1; }
/* Dump status, local data etc. */ static void dump_dump(void) { static const char *dumptypes [] = { "none", "standard error", "file", "syslog()", "cmn_err()", "/dev/console" }; Debug_unit(&dump_unit, "Dumping to %s, filename: %s", dumptypes[dump_open], dump_filename); }
static int arp_find(Conn_t *conn) { Reg_t *tmp; Lecdb_t *ltmp; Debug_unit(&conn_unit, "Arp_find called"); dump_conn(conn); Debug_unit(&conn_unit,"Arping for:"); dump_addr(&control_packet->target); dump_printf(EL_CONT,"\n"); /* If requested multicast /broadcast address, respond with BUS address */ if (is_multicast(&control_packet->target)) { tmp = mem_alloc(&conn_unit, sizeof(Reg_t)); memcpy(&tmp->atm_address, get_var_addr(&conn_unit, "S6"), sizeof(AtmAddr_t)); Debug_unit(&conn_unit,"Arp for multicast address"); send_arp_response(conn->sfd, control_packet, LE_STATUS_SUCCESS, tmp); return 1; } /* Check lecid */ ltmp = leciddb_find(control_packet->lecid); if (!ltmp) { send_arp_response(conn->sfd, control_packet, LE_STATUS_BAD_LECID, NULL); return 1; } tmp = regdb_find_mac(control_packet->target); if (tmp) { Debug_unit(&conn_unit,"Address in databases"); /* Send response */ send_arp_response(conn->sfd, control_packet, LE_STATUS_SUCCESS, tmp); return 1; } forward_arp_request(control_packet, proxylist); return 1; }
/* Release allocated memory, close files etc. */ static void load_release(void) { VarList_t *tmp; LaneDestList_t *ltmp, *ltmp2; Debug_unit(&load_unit, "Releasing unit"); for (tmp = varlist; tmp != NULL;) { Debug_unit(&load_unit, "Freeing var %s/%s", tmp->var->unit->name, tmp->var->name); assert(tmp->var != NULL); assert(tmp->var->name != NULL); varlist = varlist->next; if (tmp->var->type == VT_STR){ assert(tmp->var->val_u.strval != NULL); mem_free(&load_unit, tmp->var->val_u.strval); } if (tmp->var->type == VT_ADDR){ assert(tmp->var->val_u.addrval != NULL); mem_free(&load_unit, tmp->var->val_u.addrval); } if (tmp->var->type == VT_PVC){ assert(tmp->var->val_u.init != NULL); assert(tmp->var->val_u.init->pvc != NULL); mem_free(&load_unit, tmp->var->val_u.init->pvc); assert(tmp->var->val_u.init->address != NULL); mem_free(&load_unit, tmp->var->val_u.init->address); ltmp = tmp->var->val_u.init->destinations; while (ltmp != NULL) { ltmp2 = ltmp->next; assert(ltmp->addr != NULL); mem_free(&load_unit, ltmp->addr); mem_free(&load_unit, ltmp); ltmp = ltmp2; } mem_free(&load_unit, tmp->var->val_u.init); } mem_free(&load_unit, tmp->var->name); mem_free(&load_unit, tmp->var); mem_free(&load_unit, tmp); tmp = varlist; } }
/* Dump memory allocation information about unit, NULL == all units */ void mem_dump(const Unit_t *unit) { MemList_t *tmp; for (tmp = memlist; tmp != NULL; tmp = tmp->next) { if (unit == NULL || strcmp(tmp->unit->name, unit->name) == 0) { Debug_unit(&mem_unit, "unit %s size %u ptr 0x%x", tmp->unit->name, tmp->memsize, tmp->mem); } } }
void dump_conn(const Conn_t *connection) { Conn_t *tmp; for(tmp = connlist; tmp != NULL; tmp = tmp->next) { if (connection == NULL || tmp == connection) { Debug_unit(&conn_unit, "fd %d sfd %d state %s type %s", tmp->fd, tmp->sfd, dump_conn_state(tmp->state), dump_conn_type(tmp->type)); } } }
static int join_bad(Conn_t *conn) { Debug_unit(&conn_unit, "Join_bad called"); dump_conn(conn); if (proper_request()==0) { send_join_response(conn->sfd, control_packet, conn->lecid, (unsigned short)LE_STATUS_BAD_REQ); } return 1; }
/* Dump status, local data etc. */ static void timer_dump(void) { TimerList_t *tmp; for (tmp = timerlist; tmp != NULL; tmp = tmp->next) { assert(tmp->timer != NULL); assert(tmp->timer->unit != NULL); assert(tmp->timer->unit->name != NULL); Debug_unit(&timer_unit, "unit %s alarm %d data 0x%x", tmp->timer->unit->name, tmp->timer->alarm_time, tmp->timer->data); } }
/* Adds entry to REG-DB */ void regdb_add(AtmAddr_t aaddr, LaneDestination_t maddr) { Reg_t *tmp; Debug_unit(&conn_unit,"Regdb_add"); tmp = (Reg_t *)mem_alloc(&conn_unit, sizeof(Reg_t)); memcpy(&tmp->mac_address, &maddr,sizeof(LaneDestination_t)); memcpy(&tmp->atm_address, &aaddr, sizeof(AtmAddr_t)); tmp->next = reglist; reglist = tmp; return; }
/* Free memory block */ void mem_free(const Unit_t *unit, const void *mem) { MemList_t *tmp, *prev = NULL; Bool_t debug; freecount++; debug = get_var_bool(unit, "memdebug"); if (debug == BL_TRUE) { Debug_unit(&mem_unit, "unit %s frees ptr 0x%x", unit->name, mem); } for (tmp = memlist; tmp != NULL; prev = tmp, tmp = tmp->next) { if (tmp->mem == mem) { break; } } /* Found a match? */ if (tmp) { if (strcmp(tmp->unit->name, unit->name) != 0) { Debug_unit(&mem_unit, "unit %s frees ptr 0x%x size %d allocated by unit %s", unit->name, tmp->mem, tmp->memsize, tmp->unit->name); } if (memlist == tmp) { memlist = tmp->next; } if (prev != NULL) { prev->next = tmp->next; } if (debug == BL_TRUE) { Debug_unit(&mem_unit, "freeing %d bytes", tmp->memsize); } free(tmp->mem); free(tmp); } else { if (debug == BL_TRUE) { Debug_unit(&mem_unit, "could not find block 0x%x for freeing", mem); } } }
int send_control_frame(int fd, LaneControl_t *to_send) { int a; Debug_unit(&conn_unit,"Send control frame"); dump_control(to_send); a = write(fd, to_send, sizeof(LaneControl_t)); if (a == -1) { dump_error(&conn_unit,"Write error"); return 0; } return 1; }
/* Adds entry to LECID-DB */ void leciddb_add(LecId_t lecid, AtmAddr_t address, const int fd) { Lecdb_t *tmp; Debug_unit(&conn_unit, "Leciddb_add called"); tmp = (Lecdb_t *) mem_alloc(&conn_unit, sizeof(Lecdb_t)); tmp->fd = fd; memcpy(&tmp->address, &address, sizeof(AtmAddr_t)); tmp->lecid = lecid; tmp->next = leclist; leclist = tmp; return; }
/* Adds entry to PROXY-DB */ void proxydb_add(const Conn_t *conn, int fd) { Proxy_t *tmp; assert(conn != NULL); Debug_unit(&conn_unit,"Proxydb_add"); tmp = (Proxy_t *) mem_alloc(&conn_unit, sizeof(Proxy_t)); tmp->lecid = conn->lecid; tmp->fd = fd; tmp->next = proxylist; proxylist = tmp; return; }
int send_join_response(int fd, LaneControl_t *lc, int lecid, unsigned int status) { Debug_unit(&conn_unit,"Send_join_response called to %d",fd); lc->opcode = htons(LE_JOIN_RESPONSE); lc->status = (unsigned short)htons(0xffff & status); lc->lecid = lecid; if (send_control_frame(fd, lc) == 0) { dump_error(&conn_unit,"Send join response failed"); return 0; } return 1; }
static int forward_flush_response(Conn_t *conn) { int a; Debug_unit(&conn_unit, "Forward_flush_response called"); dump_conn(conn); for (conn = connlist; conn; conn=conn->next) { if (conn->sfd) { a = send_control_frame(conn->sfd, control_packet); if (a == 0) dump_error(&conn_unit, "Forward flush response failed"); } } return 1; }