dns_message * handle_ether(const u_char * pkt, int len) { char buf[PCAP_SNAPLEN]; struct ether_header *e = (void *) pkt; unsigned short etype = ntohs(e->ether_type); if (len < ETHER_HDR_LEN) return NULL; pkt += ETHER_HDR_LEN; len -= ETHER_HDR_LEN; if (ETHERTYPE_8021Q == etype) { if (!match_vlan(pkt)) return NULL; etype = ntohs(*(unsigned short *) (pkt + 2)); pkt += 4; len -= 4; } if (len < 0) return NULL; if (is_ethertype_ip(etype)) { memcpy(buf, pkt, len); return handle_ip((struct ip *) buf, len); } return NULL; }
static void transport_vlan_on_L1 (struct node *n, vlan_t v) { struct linklist *ll ; int l2seen, l2pat ; if (vlan_isset (n->vlanset, v)) return ; vlan_set (n->vlanset, v) ; MK_SET (n, MK_L2TRANSPORT) ; /* * First pass : avoid L2pat nodes, since we only want to * instanciate them if there is no L2 node for this vlan. */ l2pat = 0 ; l2seen = 0 ; for (ll = n->linklist ; ll != NULL ; ll = ll->next) { struct link *l ; struct node *other ; l = ll->link ; other = getlinkpeer (l, n) ; switch (other->nodetype) { case NT_L1 : transport_vlan_on_L1 (other, v) ; break ; case NT_L2 : switch (n->u.l1.l1type) { case L1T_DISABLED : break ; case L1T_TRUNK : if (other->u.l2.vlan == v) { l2seen = 1 ; transport_vlan_on_L2 (other, v) ; } break ; case L1T_ETHER : l2seen = 1 ; transport_vlan_on_L2 (other, other->u.l2.vlan) ; break ; } break ; case NT_L3 : inconsistency ("L1-L3 : Should not happen") ; exit (2) ; break ; case NT_BRIDGE : inconsistency ("L1-BRIDGE : Should not happen") ; exit (2) ; break ; case NT_ROUTER : inconsistency ("L1-ROUTER : Should not happen") ; exit (2) ; break ; case NT_L2PAT : l2pat = 1 ; break ; case NT_BRPAT : inconsistency ("L1-BRPAT : Should not happen") ; exit (2) ; break ; } } /* * Second pass : if there is no L2 node for this vlan, * look for an L2pat to instanciate. */ if (l2pat && ! l2seen) { for (ll = n->linklist ; ll != NULL ; ll = ll->next) { struct link *l ; struct node *other ; l = ll->link ; other = getlinkpeer (l, n) ; if (other->nodetype == NT_L2PAT) { if (n->u.l1.l1type == L1T_TRUNK) { if (match_vlan (v, other->u.l2pat.allowed)) transport_vlan_on_L2pat (other, v, n) ; } else { inconsistency ("L1(ether)-L2PAT : Should not happen") ; exit (2) ; } } } } }
static void transport_vlan_on_brpat (struct node *n, vlan_t v, struct node *prev) { struct linklist *ll ; struct node *bridgenode ; if (vlan_isset (n->vlanset, v)) return ; vlan_set (n->vlanset, v) ; /* * Instanciate this brpat into a bridge */ bridgenode = create_node (new_nodename (n->eq->name), n->eq, NT_BRIDGE) ; (void) create_link (NULL, prev->name, bridgenode->name) ; vlan_set (bridgenode->vlanset, v) ; for (ll = n->linklist ; ll != NULL ; ll = ll->next) { struct link *l ; struct node *other ; l = ll->link ; other = getlinkpeer (l, n) ; switch (other->nodetype) { case NT_L1 : inconsistency ("BRPAT-L1 : Should not happen") ; exit (2) ; break ; case NT_L2 : if (other->u.l2.vlan == v && other != prev) { (void) create_link (NULL, bridgenode->name, other->name) ; transport_vlan_on_L2 (other, v) ; } break ; case NT_L3 : inconsistency ("BRPAT-L3 : Should not happen") ; exit (2) ; break ; case NT_BRIDGE : inconsistency ("BRPAT-BRIDGE : Should not happen") ; exit (2) ; break ; case NT_ROUTER : inconsistency ("BRPAT-ROUTER : Should not happen") ; exit (2) ; break ; case NT_L2PAT : if (match_vlan (v, other->u.l2pat.allowed)) transport_vlan_on_L2pat (other, v, bridgenode) ; break ; case NT_BRPAT : inconsistency ("BRPAT-BRPAT : Should not happen") ; exit (2) ; break ; } } }