Пример #1
0
struct tunnel *l2tp_call (char *host, int port, struct lac *lac,
                          struct lns *lns)
{
    /*
     * Establish a tunnel from us to host
     * on port port
     */
    struct call *tmp = NULL;
    struct hostent *hp;
    struct in_addr addr;
    port = htons (port);

    hp = gethostbyname (host);
    if (!hp)
    {
        l2tp_log (LOG_WARNING, "Host name lookup failed for %s.\n", host);
        schedule_redial(lac);
        return NULL;
    }
    bcopy (hp->h_addr, &addr.s_addr, hp->h_length);
    /* Force creation of a new tunnel
       and set it's tid to 0 to cause
       negotiation to occur */
    /*
     * to do IPsec properly here, we need to set a socket policy,
     * and/or communicate with pluto.
     */

    tmp = get_call (0, 0, addr, port, IPSEC_SAREF_NULL, IPSEC_SAREF_NULL);
    if (!tmp)
    {
        l2tp_log (LOG_WARNING, "%s: Unable to create tunnel to %s.\n", __FUNCTION__,
             host);
        schedule_redial(lac);
        return NULL;
    }
    tmp->container->tid = 0;
    tmp->container->lac = lac;
    tmp->container->lns = lns;
    tmp->lac = lac;
    tmp->lns = lns;
    if (lac)
        lac->t = tmp->container;
    if (lns)
        lns->t = tmp->container;
    /*
     * Since our state is 0, we will establish a tunnel now
     */
    l2tp_log (LOG_NOTICE, "Connecting to host %s, port %d\n", host,
         ntohs (port));

    if (lac) {
        if (lac->route_rdgw == 1)
            route_add(tmp->container->peer.sin_addr, 0, &tmp->container->rt);
        else if (lac->route_rdgw == 2)
            route_add(tmp->container->peer.sin_addr, 1, &tmp->container->rt);
    }
    control_finish (tmp->container, tmp);
    return tmp->container;
}
Пример #2
0
int msi_kill(MSISession *session, Logger *log)
{
    if (session == NULL) {
        LOGGER_ERROR(log, "Tried to terminate non-existing session");
        return -1;
    }

    m_callback_msi_packet((struct Messenger *) session->messenger, NULL, NULL);

    if (pthread_mutex_trylock(session->mutex) != 0) {
        LOGGER_ERROR(session->messenger->log, "Failed to aquire lock on msi mutex");
        return -1;
    }

    if (session->calls) {
        MSIMessage msg;
        msg_init(&msg, requ_pop);

        MSICall *it = get_call(session, session->calls_head);

        while (it) {
            send_message(session->messenger, it->friend_number, &msg);
            MSICall *temp_it = it;
            it = it->next;
            kill_call(temp_it); /* This will eventually free session->calls */
        }
    }

    pthread_mutex_unlock(session->mutex);
    pthread_mutex_destroy(session->mutex);

    LOGGER_DEBUG(session->messenger->log, "Terminated session: %p", session);
    free(session);
    return 0;
}
Пример #3
0
void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data)
{
    (void)m;
    MSISession *session = (MSISession *)data;

    switch (status) {
        case 0: { /* Friend is now offline */
            LOGGER_DEBUG(m->log, "Friend %d is now offline", friend_number);

            pthread_mutex_lock(session->mutex);
            MSICall *call = get_call(session, friend_number);

            if (call == NULL) {
                pthread_mutex_unlock(session->mutex);
                return;
            }

            invoke_callback(call, msi_OnPeerTimeout); /* Failure is ignored */
            kill_call(call);
            pthread_mutex_unlock(session->mutex);
        }
        break;

        default:
            break;
    }
}
Пример #4
0
/** Answer an IPC call.
 *
 * @param callid Hash of the call to be answered.
 * @param data   Userspace address of call data with the answer.
 *
 * @return 0 on success, otherwise an error code.
 *
 */
sysarg_t sys_ipc_answer_slow(sysarg_t callid, ipc_data_t *data)
{
	/* Do not answer notification callids */
	if (callid & IPC_CALLID_NOTIFICATION)
		return 0;
	
	call_t *call = get_call(callid);
	if (!call)
		return ENOENT;
	
	ipc_data_t saved_data;
	bool saved;
	
	if (answer_need_old(call)) {
		memcpy(&saved_data, &call->data, sizeof(call->data));
		saved = true;
	} else
		saved = false;
	
	int rc = copy_from_uspace(&call->data.args, &data->args, 
	    sizeof(call->data.args));
	if (rc != 0)
		return rc;
	
	rc = answer_preprocess(call, saved ? &saved_data : NULL);
	
	ipc_answer(&TASK->answerbox, call);
	return rc;
}
Пример #5
0
void log_pidcalls (void)
{
	static unint	interval = 0;
	Pidcall_s	*pc;
	int		pid;
	int		i;
	int		rc;

	if (!Fp) return;
	++interval;
	for (i = 0; i < Num_rank; i++) {
		pc = Rank_pidcall[i];
		pid = get_pid(pc->pidcall);
		if (!pc->name) {
			pc->name = get_exe_path(pid);
		}
		rc = fprintf(Fp, "%ld,%d,%d,%lld,%s,%s\n",
			interval, pid, pc->snap.count,
			pc->snap.total_time,
			Syscall[get_call(pc->pidcall)],
			pc->name);
		if (rc < 0) {
			warn("Log failed %s:", File);
			log_close();
		}
	}
}
Пример #6
0
struct tunnel *l2tp_call (char *host, int port, struct lac *lac,
                          struct lns *lns)
{
    /*
     * Establish a tunnel from us to host
     * on port port
     */
    struct call *tmp = NULL;
    struct hostent *hp;
    struct in_addr addr;

#if !defined(__UCLIBC__) \
 || (__UCLIBC_MAJOR__ == 0 \
 && (__UCLIBC_MINOR__ < 9 || (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ < 31)))
    /* force ns refresh from resolv.conf with uClibc pre-0.9.31 */
    res_init();
#endif

    port = htons (port);
    hp = gethostbyname (host);
    if (!hp)
    {
        l2tp_log (LOG_WARNING, "Host name lookup failed for %s.\n",
             host);
        return NULL;
    }
    bcopy (hp->h_addr, &addr.s_addr, hp->h_length);
    /* Force creation of a new tunnel
       and set it's tid to 0 to cause
       negotiation to occur */
    /*
     * to do IPsec properly here, we need to set a socket policy,
     * and/or communicate with pluto.
     */
    tmp = get_call (0, 0, addr, port, IPSEC_SAREF_NULL, IPSEC_SAREF_NULL);
    if (!tmp)
    {
        l2tp_log (LOG_WARNING, "%s: Unable to create tunnel to %s.\n", __FUNCTION__,
             host);
        return NULL;
    }
    tmp->container->tid = 0;
    tmp->container->lac = lac;
    tmp->container->lns = lns;
    tmp->lac = lac;
    tmp->lns = lns;
    if (lac)
        lac->t = tmp->container;
    if (lns)
        lns->t = tmp->container;
    /*
     * Since our state is 0, we will establish a tunnel now
     */
    l2tp_log (LOG_NOTICE, "Connecting to host %s, port %d\n", host,
         ntohs (port));
    control_finish (tmp->container, tmp);
    return tmp->container;
}
Пример #7
0
bool call_handler::add_button()
{
    button* btn_in = new button(this->_floor_count+1);
    if(!btn_in)
        return false;

    this->_buttons_in.push_back(btn_in);
    connect(btn_in,SIGNAL(signal_Pressed(size_t)),this,SLOT(get_call(size_t)));
    this->_floor_count++;
    return true;
}
Пример #8
0
void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object)
{
    LOGGER_DEBUG(m->log, "Got msi message");

    MSISession *session = (MSISession *)object;
    MSIMessage msg;

    if (msg_parse_in(m->log, &msg, data, length) == -1) {
        LOGGER_WARNING(m->log, "Error parsing message");
        send_error(m, friend_number, msi_EInvalidMessage);
        return;
    }

    LOGGER_DEBUG(m->log, "Successfully parsed message");

    pthread_mutex_lock(session->mutex);
    MSICall *call = get_call(session, friend_number);

    if (call == NULL) {
        if (msg.request.value != requ_init) {
            send_error(m, friend_number, msi_EStrayMessage);
            pthread_mutex_unlock(session->mutex);
            return;
        }

        call = new_call(session, friend_number);

        if (call == NULL) {
            send_error(m, friend_number, msi_ESystem);
            pthread_mutex_unlock(session->mutex);
            return;
        }
    }

    switch (msg.request.value) {
        case requ_init:
            handle_init(call, &msg);
            break;

        case requ_push:
            handle_push(call, &msg);
            break;

        case requ_pop:
            handle_pop(call, &msg); /* always kills the call */
            break;
    }

    pthread_mutex_unlock(session->mutex);
}
Пример #9
0
struct tunnel *l2tp_call (char *host, int port, struct lac *lac,
                          struct lns *lns)
{
    /*
     * Establish a tunnel from us to host
     * on port port
     */
    struct call *tmp = NULL;
    struct hostent *hp;
    unsigned int addr;
    port = htons (port);
    hp = gethostbyname (host);
    if (!hp)
    {
        log (LOG_WARN, "Host name lookup failed for %s.\n",
             host);
        return NULL;
    }
    bcopy (hp->h_addr, &addr, hp->h_length);
    /* Force creation of a new tunnel
       and set it's tid to 0 to cause
       negotiation to occur */
    /* XXX L2TP/IPSec: Set up SA to addr:port here?  NTB 20011010
     */
    tmp = get_call (0, 0, addr, port);
    if (!tmp)
    {
        log (LOG_WARN, "%s: Unable to create tunnel to %s.\n", __FUNCTION__,
             host);
        return NULL;
    }
    tmp->container->tid = 0;
    tmp->container->lac = lac;
    tmp->container->lns = lns;
    tmp->lac = lac;
    tmp->lns = lns;
    if (lac)
        lac->t = tmp->container;
    if (lns)
        lns->t = tmp->container;
    /*
     * Since our state is 0, we will establish a tunnel now
     */
    log (LOG_NOTICE, "Connecting to host %s, port %d\n", host,
         ntohs (port));
    control_finish (tmp->container, tmp);
    return tmp->container;
}
Пример #10
0
int msi_invite(MSISession *session, MSICall **call, uint32_t friend_number, uint8_t capabilities)
{
    if (!session) {
        return -1;
    }

    LOGGER_DEBUG(session->messenger->log, "Session: %p Inviting friend: %u", session, friend_number);

    if (pthread_mutex_trylock(session->mutex) != 0) {
        LOGGER_ERROR(session->messenger->log, "Failed to aquire lock on msi mutex");
        return -1;
    }

    if (get_call(session, friend_number) != NULL) {
        LOGGER_ERROR(session->messenger->log, "Already in a call");
        pthread_mutex_unlock(session->mutex);
        return -1;
    }

    (*call) = new_call(session, friend_number);

    if (*call == NULL) {
        pthread_mutex_unlock(session->mutex);
        return -1;
    }

    (*call)->self_capabilities = capabilities;

    MSIMessage msg;
    msg_init(&msg, requ_init);

    msg.capabilities.exists = true;
    msg.capabilities.value = capabilities;

    send_message((*call)->session->messenger, (*call)->friend_number, &msg);

    (*call)->state = msi_CallRequesting;

    LOGGER_DEBUG(session->messenger->log, "Invite sent");
    pthread_mutex_unlock(session->mutex);
    return 0;
}
Пример #11
0
/** Answer an IPC call - fast version.
 *
 * This function can handle only two return arguments of payload, but is faster
 * than the generic sys_ipc_answer().
 *
 * @param callid Hash of the call to be answered.
 * @param retval Return value of the answer.
 * @param arg1   Service-defined return value.
 * @param arg2   Service-defined return value.
 * @param arg3   Service-defined return value.
 * @param arg4   Service-defined return value.
 *
 * @return 0 on success, otherwise an error code.
 *
 */
