diff -urN /home/stast/ng_netflow-0.2.5/flowctl/ng_netflow.4 ./flowctl/ng_netflow.4 --- /home/stast/ng_netflow-0.2.5/flowctl/ng_netflow.4 Tue Aug 10 16:09:27 2004 +++ ./flowctl/ng_netflow.4 Thu Jan 19 16:21:14 2006 @@ -60,7 +60,7 @@ .Pp Export information is stored in Netflow version 5 datagrams. .Nm -tries to fill in all possible fields in datagram, except of AS numbers (see +tries to fill in all possible fields in datagram, and AS numbers also (see .Sx BUGS below). .Sh HOOKS @@ -143,6 +143,48 @@ .Xr flowctl 8 , not directly from .Xr ngctl 8 . +.It Dv NGM_NETFLOW_ENABLEASFILL +This control messages permit work with AS number fields. +This message requires +.Vt struct ng_netflow_enableasfill_type +as its argument +.Bd -literal -offset 0n +struct ng_netflow_enableasfill { + u_int8_t asfillcommand; + } +.Ed +.El +.It Dv NGM_NETFLOW_ADDNETTOAS +This control messages adds information about including +network ipoct1.ipoct2.ipoct3.ipoct4/masklen into AS. +This message requires +.Vt struct ng_netflow_addnettoas +as its argument +.Bd -literal -offset 0n +struct ng_netflow_addnettoas { + u_int8_t ipoct1; + u_int8_t ipoct2; + u_int8_t ipoct3; + u_int8_t ipoct4; + u_int8_t masklen; + u_int16_t asnum; + } +.Ed +.El +.It Dv NGM_NETFLOW_GETASNUMBER +This control message returns AS number by IP, if this information contains +in node data; and returns 0 in else case. +This message requires +.Vt struct ng_netflow_getasnumber +as its argument +.Bd -literal -offset 0n +struct ng_netflow_getasnumber { + u_int8_t ipoct1; + u_int8_t ipoct2; + u_int8_t ipoct3; + u_int8_t ipoct4; + } +.Ed .El .Sh ASCII CONTROL MESSAGES Most of control messages can be sent in ASCII form. @@ -153,6 +195,9 @@ NGM_NETFLOW_SETDLT "setdlt { iface = %u dlt = %u }" NGM_NETFLOW_SETIFINDEX "setifindex { iface = %u index = %u }" NGM_NETFLOW_SETTIMEOUTS "settimeouts { inactive = %u active = %u }" +NGM_NETFLOW_ENABLEASFILL "enableasfill { enable=%u }" +NGM_NETFLOW_ADDNETTOAS "addnettoas { oct1=%u, oct2=&u, oct3=%u, oct4=%u, mask=%u, as=%u}" +NGM_NETFLOW_GETASNUMBER "getasnumber { oct1=%u, oct2=%u, oct3=%u, oct4=%u}" .Ed .Sh SHUTDOWN This node shuts down upon receipt of a diff -urN /home/stast/ng_netflow-0.2.5/ng_netflow/kernel.h ./ng_netflow/kernel.h --- /home/stast/ng_netflow-0.2.5/ng_netflow/kernel.h Tue Aug 10 16:09:27 2004 +++ ./ng_netflow/kernel.h Mon Jul 17 14:48:02 2006 @@ -71,6 +71,42 @@ { "active", &ng_parse_uint32_type }, \ { NULL } \ } +/* Parse the addnettoas structure */ +#define NG_NETFLOW_ADDNETTOAS_TYPE { \ + { "oct1", &ng_parse_uint8_type }, \ + { "oct2", &ng_parse_uint8_type }, \ + { "oct3", &ng_parse_uint8_type }, \ + { "oct4", &ng_parse_uint8_type }, \ + { "mask", &ng_parse_uint8_type }, \ + { "as", &ng_parse_uint16_type },\ + { NULL } \ +} +/* Parse the enableasfill structure */ +#define NG_NETFLOW_ENABLEASFILL_TYPE { \ + { "enable", &ng_parse_uint8_type }, \ + { NULL } \ +} +/* Parse the deletenetfromas structure */ +#define NG_NETFLOW_DELETENETFROMAS_TYPE { \ + { "oct1", &ng_parse_uint8_type }, \ + { "oct2", &ng_parse_uint8_type }, \ + { "oct3", &ng_parse_uint8_type }, \ + { "oct4", &ng_parse_uint8_type }, \ + { "mask", &ng_parse_uint8_type }, \ + { NULL } \ +} +#define NG_NETFLOW_GETASNUMBER_TYPE { \ + { "oct1", &ng_parse_uint8_type }, \ + { "oct2", &ng_parse_uint8_type }, \ + { "oct3", &ng_parse_uint8_type }, \ + { "oct4", &ng_parse_uint8_type }, \ + { NULL } \ +} +#define NG_NETFLOW_ASNUMBER_TYPE { \ + { "as", &ng_parse_uint16_type }, \ + { NULL } \ +} + struct ng_netflow_iface { hook_p hook; /* NULL when disconnected */ @@ -80,6 +116,28 @@ typedef struct ng_netflow_iface *iface_p; typedef struct ng_netflow_ifinfo *ifinfo_p; +/* Constatants and structs for AS-filling engine*/ +#define BUSYHIGH 0x01 /*set when ip include in net /16 or larger */ +#define BUSYLOW 0x02 /*set when ip include in net /17 or smaller*/ +struct ascelllow { + u_int8_t ip3; + u_int16_t asnumber; + u_int8_t mask; + struct ascelllow* ptrnext; +}; +/*struct ascellhigh { + u_int8_t flag; + union { + struct ascelllow* ptr_low; + u_int16_t AS; + } body; +};*/ + +struct ascellhigh { + struct ascelllow* ptr_low; +}; + + struct netflow { node_p node; /* link to the node itself */ @@ -99,8 +157,13 @@ * to first one */ struct netflow_v5_header header; struct netflow_v5_record r[NETFLOW_V5_MAX_RECORDS]; + /* List of Autonomous System */ + struct ascellhigh astable[255][255]; + u_int8_t isFillAS; }; - +int AddNetToAS (struct netflow*, u_int8_t, u_int8_t, u_int8_t, u_int8_t, \ + u_int8_t, u_int16_t); +u_int16_t GetAsnumber (struct netflow*, u_int8_t, u_int8_t, u_int8_t, u_int8_t); typedef struct netflow *priv_p; struct flow_hash { diff -urN /home/stast/ng_netflow-0.2.5/ng_netflow/netflow.c ./ng_netflow/netflow.c --- /home/stast/ng_netflow-0.2.5/ng_netflow/netflow.c Tue Aug 10 20:21:54 2004 +++ ./ng_netflow/netflow.c Mon Jul 17 15:33:33 2006 @@ -309,10 +309,10 @@ r->r_ip_p = ip->ip_p; r->r_tos = ip->ip_tos; - if ((*m)->m_pkthdr.rcvif) - r->r_i_ifx = (*m)->m_pkthdr.rcvif->if_index; + if ((*m)->m_pkthdr.rcvif && i_ifx<100) + r->r_i_ifx = (*m)->m_pkthdr.rcvif->if_index; /*fill with iface number */ else - r->r_i_ifx = i_ifx; + r->r_i_ifx = i_ifx; /*fill with data from setifindex */ /* * XXX NOTE: only first fragment of fragmented TCP, UDP and @@ -591,7 +591,7 @@ { struct netflow_v5_header *header = &priv->header; struct netflow_v5_record *rec; - + u_int8_t o1,o2,o3,o4; u_int16_t a1,a2; /* fle == NULL indicates that expiry run has completed and something * must be sent. However, people working with Cisco routers * say that Cisco does not send empty datagrams. We will pretend @@ -631,7 +631,21 @@ rec->tos = fle->r.r_tos; rec->dst_mask = fle->dst_mask; rec->src_mask = fle->src_mask; + /*if (priv->isFillAS) { */ + o1=(htonl(rec->src_addr)>>24)&0xFF; + o2=(htonl(rec->src_addr)>>16)&0xFF; + o3=(htonl(rec->src_addr)>>8)&0xFF; + o4=(htonl(rec->src_addr))&0xFF; + a1=GetAsnumber(priv,o1,o2,o3,o4); + rec->dst_as=htons(a1); + o1=(htonl(rec->dst_addr)>>24)&0xFF; + o2=(htonl(rec->dst_addr)>>16)&0xFF; + o3=(htonl(rec->dst_addr)>>8)&0xFF; + o4=(htonl(rec->dst_addr))&0xFF; + a2=GetAsnumber(priv,o1,o2,o3,o4); + rec->src_as=htons(a2); +/* } */ priv->flow_seq ++; if (header->count == NETFLOW_V5_MAX_RECORDS) /* end of dgram */ @@ -684,3 +698,61 @@ return (0); } +int AddNetToAS (priv_p data, u_int8_t i1, u_int8_t i2, u_int8_t i3, u_int8_t i4, \ + u_int8_t mask, u_int16_t asnumber) { + u_int16_t oldas; + oldas=GetAsnumber(data,i1,i2,i3,i4); + if (oldas==asnumber) /*this net already in list*/ + return 0; + if (mask>=8 && mask<16) { + int k; + u_int8_t netmask; + netmask=0xFF<<(16-mask); + for (k=0; k<=16-mask; k++) + AddNetToAS(data,i1,(i2&netmask)|k, i3,i4,16,asnumber); + return 0; + } + else { + /*if (mask>=16 && mask<=24) */ + if (! data->astable[i1][i2].ptr_low) { /*first net in list*/ + MALLOC(data->astable[i1][i2].ptr_low,struct ascelllow*, sizeof(struct ascelllow),M_NETFLOW,M_NOWAIT); + data->astable[i1][i2].ptr_low->ip3=i3; + data->astable[i1][i2].ptr_low->mask=mask; + data->astable[i1][i2].ptr_low->asnumber=asnumber; + data->astable[i1][i2].ptr_low->ptrnext=NULL; + return 0; + } + else {/*not first net in list*/ + struct ascelllow* ptrlast; + MALLOC(ptrlast, struct ascelllow*,sizeof(struct ascelllow),\ + M_NETFLOW, M_NOWAIT); + ptrlast->ip3=i3; + ptrlast->asnumber=asnumber; /*add net to begin of list*/ + ptrlast->mask=mask; + ptrlast->ptrnext=data->astable[i1][i2].ptr_low; + data->astable[i1][i2].ptr_low=ptrlast; + return 0; + } + } + return -1; +} +u_int16_t GetAsnumber (priv_p data, u_int8_t ip1, u_int8_t ip2, u_int8_t ip3, \ + u_int8_t ip4) { + if (data->astable[ip1][ip2].ptr_low) { + struct ascelllow* ptrlast; + u_int8_t netmask; + ptrlast=data->astable[ip1][ip2].ptr_low; + do { + netmask=ptrlast->mask-16; + netmask=0xFF<<(8-netmask); + if ( ((ptrlast->ip3)&netmask)==(ip3&netmask) ) + return (ptrlast->asnumber); + ptrlast=ptrlast->ptrnext; + } + while (ptrlast!=NULL); + return 0; + /*return (data->astable[ip1][ip2].body.ptr_low->asnumber); */ + } + else + return 0; +} diff -urN /home/stast/ng_netflow-0.2.5/ng_netflow/ng_netflow.c ./ng_netflow/ng_netflow.c --- /home/stast/ng_netflow-0.2.5/ng_netflow/ng_netflow.c Tue Aug 10 20:21:02 2004 +++ ./ng_netflow/ng_netflow.c Mon Jul 17 14:59:08 2006 @@ -113,6 +113,42 @@ &ng_parse_struct_type, &ng_netflow_settimeouts_type_fields }; +/* Parse type for ng_netflow_addnettoas */ +static const struct ng_parse_struct_field ng_netflow_addnettoas_type_fields[] + = NG_NETFLOW_ADDNETTOAS_TYPE; +static const struct ng_parse_type ng_netflow_addnettoas_type = { + &ng_parse_struct_type, + &ng_netflow_addnettoas_type_fields +}; +/* Parse type for ng_netflow_enableasfill */ +static const struct ng_parse_struct_field ng_netflow_enableasfill_type_fields[] + = NG_NETFLOW_ENABLEASFILL_TYPE; +static const struct ng_parse_type ng_netflow_enableasfill_type = { + &ng_parse_struct_type, + &ng_netflow_enableasfill_type_fields +}; +/* Parse type for ng_netflow_deletenetfromas */ +static const struct ng_parse_struct_field ng_netflow_deletenetfromas_type_fields[] + = NG_NETFLOW_DELETENETFROMAS_TYPE; +static const struct ng_parse_type ng_netflow_deletenetfromas_type = { + &ng_parse_struct_type, + &ng_netflow_deletenetfromas_type_fields +}; +/* Parse type for ng_netflow_getasnumber */ +static const struct ng_parse_struct_field ng_netflow_getasnumber_type_fields[] + = NG_NETFLOW_GETASNUMBER_TYPE; +static const struct ng_parse_type ng_netflow_getasnumber_type = { + &ng_parse_struct_type, + &ng_netflow_getasnumber_type_fields +}; +/* Parse type for ng_netflow_asnumber */ +static const struct ng_parse_struct_field ng_netflow_asnumber_type_fields[] + = NG_NETFLOW_ASNUMBER_TYPE; +static const struct ng_parse_type ng_netflow_asnumber_type = { + &ng_parse_struct_type, + &ng_netflow_asnumber_type_fields +}; + /* List of commands and how to convert arguments to/from ASCII */ static const struct ng_cmdlist ng_netflow_cmds[] = { @@ -151,6 +187,34 @@ &ng_netflow_settimeouts_type, NULL }, + { + NGM_NETFLOW_COOKIE, + NGM_NETFLOW_ADDNETTOAS, + "addnettoas", + &ng_netflow_addnettoas_type, + NULL + }, + { + NGM_NETFLOW_COOKIE, + NGM_NETFLOW_ENABLEASFILL, + "enableasfill", + &ng_netflow_enableasfill_type, + NULL + }, + { + NGM_NETFLOW_COOKIE, + NGM_NETFLOW_DELETENETFROMAS, + "deletenet", + &ng_netflow_deletenetfromas_type, + NULL + }, + { + NGM_NETFLOW_COOKIE, + NGM_NETFLOW_GETASNUMBER, + "getasnumber", + &ng_netflow_getasnumber_type, + &ng_netflow_asnumber_type + }, { 0 } }; @@ -210,13 +274,15 @@ /* Initialize timeouts to default values */ priv->info.inactive_timeout = INACTIVE_TIMEOUT; priv->info.active_timeout = ACTIVE_TIMEOUT; - + /* Allocate space for hash of accounting records, * and allocate one chunk for flow cache */ if ((error = hash_init(priv))) return (error); priv->header.version = htons(NETFLOW_V5); + /* Doesn't fill AS number by default*/ + priv->isFillAS=0; return (0); } @@ -402,6 +468,53 @@ break; } + case NGM_NETFLOW_ADDNETTOAS: + { + struct ng_netflow_addnettoas *set; + + if (msg->header.arglen != sizeof(struct ng_netflow_addnettoas)) + ERROUT(EINVAL); + + set = (struct ng_netflow_addnettoas *)msg->data; + AddNetToAS(priv,set->ipoct1,set->ipoct2,set->ipoct3,set->ipoct4,set->masklen,set->asnum); + /*(priv->astable[set->ipoct1][set->ipoct2]) = (set->asnum);*/ + + break; + } + case NGM_NETFLOW_ENABLEASFILL: + { + if (!priv->isFillAS) { /*initialisation*/ + int i=0; int k=0; + for (i=0; i<=255; i++) + for (k=0; k<=255; k++) { + priv->astable[i][k].ptr_low=NULL; + } + priv->isFillAS=1; + } + break; + } + case NGM_NETFLOW_DELETENETFROMAS: + { + break; + } + case NGM_NETFLOW_GETASNUMBER: + { + struct ng_netflow_getasnumber *set; + struct ng_netflow_asnumber *i; + u_int16_t returnas; + if (msg->header.arglen != sizeof(struct ng_netflow_getasnumber)) + ERROUT(EINVAL); + set = (struct ng_netflow_getasnumber *)msg->data; + + + NG_MKRESPONSE(resp, msg, sizeof(struct ng_netflow_asnumber), + M_NOWAIT); + i = (struct ng_netflow_asnumber *)resp->data; + returnas=GetAsnumber(priv,set->ipoct1,set->ipoct2,set->ipoct3,set->ipoct4); + memcpy((void *)i, (void *)&returnas,sizeof(returnas)); + + break; + } default: ERROUT(EINVAL); /* unknown command */ break; diff -urN /home/stast/ng_netflow-0.2.5/ng_netflow/ng_netflow.h ./ng_netflow/ng_netflow.h --- /home/stast/ng_netflow-0.2.5/ng_netflow/ng_netflow.h Tue Aug 10 17:19:47 2004 +++ ./ng_netflow/ng_netflow.h Sun Nov 27 18:05:39 2005 @@ -52,6 +52,10 @@ NGM_NETFLOW_SETDLT, /* set data-link type */ NGM_NETFLOW_SETIFINDEX, /* set interface index */ NGM_NETFLOW_SETTIMEOUTS, /* set active/inactive flow timeouts */ + NGM_NETFLOW_ADDNETTOAS, /* add network/mask with AS number to table */ + NGM_NETFLOW_ENABLEASFILL, /* turn on/off filling AS number in Netflow v.5*/ + NGM_NETFLOW_DELETENETFROMAS,/* delete network/mask from table */ + NGM_NETFLOW_GETASNUMBER, /* yahoo ! get AS number by IP from table */ }; /* This structure is returned by the NGM_NETFLOW_INFO message */ @@ -68,6 +72,10 @@ u_int32_t if_packets; /* number of packets for this iface */ u_int8_t if_dlt; /* Data Link Type, DLT_XXX */ }; +/* This structure is returned by the NGM_NETFLOW_GETASNUMBER message */ +struct ng_netflow_asnumber { + u_int16_t asnumber; +}; #define MAXDLTNAMELEN 20 @@ -87,6 +95,35 @@ struct ng_netflow_settimeouts { u_int32_t inactive_timeout; /* flow inactive timeout */ u_int32_t active_timeout; /* flow active timeout */ +}; +#define MAXIPOCT1 255 +/* This structure is passed to NGM_NETFLOW_ADDNETTOAS*/ +struct ng_netflow_addnettoas { + u_int8_t ipoct1; + u_int8_t ipoct2; + u_int8_t ipoct3; + u_int8_t ipoct4; + u_int8_t masklen; + u_int16_t asnum; +}; +/* This structure is passed to NGM_NETFLOW_ENABLEASFILL*/ +struct ng_netflow_enableasfill { + u_int8_t asfillcommand; /* different common commands */ +}; +/* This structure is passed to NGM_NETFLOW_DELETENETFROMAS*/ +struct ng_netflow_deletenetfromas { + u_int8_t ipoct1; + u_int8_t ipoct2; + u_int8_t ipoct3; + u_int8_t ipoct4; + u_int8_t masklen; +}; +/* This structure is passed to NGM_NETFLOW_GETASNUMBER*/ +struct ng_netflow_getasnumber { + u_int8_t ipoct1; + u_int8_t ipoct2; + u_int8_t ipoct3; + u_int8_t ipoct4; }; /* This is unique data, which identifies flow */