Пример #1
0
//---------------------------------------------------------------------------
void print_TOOL_pk_ipv6(struct ipv6hdr *iph)
{
  //---------------------------------------------------------------------------
  // Start debug information
#ifdef OAI_NW_DRV_DEBUG_TOOL
  printk("PRINT_TOOL_PK_IPv6 - begin \n");
#endif

  if (iph==NULL) {
#ifdef OAI_NW_DRV_DEBUG_TOOL
    printk("OAI_NW_DRV_TOOL_PK_IPv6 - input parameter iph is NULL \n");
#endif
    return;
  }

  // End debug information

  if (iph!=NULL) {
    //      char addr[OAI_NW_DRV_INET6_ADDRSTRLEN];
    printk("IP:\t version = %u, priority = %u, payload_len = %u\n", iph->version, iph->priority, ntohs(iph->payload_len));
    printk("\t fl0 = %u, fl1 = %u, fl2 = %u\n",iph->flow_lbl[0],iph->flow_lbl[1],iph->flow_lbl[2]);
    printk("\t next header = %u, hop_limit = %u\n", iph->nexthdr, iph->hop_limit);

    //      inet_ntop(AF_INET6, (void *)(&iph->saddr), addr, OAI_NW_DRV_INET6_ADDRSTRLEN);
    //      printk("\t saddr = %s",addr);
    //      inet_ntop(AF_INET6, (void *)(&iph->daddr), addr, OAI_NW_DRV_INET6_ADDRSTRLEN);
    //      printk(", daddr = %s\n",addr);
    switch(iph->nexthdr) {
    case IPPROTO_UDP:
      print_TOOL_pk_udp((struct udphdr *)((char *)iph+sizeof(struct ipv6hdr)));
      break;

    case IPPROTO_TCP:
      print_TOOL_pk_tcp((struct tcphdr *)((char *)iph+sizeof(struct ipv6hdr)));
      break;

    case IPPROTO_ICMPV6:
      print_TOOL_pk_icmp6((struct icmp6hdr *)((char *)iph+sizeof(struct ipv6hdr)));
      break;

    case IPPROTO_IPV6:
      print_TOOL_pk_ipv6((struct ipv6hdr *)((char *)iph+sizeof(struct ipv6hdr)));
      break;

    default:
      printk("Unknown upper layer\n");
    }
  }
}
Пример #2
0
//---------------------------------------------------------------------------
// Search the entity with the IPv6 address 'addr'
struct cx_entity *nas_CLASS_cx6(struct sk_buff *skb,
				unsigned char dscp,
				struct nas_priv *gpriv,
				int inst,
				unsigned char *cx_searcher){
  //---------------------------------------------------------------------------
  unsigned char cxi;
  unsigned int *addr,*dst;
  struct cx_entity *default_ip=NULL;
  struct classifier_entity *p=NULL;
#ifdef KERNEL_VERSION_GREATER_THAN_2630
  if (skb->_skb_dst!=0) { 
#else
  if (skb->dst!=NULL) {
#endif

    for (cxi=*cx_searcher; cxi<NAS_CX_MAX; cxi++) {
	
      (*cx_searcher)++;

      p = gpriv->cx[cxi].sclassifier[dscp];

      while (p!=NULL) {
	if (p->version == 6) {   // verify that this is an IPv4 rule

	   
	  if ((addr = (unsigned int *)(&(p->daddr.ipv6)))== NULL) {
	    printk("nas_CLASS_cx6: addr is null \n");
	    p = p->next;
	    continue;
	  }
	  
#ifdef NAS_DEBUG_CLASS
	  printk("cx %d : %X,%X.%X,%X\n",cxi,addr[0],addr[1],addr[2],addr[3]);
#endif //NAS_DEBUG_CLASS
#ifdef KERNEL_VERSION_GREATER_THAN_2630	  
	  if ((dst = (unsigned int*)&(((struct rt6_info *)(skb->_skb_dst))->rt6i_gateway)) == 0){
#else
	  if ((dst = (unsigned int*)&(((struct rt6_info *)(skb->dst))->rt6i_gateway)) == NULL){
	      
#endif 
	    printk("nas_CLASS_cx6: dst addr is null \n");
	    p = p->next;
	    continue;
	  }

	  if ((addr[0] == dst[0]) &&
	      (addr[1] == dst[1]) &&
	      (addr[2] == dst[2]) &&
	      (addr[3] == dst[3])) {
//#ifdef NAS_DEBUG_CLASS
	    printk("nas_CLASS_cx6: found cx %d: %X.%X.%X.%X\n",cxi,
		   dst[0],
		   dst[1],
		   dst[2],
		   dst[3]);
//#endif //NAS_DEBUG_CLASS
	    return gpriv->cx+cxi;
	  }
	  /*   
	       else if ((addr[0]==NAS_DEFAULT_IPV6_ADDR0) &&
	       (addr[1]==NAS_DEFAULT_IPV6_ADDR1) &&
	       (addr[2]==NAS_DEFAULT_IPV6_ADDR2) &&
	       (addr[3]==NAS_DEFAULT_IPV6_ADDR3))
	       default_ip = gpriv->cx+cxi;
	  */
	}
	// Go to next classifier entry for connection
	p = p->next;
      }
    }
  }
  printk("nas_CLASS_cx6 NOT FOUND: %X.%X.%X.%X\n",
		   dst[0],
		   dst[1],
		   dst[2],
		   dst[3]);
  return default_ip;
}

//---------------------------------------------------------------------------
// Search the entity with the IPv4 address 'addr'
struct cx_entity *nas_CLASS_cx4(struct sk_buff *skb,
				unsigned char dscp,
				struct nas_priv *gpriv,
				int inst,
				unsigned char *cx_searcher){
  //---------------------------------------------------------------------------
  unsigned char cxi;
  unsigned char *addr;
  struct cx_entity *default_ip=NULL;
  struct classifier_entity *p=NULL;
  
  //  if (inst >0)
  //    return(gpriv->cx);  //dump to clusterhead
  
  
#ifdef NAS_DEBUG_CLASS

#ifdef KERNEL_VERSION_GREATER_THAN_2630
  addr = (char *)&((((struct rtable *)(skb->_skb_dst))->rt_gateway));
#else
 addr = (char *)&((((struct rtable *)(skb->dst))->rt_gateway));
#endif

  if (addr)
    printk("[NAS][CLASS][IPv4] Searching for %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]);
#endif
  
#ifdef KERNEL_VERSION_GREATER_THAN_2630
  if (skb->_skb_dst!=0) {
#else
  if (skb->dst!=NULL) {
#endif    
    
      for (cxi=*cx_searcher; cxi<NAS_CX_MAX; ++cxi) {
      
      (*cx_searcher)++;
      p = gpriv->cx[cxi].sclassifier[dscp];

      while (p!=NULL) {
	if (p->version == 4) {   // verify that this is an IPv4 rule

#ifdef NAS_DEBUG_CLASS
	  addr = (char *)(&(p->daddr.ipv4));
	  printk("cx %d : %d.%d.%d.%d\n",cxi,addr[0],addr[1],addr[2],addr[3]);

#ifdef KERNEL_VERSION_GREATER_THAN_2630  
	  addr = (char *)&(((struct rtable *)(skb->_skb_dst))->rt_gateway);
#else
	  addr = (char *)&(((struct rtable *)(skb->dst))->rt_gateway);
#endif
	  printk("rt_gateway : %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]);
#endif //NAS_DEBUG_CLASS
#ifdef KERNEL_VERSION_GREATER_THAN_2630  
	  if ((p->daddr.ipv4)== (((((struct rtable *)(skb->_skb_dst))->rt_gateway)))){
#else
	  if ((p->daddr.ipv4)== (((((struct rtable *)(skb->dst))->rt_gateway)))){
#endif

	    addr = (char *)(&(p->daddr.ipv4));
#ifdef NAS_DEBUG_CLASS
	    printk("found cx %d: %d.%d.%d.%d\n",cxi,
		   addr[0],
		   addr[1],
		   addr[2],
		   addr[3]);
#endif //NAS_DEBUG_CLASS
	    return gpriv->cx+cxi;
	  }
	  /*
	  else if (gpriv->cx[cxi].sclassifier[dscp]->daddr.ipv4==NAS_DEFAULT_IPV4_ADDR) {
	  #ifdef NAS_DEBUG_CLASS
	  printk("found default_ip rule\n");
	  #endif //NAS_DEBUG_CLASS
	  default_ip = gpriv->cx+cxi;
	  }
	*/
	}
	// goto to next classification rule for the connection
	p = p->next;
      }
      
    }
    
  }
  
  return default_ip;
}

#ifdef MPLS
//---------------------------------------------------------------------------
// Search the entity with the mpls label and given exp
struct cx_entity *nas_CLASS_MPLS(struct sk_buff *skb,
				unsigned char exp,
				struct nas_priv *gpriv,
				int inst,
				unsigned char *cx_searcher){
  //---------------------------------------------------------------------------
  unsigned char cxi;
  
  struct cx_entity *default_label=NULL;
  struct classifier_entity *p=NULL;

  //  if (inst >0)
  //    return(gpriv->cx);  //dump to clusterhead


#ifdef NAS_DEBUG_CLASS
 
  
  printk("[NAS][CLASS][MPLS] Searching for label %d\n",MPLSCB(skb)->label);
#endif
    
    for (cxi=*cx_searcher; cxi<NAS_CX_MAX; ++cxi) {
      
      (*cx_searcher)++;
      p = gpriv->cx[cxi].sclassifier[exp];

      while (p!=NULL) {
	if (p->version == NAS_MPLS_VERSION_CODE) {   // verify that this is an MPLS rule

#ifdef NAS_DEBUG_CLASS
	  printk("cx %d : label %d\n",cxi,p->daddr.mpls_label);
#endif //NAS_DEBUG_CLASS
	  
	  if (p->daddr.mpls_label==MPLSCB(skb)->label){
#ifdef NAS_DEBUG_CLASS
	    printk("found cx %d: label %d, RB %d\n",cxi,
		                                    MPLSCB(skb)->label,
	                                            p->rab_id);
#endif //NAS_DEBUG_CLASS
	    return gpriv->cx+cxi;
	  }
	  /*
	  else if (gpriv->cx[cxi].sclassifier[dscp]->daddr.ipv4==NAS_DEFAULT_IPV4_ADDR) {
	  #ifdef NAS_DEBUG_CLASS
	  printk("found default_ip rule\n");
	  #endif //NAS_DEBUG_CLASS
	  default_ip = gpriv->cx+cxi;
	  }
	*/
	}
	// goto to next classification rule for the connection
	p = p->next;
      }
      
    }
    

  
  return default_label;
}

#endif 

//---------------------------------------------------------------------------
// Search the sending function
void nas_CLASS_send(struct sk_buff *skb,int inst){
  //---------------------------------------------------------------------------
  struct classifier_entity *p, *sp;
  u8 *protocolh,version;
  u8 protocol, dscp, exp,label;
  u16 classref;
  struct cx_entity *cx;
  unsigned int i;

  unsigned int router_adv = 0;
  struct net_device *dev=nasdev[inst];

  struct nas_priv *gpriv=netdev_priv(dev);

  unsigned char cx_searcher,no_connection=1;


#ifdef NAS_DEBUG_CLASS
  printk("NAS_CLASS_SEND: begin - inst %d\n",inst);
#endif
  if (skb==NULL){
#ifdef NAS_DEBUG_SEND
    printk("NAS_CLASS_SEND - input parameter skb is NULL \n");
#endif
    return;
  }
  

#ifdef NAS_DEBUG_SEND

  printk("[NAS][CLASS][SEND] Got packet from kernel:\n");
  for (i=0;i<256;i++)
    printk("%2x ",((unsigned char *)skb->data)[i]);
  printk("\n");
#endif
  // find all connections related to socket
  cx_searcher = 0;

  no_connection = 1;

  //while (cx_searcher<NAS_CX_MAX) {

    cx = NULL;
    
    // Address classification
    switch (ntohs(skb->protocol))
      {
      case ETH_P_IPV6:
	version = 6;

	protocolh=nas_TOOL_get_protocol6(
#ifdef KERNEL_VERSION_GREATER_THAN_2622				      
					 (struct ipv6hdr *)(skb_network_header(skb)),
#else
					 skb->nh.ipv6h,
#endif 
					 &protocol);
	dscp=nas_TOOL_get_dscp6(
#ifdef KERNEL_VERSION_GREATER_THAN_2622				      
				(struct ipv6hdr *)(skb_network_header(skb))
#else
				skb->nh.ipv6h
#endif
				); 
#ifdef NAS_DEBUG_CLASS
	printk("NAS_CLASS_SEND: %p %d %p %d %p \n",skb, dscp, gpriv, inst, &cx_searcher);
#endif
	cx=nas_CLASS_cx6(skb,dscp,gpriv,inst,&cx_searcher);
	
	
#ifdef NAS_DEBUG_CLASS
	printk("NAS_CLASS_SEND: Got IPv6 packet, dscp = %d\n",dscp);
#endif
	break;
      case ETH_P_IP:
      
      
#ifdef KERNEL_VERSION_GREATER_THAN_2622				      
	dscp=nas_TOOL_get_dscp4((struct iphdr *)(skb_network_header(skb)));
#else
	dscp=nas_TOOL_get_dscp4(skb->nh.iph);
#endif
	cx=nas_CLASS_cx4(skb,dscp,gpriv,inst,&cx_searcher);
	protocolh=nas_TOOL_get_protocol4(
#ifdef KERNEL_VERSION_GREATER_THAN_2622				      
					 (struct iphdr *)(skb_network_header(skb)),
#else
					 skb->nh.iph,
#endif
					 &protocol);
#ifdef NAS_DEBUG_CLASS
	printk("NAS_CLASS_SEND: Got IPv4 packet (%x), dscp = %d, cx = %x\n",ntohs(skb->protocol),dscp,cx);
#endif
	version = 4;

	break;
#ifdef MPLS
      case ETH_P_MPLS_UC:
	cx=nas_CLASS_MPLS(skb,MPLSCB(skb)->exp,gpriv,inst,&cx_searcher);

#ifdef NAS_DEBUG_CLASS
	printk("NAS_CLASS_SEND: Got MPLS unicast packet, exp = %d, label = %d, cx = %x\n",MPLSCB(skb)->exp,MPLSCB(skb)->label,cx);
#endif

	dscp = MPLSCB(skb)->exp;
	version = NAS_MPLS_VERSION_CODE;
	protocol = version;
	break;
#endif      
      default:
	printk("NAS_CLASS_SEND: Unknown protocol\n");
	version = 0;
	return;
      }



    // If a valid connection for the DSCP/EXP with destination address
    // is found scan all protocol-based classification rules

    if (cx) {
      
      classref=0;
      sp=NULL;

#ifdef NAS_DEBUG_CLASS	
	printk("[NAS][CLASSIFIER] DSCP/EXP %d : looking for classifier entry\n",dscp);
#endif      
      for (p=cx->sclassifier[dscp]; p!=NULL; p=p->next) {
#ifdef NAS_DEBUG_CLASS	
	printk("[NAS][CLASSIFIER] DSCP %d p->classref=%d,p->protocol=%d,p->version=%d\n",dscp,p->classref,p->protocol,p->version);
#endif
	// Check if transport protocol/message match
	/*	
	if ((p->protocol == protocol))
	  if ((protocol == NAS_PROTOCOL_ICMP6) && (version == 6))
	    if (p->protocol_message_type == (p->protocol_message_type )) {
	      printk("[GRAAL][CLASSIFIER] Router advertisement\n");
	    }
	*/
      // normal rule checks that network protocol version matches
	
	if (p->version == version) {
	  sp=p;
	  classref=sp->classref;
	  break;
	}
	
      }
    
      if (sp!=NULL) {
#ifdef NAS_DEBUG_CLASS

	char sfct[10], sprotocol[10];
	if (sp->fct==nas_COMMON_QOS_send)
	  strcpy(sfct, "qos");
	if (sp->fct==nas_CTL_send)
	  strcpy(sfct, "ctl");
	if (sp->fct==nas_COMMON_del_send)
	  strcpy(sfct, "del");
	if (sp->fct==nas_mesh_DC_send_sig_data_request)
	  strcpy(sfct, "dc");
	switch(protocol)
	  {
	  case NAS_PROTOCOL_UDP:strcpy(sprotocol, "udp");printk("udp packet\n");break;
	  case NAS_PROTOCOL_TCP:strcpy(sprotocol, "tcp");printk("tcp packet\n");break;
	  case NAS_PROTOCOL_ICMP4:strcpy(sprotocol, "icmp4");printk("icmp4 packet\n");break;
	  case NAS_PROTOCOL_ICMP6:strcpy(sprotocol, "icmp6"); print_TOOL_pk_icmp6((struct icmp6hdr*)protocolh);break;
#ifdef MPLS
	  case NAS_MPLS_VERSION_CODE:strcpy(sprotocol,"mpls");break;
#endif 
	  }
	printk("NAS_CLASS_SEND: (dscp %u, %s) received, (classref %u, fct %s, rab_id %u) classifier rule\n",
	       dscp, sprotocol, sp->classref, sfct, sp->rab_id);
#endif

	sp->fct(skb, cx, sp,inst);
      
      } // if classifier entry match found

      else {
	printk("NAS_CLASS_SEND: no corresponding item in the classifier, so the message is dropped\n");
	//	nas_COMMON_del_send(skb, cx, NULL,inst);
      }

      no_connection = 0;
    }   // if connection found


#ifdef NAS_DEBUG_CLASS
    if (no_connection == 1)
      printk("NAS_CLASS_SEND: no corresponding connection, so the message is dropped\n");
#endif NAS_DEBUG_CLASS
    

//  }   // while loop over connections


#ifdef NAS_DEBUG_CLASS
  printk("NAS_CLASS_SEND: end\n");
#endif
  
}