/*************************************************************************** nascell_ioctl.c - description ------------------- copyright : (C) 2002 by Eurecom email : michelle.wetterwald@eurecom.fr yan.moret@eurecom.fr *************************************************************************** ***************************************************************************/ #include "nascell_ioctl.h" #include "rrc_nas_primitives.h" //#include "rrc_qos.h" //#include "graal_local.h" #include "nasmt_constant.h" #include "nasmt_iocontrol.h" #define USHRT_MAX 255 //--------------------------------------------------------------------------- void print_error(int status) { //--------------------------------------------------------------------------- switch(status) { case -NAS_ERROR_NOMEMORY: printf(" The memory is low\n"); break; case -NAS_ERROR_NORB: printf(" The radio bearer is not identified\n"); break; case -NAS_ERROR_NOTMT: printf(" The entity must be a mobile\n"); break; case -NAS_ERROR_NOTRG: printf(" The entity must be an access router\n"); break; case -NAS_ERROR_NOTIDLE: printf(" The selected connection or radio bearer must be IDLE\n"); break; case -NAS_ERROR_NOTCONNECTED: printf(" The selected connection or radio bearer must be CONNECTED\n"); break; case -NAS_ERROR_NOTCORRECTLCR: printf(" The LCR value is not correct\n"); break; case -NAS_ERROR_NOTCORRECTDIR: printf(" The DIR value is not correct\n"); break; case -NAS_ERROR_NOTCORRECTDSCP: printf(" The DSCP value is not correct\n"); break; case -NAS_ERROR_NOTCORRECTVERSION: printf(" The version value is not correct\n"); break; case -NAS_ERROR_NOTCORRECTRABI: printf(" The rab_id value is not correct\n"); break; case -NAS_ERROR_ALREADYEXIST: printf(" Some components must not be duplicated\n"); break; default: printf(" Unknown error cause %d\n", status); } } //--------------------------------------------------------------------------- void print_state(uint8_t state) { //--------------------------------------------------------------------------- switch(state) { case NAS_IDLE: printf("NAS_IDLE\n"); return; // case NAS_STATE_CONNECTED:printf("NAS_STATE_CONNECTED\n");return; // case NAS_STATE_ESTABLISHMENT_REQUEST:printf("NAS_STATE_ESTABLISHMENT_REQUEST\n");return; // case NAS_STATE_ESTABLISHMENT_FAILURE:printf("NAS_STATE_ESTABLISHMENT_FAILURE\n");return; // case NAS_STATE_RELEASE_FAILURE:printf("NAS_STATE_RELEASE_FAILURE\n");return; case NAS_CX_FACH: printf("NAS_CX_FACH\n"); return; case NAS_CX_DCH: printf("NAS_CX_DCH\n"); return; case NAS_CX_RECEIVED: printf("NAS_CX_RECEIVED\n"); return; case NAS_CX_CONNECTING: printf("NAS_CX_CONNECTING\n"); return; case NAS_CX_RELEASING: printf("NAS_CX_RELEASING\n"); return; case NAS_CX_CONNECTING_FAILURE: printf("NAS_CX_CONNECTING_FAILURE\n"); return; case NAS_CX_RELEASING_FAILURE: printf("NAS_CX_RELEASING_FAILURE\n"); return; case NAS_RB_ESTABLISHING: printf("NAS_RB_ESTABLISHING\n"); return; case NAS_RB_RELEASING: printf("NAS_RB_RELEASING\n"); return; default: printf(" Unknown state\n"); } } //--------------------------------------------------------------------------- void print_usage_class() { //--------------------------------------------------------------------------- printf("Usage: gioctl class add {send |receive} -f {qos |del|ctl|dc} -cr [-dscp ] [-ip {6|4} ] [-p {tcp|udp|icmp4|icmp6} ]\n"); printf("Usage: gioctl class del {send |receive} -cr [-dscp ] \n"); printf("Usage: gioctl class list {send |receive} [-dscp ]\n"); } //--------------------------------------------------------------------------- void print_usage_cx() { //--------------------------------------------------------------------------- printf("Usage: gioctl cx add \n"); printf("Usage: gioctl cx del \n"); printf("Usage: gioctl cx list\n"); } //--------------------------------------------------------------------------- void print_usage_rb() { //--------------------------------------------------------------------------- printf("Usage: gioctl rb add \n"); printf("Usage: gioctl rb list \n"); } //--------------------------------------------------------------------------- int main(int argc, char *argv[]) { //--------------------------------------------------------------------------- struct nas_ioctl gifr; int err, fd; // Invalid number of arguments if (argc<2) { printf("Usage: gioctl statistic\n"); print_usage_cx(); print_usage_rb(); print_usage_class(); return -1; } // Get an UDP IPv6 socket ?? fd=socket(AF_INET6, SOCK_DGRAM, 0); if (fd<0) { printf("Error opening socket\n"); return 0; } strcpy(gifr.name, "oai0"); printf("Socket opened successfully\n"); /***************************/ if (strcmp(argv[1], "statistic")==0) { struct nas_msg_statistic_reply *msgrep; gifr.type=NAS_MSG_STATISTIC_REQUEST; gifr.msg=(char *)malloc(sizeof(msgrep)); msgrep=(struct nas_msg_statistic_reply *)(gifr.msg); printf(" Statistics requested\n"); err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); if (err<0) { printf("IOCTL error, err=%d\n",err); return -1; } printf("tx_packets = %u, rx_packets = %u\n", msgrep->tx_packets, msgrep->rx_packets); printf("tx_bytes = %u, rx_bytes = %u\n", msgrep->tx_bytes, msgrep->rx_bytes); printf("tx_errors = %u, rx_errors = %u\n", msgrep->tx_errors, msgrep->rx_errors); printf("tx_dropped = %u, rx_dropped = %u\n", msgrep->tx_dropped, msgrep->rx_dropped); return 0; } /***************************/ if (strcmp(argv[1], "cx")==0) { if (argc<3) { print_usage_cx(); return -1; } /***/ // printf("Usage: gioctl cx add \n"); if (strcmp(argv[2], "add")==0) { struct nas_msg_cx_establishment_request *msgreq; struct nas_msg_cx_establishment_reply *msgrep; if (argc<5) { print_usage_cx(); return -1; } gifr.type=NAS_MSG_CX_ESTABLISHMENT_REQUEST; gifr.msg=(char *)malloc(sizeof(msgrep)lcr=strtoul(argv[3], NULL, 0); msgreq->cellid=strtoul(argv[4], NULL, 0); // printf(" Connection establishment requested\n"); err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); if (err<0) { printf("IOCTL error, err=%d\n",err); perror("Connection establishment IOCTL error\n"); return -1; } if (msgrep->status<0) { printf(" Connexion establishment failure: "); print_error(msgrep->status); return -1; } return 0; } /***/ // printf("Usage: gioctl cx del \n"); if (strcmp(argv[2], "del")==0) { struct nas_msg_cx_release_request *msgreq; struct nas_msg_cx_release_reply *msgrep; if (argc<4) { print_usage_cx(); return -1; } gifr.type=NAS_MSG_CX_RELEASE_REQUEST; gifr.msg=(char *)malloc(sizeof(msgrep)lcr=strtoul(argv[3], NULL, 0); // printf(" Connexion release requested\n"); err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); if (err<0) { printf("IOCTL error, err=%d\n",err); return -1; } if (msgrep->status<0) { printf(" Connexion release failure: "); print_error(msgrep->status); return -1; } return 0; } /***/ // printf("Usage: gioctl cx list\n"); if (strcmp(argv[2], "list")==0) { uint8_t *msgrep; uint8_t i; struct nas_msg_cx_list_reply *list; uint8_t lcr; gifr.type=NAS_MSG_CX_LIST_REQUEST; gifr.msg=(char *)malloc(NAS_LIST_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1); msgrep=(uint8_t *)(gifr.msg); // printf(" Connexion list requested\n"); err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); if (err<0) { printf("IOCTL error, err=%d\n",err); return -1; } printf("Lcr\t\tCellId\tIID4\tIID6\t\t\tnrb\tnsclass\tState\n"); list=(struct nas_msg_cx_list_reply *)(msgrep+1); for(lcr=0; lcr \n"); if (strcmp(argv[2], "add")==0) { struct nas_msg_rb_establishment_request *msgreq; struct nas_msg_rb_establishment_reply *msgrep; if (argc<6) { print_usage_rb(); return -1; } gifr.type=NAS_MSG_RB_ESTABLISHMENT_REQUEST; gifr.msg=(char *)malloc(sizeof(msgrep)lcr=strtoul(argv[3], NULL, 0); msgreq->rab_id=strtoul(argv[4], NULL, 0); msgreq->qos=strtoul(argv[5], NULL, 0); // printf(" Radio bearer establishment requested\n"); err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); if (err<0) { printf("IOCTL error, err=%d\n",err); return -1; } if (msgrep->status<0) { printf(" Radio bearer establishment failure: "); print_error(msgrep->status); return -1; } return 0; } /***/ if (strcmp(argv[2], "del")==0) { struct nas_msg_rb_release_request *msgreq; struct nas_msg_rb_release_reply *msgrep; if (argc<5) { print_usage_rb(); return -1; } gifr.type=NAS_MSG_RB_RELEASE_REQUEST; gifr.msg=(char *)malloc(sizeof(msgrep)lcr=strtoul(argv[3], NULL, 0); msgreq->rab_id=strtoul(argv[4], NULL, 0); // printf(" Radio Bearer release requested\n"); err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); if (err<0) { printf("IOCTL error, err=%d\n",err); return -1; } if (msgrep->status<0) { printf(" Radio bearer release failure: "); print_error(msgrep->status); return -1; } return 0; } /***/ // printf("Usage: gioctl rb list \n"); if (strcmp(argv[2], "list")==0) { uint8_t *msgrep; uint8_t rbi; struct nas_msg_rb_list_reply *list; struct nas_msg_rb_list_request *msgreq; if (argc<4) { print_usage_rb(); return -1; } gifr.type=NAS_MSG_RB_LIST_REQUEST; gifr.msg=(char *)malloc(NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1); msgreq=(struct nas_msg_rb_list_request *)(gifr.msg); msgrep=(uint8_t *)(gifr.msg); msgreq->lcr=strtoul(argv[3], NULL, 0); // printf(" Radio bearer list requested\n"); err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); if (err<0) { printf("IOCTL error, err=%d\n",err); return -1; } printf("rab_id\t\tSapi\t\tQoS\t\tState\n"); list=(struct nas_msg_rb_list_reply *)(msgrep+1); for(rbi=0; rbidir=NAS_DIRECTION_SEND; msgreq->lcr=strtoul(argv[++i], NULL, 0); ++i; } else { if (strcmp(argv[i], "receive")==0) { msgreq->dir=NAS_DIRECTION_RECEIVE; ++i; } else { print_usage_class(); return -1; } } msgreq->classref=USHRT_MAX; msgreq->dscp=NAS_DSCP_DEFAULT; msgreq->version=NAS_VERSION_DEFAULT; msgreq->protocol=NAS_PROTOCOL_DEFAULT; msgreq->sport=NAS_PORT_DEFAULT; msgreq->dport=NAS_PORT_DEFAULT; msgreq->fct=0; while (iclassref=strtoul(argv[++i], NULL, 0); ++i; continue; } if (strcmp(argv[i], "-dscp")==0) { msgreq->dscp=strtoul(argv[++i], NULL, 0); ++i; continue; } if (strcmp(argv[i], "-f")==0) { ++i; if (strcmp(argv[i], "qos")==0) { msgreq->fct=NAS_FCT_QOS_SEND; msgreq->rab_id=strtoul(argv[++i], NULL, 0); ++i; continue; } if (strcmp(argv[i], "del")==0) { msgreq->fct=NAS_FCT_DEL_SEND; msgreq->rab_id=0; ++i; continue; } if (strcmp(argv[i], "ctl")==0) { msgreq->fct=NAS_FCT_CTL_SEND; msgreq->rab_id=0; ++i; continue; } if (strcmp(argv[i], "dc")==0) { msgreq->fct=NAS_FCT_DC_SEND; msgreq->rab_id=0; ++i; continue; } print_usage_class(); return -1; } if (strcmp(argv[i], "-ip")==0) { ++i; if (strcmp(argv[i], "4")==0) { if (msgreq->version!=NAS_VERSION_DEFAULT) { print_usage_class(); return -1; } msgreq->version=NAS_VERSION_4; inet_pton(AF_INET, argv[++i], (void *)(&msgreq->saddr)); msgreq->splen=strtoul(argv[++i], NULL, 0); inet_pton(AF_INET, argv[++i], (void *)(&msgreq->daddr)); msgreq->dplen=strtoul(argv[++i], NULL, 0); ++i; continue; } if (strcmp(argv[i], "6")==0) { if (msgreq->version!=NAS_VERSION_DEFAULT) { print_usage_class(); return -1; } msgreq->version=NAS_VERSION_6; inet_pton(AF_INET6, argv[++i], (void *)(&msgreq->saddr)); msgreq->splen=strtoul(argv[++i], NULL, 0); inet_pton(AF_INET6, argv[++i], (void *)(&msgreq->daddr)); msgreq->dplen=strtoul(argv[++i], NULL, 0); ++i; continue; } print_usage_class(); return -1; } if (strcmp(argv[i], "-p")==0) { ++i; if (strcmp(argv[i], "tcp")==0) { if (msgreq->protocol!=NAS_PROTOCOL_DEFAULT) { print_usage_class(); return -1; } msgreq->protocol=NAS_PROTOCOL_TCP; msgreq->sport=strtoul(argv[++i], NULL, 0); msgreq->dport=strtoul(argv[++i], NULL, 0); ++i; continue; } if (strcmp(argv[i], "udp")==0) { if (msgreq->protocol!=NAS_PROTOCOL_DEFAULT) { print_usage_class(); return -1; } msgreq->protocol=NAS_PROTOCOL_UDP; msgreq->sport=strtoul(argv[++i], NULL, 0); msgreq->dport=strtoul(argv[++i], NULL, 0); ++i; continue; } if (strcmp(argv[i], "icmp4")==0) { if (msgreq->protocol!=NAS_PROTOCOL_DEFAULT) { print_usage_class(); return -1; } msgreq->protocol=NAS_PROTOCOL_ICMP4; msgreq->sport=strtoul(argv[++i], NULL, 0); msgreq->dport=strtoul(argv[++i], NULL, 0); ++i; continue; } if (strcmp(argv[i], "icmp6")==0) { if (msgreq->protocol!=NAS_PROTOCOL_DEFAULT) { print_usage_class(); return -1; } msgreq->protocol=NAS_PROTOCOL_ICMP6; msgreq->sport=strtoul(argv[++i], NULL, 0); msgreq->dport=strtoul(argv[++i], NULL, 0); ++i; continue; } print_usage_class(); return -1; } print_usage_class(); return -1; } if ((msgreq->classref==USHRT_MAX)||(msgreq->fct==0)) { print_usage_class(); return -1; } printf(" Class add requested\n"); err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); if (err<0) { printf("IOCTL error, err=%d\n",err); return -1; } if (msgrep->status<0) { printf(" Class add failure: "); print_error(msgrep->status); return -1; } return 0; } /***/ if (strcmp(argv[2], "del")==0) { uint8_t i; struct nas_msg_class_del_request *msgreq; struct nas_msg_class_del_reply *msgrep; gifr.type=NAS_MSG_CLASS_DEL_REQUEST; gifr.msg=(char *)malloc(sizeof(msgrep)dir=NAS_DIRECTION_SEND; msgreq->lcr=strtoul(argv[++i], NULL, 0); ++i; } else { if (strcmp(argv[i], "receive")==0) { msgreq->dir=NAS_DIRECTION_RECEIVE; ++i; } else { print_usage_class(); return -1; } } msgreq->classref=USHRT_MAX; msgreq->dscp=NAS_DSCP_DEFAULT; while (iclassref=strtoul(argv[++i], NULL, 0); ++i; continue; } if (strcmp(argv[i], "-dscp")==0) { msgreq->dscp=strtoul(argv[++i], NULL, 0); ++i; continue; } print_usage_class(); return -1; } if (msgreq->classref==USHRT_MAX) { print_usage_class(); return -1; } printf(" Class del requested\n"); err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); if (err<0) { printf("IOCTL error, err=%d\n",err); return -1; } if (msgrep->status<0) { printf(" Class add failure: "); print_error(msgrep->status); return -1; } return 0; } /***/ if (strcmp(argv[2], "list")==0) { uint8_t *msgrep; uint8_t cli, i; struct nas_msg_class_list_reply *list; struct nas_msg_class_list_request *msgreq; char addr[45]; if (argc<4) { print_usage_class(); return -1; } gifr.type=NAS_MSG_CLASS_LIST_REQUEST; gifr.msg=(char *)malloc(NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1); if (gifr.msg==NULL) { printf(" No memory\n"); return -1; } msgreq=(struct nas_msg_class_list_request *)(gifr.msg); msgrep=(uint8_t *)(gifr.msg); i=3; if (strcmp(argv[i], "send")==0) { msgreq->dir=NAS_DIRECTION_SEND; msgreq->lcr=strtoul(argv[++i], NULL, 0); ++i; } else { if (strcmp(argv[i], "receive")==0) { msgreq->dir=NAS_DIRECTION_RECEIVE; msgreq->lcr=0; ++i; } else { print_usage_class(); return -1; } } msgreq->dscp=NAS_DSCP_DEFAULT; while (idscp=strtoul(argv[++i], NULL, 0); } printf(" Classifier list requested\n"); err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); // if (err<0) { printf("IOCTL error, err=%d\n",err); return -1; } printf("Lcr\trab_id\tCref\tFct\t(Vers., saddr, daddr)\t\t\t\t(Proto., Sport, Dport)\n"); list=(struct nas_msg_class_list_reply *)(msgrep+1); for(cli=0; cli