Пример #1
0
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);
}
Пример #2
0
static int setdevname_pppoatm(const char *cp, const char **argv, int doit)
{
	struct sockaddr_atmpvc addr;
	extern struct stat devstat;
	if (device_got_set)
		return 0;
	//info("PPPoATM setdevname_pppoatm: '%s'", cp);
	memset(&addr, 0, sizeof addr);
	if (text2atm(cp, (struct sockaddr *) &addr, sizeof(addr),
	    T2A_PVC | T2A_NAME) < 0) {
               if(doit)
                   info("atm does not recognize: %s", cp);
		return 0;
           }
	if (!doit) return 1;
	//if (!dev_set_ok()) return -1;
	memcpy(&pvcaddr, &addr, sizeof pvcaddr);
	strlcpy(devnam, cp, sizeof devnam);
	devstat.st_mode = S_IFSOCK;
	if (the_channel != &pppoa_channel) {
		the_channel = &pppoa_channel;
		lcp_wantoptions[0].neg_accompression = 0;
		lcp_allowoptions[0].neg_accompression = 0;
		lcp_wantoptions[0].neg_asyncmap = 0;
		lcp_allowoptions[0].neg_asyncmap = 0;
		lcp_wantoptions[0].neg_pcompression = 0;
	}
	info("PPPoATM setdevname_pppoatm - SUCCESS:%s", cp);
	device_got_set = 1;
	return 1;
}
Пример #3
0
int main(int argc,char **argv)
{
    struct sockaddr_atmpvc addr;
    struct atm_qos qos;
    int s;

    if (argc != 2) usage(argv[0]);
    if ((s = socket(PF_ATMPVC,SOCK_DGRAM,0)) < 0) {
	perror("socket");
	return 1;
    }
    memset(&addr,0,sizeof(addr));
    if (text2atm(argv[1],(struct sockaddr *) &addr,sizeof(addr),T2A_PVC) < 0)
	usage(argv[0]);
    memset(&qos,0,sizeof(qos));
    qos.aal = ATM_AAL5;
    qos.txtp.traffic_class = qos.rxtp.traffic_class = ATM_UBR;
    qos.txtp.max_sdu = qos.rxtp.max_sdu = MAX_SDU;
    if (setsockopt(s,SOL_ATM,SO_ATMQOS,&qos,sizeof(qos)) < 0) {
	perror("setsockopt SO_ATMQOS");
	return 1;
    }
    if (connect(s,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
	perror("connect");
	return 1;
    }
    srandom(0); /* we want it to be deterministic */
    torture(s);
    return 0;
}
Пример #4
0
int main(int argc,char **argv)
{
    struct sockaddr_atmpvc addr;
    struct atm_qos qos;
    int s,size,offset;

    if (argc != 3 && argc != 4) usage(argv[0]);
    if ((s = socket(PF_ATMPVC,SOCK_DGRAM,0)) < 0) {
	perror("socket");
	return 1;
    }
    memset(&addr,0,sizeof(addr));
    if (text2atm(argv[1],(struct sockaddr *) &addr,sizeof(addr),T2A_PVC) < 0)
	usage(argv[0]);
    offset = argc == 3 ? 0 : atoi(argv[3]);
    memset(&qos,0,sizeof(qos));
    qos.aal = ATM_AAL5;
    qos.txtp.traffic_class = ATM_UBR;
    qos.txtp.max_sdu = strlen(argv[2])-offset;
    if (setsockopt(s,SOL_ATM,SO_ATMQOS,&qos,sizeof(qos)) < 0) {
	perror("setsockopt SO_ATMQOS");
	return 1;
    }
    if (connect(s,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
	perror("connect");
	return 1;
    }
    size = write(s,argv[2]+offset,strlen(argv[2])-offset);
    printf("%d",size);
    if (size < 0) printf(" (%s)",strerror(errno));
    putchar('\n');
    return 0;
}
Пример #5
0
static void put_address(char *address)
{
    char *mask;

    mask = strchr(address,'/');
    if (mask) *mask++ = 0;
    if (text2atm(address,(struct sockaddr *) &rule->addr,sizeof(rule->addr),
      T2A_SVC | T2A_WILDCARD | T2A_NAME | T2A_LOCAL) < 0) {
	yyerror("invalid address");
	return;
    }
    if (!mask) rule->mask = -1;
    else rule->mask = strtol(mask,NULL,10);
    add_rule(rule);
}
Пример #6
0
void 
set_lecs_addr(const char *addr)
{
  struct sockaddr_atmsvc tmp;

  if (lecs_address) {
    printf("Error: LECS address already set\n");
  }
  if (text2atm(addr,(struct sockaddr*)&tmp,sizeof(tmp),T2A_SVC|T2A_NAME)<0) {
    printf("Couldn't get LECS address!\n");
    return;
  }
  lecs_address=(unsigned char*)mem_alloc(COMP_NAME,ATM_ESA_LEN);
  if (!lecs_address)
    return;
  memcpy(lecs_address, tmp.sas_addr.prv, ATM_ESA_LEN);
}
Пример #7
0
int setdevname_pppoatm(const char *cp)
{
	struct sockaddr_atmpvc addr;
	extern struct stat devstat;
	
	memset(&addr, 0, sizeof addr);
	if (text2atm(cp, (struct sockaddr *) &addr, sizeof(addr),
	    T2A_PVC | T2A_NAME) < 0)
		return 0;

	memcpy(&glb.pvcaddr, &addr, sizeof glb.pvcaddr);
	strlcpy(devnam, cp, sizeof devnam);
	
	info("PPPoATM setdevname_pppoatm - SUCCESS");
	if(the_channel != &pppoatm_channel) {
		the_channel = &pppoatm_channel;	
		
		{
			char **a;
			for (a = bad_options; *a != NULL; a++)
				remove_option(*a);
		}
#ifndef _DISABLE_SERIAL_
		modem = 0;
#endif

		lcp_allowoptions[0].neg_accompression = 0;
		lcp_wantoptions[0].neg_accompression = 0;

		lcp_allowoptions[0].neg_asyncmap = 0;
		lcp_wantoptions[0].neg_asyncmap = 0;

		lcp_allowoptions[0].neg_pcompression = 0;
		lcp_wantoptions[0].neg_pcompression = 0;

		ccp_allowoptions[0].deflate = 0 ;
		ccp_wantoptions[0].deflate = 0 ;

		ipcp_allowoptions[0].neg_vj=0;
		ipcp_wantoptions[0].neg_vj=0;

		ccp_allowoptions[0].bsd_compress = 0;
		ccp_wantoptions[0].bsd_compress = 0;
	}
	return 1;
}
/* 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;
}
Пример #9
0
static int setup(char *spec,int tx)
{
    struct sockaddr_atmpvc addr;
    struct atm_qos qos;
    char *here;
    int fd;

    if (!(here = strchr(spec,','))) {
        memset(&qos,0,sizeof(qos));
        if (tx) qos.txtp.traffic_class = ATM_UBR;
        else qos.rxtp.traffic_class = ATM_UBR;
    }
    else {
        *here = 0;
        if (text2qos(here+1,&qos,0) < 0) {
            fprintf(stderr,"invalid QOS: %s\n",here+1);
            exit(1);
        }
    }
    if (tx) qos.rxtp.traffic_class = ATM_NONE;
    else qos.txtp.traffic_class = ATM_NONE;
    qos.aal = ATM_AAL5;
    if (text2atm(spec,(struct sockaddr *) &addr,sizeof(addr),
                 T2A_PVC | T2A_NAME) < 0) {
        fprintf(stderr,"invalid PVC: %s\n",spec);
        exit(1);
    }
    if ((fd = socket(PF_ATMPVC,SOCK_DGRAM,0)) < 0) {
        perror("socket");
        exit(1);
    }
    if (setsockopt(fd,SOL_ATM,SO_ATMQOS,&qos,sizeof(qos)) < 0) {
        perror("setsockopt SO_ATMQOS");
        exit(1);
    }
    if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
        perror("bind");
        exit(1);
    }
    return fd;
}
Пример #10
0
int
add_les(Elan_t *elan, const char *addr)
{  
  struct sockaddr_atmsvc tmp;

  assert(elan);
  if (elan->les_addr[18] || 
      elan->les_addr[17] ||
      elan->les_addr[16] ||
      elan->les_addr[15] ||
      elan->les_addr[14] ||
      elan->les_addr[13] ||
      elan->les_addr[12]) {
    printf("LES address already set for this ELAN!\n");
    return 0;
  }
  
  if (text2atm(addr,(struct sockaddr *)&tmp,sizeof(tmp),T2A_SVC|T2A_NAME)<0) {
    return -1;
  }
  memcpy(elan->les_addr, tmp.sas_addr.prv, ATM_ESA_LEN);
  return 0;
}
Пример #11
0
int main(int argc,char **argv)
{
    struct sockaddr_atmpvc addr;
    struct atm_qos qos;
    int s;

    if (argc != 2) usage(argv[0]);
    if ((s = socket(PF_ATMPVC,SOCK_DGRAM,0)) < 0) {
	perror("socket");
	return 1;
    }
    memset(&addr,0,sizeof(addr));
    if (text2atm(argv[1],(struct sockaddr *) &addr,sizeof(addr),T2A_PVC) < 0)
	usage(argv[0]);
    memset(&qos,0,sizeof(qos));
    qos.aal = ATM_AAL5;
    qos.rxtp.traffic_class = ATM_UBR;
    qos.rxtp.max_sdu = BSIZE;
    if (setsockopt(s,SOL_ATM,SO_ATMQOS,&qos,sizeof(qos)) < 0) {
	perror("setsockopt SO_ATMQOS");
	return 1;
    }

    if (bind(s,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
	perror("bind");
	return 1;
    }
    while (1) {
	unsigned char buf[BSIZE+4096];
	unsigned char *start;
	ssize_t size;

	start = (unsigned char *) (((unsigned long) buf+4095) & ~4095U);
	size = read(s,start,BSIZE);
	if (size > 0 && write(1,start,size) != size) return 1;
    }
}
Пример #12
0
int assign_vcc(char *astr, int encap, int bufsize, struct atm_qos qos)
{
    int err;
    struct sockaddr_atmpvc addr;
    int fd;
    struct atm_backend_br2684 be;

    memset(&addr, 0, sizeof(addr));
    err=text2atm(astr,(struct sockaddr *)(&addr), sizeof(addr), T2A_PVC);
    if (err!=0)
      syslog(LOG_ERR,"Could not parse ATM parameters (error=%d)\n",err);
    
#if 0
    addr.sap_family = AF_ATMPVC;
    addr.sap_addr.itf = itf;
    addr.sap_addr.vpi = 0;
    addr.sap_addr.vci = vci;
#endif
    syslog(LOG_INFO,"Communicating over ATM %d.%d.%d, encapsulation: %s\n", addr.sap_addr.itf,
	   addr.sap_addr.vpi,
	   addr.sap_addr.vci,
	   encap?"VC mux":"LLC");
    
    if ((fd = socket(PF_ATMPVC, SOCK_DGRAM, ATM_AAL5)) < 0)
      syslog(LOG_ERR,"failed to create socket %d, reason: %s", errno,strerror(errno));
    
    if (qos.aal == 0) {
      qos.aal                     = ATM_AAL5;
      qos.txtp.traffic_class      = ATM_UBR;
      qos.txtp.max_sdu            = 1524;
      qos.txtp.pcr                = ATM_MAX_PCR;
      qos.rxtp = qos.txtp;
    }

    if ( (err=setsockopt(fd,SOL_SOCKET,SO_SNDBUF, &bufsize ,sizeof(bufsize))) )
      syslog(LOG_ERR,"setsockopt SO_SNDBUF: (%d) %s\n",err, strerror(err));
    
    if (setsockopt(fd, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos)) < 0)
      syslog(LOG_ERR,"setsockopt SO_ATMQOS %d", errno);

    err = connect(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_atmpvc));
    
    if (err < 0)
      fatal("failed to connect on socket", err);
    
    /* attach the vcc to device: */
    
    be.backend_num = ATM_BACKEND_BR2684;
    be.ifspec.method = BR2684_FIND_BYIFNAME;
    sprintf(be.ifspec.spec.ifname, "nas%d", lastitf);
    be.fcs_in = BR2684_FCSIN_NO;
    be.fcs_out = BR2684_FCSOUT_NO;
    be.fcs_auto = 0;
    be.encaps = encap ? BR2684_ENCAPS_VC : BR2684_ENCAPS_LLC;
    be.has_vpiid = 0;
    be.send_padding = 0;
    be.min_size = 0;
    err=ioctl (fd, ATM_SETBACKEND, &be);
    if (err == 0)
      syslog (LOG_INFO,"Interface configured");
    else {
      syslog (LOG_ERR,"Could not configure interface:%s",strerror(errno));
      exit(2);
    }
    return fd ;
}
Пример #13
0
int main(int argc, char **argv){
  int listen_socket;
  int opt_ret = 0;
  struct k_message msg;
  struct sockaddr_atmsvc control_listen_addr;
  struct sockaddr_atmsvc mps_ctrl_addr;
  struct sockaddr_atmsvc lec_addr;

  memset(&control_listen_addr,0,sizeof(struct sockaddr_atmsvc));
  memset(&mpc_control.data_listen_addr,0,sizeof(struct sockaddr_atmsvc));
  memset(&lec_addr,0,sizeof(struct sockaddr_atmsvc));
  memset(&mps_ctrl_addr,0,sizeof(struct sockaddr_atmsvc));
  memset(&msg,0,sizeof(struct k_message));
  memset(&mpc_control,0,sizeof(mpc_control));
  mpc_control.elan_name[32] = '\0';
  init_default_addresses(&control_listen_addr, &mpc_control.data_listen_addr);
    
  while( opt_ret != -1 ){
    opt_ret = getopt(argc, argv, "h:s:l:c:L:n:C:i:m:");
    switch(opt_ret) {
    case 'h':
      usage(argv[0]);
      exit(0);
      break;
    case 's':
      if(text2atm(optarg,(struct sockaddr *)&control_listen_addr,
		  sizeof(struct sockaddr_atmsvc),T2A_SVC | T2A_NAME)<0){
	printf("mpcd: main.c: text2atm failed.\n");
	usage(argv[0]);
        exit(1);
      }
      memcpy(mpc_control.OWN_ATM_ADDRESS,control_listen_addr.sas_addr.prv, ATM_ESA_LEN);
      break;
    case 'l':
      if(text2atm(optarg,(struct sockaddr *)&mpc_control.data_listen_addr,
		  sizeof(struct sockaddr_atmsvc),T2A_SVC | T2A_NAME)<0){
	printf("mpcd: main.c: text2atm failed.\n");
	usage(argv[0]);
	exit(1);
      }
      break;
    case 'c':
      if(text2atm(optarg,(struct sockaddr *)&mps_ctrl_addr,
		  sizeof(struct sockaddr_atmsvc),T2A_SVC | T2A_NAME)<0){
	printf("mpcd: main.c: text2atm failed.\n");
	usage(argv[0]);
	exit(1);
      }
      memcpy(mpc_control.MPS_CTRL_ATM_ADDR,mps_ctrl_addr.sas_addr.prv,ATM_ESA_LEN);
      mpc_control.mps_ctrl_addr_set = 1;
      break;
    case 'L':
      if(text2atm(optarg,(struct sockaddr *)&lec_addr,
		  sizeof(struct sockaddr_atmsvc),T2A_SVC | T2A_NAME)<0){
	printf("mpcd: main.c: text2atm failed.\n");
	usage(argv[0]);
	exit(1);
      }
      memcpy(mpc_control.LEC_ADDRESS,lec_addr.sas_addr.prv,ATM_ESA_LEN);
      mpc_control.use_lecs = 1;
      break;
    case 'n':
      strncpy(mpc_control.elan_name,optarg,33);
      break;
    case 'C':
      if(text2atm(optarg,(struct sockaddr *)&mpc_control.lecs_address,
		  sizeof(struct sockaddr_atmsvc),T2A_SVC | T2A_NAME)<0){
	printf("mpcd: main.c: text2atm failed.\n");
	usage(argv[0]);
	exit(1);
      }
      break;
    case 'm':
      strncpy(mpc_control.MPS_MAC_ADDRESS,optarg,13);
      mpc_control.mps_mac_addr_set = 1;
      break;
    case 'i':
      mpc_control.INTERFACE_NUMBER = atoi(optarg);
      break;
    }
  }
  if (argc != optind) {
    usage(argv[0]);
    exit(1);
  }
  while(1){
    create_kernel_socket(mpc_control.INTERFACE_NUMBER);
    if(mpc_control.use_lecs){
      get_mpc_config(&mpc_control.lecs_address, mpc_control.LEC_ADDRESS, mpc_control.elan_name);
    }
    msg.type = SET_MPC_CTRL_ADDR; 
    memcpy(msg.MPS_ctrl,mpc_control.OWN_ATM_ADDRESS,ATM_ESA_LEN);
    if (send_to_kernel(&msg) < 0) {
      printf("mpcd: main.c: send_to_kernel(SET_MPC_CTRL_ADDR) failed\n");
      exit(1);
    }
    if(mpc_control.mps_mac_addr_set)
      set_mps_mac_addr();
    listen_to_MPS( control_listen_addr );
    if ( (listen_socket = get_listen_socket(&mpc_control.data_listen_addr)) < 0) 
      {
      printf("mpcd: main.c: listen_socket creation failed\n");
      exit (1);
      }
    
    signal(SIGHUP, signal_handler);
    signal(SIGINT, signal_handler);
    signal(SIGQUIT, signal_handler);
    signal(SIGABRT, signal_handler);
    signal(SIGTERM, signal_handler);
    
    main_loop(listen_socket);
    sleep(5);
    printf("mpcd: main.c: going back to main loop...\n");
  }
  return 0;
}
Пример #14
0
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 */
}
Пример #15
0
int main (int argc, char **argv)
#endif
{
    int optchar, action = 0, count = 1, starting_nas_idx = -1,
                 t2a_err, srv_fd, nbytes, header = 0;
    char *endptr;
    char name[MAX_GROUPNAME_LEN] = {};
    struct be_msg smsg, rmsg;
    struct be_memstat rstatmsg;
    struct sockaddr_atmpvc vc;
    struct passwd *pw;
    // brcm
    int encap=BR2684_ENCAPS_LLC, proto_filter=0, mode=0;
    unsigned short vlan_id=-1;

#ifdef SUPPORT_VDSL
    /* start of PROTOCOL PTM by zhouyi 00037589 2006年7月11日 */
    int trafficmode =0;
    /* end of PROTOCOL PTM by zhouyi 00037589 2006年7月11日 */
#endif

    bzero(&vc, sizeof(vc));

    while(1) {
        /* start of PROTOCOL PTM by zhouyi 00037589 2006年7月11日 */
        optchar = getopt(argc, argv, "Madli:v:c:k:g:erft:");
        /* end of PROTOCOL PTM by zhouyi 00037589 2006年7月11日 */
        if (optchar == -1)
            break;

        switch(optchar) {

        case 'M':

            srv_fd = unix_connect();
            smsg.msgtype = MEM_STATS;

            if( send(srv_fd, &smsg, sizeof(smsg), 0) < 0 )
                clean_exit("Can't send MEM_STAT message");

            nbytes = recv(srv_fd, &rstatmsg, sizeof(rstatmsg), 0);
            if(nbytes == 0 )
                clean_exit("connection closed waiting for MEM_STAT response\n");
            else if(nbytes < 0)
                clean_exit("Can't receive MEM_STAT response");

            printf("VC mallocs: %d\nVC frees: %d\nGroup mallocs: %d\nGroup frees:%d\n",
                   rstatmsg.vc_mallocs,rstatmsg.vc_frees,
                   rstatmsg.group_mallocs,rstatmsg.group_frees);
            exit(0);
            break;

        case 'a':
        case 'd':
        case 'l':
            action = optchar;
            break;

        case 'i':
// brcm
            /*
                  starting_nas_idx = strtol(optarg, &endptr, 10);
                  if(*endptr || starting_nas_idx < 0) {
            	printf("Invalid interface index specified\n");
            	exit(1);
                  }
            */
            break;

        case 'v':
            if((t2a_err = (text2atm(optarg, (struct sockaddr *)&vc, sizeof(vc), T2A_PVC)))) {
                printf ("can't parse \"%s\".\n", optarg);
                exit(1);
            }
// brcm
            {
                int retval, num[3];
                retval = sscanf(optarg, "%d.%d.%d", num, num+1, num+2);
                starting_nas_idx = OFFSET*num[1]+num[2];
            }
            break;

        case 'c':
            count = strtol(optarg, &endptr, 10);
            if(*endptr || count <= 0) {
                printf("Invalid count specified\n");
                exit(1);
            }
            break;

// brcm
        case 'e':
            encap=BR2684_ENCAPS_VC;
            break;
#ifdef SUPPORT_VDSL
        /* start of PROTOCOL PTM by zhouyi 00037589 2006年7月11日 */
        case 'k':
            trafficmode = strtol(optarg, &endptr, 10);
            printf("pvc2684ctl_main trafficmode:%d\n", trafficmode);
            break;
            /* end of PROTOCOL PTM by zhouyi 00037589 2006年7月11日 */
#endif
// brcm
        case 'f':
            proto_filter = FILTER_PPPOE;
            break;

// brcm
        case 'r':
            mode=1;
            break;
// brcm  add vlan id flag
        case 't':
            vlan_id = atoi(optarg);
            break;

        case 'g':
            strncpy(name,optarg,MAX_GROUPNAME_LEN);

        case '?':

            break;

        default:
            printf ("getopt returned char %c\n", optchar);
        }
    }

    int hasname = 31;
    for(; hasname>0; hasname--) {
        if(name[hasname] != '\0') break;
    }

    switch(action) {

    case 'a':
    case 'd':

        if(vc.sap_family == AF_ATMPVC) {

            if(starting_nas_idx < 0) {

                /* If you specify a PVC, you must specify an interface too  */
                printf("No interface specified. Use the -i option.\n");
                usage(1);
            }

        } else if(action == 'a') {

            /* If this is an ADD, you need to specify the PVC.  */
            printf("No VC specified. Use the -v option.\n");
            usage(1);

        } else if (!hasname) {

            /* If it's not an ADD, it must be a DELETE. You need at least a name.  */
            printf("No VC or VC group name specified. Use the -v or -g options.\n");
            usage(1);

        } else {

            /* If we're here, no VC was specified, it's a DELETE and a group
            name was specified. Send a DELETE_GROUP message and exit.
                */

            bzero(&rmsg, sizeof(rmsg));
            srv_fd = unix_connect();
            smsg.msgtype = DELETE_GROUP;
            strncpy(smsg.name,name,MAX_GROUPNAME_LEN);

            if( send(srv_fd, &smsg, sizeof(smsg), 0) < 0 )
                clean_exit("Can't send DELETE_GROUP message");

            nbytes = recv(srv_fd, &rmsg, sizeof(rmsg), 0);
            if(nbytes == 0 )
                clean_exit("connection closed waiting for DELETE_GROUP response\n");
            else if(nbytes < 0)
                clean_exit("Can't receive response to DELETE_GROUP message");

            if(rmsg.msgtype == GROUP_NOT_FOUND)
                printf("group \"%s\" doesn't exist\n", name);

            exit(0);
        }

        smsg.msgtype = (action == 'a' ? ADD : DELETE);
        smsg.nas_idx = starting_nas_idx;
        smsg.pvc     = vc;
        strncpy(smsg.name,name,MAX_GROUPNAME_LEN);
        // brcm
        smsg.encap   = encap;
        smsg.proto_filter   = proto_filter;
        smsg.mode   = mode;
        smsg.vlan_id = vlan_id;

#ifdef SUPPORT_VDSL
        /* start of PROTOCOL PTM by zhouyi 00037589 2006年7月11日 */
        //for ptm
        smsg.trafficmode = trafficmode;
        /* end of PROTOCOL PTM by zhouyi 00037589 2006年7月11日 */
#endif

        bzero(&rmsg, sizeof(rmsg));
        srv_fd = unix_connect();

        do {

            if( send(srv_fd, &smsg, sizeof(smsg), 0) < 0 )
                clean_exit("Can't send ADD or DELETE message");

            nbytes = recv(srv_fd, &rmsg, sizeof(rmsg), 0);
            if(nbytes == 0 )
                clean_exit("connection closed waiting for ADD or DELETE response\n");
            else if(nbytes < 0)
                clean_exit("Can't receive response to ADD or DELETE message");

            switch(rmsg.msgtype) {

            case VC_NOT_FOUND:

                printf("No VC %d/%d on nas%d\n",
                       smsg.pvc.sap_addr.vpi,
                       smsg.pvc.sap_addr.vci,
                       smsg.nas_idx);
                break;

            case NOT_OWNER:

                pw = getpwuid(rmsg.uid);
                printf("Can't delete VC %d/%d on nas%d. owner is %s\n",
                       smsg.pvc.sap_addr.vpi,
                       smsg.pvc.sap_addr.vci,
                       smsg.nas_idx,
                       pw->pw_name);
                break;

            case SOCK_FAILED:

                printf("Interface nas%d already in use\n", smsg.nas_idx);
                break;

            case INTERFACE_FAILED:

                printf("Interface nas%d couldn't be created\n", smsg.nas_idx);
                break;

            case NOMEM:

                printf("Server can't allocate memory\n");
                break;

            case OK:

                break;

            default:

                printf("Weird error: %d\n", rmsg.msgtype);
            }

            smsg.nas_idx++;
            smsg.pvc.sap_addr.vci++;

        } while(--count > 0);

        break;

    case 'l':

        srv_fd = unix_connect();
        smsg.msgtype = (strlen(name) ? LIST_GROUP : LIST_ALL );
        strncpy(smsg.name,name,MAX_GROUPNAME_LEN);

        if( send(srv_fd, &smsg, sizeof(smsg), 0) < 0 )
            clean_exit("Can't send LIST_GROUP or LIST_ALL message");


        do {

            nbytes = recv(srv_fd, &rmsg, sizeof(rmsg), 0);
            if(nbytes == 0 )
                clean_exit("connection closed waiting for LIST_GROUP or LIST_ALL response\n");
            else if(nbytes < 0)
                clean_exit("Can't receive response to LIST_GROUP or LIST_ALL message");

            if(rmsg.msgtype == GROUP_NOT_FOUND) {
                if(strlen(name))
                    printf("Group %s not found\n", name);
                else
                    printf("No VCs defined\n");
                break;
            } else if(!header) {
// brcm
                printf("\nVC          interface  mode             vlan_id\n");
                printf("--          ---------  ------           ----------\n");
//	printf("\nVC          interface  group                            owner\n");
//	printf("--          ---------  ------                           -----\n");
                header = 1;
            }

            if(rmsg.msgtype == OK) {
                printf("%2d/%4d     nas%-6d  %-16s %d (X%02X)\n",
                       rmsg.pvc.sap_addr.vpi,
                       rmsg.pvc.sap_addr.vci,
                       rmsg.nas_idx,
                       rmsg.mode? "Routing":	"Bridging",
                       rmsg.vlan_id, rmsg.vlan_id
                      );
            }
        } while(rmsg.msgtype != LIST_END);

        printf("\n");

        break;

    default:
        printf("No command specified. Use -a, -d, or -l\n");
    }
    exit(0);
}
Пример #16
0
int main(int argc,char **argv)
{
    struct atmarp_req req;
    int c,i,num;
    char *here,*end;

    req.type = 0;
    while ((c = getopt(argc,argv,"acdqQsV")) != EOF)
	switch (c) {
	    case 'a':
		if (argc != optind || req.type) usage(argv[0]);
		req.type = art_table;
		/* (void) send_request(&req); @@@ fix this later */
		return print_table();
	    case 'c':
		if (req.type) usage(argv[0]);
		req.type = art_create;
		break;
	    case 'd':
		if (req.type) usage(argv[0]);
		req.type = art_delete;
		break;
	    case 'q':
		if (req.type) usage(argv[0]);
		req.type = art_qos;
		break;
	    case 'Q':
		if (req.type) usage(argv[0]);
		req.type = art_query;
		break;
	    case 's':
		if (req.type) usage(argv[0]);
		req.type = art_set;
		break;
	    case 'V':
		printf("%s\n",VERSION);
		return 0;
	    default:
		usage(argv[0]);
	}
    switch (req.type) {
	case art_create:
	    if (argc == optind) req.itf = -1;
	    else {
		if (argc != optind+1) usage(argv[0]);
		here = argv[optind];
		if (strlen(here) > 3 && !strncmp(here,"atm",3)) here += 3;
		req.itf = strtoul(here,&end,10);
		if (*end || (here[0] == '0' && here[1])) {
		    usage(argv[0]);
		    return 1;
		}
	    }
	    num = send_request(&req);
	    if (req.itf == -1) printf("atm%d\n",num);
	    return 0;
	case art_qos:
	    if (argc < optind+1) usage(argv[0]);
	    /* fall through */
	case art_set:
	    if (argc < optind+2) usage(argv[0]);
	    break;
	case art_query:
	    if (argc != optind+1) usage(argv[0]);
	    break;
	case art_delete:
	    if (argc < optind+1) usage(argv[0]);
	    break;
	default:
	    usage(argv[0]);
    }
    req.ip = text2ip(argv[optind],NULL,T2I_NAME | T2I_ERROR);
    if (req.ip == INADDR_NONE) return 1;
    req.flags = ATF_PERM;
    if (req.type == art_qos) {
	memset(&req.qos,0,sizeof(req.qos));
	req.sndbuf = 0;
	for (i = optind+1; i < argc; i++)
	    if (!strcmp(argv[i],"qos")) {
		    if (++i >= argc) usage(argv[0]);
		    if (text2qos(argv[i],&req.qos,0)) usage(argv[0]);
		}
	    else if (!strcmp(argv[i],"sndbuf")) {
		    if (++i >= argc) usage(argv[0]);
		    req.sndbuf = strtol(argv[i],&end,0);
		    if (*end) usage(argv[0]);
		}
	    else if (i != optind+1 || argc != optind+2 ||
		  text2qos(argv[optind+1],&req.qos,0)) usage(argv[0]);
    }
    if (req.type == art_set) {
	memset(&req.qos,0,sizeof(req.qos));
	req.sndbuf = 0;
	for (i = optind+2; i < argc; i++)
	    if (!strcmp(argv[i],"temp")) req.flags &= ~ATF_PERM;
	    else if (!strcmp(argv[i],"pub")) req.flags |= ATF_PUBL;
	    else if (!strcmp(argv[i],"null")) req.flags |= ATF_NULL;
	    else if (!strcmp(argv[i],"arpsrv")) req.flags |= ATF_ARPSRV;
	    else if (!strcmp(argv[i],"qos")) {
		    if (++i >= argc) usage(argv[0]);
		    if (text2qos(argv[i],&req.qos,0)) usage(argv[0]);
		}
	    else if (!strcmp(argv[i],"sndbuf")) {
		    if (++i >= argc) usage(argv[0]);
		    req.sndbuf = strtol(argv[i],&end,0);
		    if (*end) usage(argv[0]);
		}
	    else if (!strcmp(argv[i],"pcr")) {
		    if (++i >= argc) usage(argv[0]);
		    req.qos.txtp.traffic_class = req.qos.rxtp.traffic_class =
		      ATM_CBR;
		    req.qos.txtp.max_pcr = req.qos.rxtp.max_pcr =
		      strtol(argv[i],&end,0);
		    if (*end) usage(argv[0]);
		}
	    else usage(argv[0]);
	if (text2atm(argv[optind+1],(struct sockaddr *) &req.addr,
	  sizeof(req.addr),T2A_NAME) < 0) {
	    fprintf(stderr,"%s: invalid ATM address\n",argv[optind+1]);
	    return 1;
	}
    }
    if (req.type == art_delete && optind+1 < argc) {
	if (optind+2 < argc || strcmp(argv[optind+1],"arpsrv")) usage(argv[0]);
	req.flags |= ATF_ARPSRV;
    }
    if (!req.qos.aal) req.qos.aal = ATM_AAL5;
    send_request(&req);
    return 0;
}
Пример #17
0
static int atm_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
   struct nlmsghdr *n)
{
	struct sockaddr_atmsvc addr;
	struct atm_qos qos;
	struct atm_sap sap;
	unsigned char hdr[MAX_HDR_LEN];
	__u32 excess = 0;
	struct rtattr *tail;
	int sndbuf = 0;
	int hdr_len = -1;
	int set_clip = 0;
	int s;

