Exemple #1
0
/* Input vector for ACCESS ports */
static void ethsw_iv_access(ethsw_table_t *t,ethsw_packet_t *sp,
                            netio_desc_t *op)
{
   m_uint8_t pkt[ETHSW_MAX_PKT_SIZE+4];

   switch(op->vlan_port_type) {
      /* Access -> Access: no special treatment */
      case ETHSW_PORT_TYPE_ACCESS:
         netio_send(op,sp->pkt,sp->pkt_len);
         break;

      /* Access -> 802.1Q: push tag */
      case ETHSW_PORT_TYPE_DOT1Q:
         /*
          * If the native VLAN of output port is the same as input,
          * forward the packet without adding the tag.
          */
         if (op->vlan_id == sp->input_vlan) {
            netio_send(op,sp->pkt,sp->pkt_len);
         } else {
            dot1q_push_tag(pkt,sp,op->vlan_id,sp->input_port->ethertype);
            netio_send(op,pkt,sp->pkt_len+4);
         }
         break;

      default:
         fprintf(stderr,"ethsw_iv_access: unknown port type %u\n",
                 op->vlan_port_type);
   }
}
Exemple #2
0
/* Input vector for QinQ ports */
static void ethsw_iv_qinq(ethsw_table_t *t,ethsw_packet_t *sp,
                         netio_desc_t *op)
{
   m_uint8_t pkt[ETHSW_MAX_PKT_SIZE+4];

   switch(op->vlan_port_type) {
      /* QinQ -> 802.1Q: push outer tag */
      case ETHSW_PORT_TYPE_DOT1Q:
         dot1q_push_tag(pkt,sp,sp->input_port->vlan_id,sp->input_port->ethertype);
         netio_send(op,pkt,sp->pkt_len+4);
         break;

      /*
       * QinQ -> QinQ: valid situation if we have the same customer connected
       * on two ports (so with identical VLAN id on tunnel ports).
       */
      case ETHSW_PORT_TYPE_QINQ:
         if (sp->input_port->vlan_id == op->vlan_id) {
            dot1q_pop_tag(pkt,sp);
            netio_send(op,pkt,sp->pkt_len-4);
         }
         break;

      default:
         fprintf(stderr,"ethsw_iv_dot1q: unknown port type %u\n",
                 op->vlan_port_type);
   }
}
Exemple #3
0
/* 
   this is called when new data has arrived or the socket has been closed 
   datalen < 1:
     socket closed!
*/
static void 
__netio_http_cb_data(int s, void *obj, char *data, int datalen)
{
	netio_http_conn_t *conn = (netio_http_conn_t*)obj;
	int ret = -1;

	if (!netio_http_conn_lock(conn))
		return;

	if (conn->forward_socket == -1)
		ret = __netio_http_parse_data(conn, data, datalen);
	else if (datalen > 0) {
		netio_send(conn->forward_socket, data, datalen);
		ret = 1;
	}
		
	if (ret > 0) {
		ship_unlock(conn);
		return;
	}

	if (!ret) {
		LOG_DEBUG("Got total %d bytes, %d data, code %d for request to %s\n",
			  conn->data_len, conn->content_len, conn->resp_code, conn->fullurl);
		
		/* done doing a GET / POST */
		if (conn->func) {
			
			netio_http_decode_encoding(conn);
			conn->func(conn->fullurl, conn->resp_code, &(conn->buf[conn->header_len]), conn->content_len, conn->pkg);
			conn->func = 0;
		}
	}
	netio_http_conn_close(conn);
}
Exemple #4
0
/* callback on tcp connections */
static void 
__netio_http_cb_conn(int s, void *obj)
{
	netio_http_conn_t *h = (netio_http_conn_t*)obj;
	char *buf;

	if (!netio_http_conn_lock(h))
		return;
	
	/* write the data! */
	if ((buf = mallocz(strlen(post_header) + strlen(h->url) + 
			   zstrlen(h->content_type) + strlen(h->host) + 64 + h->data_len))) {
		int len = 0;
		if (h->buf) {
			sprintf(buf, post_header, h->url, h->host, h->data_len, h->content_type);
			len = strlen(buf);
			memcpy(buf + len, h->buf, h->data_len);
		} else {
			sprintf(buf, get_header, h->url, h->host);
			len = strlen(buf);
		}
		netio_send(s, buf, len + h->data_len);
		freez(buf);
		h->data_len = 0;
		ship_unlock(h);
	} else {
		netio_http_conn_close(h);
	}
}
Exemple #5
0
/* Input vector for 802.1Q ports */
static void ethsw_iv_dot1q(ethsw_table_t *t,ethsw_packet_t *sp,
                           netio_desc_t *op)
{
   m_uint8_t pkt[ETHSW_MAX_PKT_SIZE+4];

   /* If we don't have an input tag, we work temporarily as an access port */
   if (!sp->input_tag) {
      ethsw_iv_access(t,sp,op);
      return;
   }

   switch(op->vlan_port_type) {
      /* 802.1Q -> Access: pop tag */
      case ETHSW_PORT_TYPE_ACCESS:
         dot1q_pop_tag(pkt,sp);
         netio_send(op,pkt,sp->pkt_len-4);
         break;

      /* 802.1Q -> 802.1Q: pop tag if native VLAN in output otherwise no-op */
      case ETHSW_PORT_TYPE_DOT1Q:
         if (op->vlan_id == sp->input_vlan) {
            dot1q_pop_tag(pkt,sp);
            netio_send(op,pkt,sp->pkt_len-4);
         } else {
            netio_send(op,sp->pkt,sp->pkt_len);
         }
         break;

      /*
       * 802.1Q -> QinQ: pop outer tag if native VLAN in the one specified
       * tunnel port.
       */
      case ETHSW_PORT_TYPE_QINQ:
         if (op->vlan_id == sp->input_vlan) {
            dot1q_pop_tag(pkt,sp);
            netio_send(op,pkt,sp->pkt_len-4);
         }
         break;

      default:
         fprintf(stderr,"ethsw_iv_dot1q: unknown port type %u\n",
                 op->vlan_port_type);
   }
}
Exemple #6
0
void
netio_http_respond_multipart(netio_http_conn_t *conn, 
			     char *content_type, 
			     char *data, int data_len)
{
	const char *templ = "%s\r\nContent-Type: %s\r\nContent-Transfer-Encoding: binary\r\n\r\n";
	char *msg = mallocz(strlen(templ) + strlen(content_type) + 128);
	char *boundary = 0;

	/* if no header set yet, create one */
	if (!(boundary = netio_http_get_attr(conn, "boundary"))) {
		netio_http_respond_multipart_header(conn, 200, "OK");
		boundary = netio_http_get_attr(conn, "boundary");
	}
	    
	sprintf(msg, templ, boundary, content_type);
	netio_send(conn->socket, msg, strlen(msg));
	netio_send(conn->socket, data, data_len);
	freez(msg);
}
Exemple #7
0
void
netio_http_redirect(netio_http_conn_t *conn, 
		    char *url)
{
	const char *templ = "HTTP/1.1 302 Found\r\nServer: P2PSHIP proxy\r\nLocation: %s\r\nContent-Length: 0\r\nConnection: close\r\n\r\n";
	char *msg = mallocz(strlen(templ) + strlen(url) + 128);
	if (!msg)
		return;
	sprintf(msg, templ, url);
	netio_send(conn->socket, msg, strlen(msg));
	freez(msg);
}
Exemple #8
0
int flvsrv_cbWriteDataNet(void *pArg, const unsigned char *pData, unsigned int len) {
  int rc = 0;
  FLVSRV_CTXT_T *pFlvCtxt = (FLVSRV_CTXT_T *) pArg;

  if((rc = netio_send(&pFlvCtxt->pSd->netsocket, &pFlvCtxt->pSd->sain, pData, len)) < 0) {
    LOG(X_ERROR("Failed to send flv %s %u bytes, total: %llu)"),
               (pFlvCtxt->writeErrDescr ? pFlvCtxt->writeErrDescr : ""), len, pFlvCtxt->totXmit);
  } else {
    pFlvCtxt->totXmit += len;
//write(pFlvCtxt->g_fd, pData, len);
  }

  return rc;
}
Exemple #9
0
void
netio_http_respond(netio_http_conn_t *conn, 
		   int code, char *code_str, 
		   char *content_type,
		   char *data, int data_len)
{
	char *msg = 0;
	int len = 0;
	if (!netio_http_create_response(code, code_str, content_type, data, data_len,
				       &msg, &len)) {
		netio_send(conn->socket, msg, len);
		freez(msg);
	}
}
Exemple #10
0
void
netio_http_respond_auth(netio_http_conn_t *conn, 
			char *realm,
			char *content_type,
			char *data)
{
	const char *templ = "HTTP/1.1 407 Proxy Authorization Required\r\nServer: P2PSHIP proxy\r\nProxy-Authenticate: Basic realm=\"%s\"\r\nContent-Length: %d\r\nConnection: close\r\nContent-Type: %s\r\n\r\n";
	char *msg = mallocz(strlen(templ) + strlen(realm) + strlen(data) + strlen(content_type) + 128);
	if (!msg)
		return;
	sprintf(msg, templ, realm, strlen(data), content_type);
	strcat(msg, data);
	netio_send(conn->socket, msg, strlen(msg));
	freez(msg);
}
Exemple #11
0
/* Receive an ATM cell */
static int atm_bridge_recv_cell(netio_desc_t *nio,
                                u_char *atm_cell,ssize_t cell_len,
                                atm_bridge_t *t)
{   
   m_uint32_t atm_hdr,vpi,vci;
   int status,res = 0;

   if (cell_len != ATM_CELL_SIZE)
      return(-1);

   ATM_BRIDGE_LOCK(t);

   /* check the VPI/VCI */
   atm_hdr = m_ntoh32(atm_cell);

   vpi = (atm_hdr & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;
   vci = (atm_hdr & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;
   
   if ((t->vpi != vpi) || (t->vci != vci))
      goto done;

   if ((status = atm_aal5_recv(&t->arc,atm_cell)) == 1) {
      /* Got AAL5 packet, check RFC1483b encapsulation */
      if ((t->arc.len > ATM_RFC1483B_HLEN) && 
          !memcmp(t->arc.buffer,atm_rfc1483b_header,ATM_RFC1483B_HLEN)) 
      {
         netio_send(t->eth_nio,
                    t->arc.buffer+ATM_RFC1483B_HLEN,
                    t->arc.len-ATM_RFC1483B_HLEN);
      }  
       
      atm_aal5_recv_reset(&t->arc);
   } else {
      if (status < 0) {
         atm_aal5_recv_reset(&t->arc);
         res = -1;
      }
   }

 done:
   ATM_BRIDGE_UNLOCK(t);
   return(res);
}
/* Send contents of a SDMA buffer */
static void mv64460_sdma_send_buffer(struct mv64460_data *d,u_int chan_id,
                                     u_char *buffer,m_uint32_t len)
{
   struct mpsc_channel *channel;
   u_int mode;

   channel = &d->mpsc[chan_id];
   mode = mv64460_mpsc_get_channel_mode(d,chan_id);
   
   switch(mode) {
      case MV64460_MPSC_MODE_HDLC:
         if (channel->nio != NULL)
            netio_send(channel->nio,buffer,len);
         break;

      case MV64460_MPSC_MODE_UART:
         if (channel->vtty != NULL)
            vtty_put_buffer(channel->vtty,(char *)buffer,len);            
         break;
   }
}
Exemple #13
0
void
netio_http_respond_multipart_header(netio_http_conn_t *conn, 
				    int code, char *code_str)
{
	const char *templ = "HTTP/1.1 %d %s\r\nServer: P2PSHIP proxy\r\nConnection: close\r\nContent-Type: multipart/mixed;\r\n  boundary=\"%s\"\r\n\r\n";
	char *msg = mallocz(strlen(templ) + strlen(code_str) + 128);
	int i = 0;
	char boundary[32];
	if (!msg)
		return;

	for (i = 0; i < sizeof(boundary)-1; i++) {
		if (i < 5)
			boundary[i] = '-';
		else
			boundary[i] = 'a' + (rand() % 20);
	}
	boundary[sizeof(boundary)-1] = 0;

	netio_http_set_attr(conn, "boundary", boundary);
	sprintf(msg, templ, code, code_str, boundary);
	netio_send(conn->socket, msg, strlen(msg));
	freez(msg);
}
Exemple #14
0
/* callback when data is got */
static void 
__netio_http_conn_read_cb(int s, char *data, ssize_t datalen) 
{
	netio_http_conn_t *conn = 0;
	int ret = -1;
	char *newbuf = NULL;

	ASSERT_TRUE(conn = netio_http_get_conn_by_socket(s, 1), err);
	if (datalen < 1) {
		goto err;
	}


	// todo: some sort of half- ready handling #connect
	// forward-tunnel also!!
	if (conn->forward_socket != -1) {
		if (datalen > 0) {
			netio_send(conn->forward_socket, data, datalen);
			ret = 1;
		}
	} else if (conn->service_forward_service) {
		int l2;

		/* add tracking id to buffer */
		l2 = datalen + strlen(conn->tracking_id) + 1;
		ASSERT_TRUE(newbuf = mallocz(l2+1), err);
		strcpy(newbuf, conn->tracking_id);
		strcat(newbuf, "\n");
			
		memcpy(newbuf+strlen(newbuf), data, datalen);
		ASSERT_ZERO(conn_send_slow(conn->service_forward_to, conn->service_forward_from, 
					   conn->service_forward_service,
					   newbuf, l2, NULL, NULL), 
			    err);
		ret = 1;
	} else if (datalen > 0) {
		ret = __netio_http_parse_data(conn, data, datalen);
	}

	/* process.. */
	while (!ret) {
		netio_http_conn_t *new_conn = 0;

		ret = __netio_http_process_req(conn); // should ret be checked??
		if (!strcmp(conn->method, "CONNECT"))
			break;

		if (!strcmp(conn->http_version, "HTTP/1.0")) {
			ret = -1;
			goto err;
		}

		/* we create a new conn for this socket as there might
		   be another request coming. This instead of clearing
		   the one as .. the http proxy will close the http_conn if
		   after responding to just one request.
		*/
		netio_http_cut_overrun(conn, &data, &datalen);
		ship_unlock(conn);
		
		ASSERT_TRUE(new_conn = netio_http_conn_new(s), err);
		memcpy(&(new_conn->addr), &(conn->addr), sizeof(addr_t));
		new_conn->ss = conn->ss;
		conn->owns_socket = 0;

		/* ..parse the data at this point, it IS pointing at
		   the buffer in the old conn! */
		if (datalen > 0)
			ret = __netio_http_parse_data(new_conn, data, datalen);
		else
			ret = 1;
		ship_unlock(new_conn);

		netio_http_conn_lock(conn);
		if (ret < 1) {
			netio_http_conn_close(conn);
		} else {
			ship_unlock(conn);
		}
		netio_http_conn_lock(new_conn);
		conn = new_conn;
	}
 err:
	if (ret < 1) {
		netio_http_conn_close(conn);
	} else if (conn) {
		ship_unlock(conn);
	}
}
Exemple #15
0
/* Handle the TX ring */
static int dev_pos_oc3_handle_txring(struct pos_oc3_data *d)
{
   u_char pkt[POS_OC3_MAX_PKT_SIZE],*pkt_ptr;
   m_uint32_t clen,tot_len,norm_len;
   m_uint32_t tx_start,addr;
   struct tx_desc txd0,ctxd,*ptxd;
   int i,done = FALSE;

   if ((d->tx_start == 0) || (d->nio == NULL))
      return(FALSE);

   /* Copy the current txring descriptor */
   tx_start = d->tx_current;   
   ptxd = &txd0;
   txdesc_read(d,d->tx_current,ptxd);

   /* If we don't own the descriptor, we cannot transmit */
   if (!(txd0.tdes[0] & POS_OC3_TXDESC_OWN))
      return(FALSE);

#if DEBUG_TRANSMIT
   POS_LOG(d,"pos_oc3_handle_txring: 1st desc: tdes[0]=0x%x, tdes[1]=0x%x\n",
           ptxd->tdes[0],ptxd->tdes[1]);
#endif

   pkt_ptr = pkt;
   tot_len = 0;
   i = 0;

   do {
#if DEBUG_TRANSMIT
      POS_LOG(d,"pos_oc3_handle_txring: loop: tdes[0]=0x%x, tdes[1]=0x%x\n",
              ptxd->tdes[0],ptxd->tdes[1]);
#endif

      if (!(ptxd->tdes[0] & POS_OC3_TXDESC_OWN)) {
         POS_LOG(d,"pos_oc3_handle_txring: descriptor not owned!\n");
         return(FALSE);
      }

      clen = ptxd->tdes[0] & POS_OC3_TXDESC_LEN_MASK;

      /* Be sure that we have length not null */
      if (clen != 0) {
         addr = ptxd->tdes[1];

         norm_len = normalize_size(clen,4,0);
         physmem_copy_from_vm(d->vm,pkt_ptr,addr,norm_len);
         mem_bswap32(pkt_ptr,norm_len);
      }

      pkt_ptr += clen;
      tot_len += clen;

      /* Clear the OWN bit if this is not the first descriptor */
      if (i != 0)
         physmem_copy_u32_to_vm(d->vm,d->tx_current,0);

      /* Go to the next descriptor */
      txdesc_set_next(d,ptxd);

      /* Copy the next txring descriptor */
      if (ptxd->tdes[0] & POS_OC3_TXDESC_CONT) {
         txdesc_read(d,d->tx_current,&ctxd);
         ptxd = &ctxd;
         i++;
      } else
         done = TRUE;
   }while(!done);

   if (tot_len != 0) {
#if DEBUG_TRANSMIT
      POS_LOG(d,"sending packet of %u bytes (flags=0x%4.4x)\n",
              tot_len,txd0.tdes[0]);
      mem_dump(log_file,pkt,tot_len);
#endif   
      /* send it on wire */
      netio_send(d->nio,pkt,tot_len);
   }

   /* Clear the OWN flag of the first descriptor */
   txd0.tdes[0] &= ~POS_OC3_TXDESC_OWN;
   physmem_copy_u32_to_vm(d->vm,tx_start,txd0.tdes[0]);

   /* Interrupt on completion */
   pci_dev_trigger_irq(d->vm,d->pci_dev);
   return(TRUE);
}