sysarg_t sys_ipc_answer_fast(sysarg_t callid, sysarg_t retval,
    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
{
	/* Do not answer notification callids */
	if (callid & IPC_CALLID_NOTIFICATION)
		return 0;
	
	call_t *call = get_call(callid);
	if (!call)
		return ENOENT;
	
	ipc_data_t saved_data;
	bool saved;
	
	if (answer_need_old(call)) {
		memcpy(&saved_data, &call->data, sizeof(call->data));
		saved = true;
	} else
		saved = false;
	
	IPC_SET_RETVAL(call->data, retval);
	IPC_SET_ARG1(call->data, arg1);
	IPC_SET_ARG2(call->data, arg2);
	IPC_SET_ARG3(call->data, arg3);
	IPC_SET_ARG4(call->data, arg4);
	
	/*
	 * To achieve deterministic behavior, zero out arguments that are beyond
	 * the limits of the fast version.
	 */
	IPC_SET_ARG5(call->data, 0);
	int rc = answer_preprocess(call, saved ? &saved_data : NULL);
	
	ipc_answer(&TASK->answerbox, call);
	return rc;
}
Пример #12
0
struct tunnel *l2tp_call (char *host, int port, struct lac *lac,
                          struct lns *lns)
{
    /*
     * Establish a tunnel from us to host
     * on port port
     */
    struct call *tmp = NULL;
    struct hostent *hp;
    unsigned int addr;
//-------------------------------------------------    
#if defined(CONFIG_RTL8186_TR) || defined(CONFIG_RTL865X_SC)
	struct in_addr retval;
	struct in_addr intaddr;
	struct in_addr intmask;
  	char server_ip[100];
  	char l2tp_gw[30];
  	char l2tp_ipdyn[30];
  	char cmdBuffer[200];
  	FILE *fp1, *fp2;
#endif  
//------------------------------------------------
    port = htons (port);
    hp = gethostbyname (host);
    if (!hp)
    {
        log (LOG_WARN, "Host name lookup failed for %s.\n",
             host);
        return NULL;
    }
#if defined(CONFIG_RTL8186_TR) || defined(CONFIG_RTL865X_SC)
 	//Brad add   
  //if l2tp server is not in the same subnet as l2tp client, we put l2tp server ip to /var/l2tp_server
    	memcpy(&retval.s_addr, hp->h_addr, sizeof(retval.s_addr));
	if (getInAddr("eth1", IP_ADDR, (void *)&intaddr )){
  	if(getInAddr("eth1", SUBNET_MASK, (void *)&intmask)){
  		if((intaddr.s_addr & intmask.s_addr) != (retval.s_addr & intmask.s_addr)){
  			//warn("generate pptp server =%s\n", inet_ntoa(retval));
  			sprintf(server_ip, "echo %s > /var/l2tp_server", inet_ntoa(retval));
  			system(server_ip);
			fp1= fopen("/var/l2tp_dyn", "r");
				if(fp1 !=NULL){
					fscanf(fp1, "%s", l2tp_ipdyn);
					if(l2tp_ipdyn[0]=='1'){
						fp2= fopen("/var/l2tp_gw", "r");
						if (fp2 != NULL) {
							fscanf(fp2, "%s", l2tp_gw);
							sprintf(cmdBuffer, "route add -host %s gw %s", inet_ntoa(retval), l2tp_gw);
							system(cmdBuffer);
        						fclose(fp2);
   						}
					}else{
							fp2= fopen("/var/eth1_gw", "r");
							if (fp2 != NULL) {
								fscanf(fp2, "%s", l2tp_gw);
								sprintf(cmdBuffer, "route add -host %s gw %s", inet_ntoa(retval), l2tp_gw);
								system(cmdBuffer);
        							fclose(fp2);
   							}
						}
					fclose(fp1);
				}
			}
		}
	}
#endif
    bcopy (hp->h_addr, &addr, hp->h_length);
    /* Force creation of a new tunnel
       and set it's tid to 0 to cause
       negotiation to occur */
    /* XXX L2TP/IPSec: Set up SA to addr:port here?  NTB 20011010
     */
    tmp = get_call (0, 0, addr, port);
    if (!tmp)
    {
        log (LOG_WARN, "%s: Unable to create tunnel to %s.\n", __FUNCTION__,
             host);
        return NULL;
    }
    tmp->container->tid = 0;
    tmp->container->lac = lac;
    tmp->container->lns = lns;
    tmp->lac = lac;
    tmp->lns = lns;
    if (lac)
        lac->t = tmp->container;
    if (lns)
        lns->t = tmp->container;
    /*
     * Since our state is 0, we will establish a tunnel now
     */
    log (LOG_NOTICE, "Connecting to host %s, port %d\n", host,
         ntohs (port));
    control_finish (tmp->container, tmp);
    return tmp->container;
}
Пример #13
0
int main(int argc, char **argv)
{
  int i, j, fd, curfile, chars, k, in_comment = 0, in_white = 0, calls = 0, in_parens = 0, in_quotes = 0, in_define = 0, in_curly = 0;
  int maxc[NAME_SIZE], maxf[NAME_SIZE], maxg[NAME_SIZE], mcalls[NAME_SIZE];
  qdata **qs;
  char input[MAX_CHARS];
  char curname[ID_SIZE];
  FILE *FD = NULL;
  
  names_size = NAME_SIZE;
  names = (char **)calloc(names_size, sizeof(char *));
  hnames = (char **)calloc(names_size, sizeof(char *));
  nnames = (char **)calloc(names_size, sizeof(char *));
  voids = (int *)calloc(names_size, sizeof(int));
  files_size = 256;
  files = (char **)calloc(files_size, sizeof(char *));
  headers_size = 32;
  headers = (char **)calloc(headers_size, sizeof(char *));
  counts = (int **)calloc(names_size, sizeof(int *));
  lines = (char ***)calloc(names_size, sizeof(char **));
  results = (int *)calloc(names_size, sizeof(int));
  procs = (int *)calloc(names_size, sizeof(int));

  add_header("sndlib.h");
  add_header("clm.h");
  add_header("vct.h");
  add_header("sndlib2xen.h");
  add_header("clm2xen.h");
  add_header("snd.h");
#if 1
  add_header("snd-strings.h");
  add_header("sndlib-strings.h");
  add_header("clm-strings.h");
#endif
  add_header("snd-0.h");
  add_header("snd-1.h");
  add_header("snd-x0.h");
  add_header("snd-x1.h");
  add_header("snd-g0.h");
  add_header("snd-g1.h");
  add_header("snd-nogui0.h");
  add_header("snd-nogui1.h");
  add_header("snd-rec.h");
  add_header("xen.h");
  add_header("mus-config.h.in");
  add_header("libclm.def");
  add_header("snd-menu.h");
  add_header("snd-file.h");

  /* add_file("xen.h"); */
  /* add_file("snd.h"); */

  add_file("headers.c");
  add_file("audio.c");
  add_file("io.c");
  add_file("sound.c");
  add_file("clm.c");
  add_file("vct.c");
  add_file("cmus.c");
  add_file("sndlib2xen.c");
  add_file("clm2xen.c");
  add_file("midi.c");
  add_file("snd-io.c");
  add_file("snd-utils.c");
  add_file("snd-error.c");
  add_file("snd-completion.c");
  add_file("snd-menu.c");
  add_file("snd-axis.c");
  add_file("snd-data.c");
  add_file("snd-draw.c");
  add_file("snd-fft.c");
  add_file("snd-marks.c");
  add_file("snd-file.c");
  add_file("snd-edits.c");
  add_file("snd-chn.c");
  add_file("snd-sig.c");
  add_file("snd-kbd.c");
  add_file("snd-dac.c");
  add_file("snd-region.c");
  add_file("snd-run.c");
  add_file("snd-select.c");
  add_file("snd-find.c");
  add_file("snd-snd.c");
  add_file("snd-help.c");
  add_file("snd-main.c");
  add_file("snd-print.c");
  add_file("snd-trans.c");
  add_file("snd-mix.c");
  add_file("snd.c");
  add_file("snd-rec.c");
  add_file("snd-env.c");
  add_file("snd-xen.c");
  add_file("snd-ladspa.c");
  add_file("snd-xutils.c");
  add_file("snd-xhelp.c");
  add_file("snd-xfind.c");
  add_file("snd-xmenu.c");
  add_file("snd-xdraw.c");
  add_file("snd-xlistener.c");
  add_file("snd-listener.c");
  add_file("snd-xchn.c");
  add_file("snd-xsnd.c");
  add_file("snd-xregion.c");
  add_file("snd-xdrop.c");
  add_file("snd-xmain.c");
  add_file("snd-xmix.c");
  add_file("snd-xrec.c");
  add_file("snd-xenv.c");
  add_file("snd-gxutils.c");
  add_file("snd-gxbitmaps.c");
  add_file("snd-gxcolormaps.c");
  add_file("snd-xfft.c");
  add_file("snd-xprint.c");
  add_file("snd-xfile.c");
  add_file("snd-xprefs.c");
  add_file("snd-xxen.c");
  add_file("snd-gutils.c");
  add_file("snd-ghelp.c");
  add_file("snd-gfind.c");
  add_file("snd-gmenu.c");
  add_file("snd-gdraw.c");
  add_file("snd-glistener.c");
  add_file("snd-gchn.c");
  add_file("snd-gsnd.c");
  add_file("snd-gregion.c");
  add_file("snd-gdrop.c");
  add_file("snd-gmain.c");
  add_file("snd-gmix.c");
  add_file("snd-grec.c");
  add_file("snd-genv.c");
  add_file("snd-gxutils.c");
  add_file("snd-gfft.c");
  add_file("snd-gprint.c");
  add_file("snd-gfile.c");
  add_file("snd-gxen.c");
  add_file("snd-gprefs.c");
  add_file("snd-prefs.c");
  add_file("snd-nogui.c");
  add_file("xen.c");
  add_file("xm.c");
  add_file("gl.c");
  add_file("xg.c");

  add_file("cmus.c");
  add_file("sc.c");
  add_file("ffi.lisp");
  add_file("sndlib2clm.lisp");

  for (i = 0; i < headers_ctr; i++)
    {
      k = 0;
      in_quotes = 0;
      in_white = 0;
      in_parens = 0;
      in_comment = 0;
      fd = open(headers[i], O_RDONLY, 0);
      if (fd == -1)
	fprintf(stderr, "can't find %s\n", headers[i]);
      else
	{
	  do 
	    {
	      chars = read(fd, input, MAX_CHARS);
	      /* fprintf(stderr,"%s %d ", headers[i], chars); */
	      for (j = 0; j < chars; j++)
		{
		  if ((in_comment == 0) && (in_curly == 0))
		    {
		      if ((isalpha(input[j])) || (isdigit(input[j])) || (input[j] == '_'))
			{
			  in_white = 0;
			  if (k < ID_SIZE)
			    curname[k++] = input[j];
			  else fprintf(stderr, "0: curname overflow: %s[%d]: %s%c\n", headers[i], j, curname, input[j]);
			}
		      else
			{
			  in_white = 1;
			  if (k < ID_SIZE)
			    curname[k] = 0;
			  else fprintf(stderr, "1: curname overflow: %s[%d]: %s\n", headers[i], j, curname);
			  if ((k > 0) && (in_parens == 0) && (in_quotes == 0))
			    {
			      int loc;
			      loc = add_name(copy_string(curname), headers[i]);
			      if (loc >= 0)
				{
				  int start, n, maybe_proc = 1;
				  for (n = 0; n < k; n++)
				    if (isupper(curname[n]))
				      {
					maybe_proc = 0;
					break;
				      }
				  if ((maybe_proc) && ((input[j] == '(') || ((input[j] == ' ') && (input[j + 1] == '('))))
				    procs[loc] = maybe_proc;
				  else procs[loc] = 0;
				  start = j - strlen(curname) - 6;
				  if (start >= 0)
				    {
				      int m;
				      for (m = 0; m < 3; m++)
					if (strncmp((char *)(input + start + m), "void", 4) == 0)
					  {
					    voids[loc] = 1;
					    break;
					  }
				    }
				}
			    }
			  /* else if (k > 0) fprintf(stderr,"drop %s %d %d\n",curname,in_parens, in_quotes); */
			  k = 0;
			  if ((input[j] == '/') && (input[j + 1] == '*'))
			    in_comment = 1;
			  else 
			    {
			      if (input[j] == '#')
				in_define = 1;
			      else
				{
				  if ((input[j] == '{') && 
				      ((j < 6) || (strncmp((input + (j - 5)), "enum", 4) != 0)))
				    in_curly = 1;
				  else
				    {
				      if (input[j] == '(') in_parens++;
				      if (input[j] == ')') in_parens--;
				      if (input[j] == '"')
					{
					  if (in_quotes == 1)
					    in_quotes = 0;
					  else in_quotes = 1;
					}
				    }
				}
			    }
			}
		    }
		  else /* in comment or curly */
		    {
		      if ((input[j] == '*') && (input[j + 1] == '/'))
			in_comment = 0;
		      else 
			{
			  if (input[j] == '}')
			    in_curly = 2;
			  else
			    {
			      if (input[j] == ';')
				in_curly = 0;
			    }
			}
		    }
		}
	    }
	  while (chars == MAX_CHARS);
	  close(fd);
	}
    }

  fprintf(stderr, "%d names ", names_ctr);
  k = 0;
  in_comment = 0;
  in_white = 0;
  in_define = 0;
  for (i = 0; i < files_ctr; i++)
    {
      k = 0;
      fd = open(files[i], O_RDONLY, 0);
      if (fd == -1)
	fprintf(stderr, "can't find %s\n", files[i]);
      else
	{
	  int curly_ctr = 0,cancel_define = 0;
	  in_define = 0;

	  if ((strcmp(files[i], "sndlib2clm.lisp") == 0) ||
	      (strcmp(files[i], "ffi.lisp") == 0))
	    curly_ctr = 1;

	  do 
	    {
	      chars = read(fd, input, MAX_CHARS);
	      /* fprintf(stderr,"%s %d\n", files[i], chars); */

	      for (j = 0; j < chars; j++)
		{
		  if (in_comment == 0)
		    {
		      if ((isalpha(input[j])) || (isdigit(input[j])) || (input[j] == '_'))
			{
			  if (k < ID_SIZE)
			    curname[k++] = input[j];
			  else fprintf(stderr, "2: curname overflow: %s[%d]: %s\n", files[i], j, curname);
			}
		      else
			{
			  if ((input[j] == '/') && (input[j + 1] == '*'))
			    in_comment = 1;
			  else
			    {
			      if ((input[j] == '#') && (input[j + 1] == 'd'))
				{
				  /*
				  int m;
				  fprintf(stderr,"def...");
				  for (m = j; (m < j + 16) && (m < chars); m++) fprintf(stderr,"%c", input[m]);
				  */
				  in_define = 1;
				}
			      else
				{
				  if ((in_define == 1) && (input[j] == '\n') && (j > 0) && (input[j - 1] != '\\'))
				    {
				      /*
				      fprintf(stderr,"!\n");
				      */
				      cancel_define = 1;
				    }
				}
			      if ((in_define == 0) && 
				  (j < (chars - 1)) && 
				  ((input[j - 1] != '\'') || (input[j + 1] != '\'')))
				{
				  if (input[j] == '{') curly_ctr++;
				  else if (input[j] == '}') curly_ctr--;
				}
			    }
			  if (k > 0)
			    {
			      if (k < ID_SIZE)
				curname[k] = 0;
			      else fprintf(stderr, "3: curname overflow: %s[%d]: %s\n", files[i], j, curname);
			      if ((k < ID_SIZE) && 
				  ((curly_ctr > 0) || (in_define == 1)))
				{
				  int loc;
				  loc = add_count(curname, i);
				  if (loc >= 0)
				    {
				      if (procs[loc])
					results[loc] += get_result(input, j, k);
				      if (lines[loc] == NULL)
					{
					  lines[loc] = (char **)calloc(MAX_LINES, sizeof(char *));
					  lines[loc][0] = get_call(input, j, k, curname, chars);
					}
				      else
					{
					  int m;
					  for (m = 0; m < MAX_LINES; m++)
					    if (lines[loc][m] == NULL)
					      {
						lines[loc][m] = get_call(input, j, k, curname, chars);
						break;
					      }
					}
				    }
				}
			      k = 0;
			    }
			  if (cancel_define == 1)
			    {
			      cancel_define = 0;
			      in_define = 0;
			    }
			}
		    }
		  else
		    {
		      if ((input[j] == '*') && (input[j + 1] == '/'))
			in_comment = 0;
		    }
		}
	    }
	  while (chars == MAX_CHARS);
	  close(fd);
	}
    }

  FD = fopen("xref.data","w");
  if (!FD)
    fprintf(stderr, "can't write xref.data?");
  else
    {
      for (i = 0; i < names_ctr; i++)
	{
	  maxc[i] = 0;
	  maxf[i] = 0;
	  maxg[i] = 0;
	  for (j = 0; j < files_ctr; j++)
	    if ((counts[i]) && (counts[i][j] > 0)) 
	      {
		maxc[i] += counts[i][j]; 
		maxf[i]++;
		if ((j == snd_xen_c) || (j == snd_nogui_c)) maxg[i]++;
	      }
	}
      for (i = 0; i < names_ctr; i++)
	{
	  calls = 0;
	  if (counts[i])
	    for (j = 0; j < files_ctr; j++)
	      calls += counts[i][j];
	  mcalls[i] = calls;
	}
      qs = (qdata **)calloc(NAME_SIZE, sizeof(qdata *));
      for (i = 0; i < names_ctr; i++)
	{
	  qdata *q;
	  q = calloc(1, sizeof(qdata));
	  qs[i] = q;
	  q->i = i;
	  q->v = voids[i];
	  q->name = names[i];
	  q->hname = hnames[i];
	  q->calls = mcalls[i];
	  q->results = results[i];
	  q->proc = procs[i];
	}
      qsort((void *)qs, names_ctr, sizeof(qdata *), greater_compare);
      for (i = 0; i < names_ctr; i++)
	{
	  bool menu_case = false, file_case = false, rec_case = false, nonogui_case = false;
	  int menu_count = 0, file_count = 0, rec_count = 0;
	  int nfiles;
	  nfiles = 0;
	  /* try to get rid of a bunch of annoying false positives */
	  if ((qs[i]->calls == 0) &&
	      ((strcmp(qs[i]->hname, "xen.h") == 0) || 
	       (strcmp(qs[i]->hname, "mus-config.h.in") == 0) ||
	       (qs[i]->name[strlen(qs[i]->name) - 2] == '_') &&
	       ((qs[i]->name[strlen(qs[i]->name) - 1] == 't') || (qs[i]->name[strlen(qs[i]->name) - 1] == 'H'))))
	    {
	    }
	  else
	    {
	      fprintf(FD, "\n\n%s: %d [%s]", qs[i]->name, qs[i]->calls, qs[i]->hname);
	      if (qs[i]->v) 
		{
		  fprintf(FD, " (void)");
		}
	      else
		{
		  if ((qs[i]->results == 0) && (qs[i]->proc > 0) && (qs[i]->calls > 0) &&
		      (strncmp(qs[i]->name, "set_", 4) != 0) &&
		      (strncmp(qs[i]->name, "in_set_", 7) != 0))
		    fprintf(FD, " (not void but result not used?)");
		}
	      menu_case = (strcmp(qs[i]->hname, "snd-menu.h") != 0);
	      file_case = (strcmp(qs[i]->hname, "snd-file.h") != 0);
	      rec_case = (strcmp(qs[i]->hname, "snd-rec.h") != 0);
	      menu_count  = 0;
	      file_count = 0;
	      rec_count = 0;

	      nonogui_case = in_nogui_h(qs[i]->name);
	      if ((nonogui_case) && (counts[qs[i]->i]))
		{
		  /* fprintf(stderr, "%s...", qs[i]->name); */
		  for (j = 0; j < files_ctr; j++)
		    if ((counts[qs[i]->i][j] > 0) &&
			((strcmp(files[j], "snd-xen.c") == 0) ||
			 ((strcmp(files[j], "snd-nogui.c") != 0) &&
			  (strncmp(files[j], "snd-x", 5) != 0) &&
			  (strncmp(files[j], "snd-g", 5) != 0))))
		      {
			/* fprintf(stderr,"in %s\n", files[j]); */
			nonogui_case = false;
			break;
		      }
		  /* if (nonogui_case) fprintf(stderr, "!\n"); */
		}

	      for (j = 0; j < files_ctr; j++)
		{
		  if ((counts[qs[i]->i]) && (counts[qs[i]->i][j] > 0))
		    {
		      if (menu_case)
			{
			  if ((strcmp(files[j], "snd-menu.c") != 0) &&
			      (strcmp(files[j], "snd-xmenu.c") != 0) &&
			      (strcmp(files[j], "snd-gmenu.c") != 0))
			    {
			      if (strcmp(files[j], "snd-nogui.c") != 0)
				menu_case = false;
			    }
			  else menu_count++;
			}
		      if (file_case)
			{
			  if ((strcmp(files[j], "snd-file.c") != 0) &&
			      (strcmp(files[j], "snd-xfile.c") != 0) &&
			      (strcmp(files[j], "snd-gfile.c") != 0))
			    {
			      if (strcmp(files[j], "snd-nogui.c") != 0)
				file_case = false;
			    }
			  else file_count++;
			}
		      if (rec_case)
			{
			  if ((strcmp(files[j], "snd-rec.c") != 0) &&
			      (strcmp(files[j], "snd-xrec.c") != 0) &&
			      (strcmp(files[j], "snd-grec.c") != 0))
			    {
			      if (strcmp(files[j], "snd-nogui.c") != 0)
				rec_case = false;
			    }
			  else rec_count++;
			}
		      
		      fprintf(FD,"\n    %s: %d", files[j], counts[qs[i]->i][j]);
		      nfiles++;
		    }
		}
	      if ((menu_case) && (menu_count > 0)) fprintf(FD, "\n->SND-MENU.H\n");
	      if ((file_case) && (file_count > 0)) fprintf(FD, "\n->SND-FILE.H\n");
	      if ((rec_case) && (rec_count > 0)) fprintf(FD, "\n->SND-REC.H\n");
	      if (nonogui_case) fprintf(FD, "\nnot needed in snd-nogui?\n");
	      {
		int m;
		if ((nfiles > 0) && (lines[qs[i]->i]))
		  {
		    fprintf(FD, "\n");
		    for (m = 0; m < MAX_LINES; m++)
		      {
			if (lines[qs[i]->i][m] == NULL) break;
			fprintf(FD, "\n        %s", lines[qs[i]->i][m]);
		      }
		  }
	      }
	      if ((nfiles < 2) &&
		  (qs[i]->calls > 1) &&
		  (islower(qs[i]->name[0])) &&
		  (strncmp(qs[i]->name, "snd_K", 5) != 0) &&
		  (strncmp(qs[i]->name, "mus_", 4) != 0) &&
		  (strncmp(qs[i]->name, "ps_", 3) != 0))
		fprintf(FD, "\n----------------- (static?) -----------------------");
	      else fprintf(FD, "\n----------------");
	    }
	}
      fclose(FD);
    }
  return(0);
}
struct tunnel *l2tp_call (char *host, int port, struct lac *lac,
                          struct lns *lns)
{
    /*
     * Establish a tunnel from us to host
     * on port port
     */
    struct call *tmp = NULL;
    struct hostent *hp;
    unsigned int addr;
    FILE *fp;
    port = htons (port);

    /* Foxconn, added by MJ. 01/29/2010 */
    struct in_addr l2tp_serv_ip;

    /* add routing for DNS server 01/29/2010*/
    fxc_add_gw(1, l2tp_serv_ip);
    /* Foxconn, added end.*/

    hp = gethostbyname (host);

    if (!hp)
    {
        log (LOG_WARN, "%s: gethostbyname() failed for %s.\n", __FUNCTION__,
             host);
        return NULL;
    }
    bcopy (hp->h_addr, &addr, hp->h_length);

    /* Foxconn, add start by MJ., for l2tp. 01/28/2010 */

    if (hp->h_addrtype == AF_INET){
        memcpy(&l2tp_serv_ip.s_addr, hp->h_addr, sizeof(l2tp_serv_ip.s_addr));
        if ( fp = fopen("/tmp/ppp/l2tpSrvIp", "w") )
        {
            fprintf(fp, "%s", inet_ntoa(l2tp_serv_ip));
            fclose(fp);
        }
    }

    /* Add routing for L2TP server */
    fxc_add_gw(2, l2tp_serv_ip);
    /* Foxconn, add end, by MJ., for l2tp. 01/28/2010 */    


    /* Force creation of a new tunnel
       and set it's tid to 0 to cause
       negotiation to occur */
    /* XXX L2TP/IPSec: Set up SA to addr:port here?  NTB 20011010
     */
    tmp = get_call (0, 0, addr, port);
    if (!tmp)
    {
        log (LOG_WARN, "%s: Unable to create tunnel to %s.\n", __FUNCTION__,
             host);
        return NULL;
    }
    tmp->container->tid = 0;
    tmp->container->lac = lac;
    tmp->container->lns = lns;
    tmp->lac = lac;
    tmp->lns = lns;
    if (lac)
        lac->t = tmp->container;
    if (lns)
        lns->t = tmp->container;
    /*
     * Since our state is 0, we will establish a tunnel now
     */
    log (LOG_LOG, "%s:Connecting to host %s, port %d\n", __FUNCTION__, host,
         ntohs (port));
    control_finish (tmp->container, tmp);
    return tmp->container;
}
Пример #15
0
/** Forward a received call to another destination
 *
 * Common code for both the fast and the slow version.
 *
 * @param callid  Hash of the call to forward.
 * @param phoneid Phone handle to use for forwarding.
 * @param imethod New interface and method to use for the forwarded call.
 * @param arg1    New value of the first argument for the forwarded call.
 * @param arg2    New value of the second argument for the forwarded call.
 * @param arg3    New value of the third argument for the forwarded call.
 * @param arg4    New value of the fourth argument for the forwarded call.
 * @param arg5    New value of the fifth argument for the forwarded call.
 * @param mode    Flags that specify mode of the forward operation.
 * @param slow    If true, arg3, arg4 and arg5 are considered. Otherwise
 *                the function considers only the fast version arguments:
 *                i.e. arg1 and arg2.
 *
 * @return 0 on succes, otherwise an error code.
 *
 * Warning: Make sure that ARG5 is not rewritten for certain system IPC
 *
 */
static sysarg_t sys_ipc_forward_common(sysarg_t callid, sysarg_t phoneid,
    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    sysarg_t arg4, sysarg_t arg5, unsigned int mode, bool slow)
{
	call_t *call = get_call(callid);
	phone_t *phone;
	bool need_old = answer_need_old(call);
	bool after_forward = false;
	ipc_data_t old;
	int rc;

	if (!call)
		return ENOENT;

	if (need_old)
		old = call->data;
	
	if (phone_get(phoneid, &phone) != EOK) {
		rc = ENOENT;
		goto error;
	}
	
	if (!method_is_forwardable(IPC_GET_IMETHOD(call->data))) {
		rc = EPERM;
		goto error;
	}

	call->flags |= IPC_CALL_FORWARDED;
	
	/*
	 * User space is not allowed to change interface and method of system
	 * methods on forward, allow changing ARG1, ARG2, ARG3 and ARG4 by
	 * means of imethod, arg1, arg2 and arg3.
	 * If the interface and method is immutable, don't change anything.
	 */
	if (!method_is_immutable(IPC_GET_IMETHOD(call->data))) {
		if (method_is_system(IPC_GET_IMETHOD(call->data))) {
			if (IPC_GET_IMETHOD(call->data) == IPC_M_CONNECT_TO_ME)
				phone_dealloc(IPC_GET_ARG5(call->data));
			
			IPC_SET_ARG1(call->data, imethod);
			IPC_SET_ARG2(call->data, arg1);
			IPC_SET_ARG3(call->data, arg2);
			
			if (slow)
				IPC_SET_ARG4(call->data, arg3);
			
			/*
			 * For system methods we deliberately don't
			 * overwrite ARG5.
			 */
		} else {
			IPC_SET_IMETHOD(call->data, imethod);
			IPC_SET_ARG1(call->data, arg1);
			IPC_SET_ARG2(call->data, arg2);
			if (slow) {
				IPC_SET_ARG3(call->data, arg3);
				IPC_SET_ARG4(call->data, arg4);
				IPC_SET_ARG5(call->data, arg5);
			}
		}
	}
	
	rc = ipc_forward(call, phone, &TASK->answerbox, mode);
	if (rc != EOK) {
		after_forward = true;
		goto error;
	}

	return EOK;

error:
	IPC_SET_RETVAL(call->data, EFORWARD);
	(void) answer_preprocess(call, need_old ? &old : NULL);
	if (after_forward)
		_ipc_answer_free_call(call, false);
	else
		ipc_answer(&TASK->answerbox, call);

	return rc;
}
Пример #16
0
void network_thread ()
{
    /*
     * We loop forever waiting on either data from the ppp drivers or from
     * our network socket.  Control handling is no longer done here.
     */
    struct sockaddr_in from;
    struct in_pktinfo to;
    unsigned int fromlen;
    int tunnel, call;           /* Tunnel and call */
    int recvsize;               /* Length of data received */
    struct buffer *buf;         /* Payload buffer */
    struct call *c, *sc;        /* Call to send this off to */
    struct tunnel *st;          /* Tunnel */
    fd_set readfds;             /* Descriptors to watch for reading */
    int max;                    /* Highest fd */
    struct timeval tv, *ptv;    /* Timeout for select */
    struct msghdr msgh;
    struct iovec iov;
    char cbuf[256];
    unsigned int refme, refhim;
    int * currentfd;
    int server_socket_processed;

#ifdef HIGH_PRIO
    /* set high priority */
    if (setpriority(PRIO_PROCESS, 0, -20) < 0)
	l2tp_log (LOG_INFO, "xl2tpd: can't set priority to high: %m");
#endif

    /* This one buffer can be recycled for everything except control packets */
    buf = new_buf (MAX_RECV_SIZE);

    tunnel = 0;
    call = 0;

    for (;;)
    {
        int ret;
        process_signal();
        max = build_fdset (&readfds);
        ptv = process_schedule(&tv);
        ret = select (max + 1, &readfds, NULL, NULL, ptv);

        if (ret <= 0)
        {
#ifdef DEBUG_MORE
            if (ret == 0)
            {
                if (gconfig.debug_network)
                {
                    l2tp_log (LOG_DEBUG, "%s: select timeout\n", __FUNCTION__);
                }
            }
            else
            {
                if (gconfig.debug_network)
                {
                    l2tp_log (LOG_DEBUG,
                        "%s: select returned error %d (%s)\n",
                        __FUNCTION__, errno, strerror (errno));
                }
            }
#endif
            continue;
        }

        if (FD_ISSET (control_fd, &readfds))
        {
            do_control ();
        }
        server_socket_processed = 0;
        currentfd = NULL;
        st = tunnels.head;
        while (st || !server_socket_processed) {
            if (st && (st->udp_fd == -1)) {
                st=st->next;
                continue;
            }
            if (st) {
                currentfd = &st->udp_fd;
            } else {
                currentfd = &server_socket;
                server_socket_processed = 1;
            }
            if (FD_ISSET (*currentfd, &readfds))
        {
            /*
             * Okay, now we're ready for reading and processing new data.
             */
            recycle_buf (buf);

            /* Reserve space for expanding payload packet headers */
            buf->start += PAYLOAD_BUF;
            buf->len -= PAYLOAD_BUF;

	    memset(&from, 0, sizeof(from));
	    memset(&to,   0, sizeof(to));
	    
	    fromlen = sizeof(from);
	    
	    memset(&msgh, 0, sizeof(struct msghdr));
	    iov.iov_base = buf->start;
	    iov.iov_len  = buf->len;
	    msgh.msg_control = cbuf;
	    msgh.msg_controllen = sizeof(cbuf);
	    msgh.msg_name = &from;
	    msgh.msg_namelen = fromlen;
	    msgh.msg_iov  = &iov;
	    msgh.msg_iovlen = 1;
	    msgh.msg_flags = 0;
	    
	    /* Receive one packet. */
	    recvsize = recvmsg(*currentfd, &msgh, 0);

            if (recvsize < MIN_PAYLOAD_HDR_LEN)
            {
                if (recvsize < 0)
                {
                    if (errno == ECONNREFUSED) {
                        close(*currentfd);
                    }
                    if ((errno == ECONNREFUSED) ||
                        (errno == EBADF)) {
                        *currentfd = -1;
                    }
                    if (errno != EAGAIN)
                        l2tp_log (LOG_WARNING,
                             "%s: recvfrom returned error %d (%s)\n",
                             __FUNCTION__, errno, strerror (errno));
                }
                else
                {
                    l2tp_log (LOG_WARNING, "%s: received too small a packet\n",
                         __FUNCTION__);
                }
                if (st) st=st->next;
		continue;
            }


	    refme=refhim=0;


		struct cmsghdr *cmsg;
		/* Process auxiliary received data in msgh */
		for (cmsg = CMSG_FIRSTHDR(&msgh);
			cmsg != NULL;
			cmsg = CMSG_NXTHDR(&msgh,cmsg)) {
			/* extract destination(our) addr */
			if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
				struct in_pktinfo* pktInfo = ((struct in_pktinfo*)CMSG_DATA(cmsg));
				to = *pktInfo;
			}
			/* extract IPsec info out */
			else if (gconfig.ipsecsaref && cmsg->cmsg_level == IPPROTO_IP
			&& cmsg->cmsg_type == gconfig.sarefnum) {
				unsigned int *refp;
				
				refp = (unsigned int *)CMSG_DATA(cmsg);
				refme =refp[0];
				refhim=refp[1];
			}
		}

	    /*
	     * some logic could be added here to verify that we only
	     * get L2TP packets inside of IPsec, or to provide different
	     * classes of service to packets not inside of IPsec.
	     */
	    buf->len = recvsize;
	    fix_hdr (buf->start);
	    extract (buf->start, &tunnel, &call);

	    if (gconfig.debug_network)
	    {
		l2tp_log(LOG_DEBUG, "%s: recv packet from %s, size = %d, "
			 "tunnel = %d, call = %d ref=%u refhim=%u\n",
			 __FUNCTION__, inet_ntoa (from.sin_addr),
			 recvsize, tunnel, call, refme, refhim);
	    }

	    if (gconfig.packet_dump)
	    {
		do_packet_dump (buf);
	    }
			if (!(c = get_call (tunnel, call, from.sin_addr,
			       from.sin_port, refme, refhim)))
	    {
				if ((c = get_tunnel (tunnel, from.sin_addr.s_addr, from.sin_port)))
		{
		    /*
		     * It is theoretically possible that we could be sent
		     * a control message (say a StopCCN) on a call that we
		     * have already closed or some such nonsense.  To
		     * prevent this from closing the tunnel, if we get a
		     * call on a valid tunnel, but not with a valid CID,
		     * we'll just send a ZLB to ack receiving the packet.
		     */
		    if (gconfig.debug_tunnel)
			l2tp_log (LOG_DEBUG,
				  "%s: no such call %d on tunnel %d. Sending special ZLB\n",
				  __FUNCTION__, call, tunnel);
		    if (handle_special (buf, c, call) == 0)
			/* get a new buffer */
			buf = new_buf (MAX_RECV_SIZE);
		}
#ifdef DEBUG_MORE
		else{
		    l2tp_log (LOG_DEBUG,
			      "%s: unable to find call or tunnel to handle packet.  call = %d, tunnel = %d Dumping.\n",
			      __FUNCTION__, call, tunnel);
		    }
#endif
	    }
	    else
	    {
		if (c->container) {
			c->container->my_addr = to;
		}

		buf->peer = from;
		/* Handle the packet */
		c->container->chal_us.vector = NULL;
		if (handle_packet (buf, c->container, c))
		{
		    if (gconfig.debug_tunnel)
			l2tp_log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__);
		}
		if (c->cnu)
		{
		    /* Send Zero Byte Packet */
		    control_zlb (buf, c->container, c);
		    c->cnu = 0;
		}
		}
	}
	if (st) st=st->next;
	}

	/*
	 * finished obvious sources, look for data from PPP connections.
	 */
	st = tunnels.head;
        while (st)
        {
            sc = st->call_head;
            while (sc)
            {
                if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds))
                {
                    /* Got some payload to send */
                    int result;

                    while ((result = read_packet (sc)) > 0)
                    {
                        add_payload_hdr (sc->container, sc, sc->ppp_buf);
                        if (gconfig.packet_dump)
                        {
                            do_packet_dump (sc->ppp_buf);
                        }


                        sc->prx = sc->data_rec_seq_num;
                        if (sc->zlb_xmit)
                        {
                            deschedule (sc->zlb_xmit);
                            sc->zlb_xmit = NULL;
                        }
                        sc->tx_bytes += sc->ppp_buf->len;
                        sc->tx_pkts++;
                        udp_xmit (sc->ppp_buf, st);
                        recycle_payload (sc->ppp_buf, sc->container->peer);
                    }
                    if (result != 0)
                    {
                        l2tp_log (LOG_WARNING,
                             "%s: tossing read packet, error = %s (%d).  Closing call.\n",
                             __FUNCTION__, strerror (-result), -result);
                        strcpy (sc->errormsg, strerror (-result));
                        sc->needclose = -1;
                    }
                }
                sc = sc->next;
            }
            st = st->next;
        }
    }

}
Пример #17
0
void network_thread ()
{
    /*
     * We loop forever waiting on either data from the ppp drivers or from
     * our network socket.  Control handling is no longer done here.
     */
    struct sockaddr_in from, to;
    unsigned int fromlen, tolen;
    int tunnel, call;           /* Tunnel and call */
    int recvsize;               /* Length of data received */
    struct buffer *buf;         /* Payload buffer */
    struct call *c, *sc;        /* Call to send this off to */
    struct tunnel *st;          /* Tunnel */
    fd_set readfds;             /* Descriptors to watch for reading */
    int max;                    /* Highest fd */
    struct timeval tv, *ptv;    /* Timeout for select */
    struct msghdr msgh;
    struct iovec iov;
    char cbuf[256];
    unsigned int refme, refhim;

    /* This one buffer can be recycled for everything except control packets */
    buf = new_buf (MAX_RECV_SIZE);

    tunnel = 0;
    call = 0;

    for (;;)
    {
        int ret;
        process_signal();
        max = build_fdset (&readfds);
        ptv = process_schedule(&tv);
        ret = select (max + 1, &readfds, NULL, NULL, ptv);
        if (ret <= 0)
        {
            if (ret == 0)
            {
                if (gconfig.debug_network)
                {
                    l2tp_log (LOG_DEBUG, "%s: select timeout\n", __FUNCTION__);
                }
            }
            else
            {
                if (gconfig.debug_network)
                {
                    l2tp_log (LOG_DEBUG,
                        "%s: select returned error %d (%s)\n",
                        __FUNCTION__, errno, strerror (errno));
                }
            }
            continue;
        }
        if (FD_ISSET (control_fd, &readfds))
        {
            do_control ();
        }
        if (FD_ISSET (server_socket, &readfds))
        {
            /*
             * Okay, now we're ready for reading and processing new data.
             */
            recycle_buf (buf);

            /* Reserve space for expanding payload packet headers */
            buf->start += PAYLOAD_BUF;
            buf->len -= PAYLOAD_BUF;

	    memset(&from, 0, sizeof(from));
	    memset(&to,   0, sizeof(to));
	    
	    fromlen = sizeof(from);
	    tolen   = sizeof(to);
	    
	    memset(&msgh, 0, sizeof(struct msghdr));
	    iov.iov_base = buf->start;
	    iov.iov_len  = buf->len;
	    msgh.msg_control = cbuf;
	    msgh.msg_controllen = sizeof(cbuf);
	    msgh.msg_name = &from;
	    msgh.msg_namelen = fromlen;
	    msgh.msg_iov  = &iov;
	    msgh.msg_iovlen = 1;
	    msgh.msg_flags = 0;
	    
	    /* Receive one packet. */
	    recvsize = recvmsg(server_socket, &msgh, 0);

            if (recvsize < MIN_PAYLOAD_HDR_LEN)
            {
                if (recvsize < 0)
                {
                    if (errno != EAGAIN)
                        l2tp_log (LOG_WARNING,
                             "%s: recvfrom returned error %d (%s)\n",
                             __FUNCTION__, errno, strerror (errno));
                }
                else
                {
                    l2tp_log (LOG_WARNING, "%s: received too small a packet\n",
                         __FUNCTION__);
                }
		continue;
            }


	    refme=refhim=0;

	    /* extract IPsec info out */
	    if(gconfig.ipsecsaref) {
		    struct cmsghdr *cmsg;
		    /* Process auxiliary received data in msgh */
		    for (cmsg = CMSG_FIRSTHDR(&msgh);
			 cmsg != NULL;
			 cmsg = CMSG_NXTHDR(&msgh,cmsg)) {
			    if (cmsg->cmsg_level == IPPROTO_IP
				&& cmsg->cmsg_type == IP_IPSEC_REFINFO) {
				    unsigned int *refp;
				    
				    refp = (unsigned int *)CMSG_DATA(cmsg);
				    refme =refp[0];
				    refhim=refp[1];
			    }
		    }
	    }

	    /*
	     * some logic could be added here to verify that we only
	     * get L2TP packets inside of IPsec, or to provide different
	     * classes of service to packets not inside of IPsec.
	     */
	    buf->len = recvsize;
	    fix_hdr (buf->start);
	    extract (buf->start, &tunnel, &call);

	    if (gconfig.debug_network)
	    {
		l2tp_log(LOG_DEBUG, "%s: recv packet from %s, size = %d, "
			 "tunnel = %d, call = %d ref=%u refhim=%u\n",
			 __FUNCTION__, inet_ntoa (from.sin_addr),
			 recvsize, tunnel, call, refme, refhim);
	    }

	    if (gconfig.packet_dump)
	    {
		do_packet_dump (buf);
	    }
	    if (!
		(c = get_call (tunnel, call, from.sin_addr.s_addr,
			       from.sin_port, refme, refhim)))
	    {
		if ((c =
		     get_tunnel (tunnel, from.sin_addr.s_addr,
				 from.sin_port)))
		{
		    /*
		     * It is theoretically possible that we could be sent
		     * a control message (say a StopCCN) on a call that we
		     * have already closed or some such nonsense.  To
		     * prevent this from closing the tunnel, if we get a
		     * call on a valid tunnel, but not with a valid CID,
		     * we'll just send a ZLB to ack receiving the packet.
		     */
		    if (gconfig.debug_tunnel)
			l2tp_log (LOG_DEBUG,
				  "%s: no such call %d on tunnel %d.  Sending special ZLB\n",
				  __FUNCTION__);
		    handle_special (buf, c, call);

		    /* get a new buffer */
		    buf = new_buf (MAX_RECV_SIZE);
		}
		else
		    l2tp_log (LOG_DEBUG,
			      "%s: unable to find call or tunnel to handle packet.  call = %d, tunnel = %d Dumping.\n",
			      __FUNCTION__, call, tunnel);
		
	    }
	    else
	    {
		buf->peer = from;
		/* Handle the packet */
		c->container->chal_us.vector = NULL;
		if (handle_packet (buf, c->container, c))
		{
		    if (gconfig.debug_tunnel)
			l2tp_log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__);
		};
		if (c->cnu)
		{
		    /* Send Zero Byte Packet */
		    control_zlb (buf, c->container, c);
		    c->cnu = 0;
		}
	    };
	}

	/*
	 * finished obvious sources, look for data from PPP connections.
	 */
	st = tunnels.head;
        while (st)
        {
            sc = st->call_head;
            while (sc)
            {
                if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds))
                {
                    /* Got some payload to send */
                    int result;
                    recycle_payload (buf, sc->container->peer);
/*
#ifdef DEBUG_FLOW_MORE
                    l2tp_log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n",
                         __FUNCTION__, sc->rws, sc->pSs, sc->pLr);
#endif
		    if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) {
#ifdef DEBUG_FLOW
						log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__,
								 sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws); 
#endif
						sc->throttle = -1;
						We unthrottle in handle_packet if we get a payload packet, 
						valid or ZLB, but we also schedule a dethrottle in which
						case the R-bit will be set
						FIXME: Rate Adaptive timeout? 						
						tv.tv_sec = 2;
						tv.tv_usec = 0;
						sc->dethrottle = schedule(tv, dethrottle, sc); 					
					} else */
/*					while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */
                    while ((result =
                            read_packet (buf, sc->fd, SYNC_FRAMING)) > 0)
                    {
                        add_payload_hdr (sc->container, sc, buf);
                        if (gconfig.packet_dump)
                        {
                            do_packet_dump (buf);
                        }


                        sc->prx = sc->data_rec_seq_num;
                        if (sc->zlb_xmit)
                        {
                            deschedule (sc->zlb_xmit);
                            sc->zlb_xmit = NULL;
                        }
                        sc->tx_bytes += buf->len;
                        sc->tx_pkts++;
                        udp_xmit (buf, st);
                        recycle_payload (buf, sc->container->peer);
                    }
                    if (result != 0)
                    {
                        l2tp_log (LOG_WARNING,
                             "%s: tossing read packet, error = %s (%d).  Closing call.\n",
                             __FUNCTION__, strerror (-result), -result);
                        strcpy (sc->errormsg, strerror (-result));
                        sc->needclose = -1;
                    }
                }
                sc = sc->next;
            }
            st = st->next;
        }
    }

}
Пример #18
0
void network_thread ()
{
    /*
     * We loop forever waiting on either data from the ppp drivers or from
     * our network socket.  Control handling is no longer done here.
     */
    int fromlen;                /* Length of the address */
    int tunnel, call;           /* Tunnel and call */
    int recvsize;               /* Length of data received */
    struct buffer *buf;         /* Payload buffer */
    struct call *c, *sc;        /* Call to send this off to */
    struct tunnel *st;          /* Tunnel */
    fd_set readfds;             /* Descriptors to watch for reading */
    int max;                    /* Highest fd */
    struct timeval tv;          /* Timeout for select */
    /* This one buffer can be recycled for everything except control packets */
    buf = new_buf (MAX_RECV_SIZE);
    for (;;)
    {
        /*
           * First, let's send out any outgoing packets that are waiting on us.
           * xmit_udp should only
           * contain control packets in the unthreaded version!
         */
        max = 0;
        FD_ZERO (&readfds);
        st = tunnels.head;
        while (st)
        {
            if (st->self->needclose ^ st->self->closing)
            {
                if (debug_tunnel)
                    log (LOG_DEBUG, "%S: closing down tunnel %d\n",
                         __FUNCTION__, st->ourtid);
                call_close (st->self);
                /* Reset the while loop
                   and check for NULL */
                st = tunnels.head;
                if (!st)
                    break;
                continue;
            }
            sc = st->call_head;
            while (sc)
            {
                if (sc->needclose ^ sc->closing)
                {
                    call_close (sc);
                    sc = st->call_head;
                    if (!sc)
                        break;
                    continue;
                }
                if (sc->fd > -1)
                {
/*					if (!sc->throttle && !sc->needclose && !sc->closing) { */
                    if (!sc->needclose && !sc->closing)
                    {
                        if (sc->fd > max)
                            max = sc->fd;
                        FD_SET (sc->fd, &readfds);
                    }
                }
                sc = sc->next;
            }
            st = st->next;
        }
        FD_SET (server_socket, &readfds);
        if (server_socket > max)
            max = server_socket;
        FD_SET (control_fd, &readfds);
        if (control_fd > max)
            max = control_fd;
        tv.tv_sec = 1;
        tv.tv_usec = 0;

        /*add start, by MJ.*/
        extern int is_first_run;
        if(is_first_run)
        {
            int lac_fp;  /* to get conn_id which written by acos */
            char cmd[64]={0};
            char conn_id[64] = "c default";            

            lac_fp = fopen("/tmp/l2tp/l2tpd.info", "r");

            if (lac_fp != NULL){
                //fscanf(lac_fp, "%s", conn_id);
                fgets(conn_id, sizeof(conn_id), lac_fp);
                fclose(lac_fp);
            }
            else
                log (LOG_DEBUG, "open /tmp/l2tp/l2tpd.info fialed\n");

            log (LOG_DEBUG, "%s: -> the first run.\n", __FUNCTION__);
            
            sprintf(cmd, "c %s", conn_id);

            //do_control("c MJ.");
            do_control(cmd);
            //write(control_fd, cmd, strlen(cmd) );
            is_first_run = 0;
        }
        /*add end. by MJ.*/        

        schedule_unlock ();
        select (max + 1, &readfds, NULL, NULL, NULL);
        schedule_lock ();

        if (FD_ISSET (control_fd, &readfds))
        {
            do_control (NULL);
        }
        if (FD_ISSET (server_socket, &readfds))
        {
            /*  wklin added start, 04/12/2011 */
            extern void connect_pppunit(void);
            connect_pppunit();
            /*  wklin added end, 04/12/2011 */
            /*
             * Okay, now we're ready for reading and processing new data.
             */
            recycle_buf (buf);
            /* Reserve space for expanding payload packet headers */
            buf->start += PAYLOAD_BUF;
            buf->len -= PAYLOAD_BUF;
            fromlen = sizeof (from);
            recvsize =
                recvfrom (server_socket, buf->start, buf->len, 0,
                          (struct sockaddr *) &from, &fromlen);

            /* , by MJ. for debugging.*/
            //log (LOG_DEBUG, "receive %d bytes from server_scoket.\n", recvsize);


            if (recvsize < MIN_PAYLOAD_HDR_LEN)
            {
                if (recvsize < 0)
                {
                    if (errno != EAGAIN)
                        log (LOG_WARN,
                             "%s: recvfrom returned error %d (%s)\n",
                             __FUNCTION__, errno, strerror (errno));
                }
                else
                {
                    log (LOG_WARN, "%s: received too small a packet\n",
                         __FUNCTION__);
                }
            }
            else
            {
                buf->len = recvsize;
                fix_hdr (buf->start);
                extract (buf->start, &tunnel, &call);
                if (debug_network)
                {
                    log (LOG_DEBUG, "%s: recv packet from %s, size = %d,"
"tunnel = %d, call = %d\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call);
                }
                if (packet_dump)
                {
                    do_packet_dump (buf);
                }
                if (!
                    (c =
                     get_call (tunnel, call, from.sin_addr.s_addr,
                               from.sin_port)))
                {
                    if ((c =
                         get_tunnel (tunnel, from.sin_addr.s_addr,
                                     from.sin_port)))
                    {
                        /*
                         * It is theoretically possible that we could be sent
                         * a control message (say a StopCCN) on a call that we
                         * have already closed or some such nonsense.  To prevent
                         * this from closing the tunnel, if we get a call on a valid
                         * tunnel, but not with a valid CID, we'll just send a ZLB
                         * to ack receiving the packet.
                         */
                        if (debug_tunnel)
                            log (LOG_DEBUG,
                                 "%s: no such call %d on tunnel %d.  Sending special ZLB\n",
                                 __FUNCTION__);
                        handle_special (buf, c, call);
                    }
                    else
                        log (LOG_DEBUG,
                             "%s: unable to find call or tunnel to handle packet.  call = %d, tunnel = %d Dumping.\n",
                             __FUNCTION__, call, tunnel);

                }
                else
                {
                    buf->peer = from;
                    /* Handle the packet */
                    c->container->chal_us.vector = NULL;
                    if (handle_packet (buf, c->container, c))
                    {
                        if (debug_tunnel)
                            log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__);
                    };
                    if (c->cnu)
                    {
                        /* Send Zero Byte Packet */
                        control_zlb (buf, c->container, c);
                        c->cnu = 0;

                        
    
                    }
                }
            }
        };

        st = tunnels.head;
        while (st)
        {
            sc = st->call_head;
            while (sc)
            {
                if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds))
                {
                    /* Got some payload to send */
                    int result;
                    recycle_payload (buf, sc->container->peer);
#ifdef DEBUG_FLOW_MORE
                    log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n",
                         __FUNCTION__, sc->rws, sc->pSs, sc->pLr);
#endif
/*					if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) {
#ifdef DEBUG_FLOW
						log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__,
								 sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws); 
#endif
						sc->throttle = -1;
						We unthrottle in handle_packet if we get a payload packet, 
						valid or ZLB, but we also schedule a dethrottle in which
						case the R-bit will be set
						FIXME: Rate Adaptive timeout? 						
						tv.tv_sec = 2;
						tv.tv_usec = 0;
						sc->dethrottle = schedule(tv, dethrottle, sc); 					
					} else */
/*					while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */
                    while ((result =
                            read_packet (buf, sc->fd, SYNC_FRAMING)) > 0)
                    {
                        add_payload_hdr (sc->container, sc, buf);
                        if (packet_dump)
                        {
                            do_packet_dump (buf);
                        }


                        sc->prx = sc->data_rec_seq_num;
                        if (sc->zlb_xmit)
                        {
                            deschedule (sc->zlb_xmit);
                            sc->zlb_xmit = NULL;
                        }
                        sc->tx_bytes += buf->len;
                        sc->tx_pkts++;
                        udp_xmit (buf);
                        recycle_payload (buf, sc->container->peer);
                    }
                    if (result != 0)
                    {
                        log (LOG_WARN,
                             "%s: tossing read packet, error = %s (%d).  Closing call.\n",
                             __FUNCTION__, strerror (-result), -result);
                        strcpy (sc->errormsg, strerror (-result));
                        sc->needclose = -1;
                    }
                }
                sc = sc->next;
            }
            st = st->next;
        }
    }

}
Пример #19
0
void network_thread ()
{
    /*
     * We loop forever waiting on either data from the ppp drivers or from
     * our network socket.  Control handling is no longer done here.
     */
    int fromlen;                /* Length of the address */
    int tunnel, call;           /* Tunnel and call */
    int recvsize;               /* Length of data received */
    struct buffer *buf;         /* Payload buffer */
    struct call *c, *sc;        /* Call to send this off to */
    struct tunnel *st;          /* Tunnel */
    fd_set readfds;             /* Descriptors to watch for reading */
    int max;                    /* Highest fd */
    struct timeval tv;          /* Timeout for select */
    /* This one buffer can be recycled for everything except control packets */
    buf = new_buf (MAX_RECV_SIZE);

gconfig.debug_tunnel = 1;
    for (;;)
    {
        max = build_fdset (&readfds);
        tv.tv_sec = 1;
        tv.tv_usec = 0;
        schedule_unlock ();
        select (max + 1, &readfds, NULL, NULL, NULL);
        schedule_lock ();
        if (FD_ISSET (control_fd, &readfds))
        {
            do_control ();
        }
        if (FD_ISSET (server_socket, &readfds))
        {
            /*
             * Okay, now we're ready for reading and processing new data.
             */
            recycle_buf (buf);
            /* Reserve space for expanding payload packet headers */
            buf->start += PAYLOAD_BUF;
            buf->len -= PAYLOAD_BUF;
            fromlen = sizeof (from);
            recvsize =
                recvfrom (server_socket, buf->start, buf->len, 0,
                          (struct sockaddr *) &from, &fromlen);
            if (recvsize < MIN_PAYLOAD_HDR_LEN)
            {
                if (recvsize < 0)
                {
                    if (errno != EAGAIN)
                        log (LOG_WARN,
                             "%s: recvfrom returned error %d (%s)\n",
                             __FUNCTION__, errno, strerror (errno));
                }
                else
                {
                    log (LOG_WARN, "%s: received too small a packet\n",
                         __FUNCTION__);
                }
            }
            else
            {
                buf->len = recvsize;
                if (gconfig.debug_network)
                {
                    log (LOG_DEBUG, "%s: recv packet from %s, size = %d, "
							"tunnel = %d, call = %d\n", __FUNCTION__,
							inet_ntoa (from.sin_addr), recvsize, tunnel, call);
                }
                if (gconfig.packet_dump)
                {
                    do_packet_dump (buf);
                }
                fix_hdr (buf->start);
                extract (buf->start, &tunnel, &call);
                if (!
                    (c =
                     get_call (tunnel, call, from.sin_addr.s_addr,
                               from.sin_port)))
                {
        log(LOG_DEBUG, "%s(%d)\n", __FUNCTION__,__LINE__);
                    if ((c =
                         get_tunnel (tunnel, from.sin_addr.s_addr,
                                     from.sin_port)))
                    {
                        /*
                         * It is theoretically possible that we could be sent
                         * a control message (say a StopCCN) on a call that we
                         * have already closed or some such nonsense.  To prevent
                         * this from closing the tunnel, if we get a call on a valid
                         * tunnel, but not with a valid CID, we'll just send a ZLB
                         * to ack receiving the packet.
                         */
                        if (gconfig.debug_tunnel)
                            log (LOG_DEBUG,
                                 "%s: no such call %d on tunnel %d.  Sending special ZLB\n",
                                 __FUNCTION__);
                        handle_special (buf, c, call);
                    }
                    else
                        log (LOG_DEBUG,
                             "%s: unable to find call or tunnel to handle packet.  call = %d, tunnel = %d Dumping.\n",
                             __FUNCTION__, call, tunnel);

                }
                else
                {

                    buf->peer = from;
                    /* Handle the packet */
                    c->container->chal_us.vector = NULL;

                    if (handle_packet (buf, c->container, c))
                    {
                        if (gconfig.debug_tunnel)
                            log (LOG_DEBUG, "%s(%d): bad packet\n", __FUNCTION__,__LINE__);
                    };
                    if (c->cnu)
                    {
                        /* Send Zero Byte Packet */
                        control_zlb (buf, c->container, c);
                        c->cnu = 0;
                    }
                }
            }
        };

        st = tunnels.head;

        while (st)
        {
            sc = st->call_head;
            while (sc)
            {
                if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds))
                {
                    /* Got some payload to send */
                    int result;
                    recycle_payload (buf, sc->container->peer);
#ifdef DEBUG_FLOW_MORE
                    log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n",
                         __FUNCTION__, sc->rws, sc->pSs, sc->pLr);
#endif
/*					if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) {
#ifdef DEBUG_FLOW
						log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__,
								 sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws);
#endif
						sc->throttle = -1;
						We unthrottle in handle_packet if we get a payload packet,
						valid or ZLB, but we also schedule a dethrottle in which
						case the R-bit will be set
						FIXME: Rate Adaptive timeout?
						tv.tv_sec = 2;
						tv.tv_usec = 0;
						sc->dethrottle = schedule(tv, dethrottle, sc);
					} else */
/*					while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */
                    while ((result =
                            read_packet (buf, sc->fd, SYNC_FRAMING)) > 0)
                    {
                        add_payload_hdr (sc->container, sc, buf);
                        if (gconfig.packet_dump)
                        {
                            do_packet_dump (buf);
                        }


                        sc->prx = sc->data_rec_seq_num;
                        if (sc->zlb_xmit)
                        {
                            deschedule (sc->zlb_xmit);
                            sc->zlb_xmit = NULL;
                        }
                        sc->tx_bytes += buf->len;
                        sc->tx_pkts++;
                        udp_xmit (buf);
                        recycle_payload (buf, sc->container->peer);
                    }
                    if (result != 0)
                    {
                        log (LOG_WARN,
                             "%s: tossing read packet, error = %s (%d).  Closing call.\n",
                             __FUNCTION__, strerror (-result), -result);
                        strcpy (sc->errormsg, strerror (-result));
                        sc->needclose = -1;
                    }
                }
                sc = sc->next;
            }
            st = st->next;
        }
    }

}