int main(int argc, char **argv) { int i; unsigned char *pnsap; struct sockaddr_atmsvc addr; unsigned char buffer[1024]; if (argc != 2) { printf("Usage: %s <name> \n", argv[0]); exit(0); } if (text2atm(argv[1], (struct sockaddr *) &addr, sizeof(addr), T2A_NAME) < 0) { perror("text2atm()"); exit(1); } if (atm2text(buffer, 1024, (struct sockaddr *) &addr, A2T_NAME) < 0) { perror("atm2text()"); exit(2); } printf("Looking up %s \n", argv[1]); printf("Direct: "); pnsap = (unsigned char *) &(addr.sas_addr.prv); for (i = 0; i < 20; i++) { printf("%02X", pnsap[i]); } printf("\n"); printf("Reverse: %s \n", buffer); exit(0); }
static int atm_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) { struct rtattr *tb[TCA_ATM_MAX+1]; char buffer[MAX_ATM_ADDR_LEN+1]; if (opt == NULL) return 0; parse_rtattr_nested(tb, TCA_ATM_MAX, opt); if (tb[TCA_ATM_ADDR]) { if (RTA_PAYLOAD(tb[TCA_ATM_ADDR]) < sizeof(struct sockaddr_atmpvc)) fprintf(stderr,"ATM: address too short\n"); else { if (atm2text(buffer,MAX_ATM_ADDR_LEN, RTA_DATA(tb[TCA_ATM_ADDR]),A2T_PRETTY | A2T_NAME) < 0) fprintf(stderr,"atm2text error\n"); fprintf(f,"pvc %s ",buffer); } } if (tb[TCA_ATM_HDR]) { int i; const __u8 *hdr = RTA_DATA(tb[TCA_ATM_HDR]); fprintf(f,"hdr"); for (i = 0; i < RTA_PAYLOAD(tb[TCA_ATM_HDR]); i++) fprintf(f,"%c%02x", i ? '.' : ' ', hdr[i]); if (!i) fprintf(f," ."); fprintf(f," "); } if (tb[TCA_ATM_EXCESS]) { __u32 excess; if (RTA_PAYLOAD(tb[TCA_ATM_EXCESS]) < sizeof(excess)) fprintf(stderr,"ATM: excess class ID too short\n"); else { excess = rta_getattr_u32(tb[TCA_ATM_EXCESS]); if (!excess) fprintf(f,"excess clp "); else { char buf[64]; print_tc_classid(buf,sizeof(buf),excess); fprintf(f,"excess %s ",buf); } } } if (tb[TCA_ATM_STATE]) { static const char *map[] = { ATM_VS2TXT_MAP }; int state; if (RTA_PAYLOAD(tb[TCA_ATM_STATE]) < sizeof(state)) fprintf(stderr,"ATM: state field too short\n"); else { state = *(int *) RTA_DATA(tb[TCA_ATM_STATE]); fprintf(f,"%s ",map[state]); } } return 0; }
int arp_ioctl(struct atmarp_req *req) { ITF *itf; char buffer[MAX_ATM_ADDR_LEN+1]; unsigned char *ipp; diag(COMPONENT,DIAG_DEBUG,"arp_ioctl %d",req->type); itf = lookup_itf_by_ip(req->ip); if (!itf) return -EHOSTUNREACH; if (!(req->ip & ~itf->netmask) && !(req->flags & ATF_ARPSRV) && req->type != art_qos) return -EADDRNOTAVAIL; ipp = (unsigned char *) &req->ip; switch (req->type) { case art_qos: diag(COMPONENT,DIAG_DEBUG,"got art_qos for itf %d",itf->number); if (qos_present(&req->qos)) itf->qos = req->qos; if (req->sndbuf) itf->sndbuf = req->sndbuf; return 0; case art_set: if (atm2text(buffer,MAX_ATM_ADDR_LEN+1, (struct sockaddr *) &req->addr,pretty) < 0) { diag(COMPONENT,DIAG_ERROR,"a2t fails on art_set"); return -EINVAL; } diag(COMPONENT,DIAG_DEBUG,"got art_set for itf %d, IP %d.%d.%d.%d" ", ATM %s, flags 0x%x",itf->number,ipp[0],ipp[1],ipp[2],ipp[3], buffer,req->flags); if (!qos_present(&req->qos)) req->qos = itf->qos; if (!req->sndbuf) req->sndbuf = itf->sndbuf; switch (req->addr.sas_family) { case AF_ATMPVC: adjust_qos(itf,&req->qos,req->flags & ATF_NULL); return ioctl_set_pvc(itf,req->ip, (struct sockaddr_atmpvc *) &req->addr,&req->qos, req->sndbuf,req->flags); case AF_ATMSVC: adjust_qos(itf,&req->qos,0); return ioctl_set_svc(itf,req->ip, (struct sockaddr_atmsvc *) &req->addr,&req->qos, req->sndbuf,req->flags); default: /* not reached - atm2text complains before */ diag(COMPONENT,DIAG_ERROR,"art_set: bad HA AF 0x%x", req->addr.sas_family); return -EINVAL; } case art_delete: diag(COMPONENT,DIAG_DEBUG,"got art_delete for itf %d, IP " "%d.%d.%d.%d",itf->number,ipp[0],ipp[1],ipp[2],ipp[3]); return ioctl_delete(itf,req->ip,req->flags); default: diag(COMPONENT,DIAG_ERROR,"unrecognized type %d",req->type); return -EINVAL; } }
static int query_result(struct atmarp_req *reply) { unsigned char *ipp = (unsigned char *) &reply->ip; char buf[MAX_ATM_ADDR_LEN+1]; int error; printf("IP: %d.%d.%d.%d\n",ipp[0],ipp[1],ipp[2],ipp[3]); if (!atmsvc_addr_in_use(reply->addr)) return 0; error = atm2text(buf,sizeof(buf),(struct sockaddr *) &reply->addr, A2T_PRETTY | A2T_NAME) < 0; if (error) strcpy(buf,"<invalid>"); printf("ATM: %s\n",buf); return error ? 1 : 0; }
/* Assign vcc to a atmxxx device and connect to the ATM socket */ void rt2684_setup(void) { struct atm_qos qos; struct sockaddr_atmpvc addr; int flags,sndbuf; int fd; char buffer[MAX_ATM_ADDR_LEN+1]; text2atm(local_addr, (struct sockaddr *) &addr, sizeof(addr),T2A_PVC); // "0.0.40" if (!vcc_encap) flags = ATF_NULL; memset(&qos, 0, sizeof(qos)); qos.aal = ATM_AAL5; qos.txtp.traffic_class = ATM_UBR; qos.txtp.max_sdu = RFC1483LLC_LEN+RFC1626_MTU; qos.rxtp = qos.txtp; sndbuf = 0; if (atm2text(buffer,MAX_ATM_ADDR_LEN+1, (struct sockaddr *) &addr,pretty) < 0) { diag(COMPONENT,DIAG_ERROR,"rt2684_setup: atm2text fails"); return; } if (addr.sap_family != AF_ATMPVC) { diag(COMPONENT,DIAG_ERROR,"rt2684_setup: bad HA AF 0x%x", addr.sap_family); return; } adjust_qos(&qos,flags & ATF_NULL); if ((fd = connect_vcc((struct sockaddr *)&addr,&qos,sndbuf,0)) < 0) return; #if 0 if (flags & ATF_NULL) { if ((result = set_encap(fd,0)) < 0) return; flags |= ATF_PERM; } #endif setup_done=1; }
static void setup_call(SIG_ENTITY *sig,unsigned long call_ref) { SOCKET *sock,*this,**walk; struct sockaddr_atmsvc in_addr; struct atm_sap in_sap; struct atm_qos in_qos; unsigned int problem; int i; problem = sap_decode(&in_dsc,&in_addr,&in_sap,&in_qos,sig->uni); if (problem) { send_release_complete(sig,call_ref,IE_PB_CAUSE(problem), IE_PB_IE(problem)); return; } if (!atmsvc_addr_in_use(in_addr)) { send_release_complete(sig,call_ref,ATM_CV_UNALLOC); return; } if (!allow(&in_addr,ACL_IN)) { send_release_complete(sig,call_ref,ATM_CV_REJ_CLIR); return; } this = new_sock(kptr_null); this->sig = sig; sock = lookup_sap(&in_addr,&in_sap,&in_qos,&this->local,&this->sap, &this->qos,0); if (!sock) { free_sock(this); send_release_complete(sig,call_ref,ATM_CV_INCOMP_DEST); return; } this->state = sig->mode == sm_net ? ss_proceeding : ss_indicated; this->call_state = cs_in_proc; this->call_ref = call_ref; if (q_present(&in_dsc,QF_ep_ref)) this->ep_ref = cvt_ep_ref(sig,q_fetch(&in_dsc,QF_ep_ref)); #ifdef CISCO else #endif if (sig->mode == sm_net) { int error; error = send_call_proceeding(this); if (error) { free_sock(this); send_release_complete(sig,call_ref,ATM_CV_NO_CI); return; } } /* if (sock->local) *this->local->sas_addr = sock->local->sas_addr; ??? */ diag(COMPONENT,DIAG_DEBUG,"AAL type %ld",q_fetch(&in_dsc,QF_aal_type)); if (sig->mode == sm_user) { /* already set by send_call_proceeding */ int vpci; vpci = q_fetch(&in_dsc,QF_vpi); this->pvc.sap_family = AF_ATMPVC; this->pvc.sap_addr.itf = get_itf(sig,&vpci); this->pvc.sap_addr.vpi = vpci; this->pvc.sap_addr.vci = q_fetch(&in_dsc,QF_vci); } diag(COMPONENT,DIAG_DEBUG,"ITF.VPI.VCI: %d.%d.%d",this->pvc.sap_addr.itf, this->pvc.sap_addr.vpi,this->pvc.sap_addr.vci); if (q_present(&in_dsc,QF_cgpn)) { /* should handle E.164 too */ char buffer[MAX_ATM_ADDR_LEN+1]; int plan; plan = q_fetch(&in_dsc,QF_cgpn_plan); switch (plan) { case ATM_NP_AEA: i = q_read(&in_dsc,QF_cgpn,(void *) this->remote.sas_addr.prv, ATM_ESA_LEN); break; case ATM_NP_E164: i = q_read(&in_dsc,QF_cgpn,(void *) this->remote.sas_addr.pub, ATM_E164_LEN); break; default: diag(COMPONENT,DIAG_WARN,"Ignoring cgpn with unrecognized " "numbering plan 0x%x\n",plan); i = 0; } if (i) { this->remote.sas_family = AF_ATMSVC; if (atm2text(buffer,MAX_ATM_ADDR_LEN+1, (struct sockaddr *) &this->remote,pretty) < 0) strcpy(buffer,"<invalid address>"); diag(COMPONENT,DIAG_DEBUG,"Incoming call from %s",buffer); } } send_kernel(kptr_null,sock->id,as_indicate,0,&this->pvc,&this->remote, &in_addr,&this->sap,&this->qos); for (walk = &sock->listen; *walk; walk = &(*walk)->listen); *walk = this; diag(COMPONENT,DIAG_DEBUG,"SE vpi.vci=%d.%d",this->pvc.sap_addr.vpi, this->pvc.sap_addr.vci); }
static void uni_call(SOCKET *sock,unsigned char mid) { char buffer[MAX_ATM_ADDR_LEN+1]; int error; switch (mid) { case ATM_MSG_STATUS: /* 5.5.6.12 */ { CALL_STATE state; /* * NOTE: T322 isn't implemented yet, but when it is, make sure * to only stop it on STATUS iff the cause is * ATM_CV_RESP_STAT_ENQ. Supplementary services break if * you stop on any STATUS. */ state = q_fetch(&in_dsc,QF_call_state); if (state == cs_null) break; /* clear call */ if (sock->call_state == cs_rel_req || sock->call_state == cs_rel_ind) return; if (state != sock->call_state) diag(COMPONENT,DIAG_WARN,"STATUS %s received in state %s", cs_name[state],cs_name[sock->call_state]); } return; default: ; } switch (mid) { case ATM_MSG_CALL_PROC: /* CONNECTING, WAIT_REL, REL_REQ */ if (sock->state == ss_wait_rel || sock->state == ss_rel_req) { send_status(sock->sig,sock,0,ATM_CV_INCOMP_MSG, ATM_MSG_CALL_PROC); return; } if (sock->state != ss_connecting) break; /* check for 2nd CALL_PROC @@@ */ STOP_TIMER(sock); if (q_present(&in_dsc,QG_conn_id)) { int vpci; vpci = q_fetch(&in_dsc,QF_vpi); sock->pvc.sap_family = AF_ATMPVC; sock->pvc.sap_addr.itf = get_itf(sock->sig,&vpci); sock->pvc.sap_addr.vpi = vpci; sock->pvc.sap_addr.vci = q_fetch(&in_dsc,QF_vci); diag(COMPONENT,DIAG_DEBUG,"ITF.VPI.VCI: %d.%d.%d", sock->pvc.sap_addr.itf,sock->pvc.sap_addr.vpi, sock->pvc.sap_addr.vci); } START_TIMER(sock,T310); sock->call_state = cs_out_proc; return; case ATM_MSG_CONNECT: /* CONNECTING, REL_REQ */ if (sock->state == ss_rel_req) { send_status(sock->sig,sock,0,ATM_CV_INCOMP_MSG,ATM_MSG_CONNECT); return; } if (sock->state != ss_connecting) break; STOP_TIMER(sock); if (q_present(&in_dsc,QG_conn_id)) { int vpci; vpci = q_fetch(&in_dsc,QF_vpi); sock->pvc.sap_family = AF_ATMPVC; sock->pvc.sap_addr.itf = get_itf(sock->sig,&vpci); sock->pvc.sap_addr.vpi = vpci; sock->pvc.sap_addr.vci = q_fetch(&in_dsc,QF_vci); diag(COMPONENT,DIAG_DEBUG,"ITF.VPI.VCI: %d/%d.%d", sock->pvc.sap_addr.itf,sock->pvc.sap_addr.vpi, sock->pvc.sap_addr.vci); } error = 0; if (!sock->pvc.sap_addr.vpi && !sock->pvc.sap_addr.vci) error = -EPROTO; /* more problems */ if (error) { set_error(sock,error); send_release(sock,0); /* @@@ cause follows reason ??? */ START_TIMER(sock,T308_1); new_state(sock,ss_rel_req); return; } send_connect_ack(sock); /* @@@ fill in sock->remote */ /* @@@ fill in traffic parameters */ send_kernel(sock->id,kptr_null,as_okay,0,&sock->pvc,NULL, &sock->local,&sock->sap,&sock->qos); new_state(sock,ss_connected); #if defined(Q2963_1) || defined(DYNAMIC_UNI) sock->owner = 1; #endif if (atm2text(buffer,MAX_ATM_ADDR_LEN+1,(struct sockaddr *) &sock->remote,0) < 0) strcpy(buffer,"<invalid>"); diag(COMPONENT,DIAG_INFO,"Active open succeeded (CR 0x%06X, " "ID %s, to %s)",sock->call_ref,kptr_print(&sock->id),buffer); return; case ATM_MSG_CONN_ACK: /* ACCEPTING, WAIT_REL, REL_REQ */ diag(COMPONENT,DIAG_DEBUG,"CA vpi.vci=%d.%d", sock->pvc.sap_addr.vpi,sock->pvc.sap_addr.vci); if (sock->state == ss_wait_rel || sock->state == ss_rel_req) { send_status(sock->sig,sock,0,ATM_CV_INCOMP_MSG, ATM_MSG_CONN_ACK); return; } if (sock->state != ss_accepting) break; STOP_TIMER(sock); send_kernel(sock->id,kptr_null,as_okay,0,NULL,NULL,&sock->local, &sock->sap,NULL); new_state(sock,ss_connected); #if defined(Q2963_1) || defined(DYNAMIC_UNI) sock->owner = 0; #endif if (atm2text(buffer,MAX_ATM_ADDR_LEN+1, (struct sockaddr *) &sock->remote,0) < 0) strcpy(buffer,"<invalid>"); diag(COMPONENT,DIAG_INFO,"Passive open succeeded (CR 0x%06X, " "ID %s, from %s)",sock->call_ref,kptr_print(&sock->id),buffer); return; case ATM_MSG_RELEASE: /* all states */ { unsigned char cause; cause = q_fetch(&in_dsc,QF_cause); diag(COMPONENT,DIAG_DEBUG,"Cause %d (%s)",cause,cause > 127 ? "invalid cause" : cause_text[cause]); } switch (sock->state) { case ss_connecting: set_error(sock,-ECONNREFUSED); /* fall through */ case ss_accepting: set_error(sock,-ECONNRESET); /* ERESTARTSYS ? */ send_release_complete(sock->sig,sock->call_ref,0); SEND_ERROR(sock->id,sock->error); STOP_TIMER(sock); free_sock(sock); return; case ss_rel_req: send_close(sock); /* fall through */ case ss_wait_rel: STOP_TIMER(sock); free_sock(sock); return; #if defined(Q2963_1) || defined(DYNAMIC_UNI) case ss_mod_req: #endif STOP_TIMER(sock); /* fall through */ #if defined(Q2963_1) || defined(DYNAMIC_UNI) case ss_mod_lcl: case ss_mod_rcv: case ss_mod_fin_ok: case ss_mod_fin_fail: case ss_mod_fin_ack: #endif case ss_connected: diag(COMPONENT,DIAG_INFO,"Passive close (CR 0x%06X)", sock->call_ref); #if defined(Q2963_1) || defined(DYNAMIC_UNI) if (timer_handler(sock->conn_timer) == on_T361) STOP_TIMER(sock); #endif send_close(sock); new_state(sock,ss_rel_ind); return; case ss_indicated: /* fall through */ case ss_proceeding: send_release_complete(sock->sig,sock->call_ref,0); new_state(sock,ss_zombie); /* fall through */ case ss_rel_ind: return; default: send_release_complete(sock->sig,sock->call_ref,0); /* @@@ should be ATM_CV_INCOMP_MSG */ break; } break; case ATM_MSG_RESTART: set_error(sock,-ENETRESET); /* fall through */ case ATM_MSG_STATUS: /* fall through when clearing */ case ATM_MSG_REL_COMP: /* basically any state (except LISTENING and ZOMBIE) */ { unsigned char cause; if (mid != ATM_MSG_REL_COMP || !q_present(&in_dsc,QF_cause)) cause = 0; else { cause = q_fetch(&in_dsc,QF_cause); diag(COMPONENT,DIAG_DEBUG,"Cause %d (%s)",cause, cause > 127 ? "invalid cause" : cause_text[cause]); } switch (sock->state) { case ss_connecting: set_error(sock,cause == ATM_CV_UNALLOC ? -EADDRNOTAVAIL : cause == ATM_CV_RES_UNAVAIL || #if defined(UNI31) || defined(UNI40) || defined(DYNAMIC_UNI) cause == ATM_CV_UCR_UNAVAIL_NEW || #endif cause == ATM_CV_NO_ROUTE_DEST ? -EHOSTUNREACH : cause == ATM_CV_NUM_CHANGED ? -EREMCHG : cause == ATM_CV_DEST_OOO ? -EHOSTDOWN : -ECONNREFUSED); /* fall through */ case ss_accepting: set_error(sock,-ECONNRESET); /* ERESTARTSYS ? */ SEND_ERROR(sock->id,sock->error); STOP_TIMER(sock); free_sock(sock); return; case ss_rel_req: send_close(sock); /* fall through */ case ss_wait_rel: STOP_TIMER(sock); free_sock(sock); return; #if defined(Q2963_1) || defined(DYNAMIC_UNI) case ss_mod_req: #endif STOP_TIMER(sock); /* fall through */ #if defined(Q2963_1) || defined(DYNAMIC_UNI) case ss_mod_lcl: case ss_mod_rcv: case ss_mod_fin_ok: case ss_mod_fin_fail: case ss_mod_fin_ack: #endif case ss_connected: diag(COMPONENT,DIAG_INFO,"Passive close (CR 0x%06X)", sock->call_ref); #if defined(Q2963_1) || defined(DYNAMIC_UNI) if (timer_handler(sock->conn_timer) == on_T361) STOP_TIMER(sock); #endif send_close(sock); /* fall through */ case ss_rel_ind: new_state(sock,ss_wait_close); return; case ss_indicated: /* fall through */ case ss_proceeding: new_state(sock,ss_zombie); return; default: break; } break; /* fail */ } case ATM_MSG_ALERTING: /* * We basically ignore this junk message, except for the connection * identifier it may carry. */ if (q_present(&in_dsc,QG_conn_id)) { int vpci; vpci = q_fetch(&in_dsc,QF_vpi); sock->pvc.sap_family = AF_ATMPVC; sock->pvc.sap_addr.itf = get_itf(sock->sig,&vpci); sock->pvc.sap_addr.vpi = vpci; sock->pvc.sap_addr.vci = q_fetch(&in_dsc,QF_vci); diag(COMPONENT,DIAG_DEBUG,"ITF.VPI.VCI: %d.%d.%d", sock->pvc.sap_addr.itf,sock->pvc.sap_addr.vpi, sock->pvc.sap_addr.vci); } return; case ATM_MSG_NOTIFY: /* silently ignore this junk */ return; #if defined(Q2963_1) || defined(DYNAMIC_UNI) /* * Buglet ahead: should actually test "call_state" */ case ATM_MSG_MODIFY_REQ: if (!(sock->sig->uni & S_Q2963_1)) goto _default; if (sock->state != ss_connected || sock->owner) break; sock->new_qos = sock->qos; if (q_present(&in_dsc,QF_fw_pcr_01)) sock->new_qos.rxtp.max_pcr = q_fetch(&in_dsc,QF_fw_pcr_01); if (q_present(&in_dsc,QF_bw_pcr_01)) sock->new_qos.txtp.max_pcr = q_fetch(&in_dsc,QF_bw_pcr_01); send_kernel(sock->id,kptr_null,as_modify, ATM_MF_INC_RSV | ATM_MF_DEC_RSV | ATM_MF_DEC_SHP, NULL,NULL,NULL,NULL,&sock->new_qos); new_state(sock,ss_mod_rcv); return; case ATM_MSG_MODIFY_ACK: if (!(sock->sig->uni & S_Q2963_1)) goto _default; if (sock->state != ss_mod_req) break; STOP_TIMER(sock); sock->qos = sock->new_qos; if (q_present(&in_dsc,QG_bbrt)) send_conn_avail(sock); send_kernel(sock->id,kptr_null,as_modify,ATM_MF_SET,NULL,NULL,NULL, NULL,&sock->qos); new_state(sock,ss_mod_fin_ok); return; case ATM_MSG_MODIFY_REJ: if (!(sock->sig->uni & S_Q2963_1)) goto _default; if (sock->state != ss_mod_req) break; STOP_TIMER(sock); sock->error = -EAGAIN; send_kernel(sock->id,kptr_null,as_modify,ATM_MF_SET,NULL,NULL,NULL, NULL,&sock->qos); new_state(sock,ss_mod_fin_fail); return; case ATM_MSG_CONN_AVAIL: if (!(sock->sig->uni & S_Q2963_1)) goto _default; if (sock->state != ss_connected || sock->owner) break; STOP_TIMER(sock); send_kernel(sock->id,kptr_null,as_modify,ATM_MF_SET,NULL,NULL,NULL, NULL,&sock->qos); new_state(sock,ss_mod_fin_ack); return; _default: /* jump here if we don't want to understand a message */ #endif default: diag(COMPONENT,DIAG_WARN,"Bad signaling message %d",mid); send_status(sock->sig,sock,0,ATM_CV_UNKNOWN_MSG_TYPE,mid); return; } diag(COMPONENT,DIAG_WARN, "Signaling message %s is incompatible with state %s/%s (%d?%d)", mid2name(mid),state_name[sock->state],cs_name[sock->call_state], (int) sock->state,(int) sock->call_state); send_status(sock->sig,sock,0,ATM_CV_INCOMP_MSG,mid); }
int main(int argc, char **argv) { char mac_addr[ETH_ALEN]; char elan_name[32 + 1]; char preferred_les[ATM_ESA_LEN]; /* LANE2 */ char foreId[255]; /* Max size for a TLV */ char atm2textbuff[100]; char esibuff[20]; int esi_set = 0; int listen_addr_set = 0; int atm_set=0; int proxy_flag = 0; int lane_version = 0; /* LANE2 */ int max_frame_size = MTU_UNSPEC; int lecs_method = LECS_WELLKNOWN; int poll_ret = 0, itf = 0, phys_itf = 0, selector = 0; int daemon_flag = 0; pid_t pid; struct sockaddr_atmsvc manual_atm_addr; struct sockaddr_atmsvc listen_addr; char pidbuf[PATH_MAX + 1]; int fd; int retval; memset(elan_name, '\0', sizeof(elan_name)); memset(foreId, '\0', sizeof(foreId)); memset(preferred_les, 0, ATM_ESA_LEN); memset(&manual_atm_addr, 0, sizeof(struct sockaddr_atmsvc)); memset(&listen_addr, 0, sizeof(struct sockaddr_atmsvc)); listen_addr.sas_family = AF_ATMSVC; set_application("zeppelin"); /* for debug msgs */ while(poll_ret != -1) { poll_ret = getopt(argc, argv, "bc:e:n:s:m:l:i:I:q:12pf:t:F:"); switch(poll_ret) { case 'b': daemon_flag = 1; break; case 'c': if (atm_set) { usage(argv[0]); exit(-1); } if (text2atm(optarg, (struct sockaddr *)&manual_atm_addr, sizeof(struct sockaddr_atmsvc), T2A_NAME) < 0) { diag(COMPONENT, DIAG_ERROR, "Invalid LECS address"); usage(argv[0]); exit(-1); } atm2text(atm2textbuff, sizeof(atm2textbuff), (struct sockaddr *)&manual_atm_addr, 0); diag(COMPONENT, DIAG_INFO, "LECS address: %s", atm2textbuff); lecs_method = LECS_MANUAL; atm_set=1; break; case 'e': if(esi_convert(optarg, mac_addr)<0) { diag(COMPONENT, DIAG_ERROR, "Invalid ESI format"); usage(argv[0]); exit(-1); } mac2text(esibuff, mac_addr); diag(COMPONENT, DIAG_DEBUG, "LEC ESI:%s", esibuff); esi_set=1; break; case 'n': if (strlen(optarg) > 32) { diag(COMPONENT, DIAG_ERROR, "ELAN name too long"); exit(-1); } strcpy(elan_name, optarg); diag(COMPONENT, DIAG_INFO, "Vlan name :'%s'", elan_name); break; case 's': if (atm_set) { usage(argv[0]); exit(-1); } if (text2atm(optarg, (struct sockaddr *)&manual_atm_addr, sizeof(struct sockaddr_atmsvc), T2A_NAME) < 0) { diag(COMPONENT, DIAG_ERROR, "Invalid LES address"); usage(argv[0]); exit(-1); } atm2text(atm2textbuff, sizeof(atm2textbuff), (struct sockaddr *)&manual_atm_addr, 0); diag(COMPONENT, DIAG_INFO, "LES address: %s", atm2textbuff); lecs_method = LECS_NONE; atm_set=1; break; case 'm': set_verbosity(NULL, DIAG_DEBUG); break; case 'l': if (isdigit(optarg[0]) && strlen(optarg) < 4 && sscanf(optarg, "%d", &selector) && selector >=0 && selector <= 0xff) { listen_addr.sas_addr.prv[ATM_ESA_LEN - 1] = (char) selector; diag(COMPONENT, DIAG_INFO, "Selector byte set " "to %d", selector); } else { if (text2atm(optarg, (struct sockaddr *)&listen_addr, sizeof(struct sockaddr_atmsvc), T2A_NAME) < 0) { diag(COMPONENT, DIAG_ERROR, "Invalid ATM listen address"); usage(argv[0]); exit(-1); } listen_addr_set = 1; } break; case 'i': if (sscanf(optarg, "%d", &itf) <= 0 || itf >= MAX_LEC_ITF) { diag(COMPONENT, DIAG_ERROR, "Invalid interface number"); usage(argv[0]); exit(-1); } diag(COMPONENT, DIAG_INFO, "Interface number set to %d", itf); break; case 'I': if (sscanf(optarg, "%d", &phys_itf) <= 0 || phys_itf < 0) { diag(COMPONENT, DIAG_ERROR, "Invalid physical interface number"); usage(argv[0]); exit(-1); } diag(COMPONENT, DIAG_INFO, "Physical interface number set to %d", phys_itf); break; case 'q': #if 0 if (text2qos(optarg,NULL,0) < 0) { diag(COMPONENT, DIAG_ERROR, "Invalid QOS specification"); usage(argv[0]); exit(-1); } qos_spec = optarg; #endif diag(COMPONENT, DIAG_INFO, "-q is deprecated, ignoring it"); break; case '1': lane_version = 1; break; case '2': lane_version = 2; break; case 'p': proxy_flag = 1; break; case 'f': if (strlen(optarg) > 255) { diag(COMPONENT, DIAG_ERROR, "foreId too long"); exit(-1); } memcpy (foreId, optarg, strlen(optarg)); foreId[strlen(optarg)] = '\0'; diag(COMPONENT, DIAG_INFO, "foreId :'%s'", foreId); break; case 't': /* ERIC */ if( !strncmp( optarg, "1516", 4 )) max_frame_size = MTU_1516; else if( !strncmp( optarg, "1580", 4 )) max_frame_size = MTU_1580; else if( !strncmp( optarg, "4544", 4 )) max_frame_size = MTU_4544; else if( !strncmp( optarg, "9234", 4 )) max_frame_size = MTU_9234; else if( !strncmp( optarg, "18190", 5 )) max_frame_size = MTU_18190; break; case 'F': set_logfile(optarg); diag(COMPONENT, DIAG_DEBUG, "logfile set to %s", optarg); break; case -1: break; default: usage(argv[0]); exit(-1); } } if (argc != optind) { usage(argv[0]); exit(1); } if (lane_version == 1 && max_frame_size == MTU_1580) { diag(COMPONENT, DIAG_ERROR, "MTU 1580 not defined with LANEv1"); exit(-1); } /* Reserve signals */ signal(SIGHUP, sig_reset); signal(SIGPIPE, SIG_IGN); if (!esi_set) { if(addr_getesi(mac_addr, phys_itf) < 0) { diag(COMPONENT, DIAG_ERROR, "Can't get ESI from kernel!"); return -1; } mac2text(esibuff, mac_addr); diag(COMPONENT, DIAG_DEBUG, "LEC ESI:%s", esibuff); if (itf != 0) mac_addr[0] = 0x2 | ((itf - 1) << 2); } if ((itf = kernel_init(mac_addr, itf)) < 0 ) { diag(COMPONENT, DIAG_FATAL, "Kernel interface creation failed, exiting..."); return -1; } if (daemon_flag == 1) { daemon_flag = 0; pid = fork(); if (pid < 0) { diag(COMPONENT, DIAG_FATAL, "fork failed, exiting..."); return -1; } if (pid) { /* parent */ return 0; } else { /* child */ if (setsid() < 0) { diag(COMPONENT, DIAG_FATAL, "setsid failed, exiting..."); return -1; } } } sprintf(pidbuf, "/var/run/lec%d.pid", itf); fd = open(pidbuf, O_CREAT | O_WRONLY, 0600); if (fd < 0) { diag(COMPONENT, DIAG_FATAL, "open(%s, ..) failed, %s", pidbuf, strerror(errno)); return -1; } sprintf(pidbuf, "%d\n", getpid()); write(fd, pidbuf, strlen(pidbuf)); close(fd); /* Loop here until the Sun gets cold */ while (1) { if (!listen_addr_set) { char sel = listen_addr.sas_addr.prv[ATM_ESA_LEN - 1]; if (get_listenaddr(listen_addr.sas_addr.prv, phys_itf) < 0) { diag(COMPONENT, DIAG_FATAL, "Could not figure out my ATM address"); exit(-1); } listen_addr.sas_addr.prv[ATM_ESA_LEN - 1] = sel; } atm2text(atm2textbuff, sizeof(atm2textbuff), (struct sockaddr *)&listen_addr, A2T_NAME | A2T_PRETTY | A2T_LOCAL); diag(COMPONENT, DIAG_INFO, "Our ATM address: %s", atm2textbuff); diag(COMPONENT, DIAG_DEBUG, "initializing lec parameters"); init_lec_params(mac_addr, elan_name, listen_addr.sas_addr.prv, itf, foreId, max_frame_size, proxy_flag, lane_version); if (lecs_method != LECS_MANUAL && lecs_method != LECS_NONE) { diag(COMPONENT, DIAG_DEBUG, "trying to get LECS address from ILMI"); /* Not sure why this memset is necessary */ memset(&manual_atm_addr, 0, sizeof(struct sockaddr_atmsvc)); retval = get_lecsaddr(phys_itf, &manual_atm_addr); if (retval <= 0) { diag(COMPONENT, DIAG_DEBUG, "get_lecsaddr failed; not enough " "memory allocated for all addresses " "or no LECS address registered"); } else { diag(COMPONENT, DIAG_DEBUG, "obtained LECS address from ILMI"); lecs_method = LECS_FROM_ILMI; } } diag(COMPONENT, DIAG_DEBUG, "About to connect LECS"); if (lec_configure(lecs_method, &manual_atm_addr, &listen_addr) < 0) { close_connections(); random_delay(); continue; } diag(COMPONENT, DIAG_DEBUG, "About to connect LES"); if (les_connect(lecs_method, &manual_atm_addr, &listen_addr) < 0) { close_connections(); random_delay(); continue; } diag(COMPONENT, DIAG_DEBUG, "About to connect BUS"); if (bus_connect() < 0) { close_connections(); random_delay(); continue; } diag(COMPONENT, DIAG_DEBUG, "About to create data direct listen socket"); if (create_data_listen() < 0) { close_connections(); random_delay(); continue; } diag(COMPONENT, DIAG_DEBUG, "About to tell kernel our LEC_ID %d", lec_params.c14_lec_id); if (set_lec_id(lec_params.c14_lec_id) < 0) { close_connections(); continue; } diag(COMPONENT, DIAG_DEBUG, "About to tell kernel LEC parameters"); if (config_kernel() < 0) { close_connections(); continue; } diag(COMPONENT, DIAG_DEBUG, "Joined ELAN '%s' successfully", lec_params.c5_elan_name); main_loop(); diag(COMPONENT, DIAG_INFO, "Resetting..."); close_connections(); random_delay(); reset = 0; } return 0; /* not reached */ }
char* ACE_ATM_Stream::get_peer_name (void) const { ACE_TRACE ("ACE_ATM_Stream::get_peer_name"); #if defined (ACE_HAS_FORE_ATM_XTI) // // Use t_getprotaddr for XTI/ATM // struct t_bind *localaddr // = (struct t_bind *) ACE_OS::t_alloc (get_handle (), // T_BIND, // T_ADDR); // struct t_bind *peeraddr // = (struct t_bind *) ACE_OS::t_alloc (get_handle (), // T_BIND, // T_ADDR); // ::t_getprotaddr (get_handle (), // localaddr, // peeraddr); // char* connected_name = (char*) ACE_OS::malloc (peeraddr->addr.len + 1); // ACE_OS::strcpy (connected_name, // peeraddr->addr.buf); // ACE_OS::t_free ((char *) localaddr, // T_BIND); // ACE_OS::t_free ((char *) peeraddr, // T_BIND); // return (connected_name); #error "This doesn't seem to work. May need to jimmy-rig something with the" #error "/etc/xti_hosts file - Ugh!" ACE_ATM_Addr sa; struct netbuf name; name.maxlen = sa.get_size (); name.buf = (char *) sa.get_addr (); ACE_OS::t_getname (this->get_handle (), &name, REMOTENAME); // ACE_OS::ioctl (this->get_handle (), // TI_GETPEERNAME, // &name); return (name.buf); #elif defined (ACE_HAS_FORE_ATM_WS2) // Use getpeername for WinSock2. struct sockaddr_atm name; ACE_OS::memset (&name, 0, sizeof (name)); int nameSize = sizeof (name); if (ACE_OS::getpeername (this->get_handle (), (struct sockaddr *) &name, &nameSize) != 0) { return 0; } char buffer[256]; for (unsigned int index = 0; index < ATM_ADDR_SIZE - 1; index++) { buffer[ index * 3 ] = '\0'; ACE_OS::sprintf (buffer, "%s%02x.", buffer, name.satm_number.Addr[ index ]); } buffer[ (ATM_ADDR_SIZE - 1) * 3 ] = '\0'; ACE_OS::sprintf (buffer, "%s%02x.", buffer, 0); buffer[ ATM_ADDR_SIZE * 3 - 1 ] = '\0'; for (index = 0; index < ACE_OS::strlen (buffer); ++index) buffer[index] = ACE_OS::ace_tolower (buffer[index]); ifstream atm_hosts ("C:/WINNT/atmhosts"); assert (atm_hosts.is_open ()); // Find the host address in the ATM hosts file and return the // host name char line[256]; char *host_ptr, *host_name = 0; ACE_NEW_RETURN (host_name, char[256], 0); while (!atm_hosts.eof ()) { atm_hosts.getline (line, 256); // Convert the line to lower case to ease comparison for (index = 0; index < ACE_OS::strlen (line); ++index) line[index] = ACE_OS::ace_tolower (line[index]); if (ACE_OS::strstr (line, buffer) != 0) { char *strtok_p; // Grab the second token which is the host name ACE_OS::strtok_r (line, " \t", &strtok_p); host_ptr = ACE_OS::strtok (0, " \t", &strtok_p); ACE_OS::strcpy (host_name, host_ptr); break; } } return host_name; #elif defined (ACE_HAS_LINUX_ATM) ATM_Addr name; int nameSize = sizeof (name.sockaddratmsvc); if (ACE_OS::getpeername (this->get_handle (), (struct sockaddr *) & (name.sockaddratmsvc), &nameSize) < 0) { ACE_OS::perror ("ACE_ATM_Stream (get_peer_name) : "); return 0; } static ACE_TCHAR buffer[MAX_ATM_ADDR_LEN + 1]; int total_len; if ((total_len = atm2text (buffer,sizeof buffer, (struct sockaddr *) & (name.sockaddratmsvc), A2T_PRETTY|A2T_NAME)) < 0) { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("ACE_ATM_Stream (get_peer_name) :%d"),errno)); return 0; } return (char*) buffer; #else return 0; #endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ }
static void accept_new(void) { char buffer[MAX_ATM_ADDR_LEN+1]; struct sockaddr_atmsvc addr; struct atm_qos qos; ENTRY *entry; VCC *vcc; int fd,error; socklen_t len,size; len = sizeof(addr); if ((fd = accept(incoming,(struct sockaddr *) &addr,&len)) < 0) { error = errno; diag(COMPONENT,DIAG_ERROR,"accept: %s",strerror(errno)); if (error == EUNATCH) { diag(COMPONENT,DIAG_WARN,"disabling SVCs"); (void) close(incoming); incoming = -1; } return; } /* the following code probably belongs to arp.c ... */ if (atm2text(buffer,MAX_ATM_ADDR_LEN+1,(struct sockaddr *) &addr,pretty) < 0) strcpy(buffer,"<atm2text error>"); diag(COMPONENT,DIAG_DEBUG,"Incoming call from %s",buffer); size = sizeof(qos); if (getsockopt(fd,SOL_ATM,SO_ATMQOS,&qos,&size) < 0) diag(COMPONENT,DIAG_FATAL,"getsockopt SO_ATMQOS: %s",strerror(errno)); if (size != sizeof(qos)) diag(COMPONENT,DIAG_FATAL,"SO_ATMQOS: size %d != %d",size,sizeof(qos)); if (ioctl(fd,ATMARP_MKIP,qos.txtp.traffic_class == ATM_NONE ? 0 : CLIP_DEFAULT_IDLETIMER) < 0) { diag(COMPONENT,DIAG_ERROR,"ioctl ATMARP_MKIP: %s",strerror(errno)); (void) do_close(fd); return; } vcc = alloc_t(VCC); vcc->active = 0; vcc->connecting = 0; vcc->fd = fd; if (qos.txtp.traffic_class == ATM_NONE) { vcc->entry = NULL; incoming_unidirectional(vcc); Q_INSERT_HEAD(unidirectional_vccs,vcc); return; } if (merge) { ITF *itf; for (itf = itfs; itf; itf = itf->next) { entry = lookup_addr(itf,&addr); if (entry) { vcc->entry = entry; Q_INSERT_HEAD(entry->vccs,vcc); if (entry->state == as_valid) { if (set_ip(vcc->fd,entry->ip) < 0) { diag(COMPONENT,DIAG_ERROR,"set_ip: %s", strerror(errno)); disconnect_vcc(vcc); } else set_sndbuf(vcc); } return; } } } entry = alloc_entry(1); entry->state = as_invalid; entry->addr = alloc_t(struct sockaddr_atmsvc); *entry->addr = addr; entry->flags = ATF_PUBL; Q_INSERT_HEAD(unknown_incoming,entry); vcc->entry = entry; Q_INSERT_HEAD(entry->vccs,vcc); incoming_call(vcc); }
void incoming_arp(VCC *vcc,struct atmarphdr *hdr,int len) { ITF *itf; ENTRY *entry; void *sha,*ssa,*spa,*tha,*tsa,*tpa; struct sockaddr_atmsvc source,target; uint32_t src_ip,tgt_ip; unsigned char *here; if (len < hdr->data-(unsigned char *) hdr) { diag(COMPONENT,DIAG_ERROR,"got truncated ARP packet (%d bytes)",len); return; } if (hdr->ar_hrd != htons(ARPHRD_ATM)) { diag(COMPONENT,DIAG_ERROR,"unknown hw protocol 0x%04x", ntohs(hdr->ar_hrd)); return; } if (hdr->ar_pro != htons(ETH_P_IP)) { diag(COMPONENT,DIAG_ERROR,"unknown upper protocol 0x%04x", ntohs(hdr->ar_pro)); return; } if (!(hdr->ar_shtl & TL_LEN)) hdr->ar_shtl = 0; /* paranoia */ if (!(hdr->ar_thtl & TL_LEN)) hdr->ar_thtl = 0; here = hdr->data; sha = get_addr(&here,hdr->ar_shtl & TL_LEN); ssa = get_addr(&here,hdr->ar_sstl & TL_LEN); spa = get_addr(&here,hdr->ar_spln); tha = get_addr(&here,hdr->ar_thtl & TL_LEN); tsa = get_addr(&here,hdr->ar_tstl & TL_LEN); tpa = get_addr(&here,hdr->ar_tpln); if (here-(unsigned char *) hdr > len) { diag(COMPONENT,DIAG_ERROR,"message too short (got %d, need %d)",len, here-(unsigned char *) hdr); return; } set_addr(&source,sha,ssa,hdr->ar_shtl,hdr->ar_sstl); set_addr(&target,tha,tsa,hdr->ar_thtl,hdr->ar_tstl); src_ip = get_ip(spa); tgt_ip = get_ip(tpa); { unsigned char *ipp; char buffer[MAX_ATM_ADDR_LEN+1]; ipp = (unsigned char *) &src_ip; diag(COMPONENT,DIAG_DEBUG," SRC IP: %d.%d.%d.%d",ipp[0],ipp[1],ipp[2], ipp[3]); if (atm2text(buffer,MAX_ATM_ADDR_LEN+1,(struct sockaddr *) &source,pretty) >= 0) diag(COMPONENT,DIAG_DEBUG," SRC ATM: %s",buffer); ipp = (unsigned char *) &tgt_ip; diag(COMPONENT,DIAG_DEBUG," DST IP: %d.%d.%d.%d",ipp[0],ipp[1],ipp[2], ipp[3]); if (atm2text(buffer,MAX_ATM_ADDR_LEN+1,(struct sockaddr *) &target,pretty) >= 0) diag(COMPONENT,DIAG_DEBUG," DST ATM: %s",buffer); } switch (ntohs(hdr->ar_op)) { case ARPOP_REQUEST: diag(COMPONENT,DIAG_DEBUG,"got ARP_REQ"); if (learn(vcc,src_ip,&source)) break; entry = NULL; itf = lookup_itf_by_ip(tgt_ip); entry = itf ? lookup_ip(itf,tgt_ip) : NULL; if (entry && entry->state == as_valid && (entry->flags & ATF_PUBL)) { if (entry->addr) arp_reply(vcc,tgt_ip,entry->addr,src_ip,&source); else arp_nak(vcc,tgt_ip,src_ip,&source); } else { if (itf && itf->local_ip == tgt_ip) arp_reply(vcc,tgt_ip,NULL,src_ip,&source); else arp_nak(vcc,tgt_ip,src_ip,&source); } break; case ARPOP_REPLY: diag(COMPONENT,DIAG_DEBUG,"got ARP_REP"); if (!vcc->entry || !(vcc->entry->flags & ATF_ARPSRV)) { diag(COMPONENT,DIAG_ERROR,"got ARP response from charlatan"); break; } (void) learn(NULL,src_ip,&source); break; case ARPOP_InREQUEST: diag(COMPONENT,DIAG_DEBUG,"got InARP_REQ"); if (!learn(vcc,src_ip,&source)) inarp_reply(vcc,src_ip,&source); break; case ARPOP_InREPLY: diag(COMPONENT,DIAG_DEBUG,"got InARP_REP"); (void) learn(vcc,src_ip,&source); break; case ARPOP_NAK: diag(COMPONENT,DIAG_DEBUG,"got ARP_NAK"); if (!vcc->entry || !(vcc->entry->flags & ATF_ARPSRV)) { diag(COMPONENT,DIAG_ERROR,"got ARP response from charlatan"); break; } learn_nak(tgt_ip); break; default: diag(COMPONENT,DIAG_ERROR,"unrecognized ARP op 0x%x", ntohs(hdr->ar_op)); } }