	memset(&addr,0,sizeof(addr));
	(void) text2qos("aal5,ubr:sdu=9180,rx:none",&qos,0);
	(void) text2sap("blli:l2=iso8802",&sap,0);
	while (argc > 0) {
		if (!strcmp(*argv,"pvc")) {
			NEXT_ARG();
			if (text2atm(*argv,(struct sockaddr *) &addr,
			    sizeof(addr),T2A_PVC | T2A_NAME) < 0) {
				explain();
				return -1;
			}
		}
		else if (!strcmp(*argv,"svc")) {
			NEXT_ARG();
			if (text2atm(*argv,(struct sockaddr *) &addr,
			    sizeof(addr),T2A_SVC | T2A_NAME) < 0) {
				explain();
				return -1;
			}
		}
		else if (!strcmp(*argv,"qos")) {
			NEXT_ARG();
			if (text2qos(*argv,&qos,0) < 0) {
				explain();
				return -1;
			}
		}
		else if (!strcmp(*argv,"sndbuf")) {
			char *end;

			NEXT_ARG();
			sndbuf = strtol(*argv,&end,0);
			if (*end) {
				explain();
				return -1;
			}
		}
		else if (!strcmp(*argv,"sap")) {
			NEXT_ARG();
			if (addr.sas_family != AF_ATMSVC ||
			    text2sap(*argv,&sap,T2A_NAME) < 0) {
				explain();
				return -1;
			}
		}
		else if (!strcmp(*argv,"hdr")) {
			unsigned char *ptr;
			char *walk;

			NEXT_ARG();
			ptr = hdr;
			for (walk = *argv; *walk; walk++) {
				int tmp;

				if (ptr == hdr+MAX_HDR_LEN) {
//					fprintf(stderr,"header is too long\n");
					return -1;
				}
				if (*walk == '.') continue;
				if (!isxdigit(walk[0]) || !walk[1] ||
				    !isxdigit(walk[1])) {
					explain();
					return -1;
				}
				sscanf(walk,"%2x",&tmp);
				*ptr++ = tmp;
				walk++;
			}
			hdr_len = ptr-hdr;
		}
		else if (!strcmp(*argv,"excess")) {
			NEXT_ARG();
			if (!strcmp(*argv,"clp")) excess = 0;
			else if (get_tc_classid(&excess,*argv)) {
					explain();
					return -1;
				}
		}
		else if (!strcmp(*argv,"clip")) {
			set_clip = 1;
		}
		else {
			explain();
			return 1;
		}
		argc--;
		argv++;
	}
	s = socket(addr.sas_family,SOCK_DGRAM,0);
	if (s < 0) {
//		perror("socket");
		return -1;
	}
	if (setsockopt(s,SOL_ATM,SO_ATMQOS,&qos,sizeof(qos)) < 0) {
//		perror("SO_ATMQOS");
		return -1;
	}
	if (sndbuf)
	    if (setsockopt(s,SOL_SOCKET,SO_SNDBUF,&sndbuf,sizeof(sndbuf)) < 0) {
//		perror("SO_SNDBUF");
	    return -1;
	}
	if (addr.sas_family == AF_ATMSVC && setsockopt(s,SOL_ATM,SO_ATMSAP,
	    &sap,sizeof(sap)) < 0) {
//		perror("SO_ATMSAP");
		return -1;
	}
	if (connect(s,(struct sockaddr *) &addr,addr.sas_family == AF_ATMPVC ?
	    sizeof(struct sockaddr_atmpvc) : sizeof(addr)) < 0) {
///		perror("connect");
		return -1;
	}
	if (set_clip)
		if (ioctl(s,ATMARP_MKIP,0) < 0) {
//			perror("ioctl ATMARP_MKIP");
			return -1;
		}
	tail = NLMSG_TAIL(n);
	addattr_l(n,1024,TCA_OPTIONS,NULL,0);
	addattr_l(n,1024,TCA_ATM_FD,&s,sizeof(s));
	if (excess) addattr_l(n,1024,TCA_ATM_EXCESS,&excess,sizeof(excess));
	if (hdr_len != -1) addattr_l(n,1024,TCA_ATM_HDR,hdr,hdr_len);
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
Пример #18
0
int main(int argc,char **argv)
{
    unsigned long buf[13]; /* ugly */
    struct sockaddr_atmpvc addr;
    struct atm_qos qos;
    char *name,*end;
    int type,gfc,clp;
    int c,s,size;

    type = -1;
    gfc = clp = 0; /* for GCC */
    name = argv[0];
    while ((c = getopt(argc,argv,"t:g:c")) != EOF)
	switch (c) {
	    case 'i':
		interval = 1;
		break;
	    case 't':
		type = strtol(optarg,&end,0);
		if (*end || type < 0 || type > 7) usage(name);
		break;
	    case 'g':
		gfc = strtol(optarg,&end,0);
		if (*end || gfc < 0 || gfc > 15) usage(name);
		break;
	    case 'c':
		clp = 1;
		break;
	    default:
		usage(name);
	}
    if (argc != optind+1) usage(name);
    if ((s = socket(PF_ATMPVC,SOCK_DGRAM,0)) < 0) {
	perror("socket");
	return 1;
    }
    memset(&addr,0,sizeof(addr));
    if (text2atm(argv[optind],(struct sockaddr *) &addr,sizeof(addr),T2A_PVC)
      < 0) usage(name);
    memset(&qos,0,sizeof(qos));
    qos.aal = ATM_AAL0;
    if (type == -1) {
	qos.rxtp.traffic_class = ATM_UBR;
	qos.rxtp.max_sdu = 52;
    }
    else {
	qos.txtp.traffic_class = ATM_UBR;
	qos.txtp.max_sdu = 52;
    }
    if (setsockopt(s,SOL_ATM,SO_ATMQOS,&qos,sizeof(qos)) < 0) {
	perror("setsockopt SO_ATMQOS");
	return 1;
    }
    if (bind(s,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
	perror("bind");
	return 1;
    }
    if (type == -1) {
	while ((size = read(s,buf,52)) == 52) {
	    struct timeval stamp;

	    if (ioctl(s,SIOCGSTAMP,&stamp) < 0) {
		perror("ioctl SIOCGSTAMP");
		return 1;
	    }
	    analyze(buf,stamp);
	    fflush(stdout);
	}
	if (size < 0) perror("read");
	else fprintf(stderr,"short read (%d bytes)\n",size);
	return 1;
    }
    if ((size = read(0,buf+1,ATM_CELL_PAYLOAD)) < 0) {
	perror("read stdin");
	return 1;
    }
    if (size < ATM_CELL_PAYLOAD)
	memset((unsigned char *) (buf+1)+size,0,ATM_CELL_PAYLOAD-size);
    *buf = (gfc << ATM_HDR_GFC_SHIFT) |
      (addr.sap_addr.vpi << ATM_HDR_VPI_SHIFT) |
      (addr.sap_addr.vci << ATM_HDR_VCI_SHIFT) |
      (type << ATM_HDR_PTI_SHIFT) | clp;
    if ((size = write(s,buf,ATM_CELL_SIZE-1)) < 0) {
	perror("write to network");
	return 1;
    }
    if (size < ATM_CELL_SIZE-1) {
	fprintf(stderr,"short write (%d bytes)\n",size);
	return 1;
    }
    return 0;
}