Пример #1
0
static int connect_pppoatm(void)
{
	int fd;
	struct atm_qos qos;

	/* XXX: This won't work on Android */
	system ("/sbin/modprobe pppoatm");

	if (!device_got_set)
		no_device_given_pppoatm();
	fd = socket(AF_ATMPVC, SOCK_DGRAM, 0);
	if (fd < 0)
		fatal("failed to create socket: %m");
	memset(&qos, 0, sizeof qos);
	qos.txtp.traffic_class = qos.rxtp.traffic_class = ATM_UBR;
	/* TODO: support simplified QoS setting */
	if (qosstr != NULL)
		if (text2qos(qosstr, &qos, 0))
			fatal("Can't parse QoS: \"%s\"");
	qos.txtp.max_sdu = lcp_allowoptions[0].mru + pppoatm_overhead();
	qos.rxtp.max_sdu = lcp_wantoptions[0].mru + pppoatm_overhead();
	qos.aal = ATM_AAL5;
	if (setsockopt(fd, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos)) < 0)
		fatal("setsockopt(SO_ATMQOS): %m");
	/* TODO: accept on SVCs... */
	if (connect(fd, (struct sockaddr *) &pvcaddr,
	    sizeof(struct sockaddr_atmpvc)))
		fatal("connect(%s): %m", devnam);
	pppoatm_max_mtu = lcp_allowoptions[0].mru;
	pppoatm_max_mru = lcp_wantoptions[0].mru;
	set_line_discipline_pppoatm(fd);
	strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
	pppoa_fd = fd;
	return fd;
}
Пример #2
0
static int connect_pppoatm_ses(void)
{
	info("connect_pppoatm_ses...Enter");
	glb.real_ttyfd = socket(AF_ATMPVC, SOCK_DGRAM, 0);
	if (glb.real_ttyfd < 0)
		fatal("failed to create socket: %m");
	info("connect_pppoatm_ses: socket created fd - 0x%x.",glb.real_ttyfd);

	memset(&glb.qos, 0, sizeof glb.qos);
	glb.qos.txtp.traffic_class = glb.qos.rxtp.traffic_class = ATM_UBR;
	/* TODO: support simplified QoS setting */
	if (glb.qosstr != NULL) {
	  if (text2qos(glb.qosstr, &glb.qos, 0))
	    fatal("Can't parse QoS: \"%s\"");

	fprintf(stderr, "glb.qos.rxtp.traffic_class = %d\n", glb.qos.rxtp.traffic_class); 

	  glb.qos.txtp.pcr = glb.qos.rxtp.pcr = atoi(glb.qos_pcr);
	  info("glb.qos.txtp.pcr = glb.qos.rxtp.pcr = %d", glb.qos.txtp.pcr);
	  if ((strcmp(glb.qosstr, "VBR") == 0) || (strcmp(glb.qosstr, "NRTVBR") == 0)) {
	       glb.qos.txtp.scr = glb.qos.rxtp.scr = atoi(glb.qos_scr);
	      info("glb.qos.txtp.scr = glb.qos.rxtp.scr = %d", glb.qos.txtp.scr);
		glb.qos.txtp.mbs = glb.qos.rxtp.mbs = atoi(glb.qos_mbs);
	      info("glb.qos.txtp.mbs = glb.qos.rxtp.mbs = %d", glb.qos.txtp.mbs);
	  }
	}
	glb.qos.txtp.max_sdu = lcp_allowoptions[0].mru + (glb.llc_encaps ? 6 : 2);
	glb.qos.rxtp.max_sdu = lcp_wantoptions[0].mru + (glb.llc_encaps ? 6 : 2);
	glb.qos.aal = ATM_AAL5;
	if (setsockopt(glb.real_ttyfd, SOL_ATM, SO_ATMQOS, &glb.qos, sizeof(glb.qos)) < 0)
		fatal("setsockopt(SO_ATMQOS): %m");
	/* TODO: accept on SVCs... */
	info("connect_pppoatm_ses: setsockopt called.");
	if (connect(glb.real_ttyfd, (struct sockaddr *) &glb.pvcaddr,
	    sizeof(struct sockaddr_atmpvc)))
		fatal("connect(%s): %m", devnam);
	info("connect_pppoatm_ses: connect successful.");
	glb.pppoatm_max_mtu = lcp_allowoptions[0].mru;
	glb.pppoatm_max_mru = lcp_wantoptions[0].mru;
	return glb.real_ttyfd;
}
Пример #3
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;
}
Пример #4
0
static int open_signaling(SIG_ENTITY *sig)
{
    struct atm_qos qos;
    int s;

    if ((s = socket(PF_ATMPVC,SOCK_DGRAM,0)) < 0) {
	perror("socket");
	return -1;
    }
    memset(&qos,0,sizeof(qos));
    qos.aal = ATM_AAL5;
    qos.rxtp.max_sdu = qos.txtp.max_sdu = MAX_Q_MSG;
    if (sig->sig_qos) {
	if (text2qos(sig->sig_qos,&qos,T2Q_DEFAULTS) < 0) {
	    fprintf(stderr,"invalid qos: %s\n",sig->sig_qos);
	    return -1;
	}
    }
    else {
	if (sig->sig_pcr == -1)
	    qos.rxtp.traffic_class = qos.txtp.traffic_class = ATM_UBR;
	else {
	    qos.rxtp.traffic_class = qos.txtp.traffic_class = ATM_CBR;
	    qos.rxtp.min_pcr = qos.txtp.min_pcr = sig->sig_pcr;
	}
    }
    if (setsockopt(s,SOL_ATM,SO_ATMQOS,&qos,sizeof(qos)) < 0) {
	perror("setsockopt SO_ATMQOS");
	return -1;
    }
    sig->signaling_pvc.sap_family = AF_ATMPVC;
    if (bind(s,(struct sockaddr *) &sig->signaling_pvc,
      sizeof(sig->signaling_pvc)) < 0) {
	perror("bind");
	return -1;
    }
    return s;
}
Пример #5
0
int main(void)
{
    static int fd[MAX_PAR]; /* to force initialization */
    struct sockaddr_atmsvc local[MAX_ADDR];
    struct atmif_sioc req;
    struct atm_sap sap;
    struct atm_qos qos;
    int listen_fd;
    fd_set rset,wset;
    int fds,completed = 0,connects = 0,accepts = 0;

    FD_ZERO(&rset);
    FD_ZERO(&wset);
    if (text2sap(SAP,&sap,0) < 0) {
	fprintf(stderr,"text2sap\n");
	return 1;
    }
    if (text2qos(QOS,&qos,0) < 0) {
	fprintf(stderr,"text2qos\n");
	return 1;
    }
    listen_fd = socket(PF_ATMSVC,SOCK_DGRAM,0);
    if (listen_fd < 0) {
	perror("socket");
	return 1;
    }
    req.number = ITF;
    req.arg = local;
    req.length = sizeof(local);
    if (ioctl(listen_fd,ATM_GETADDR,&req) < 0) {
	perror("ioctl");
	return 1;
    }
    if (!req.length) {
	fprintf(stderr,"No local address\n");
	return 1;
    }
    if (setsockopt(listen_fd,SOL_ATM,SO_ATMSAP,&sap,sizeof(sap)) < 0) {
	perror("setsockopt SO_ATMSAP");
	return 1;
    }
    if (setsockopt(listen_fd,SOL_ATM,SO_ATMQOS,&qos,sizeof(qos)) < 0) {
	perror("setsockopt SO_ATMQOS");
	return 1;
    }
    if (bind(listen_fd,(struct sockaddr *) local,sizeof(*local)) < 0) {
	perror("bind");
	return 1;
    }
    if (fcntl(listen_fd,F_SETFL,O_NONBLOCK) < 0) {
	perror("fnctl");
	return 1;
    }
    if (listen(listen_fd,5) < 0) {
	perror("listen");
	return 1;
    }
    FD_SET(listen_fd,&rset);
    fds = listen_fd+1;
    (void) signal(SIGCHLD,SIG_IGN);
    while (1) {
	static struct timeval no_delay;
	fd_set _rset = rset;
	fd_set _wset = wset;
	int ret,i,empty;

	no_delay.tv_sec = 0;
	no_delay.tv_usec = 100000;
	ret = select(fds,&_rset,&_wset,NULL,&no_delay);
	if (ret < 0) {
	    perror("select");
	    return 1;
	}
	if (FD_ISSET(listen_fd,&_rset)) {
	    pid_t pid;

	    pid = fork();
	    if (pid < 0) {
		perror("fork");
		return 1;
	    }
	    if (!pid) {
		if (accept(listen_fd,NULL,NULL) >= 0) exit(0);
		perror("accept");
		return 1;
	    }
	    accepts++;
	}
	empty = -1;
	for (i = 0; i < MAX_PAR; i++)
	    if (!fd[i]) empty = i;
	    else if (FD_ISSET(fd[i],&_wset)) {
		    struct sockaddr_atmsvc dummy;

		    if (connect(fd[i],(struct sockaddr *) &dummy,sizeof(dummy))
		      < 0) {
			perror("connect");
			return 1;
		    }
		    FD_CLR(fd[i],&wset);
		    fd[i] = 0;
		    empty = i;
		    if (++completed == EXIT_LIM) {
			printf("%d attempted, %d completed, %d accepts\n",
			  connects,completed,accepts);
			return 0;
		    }
		}
	if (empty != -1) {
	    fd[empty] = socket(PF_ATMSVC,SOCK_DGRAM,0);
	    if (fd[empty] < 0) {
		perror("socket");
		return 1;
	    }
	    if (fcntl(fd[empty],F_SETFL,O_NONBLOCK) < 0) {
		perror("fnctl");
		return 1;
	    }
	    if (setsockopt(fd[empty],SOL_ATM,SO_ATMSAP,&sap,sizeof(sap)) < 0) {
		perror("setsockopt SO_ATMSAP");
		return 1;
	    }
	    if (setsockopt(fd[empty],SOL_ATM,SO_ATMQOS,&qos,sizeof(qos)) < 0) {
		perror("setsockopt SO_ATMQOS");
		return 1;
	    }
	    if (connect(fd[empty],(struct sockaddr *) local,sizeof(*local)) < 0
	      && errno != EINPROGRESS) {
		perror("connect");
		return 1;
	    }
	    FD_SET(fd[empty],&wset);
	    if (fds <= fd[empty]) fds = fd[empty]+1;
	    connects++;
	}
    }
    return 0;
}
Пример #6
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 */
}
Пример #7
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;
}
Пример #8
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;
}
Пример #9
0
int main (int argc, char **argv)
{
  int c, background=0, encap=0, sndbuf=8192;
  struct atm_qos reqqos;
  int itfnum;
  lastsock=-1;
  lastitf=0;
  
  /* st qos to 0 */
  memset(&reqqos, 0, sizeof(reqqos));

  openlog (LOG_NAME,LOG_OPTION,LOG_FACILITY);
  if (argc>1)
    while ((c = getopt(argc, argv,"q:a:bc:e:s:?h")) !=EOF)
      switch (c) {
      case 'q':
	printf ("optarg : %s",optarg);
	if (text2qos(optarg,&reqqos,0)) fprintf(stderr,"QOS parameter invalid\n"); 
	break;
      case 'a':
	assign_vcc(optarg, encap, sndbuf, reqqos);
	break;
      case 'b':
	background=1;
	break;
      case 'c':
	create_br(optarg);
	itfnum = atoi(optarg);
	break;
      case 'e':
	encap=(atoi(optarg));
	if(encap<0){
	  syslog (LOG_ERR, "invalid encapsulation: %s:\n",optarg);
	  encap=0;
	}
	break;
      case 's':
	sndbuf=(atoi(optarg));
	if(sndbuf<0){
	  syslog(LOG_ERR, "Invalid sndbuf: %s, using size of 8192 instead\n",optarg);
	  sndbuf=8192;
	}
	break;
      case '?':
      case 'h':
      default:
	usage(argv[0]);
      }
  else
    usage(argv[0]);

  if (argc != optind) usage(argv[0]);
  
  if(lastsock>=0) close(lastsock);
  
  if (background) {
    pid_t pid;
    
    pid=fork();
    if (pid < 0) {
      fprintf(stderr,"Error detaching\n");
      exit(2);
    } else if (pid) 
      exit(0); // This is the parent
    
    // Become a process group and session group leader
    if (setsid()<0) {
      fprintf (stderr,"Could not set process group\n");
      exit(2);
    }
    
    // Fork again to let process group leader exit
    pid = fork();
    if (pid < 0) {
      fprintf(stderr,"Error detaching during second fork\n");
      exit(2);
    } else if (pid)
      exit(0); // This is the parent
    
    // Now we're ready for buisness
    chdir("/");            // Don't keep directories in use
    close(0); close(1); close(2);  // Close stdin, -out and -error
    /*
      Note that this implementation does not keep an open 
      stdout/err.
      If we need them they can be opened now
    */
    
  }
  
  create_pidfile(itfnum);

  syslog (LOG_INFO, "RFC 1483/2684 bridge daemon started\n");	
  atexit (exitFunc);
  
  while (1) sleep(30);	/* to keep the sockets... */
  return 0;
}