Tuesday, August 11, 2009

reader digest: ssh-nat--udp--tcp

// dns-dproxy-tor dhcp wget
// thttp
// bridge
// iptable-iproute
// net-tools busybox
// stunnel
// vconfig
//
//-------------------------------------
SSH (Secure SHell) is a network protocol that allows data to be exchanged over a secure channel between two host; encryption provides confidentiality and integrity of data. SSH uses public-key cryptography to authenticate the remote host and allow the remote host to authenticate the user, if necessary.

It is possible to distinguish between SSH “Client” and “Server” processes: client processes create the login request and provide the connection establishment with the remote unit, while server processes are hosted on the remote system and provide the login service to the request of the clients.
//-------------------------------------
12.1. NAT resource
Abilis implements NAT (Network Address Translation) with PAT (Port Address Translation) and IPACL (IP Access Control List) services that ensure sophisticated filters applying on IP traffic (“packet filtering”) by specifying for example:
Source IP address or network.
Destination IP address or network.
Source UDP/TCP port.
Destination UDP/TCP port.
Source/Destination IP resource.
TOS (Type of Service) for packets priority management by services.
By properly combining the services above it's possible obtain a high level of security.
Others elements that increase the security level are:
Proprietary operating system: it's not based on Microsoft or Linux, so it's unknown to hackers.
Proprietary VPN activating protocol.
Data encrypting based on 256 bit cypher key.

Abilis is not a Firewall! It implements basic firewall function, but evolved features must be commissioned to a “real” firewall. Abilis and firewall can coexist with no problems.


//-------------------------------------
13.1. IP Access Control List
The IP Access Control List is a security procedure through that the Abilis CPX executes control, basing on base addresses and the requested services, and check functionalities on the datagrams in transit from and to Abilis CPX.
Transit datagrams are filtered and then selected basing on the information carried by the header (source address and destination, internet protocol version and numbers of logical port) and not on their content. Two ways of filtering are allowed:
STD (Standard): in this case the such called "address filtering" procedure is executed; only IP source and destination addresses of the packet are checked.
EXT (Extended): in this case the "service filtering" procedure is executed; not only IP source and destination addresses of the packet are checked but also the internet protocol version and for TCP, UDP protocols the logical port numbers (indeed also the requested service).
By defining suitable filters in the IP access list it is so possible to set which data can transit and which no. This list provides two different kinds of filters:
PERMIT: permitted to transit.
DENY: denied to transit.
Filters also allow assigning each datagram data flow a different service class:
HIGH: service class "HIGH".
NORMAL: service class "NORMAL".
LOW: service class "LOW".
Usually the service classes are also called "priorities" so that it is possible to speak of "the traffic prioritisation"; further on the filter priorities will be introduced, the User should not confuse the two definition of priority, with the latter it is meant the evaluation order of filters.
Tip
This feature is very important when VoIp and Data applications coexist and use the same link. In these cases, voice packets must have the highest priority for not make the compressed voice quality worse.
Moreover it is possible to activate the cryptographic functionalities of data content in datagrams:
CRKEY: cryptography key to be used.
CRDIR: cryptography direction (encode decode).
Filters can be added, modified, deleted from the IP access list during Abilis CPX working mode, without needing to restart it. Changes are immediately active.
Caution
"Packet filtering" definitions must be added carefully cause the access to the Abilis by IP may be blocked!
13.1.1. TOS (Type Of Service)
It is possible to assign to each datagram data flow a different Type Of Service (TOS). TOS is just a hint to the routing algorithm that helps it choose among various paths to a destination. An internet does not guarantee the type of transport requested.
The Type of Service is used to indicate the quality of the service desired. The type of service is an abstract or generalized set of parameters which characterize the service choices provided in the networks that make up the internet. This type of service indication is to be used by gateways to select the actual transmission parameters for a particular network, the network to be used for the next hop, or the next gateway when routing an internet datagram. The five values allowed are:
N = None;
D = Minimize Delay;
T = Maximize Throughput;
R = Maximize Reliability;
C = Minimize Monetary Cost.
13.1.2. Activating IPACL
The IP Access Control List must be enabled into the IPRTR Resource.
[15:14:30] ABILIS_CPX:d p iprtr
RES:Iprtr ---------------------------------------------------------------------
DESCR:IP_Router_general_properties
- General --------------------------------------------------------------
R-ID:AUTO (192.168.001.001)
maxroute:500 DFTTTL:64 ps:2048
DEF-LOCAL-AD:0 DEF-STATIC-AD:1 DEF-OSPF-AD:110 DEF-RIP-AD:120
pvc:0 bsvc:0 LINKS:4 virtual:0
- IP Access List -------------------------------------------------------
ACL:NO ACLBYPASS:#
COS:DISABLED COSDFT:NORMAL
COSBALANCE:NO NORMRATE:50 LOWRATE:50
- IP Trace -------------------------------------------------------------
tracerec:100
- Ppp-Dns --------------------------------------------------------------
PPP-DNS-PRI:062.094.000.001 PPP-DNS-SEC:062.094.000.002
The highlight parameters manages the IPACL activation and functionality mode.


//-------------------------------------
15.1. VRRP resource

VRRP (Virtual Router Redundancy Protocol) specifies an election protocol that dynamically assigns responsibility for a virtual router to one of the VRRP routers on a LAN. The VRRP router controlling the IP address(es) associated with a virtual router is called the Master, and forwards packets sent to these IP addresses. The election process provides dynamic fail over in the forwarding responsibility should the Master become unavailable. This allows any of the virtual router IP addresses on the LAN to be used as the default first hop router by end-hosts. The advantage from using VRRP is a higher availability default path without requiring configuration of dynamic routing or router discovery protocols on every end-host.

The Virtual Router Redundancy Protocol (VRRP) is designed to eliminate the single point of failure inherent in the static default routed environment. It is available in every distribution of the Abilis firmware; however, in order to be used, it must be set active.

15.1.1. Activating the VRRP resource

Add the resource to the Abilis system with the command a res:vrrp; the VRRP resource may already exist in the system, but may not yet be active: set it active with the command s act res:vrrp.

[15:43:30] ABILIS_CPX:a res:vrrp

RES:VRRP ALREADY EXISTS

[16:02:48] ABILIS_CPX:s act res:vrrp

COMMAND EXECUTED
Caution
After adding or setting the VRRP active, you must restart the Abilis to make the resource running (use the command warm start to reboot the Abilis).

[16:51:53] ABILIS_CPX:s p vrrp act:yes

COMMAND EXECUTED

[16:52:04] ABILIS_CPX:d p vrrp

RES:Vrrp - Not Saved (SAVE CONF), Not Refreshed (INIT) ------------------------
------------------------------------------------------------------------
DESCR:Virtual_Router_Redundancy_Protocol
LOG:NO ACT:YES mxps:256 TOS:0-N
15.1.2. VRRP resource parameters

Use d p vrrp command to display the parameters of the resource; by typing d p vrrp ? command it is possible to display the meaning of all parameters.

[16:52:04] ABILIS_CPX:d p vrrp

RES:Vrrp ----------------------------------------------------------------------
Run DESCR:Virtual_Router_Redundancy_Protocol
LOG:NO ACT:NO mxps:256 TOS:0-N
Meaning of the parameters:

LOG
Logging functionalities activation/deactivation.

ACT
Runtime VRRP activation/deactivation.

mxps
Sets the maximum size of the packets handled (expressed in bytes).

TOS
Sets the TOS value for VRRP service.

The following command allows the administrator to change the configuration of the resource:

s p vrrp parameter:value...

Caution
To activate the changes made on the upper case parameters, execute the initialization command init res:vrrp; while to set act the changes made on the lowercase parameters a save conf and an Abilis restart are required (i.e. with warm start command).
//-------------------------------------
DHCP (Dynamic Host Configuration Protocol) is a protocol used by network devices (clients) to obtain various parameters (DNS, gateway, WINS, SNTP, SMTP, …) necessary for the clients to operate in an Internet Protocol (IP) network. By using this protocol, system administration workload greatly decreases, and devices can be added to the network with minimal or no manual configurations.

The Abilis DHCP module implements two working mode:

BOOTP relay agent (Relay mode): internet host or router that passes DHCP messages between DHCP clients and DHCP servers.

DHCP Server: internet host that returns configuration parameters to DHCP clients.

16.1.1. Activating DHCP resource

Add the resource to the Abilis system with the command a res:dhcp; the DHCP resource may already exist in the system, but may not yet be active: set it active with the command s act res:dhcp.

[17:14:59] ABILIS_CPX:a res:dhcp

RES:DHCP ALREADY EXISTS

[17:15:17] ABILIS_CPX:s act res:dhcp

COMMAND EXECUTED
Caution
After adding or setting the DHCP active, you must restart the Abilis to make the resource running (use the command warm start to reboot the Abilis).

[17:14:59] ABILIS_CPX:s p dhcp act:yes

COMMAND EXECUTED

[17:15:17] ABILIS_CPX:d p dhcp

RES:Dhcp - Not Saved (SAVE CONF), Not Refreshed (INIT) ------------------------
------------------------------------------------------------------------
Run DESCR:Dynamic_Host_Configuration_Protocol
LOG:DS ACT:YES srv-udp-locport:67 cli-udp-locport:68
msg-len:1472 mode:RELAY MAX-HOPS:4 SRV:#
LOCIPADD:R-ID (192.168.001.001)
WDIR:C:\APP\DHCP\
16.1.2. DHCP resource parameters

Use d p dhcp command to display the parameters of the resource; by typing d p dhcp ? command it is possible to display the meaning of all parameters.

[17:15:17] ABILIS_CPX:d p dhcp

RES:Dhcp ----------------------------------------------------------------------
Run DESCR:Dynamic_Host_Configuration_Protocol
LOG:DS ACT:YES srv-udp-locport:67 cli-udp-locport:68
msg-len:1472 mode:RELAY MAX-HOPS:4 SRV:#
LOCIPADD:R-ID (192.168.001.001)
WDIR:C:\APP\DHCP\
Meaning of the most important parametrs:

LOG
Logging functionalities activation/deactivation.

ACT
Runtime DHCP activation/deactivation.

mode
It specifies the mode of DHCP port working [SERVER, RELAY].

Parameters for mode:RELAY only:

MAX-HOPS
It specifies the maximum number of DHCP relay agent hops.

SRV
It specifies the DHCP Server to which requests must be forwarded; it can be set to an IP address, in Dotted Decimal Notation, or the name of an IP list;

LOCIPADD
It specifies the IP address that DHCP relay agent will use as "source address" in the requests relayed to the server.

Parameters for mode:SERVER only:

max-clients
Maximum number of supported DHCP clients; it actually determines the size of the binding database on disk and in memory.

ICMPCHK
Enables ICMP checking of IP address. When it is set to YES, ICMP checking is enabled. Before sending the DHCPOFFER message, the server sends two ICMP ping requests to check the IP address which was allocated. If both timeouts expire, the server will send the DHCP offer message, otherwise it will mark this IP address as abandoned and will not send response.

MAC-FILTER
Enables/disables the selection of serviceable clients based on their MAC address. When it is set to YES, MAC filtering is enabled. When DHCP receives an incoming request and before processing it, the DHCP verifies that the sender's MAC address is allowed by using MAC-LIST and MAC-RULE parameters current setting (MAC-LIST and MAC-RULE appear when MAC-FILTER is set to YES).

WDIR
Selects the directory where DHCP.BND (BND stays for binding) file is saved. A binding is a collection of configuration parameters, including at least an IP address, associated with or "bound to" a DHCP client. Bindings are managed by DHCP servers.

The following command allows the administrator to change the configuration of the resource:

s p dhcp parameter:value...

Caution
To activate the changes made on the upper case parameters, execute the initialization command init res:dhcp; while to set act the changes made on the lowercase parameters a save conf and an Abilis restart are required (i.e. with warm start command).
16.2. DHCP Relay Mode

A BOOTP relay agent or relay agent is an Internet host or router which allows DHCP messages being passed between DHCP clients and DHCP servers. DHCP is designed to use the same relay agent behaviour as specified in the BOOTP protocol specification.

For example, to allow the relay of DHCP packets to the server 192.168.0.250, type the command:

[18:08:56] ABILIS_CPX:s p dhcp act:yes mode:relay srv:192.168.0.250

COMMAND EXECUTED

[18:08:56] ABILIS_CPX:d p dhcp

RES:Dhcp - Not Saved (SAVE CONF), Not Refreshed (INIT) ------------------------
------------------------------------------------------------------------
DESCR:Dynamic_Host_Configuration_Protocol
LOG:DS ACT:YES srvport:67 cliport:68
msg-len:1472 mode:RELAY MAX-HOPS:4 SRV:192.168.000.250
LOCIPADD:R-ID (192.168.001.001)
WDIR:C:\APP\DHCP\

16.3. DHCP Server Mode

A DHCP server is an Internet host that returns configuration parameters to DHCP clients, as IP Address, subnet mask, DNS, gateway, WINS, SNTP, SMTP, etc.

To configure Abilis as a DHCP server it is needed to set the mode parameter to SERVER and to configure the DHCP Server tables.

[09:56:36] ABILIS_CPX:s p dhcp mode:server

COMMAND EXECUTED

[09:56:45] ABILIS_CPX:d p dhcp

RES:Dhcp - Not Saved (SAVE CONF), Not Refreshed (INIT) ------------------------
------------------------------------------------------------------------
DESCR:Dynamic_Host_Configuration_Protocol
LOG:DS ACT:YES srvport:67 cliport:68
msg-len:1472 mode:SERVER max-clients:300 ICMPCHK:NO
MAC-FILTER:NO
WDIR:C:\APP\DHCP\
Caution
To activate the changes made on the lowercase parameters a save conf and an Abilis restart are required (i.e. with warm start command).

16.3.1. DHCP Server tables

The configuration of DHCP server mode is based on three tables:

DHCP Profiles table: table conaining all the parameters to be distributed to clients (i.e. IP Address, Gateway, WINS, DSN, Domain, …);

DHCP Subnets: table containing the network IP address of the DHCP subnet, the subnet mask, the pools of addresses to distribute and the "lease" time of the IP addresses;

DHCP Hosts: t allows to define a static association between a specific MAC-ADDRESS of a client and an IP address (in this way, the PC will always obtain the same address).

16.3.1.1. DHCP Profiles table

The DHCP Profiles table can hold up to 129 definitions, indexed from 0 up to 128. The first definition, i.e. the profile identified by the index equal to zero, is a default profile that is always present within the table and that cannot be deleted by the user. Instead the user can arbitrarily add/delete the definitions from the index 1 to 128.

The table of DHCP Profiles can be modified while the Abilis CPX is working without needing to restart it. Changes made on the table can be activated by executing the initialization command init res:dhcp.

The commands for the DHCP Profiles table management are:

d dhcp prof:xxx[,yyy,...] : display DHCP profile;

a dhcp prof:xxx [par:val] : add DHCP profile;

c dhcp prof:xxx[,yyy,...] :clears DHCP profile;

s dhcp prof:xxx[,yyy,...] par:val [par:val]: set DHCP profile parameters.

A complete list of available configuration parameters is available by typing d dhcp prof: ?.

[10:50:20] ABILIS_CPX:d dhcp prof: ?

D DHCP PROF:xxx[,yyy,...] Display DHCP profile [0..128, A]

DHCP Profile parameters:

NAME: Profile name. From 0 up to 32 ASCII characters.
Spaces are not allowed. Case is preserved.
TTL: IP time-to-live [0, 1..255]
KEEPALIVE: TCP keepalive interval [0, 15..65535 sec.]
NB-SCOPE-ID: Netbios scope identifier. From 0 up to 32 ASCII characters.
Spaces are not allowed. Case is preserved.
NB-NODE-TYPE: Netbios node type [UNK, B, P, M, H]
DOMAIN: IP domain name. From 0 up to 32 ASCII characters.
Spaces are not allowed. Case is preserved.
GW1: First gateway [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]
GW2: Second (backup) gateway [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]
GW3: Third (backup) gateway [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]
DNS1: Primary Domain Name server [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]
DNS2: Secondary Domain Name server [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]
SMTP: Simple Mail Transport Protocol (SMTP) server [0.0.0.0,
1-126.x.x.x, 128-223.x.x.x]
POP3: Post Office Protocol (POP3) server [0.0.0.0, 1-126.x.x.x,
128-223.x.x.x]
NNTP: Network News Transport Protocol (NNTP) server [0.0.0.0,
1-126.x.x.x, 128-223.x.x.x]
WWW: World Wide Web (WWW) server [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]
FINGER: Finger server [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]
IRC: Internet Relay Chat server [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]
NTP: NTP/SNTP server [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]
TIME: TIME server [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]
WINS1: First WINS server [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]
WINS2: Second WINS server [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]
16.3.1.2. DHCP Subnets table

The DHCP Subnets table can hold up to 128 definitions.

The table of DHCP Subnets can be modified while the Abilis CPX is working without needing to restart it. Changes made on the table can be activated by executing the initialization command init res:dhcp.

The commands for the DHCP Subnets table management are:

d dhcp lan:xxx[,yyy,...] : display DHCP subnet;

a dhcp lan:xxx [par:val] : add DHCP subnet;

c dhcp lan:xxx[,yyy,...] :clears DHCP subnet;

s dhcp lan:xxx[,yyy,...] par:val [par:val]: set DHCP subnet parameters.

A complete list of available configuration parameters is available by typing d dhcp lan: ?.

[10:50:25] ABILIS_CPX:d dhcp lan: ?

D DHCP LAN:xxx[,yyy,...] Display DHCP subnet [1..128, A]

DHCP Subnet parameters:

NAME: Subnet name. From 0 up to 32 ASCII characters.
Spaces are not allowed. Case is preserved.
NET: Network address in DDN or network address and mask in Slash
Notation [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]/[0..32]
MASK: Network mask in DDN [0.0.0.0, 128.0.0.0-255.255.255.252]
POOL1: First IP pool. A single IP address [1.0.0.0-126.255.255.255,
128.0.0.0-223.255.255.255] or two IP addresses separated by ':'
(colon). (E.g.: 150.200.192.192 or 192.168.0.0:192.168.0.100)
POOL2: Second IP pool. A single IP address [1.0.0.0-126.255.255.255,
128.0.0.0-223.255.255.255] or two IP addresses separated by ':'
(colon). (E.g.: 150.200.192.192 or 192.168.0.0:192.168.0.100)
POOL3: Third IP pool. A single IP address [1.0.0.0-126.255.255.255,
128.0.0.0-223.255.255.255] or two IP addresses separated by ':'
(colon). (E.g.: 150.200.192.192 or 192.168.0.0:192.168.0.100)
POOL4: Fourth IP pool. A single IP address [1.0.0.0-126.255.255.255,
128.0.0.0-223.255.255.255] or two IP addresses separated by ':'
(colon). (E.g.: 150.200.192.192 or 192.168.0.0:192.168.0.100)
POOL5: Fifth IP pool. A single IP address [1.0.0.0-126.255.255.255,
128.0.0.0-223.255.255.255] or two IP addresses separated by ':'
(colon). (E.g.: 150.200.192.192 or 192.168.0.0:192.168.0.100)
PROF: Profile [NONE, 1..128]
DEF-LEASE: Default lease time of the IP address [60..1000000 sec.]
MAX-LEASE: Maximum lease time of the IP address [60..1000000 sec.]
16.3.1.3. DHCP Hosts table

The DHCP Hosts table can hold up to 500 definitions, indexed from 1 up to 500 hosts bindings.

The table of DHCP Hosts can be modified while the Abilis CPX is working without needing to restart it. Changes made on the table can be activated by executing the initialization command init res:dhcp.

The commands for the DHCP Hosts table management are:

d dhcp host:xxx[,yyy,...] : display DHCP host;

a dhcp host:xxx [par:val] : add DHCP host;

c dhcp host:xxx[,yyy,...] :clears DHCP host;

s dhcp host:xxx[,yyy,...] par:val [par:val]: set DHCP host parameters.

A complete list of available configuration parameters is available by typing d dhcp host: ?

[15:11:54] ABILIS_CPX:d dhcp host: ?

D DHCP HOST [MAC:] Display DHCP hosts table

DHCP Hosts parameters:

MAC: MAC address [00-00-00-00-00-01..FF-FF-FF-FF-FF-FF]
IP: IP address [0.0.0.0, 1-126.x.x.x, 128-223.x.x.x]
PROF: Profile [LAN, 1..128]
NAME: Host name. From 0 up to 32 ASCII characters.
Spaces are not allowed. Case is preserved.
16.3.2. Example of configuration of DHCP in Server mode

In this example the DHCP Server is configured to distribute the following parameters:

Network address: 192.168.0.0/24

IP pool of addresses: from 192.168.0.131 to 192.168.0.179

DNS server 1:192.168.0.232

DNS server 2:192.168.0.251

Default Gateway: 192.168.0.232

WINS server: 192.168.0.50

SMTP server: 192.168.0.250

POP3 server: 192.168.0.250

No static association between MAC-ADDRESS and any leased IP

ICMP checking of IP address

No MAC Filtering

First, set the dhcp resource active. To do so, issue the command:

[15:20:37] ABILIS_CPX:s p dhcp act:yes mode:server

COMMAND EXECUTED

[15:40:56] ABILIS_CPX:d p dhcp

RES:Dhcp - Not Saved (SAVE CONF), Not Refreshed (INIT) ------------------------
------------------------------------------------------------------------
DESCR:Dynamic_Host_Configuration_Protocol
LOG:DS ACT:YES srvport:67 cliport:68
msg-len:1472 mode:SERVER max-clients:300 ICMPCHK:NO
MAC-FILTER:NO
WDIR:C:\APP\DHCP\
Now let configure the DHCP Profiles table. This is done by typing:

[15:54:54] ABILIS_CPX:a dhcp prof:1 name:Private_LAN gw1:192.168.0.232 dns1:192.168.0.232 dns2:192.168.0.251 smtp:192.168.0.250 pop3:192.168.0.250 wins:192.168.0.50

COMMAND EXECUTED

[15:55:11] ABILIS_CPX:d dhcp prof

- Not Saved (SAVE CONF), Not Refreshed (INIT) ---------------------------------

PROF: |NAME:
-------------------------------------------------------------------------------
0 Default_profile
1 Private_LAN

[15:55:27] ABILIS_CPX:d dhcp prof:1

- Not Saved (SAVE CONF), Not Refreshed (INIT) ---------------------------------

Parameter: | Value:
-------------+-----------------------------------------------------------------
PROF: 1
NAME: Private_Lan
GW1: 192.168.000.232
DNS1: 192.168.000.232
DNS2: 192.168.000.251
SMTP: 192.168.000.250
POP3: 192.168.000.250
WINS1: 192.168.000.050
---------------------------------------------------
Now let's configure the DHCP Subnets table: we are going to insert the network address, the pool and the identifier of DHCP Profile to be used when assigning an IP from the pool. This is the command:

[16:02:17] ABILIS_CPX:a dhcp lan:1 name:Private_Lan net:192.168.0.0/24 pool1:192.168.0.131:192.168.0.179 prof:1

COMMAND EXECUTED

[16:03:22] ABILIS_CPX:d dhcp lan

- Not Saved (SAVE CONF), Not Refreshed (INIT) ---------------------------------

LAN: |NET: |MASK:
-------------------------------------------------------------------------------
1 192.168.000.000 255.255.255.000

[16:03:26] ABILIS_CPX:d dhcp lan:1

- Not Saved (SAVE CONF), Not Refreshed (INIT) ---------------------------------

Parameter: | Value:
-------------+-----------------------------------------------------------------
LAN: 1
NAME: Private_Lan
NET: 192.168.000.000/24
MASK: 255.255.255.000
POOL1: 192.168.000.131:192.168.000.179
PROF: 1
-------------------------------------------------------------------------------
Configuration of DHCP Hosts table is not required.

Now the configuration is complete.

Caution
To initialize the resource, use command init res:dhcp (to set act the changes made on uppercase parameters and in the tables) and save the configuration with save conf command to make the changes permanent.

Caution
To set act changes made on lowercase parameters a save conf and an Abilis restart are needed (i.e. with warm start command).

16.3.3. DHCP bindings table

The DHCP bindings table is the memory data base which stores bindings allocated for DHCP clients. A binding record includes the information about allocated IP address, start time and end time of lease, profile which is currently used by a DHCP client and some other information.

The Table of DHCP bindings is used in server mode only.

It is stored in the DHCP.BND file in the location defined by the WDIR parameter, that is by default the C:\APP\DHCP\ directory, and it allows storage of up to max-clients bindings, one per each record. Every one minute the DHCP server checks the bindings table in the memory and, if the table was changed since the last time it was updated, the DHCP server saves all bindings to the file.

During Abilis CPX DHCP resource start-up, the DHCP driver tries to read the bindings table from the CF. If the DHCP server finds the bindings file, it check wheter the file is can be updated, making a write operation try. If the writing attempt is successful the DHCP server goes to the ACTIVE state. If writing attempt fails the DHCP server goes to the STOP state; it writes a warning message into the System Log (i.e. "W: DHCP STOPPED") and it doesn't load the bindings DHCP.BND file content. If the DHCP server doesn't find the bindings file, it tries to create it. If it is not possible the server goes to the STOP state and it writes a warning message into the System Log (i.e. "W: DHCP STOPPED").

After loading the bindings from the DHCP.BND file, the DHCP server checks the bindings according to the current configuration of the DHCP driver and binding records that don't conform to the current configuration will be marked as "not valid" and they will not be used by the DHCP server.

The DHCP server makes the next checks of the loading bindings and marks the binding as "invalid" in all the following cases:

The subnet record which is coressponding to the IP address from the binding is not found in the subnets table.

The profile identifier from the binding is not found in the the profiles table.

If the binding is static (i.e. allocated from the hosts):

The host record with the IP and MAC addresses which are corresponding to the IP and MAC addresses from the loading binding is not found in the hosts table.

The IP address from the binding is found in one of the pools of the subnet record (i.e. if the corresponding subnet record was found).

if the binding is dynamic (i.e. allocated from the pools):

The host record with the IP and MAC addresses which are corresponding to the IP and MAC adresses from the loading binding is found in the hosts table;

The IP address from the binding is not found in one of the pools of the subnet record (i.e. if the corresponding subnet record was found).

Commands for handling DHCP bindings table are:

d dhcp bind: it displays DHCP bindings summary, in a synthetic format;

d dhcp binde: it display DHCP bindings details, in an extended format;

c dhcp bind: this command allows to remove a DHCP binding entry from the DHCP bindings table identified by the specified IP address.

Some examples follow.

[11:34:14] ABILIS_CPX:d dhcp bind

------------------+----------------+------+-----------------+------------------
MAC: |IP: |PROF: |Last request(GMT)|Expiry on(GMT)
------------------+----------------+------+-----------------+------------------
00-0C-6E-DE-2B-C1 192.168.000.002 1 27/12/2007 14:26 07/02/2036 06:28
00-0C-6E-E9-DE-29 192.168.000.003 1 27/12/2007 11:56 07/02/2036 06:28
00-0C-6E-DE-2C-15 192.168.000.005 1 28/12/2007 09:46 07/02/2036 06:28
00-08-54-01-D5-B7 192.168.000.006 1 05/10/2007 06:27 07/02/2036 06:28
00-40-CA-63-34-E5 192.168.000.008 1 28/12/2007 07:45 07/02/2036 06:28
00-48-54-13-23-E7 192.168.000.009 1 28/12/2007 10:22 07/02/2036 06:28
00-48-54-13-22-78 192.168.000.010 1 27/12/2007 12:45 07/02/2036 06:28
00-40-CA-63-34-6A 192.168.000.011 1 20/12/2007 09:46 07/02/2036 06:28
00-40-CA-63-34-CD 192.168.000.012 1 11/12/2007 15:49 07/02/2036 06:28
00-03-93-D9-71-94 192.168.000.014 1 28/12/2007 10:23 07/02/2036 06:28
00-08-54-02-00-78 192.168.000.024 1 12/12/2007 18:19 07/02/2036 06:28
00-40-CA-63-35-15 192.168.000.025 1 28/12/2007 07:16 07/02/2036 06:28
00-40-CA-63-34-E3 192.168.000.029 1 28/12/2007 08:57 07/02/2036 06:28
00-0C-6E-DE-2B-FD 192.168.000.030 1 28/12/2007 08:12 07/02/2036 06:28
00-40-CA-63-34-F2 192.168.000.032 1 28/12/2007 08:36 07/02/2036 06:28
00-40-CA-63-34-F8 192.168.000.033 1 28/12/2007 08:14 07/02/2036 06:28
00-0C-6E-DE-2B-C8 192.168.000.034 1 13/12/2006 11:33 07/02/2036 06:28
00-40-CA-63-34-82 192.168.000.035 1 28/12/2007 08:12 07/02/2036 06:28
00-40-CA-63-34-97 192.168.000.158 1 28/12/2007 07:45 28/12/2007 17:45
00-09-45-52-65-5B 192.168.000.161 1 28/12/2007 10:07 28/12/2007 20:07
00-09-45-52-10-44 192.168.000.166 1 28/12/2007 08:34 28/12/2007 18:34
00-07-85-51-F5-D6 192.168.000.171 1 28/12/2007 09:53 28/12/2007 19:53
00-40-CA-63-34-99 192.168.000.174 1 28/12/2007 09:45 28/12/2007 19:45

[11:34:21] ABILIS_CPX:d dhcp binde

----+-----+-------------------+-----------------+-------+----------------------
O: | ST: | MAC: | IP: | PROF: | Last request(GMT)
| Expiry on(GMT)
----+-----+-------------------+-----------------+-------+----------------------
H ACT 00-0C-6E-DE-2B-C1 192.168.000.002 1 27/12/2007 14:26:45
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-0C-6E-E9-DE-29 192.168.000.003 1 27/12/2007 11:56:22
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-0C-6E-DE-2C-15 192.168.000.005 1 28/12/2007 09:46:46
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-08-54-01-D5-B7 192.168.000.006 1 05/10/2007 06:27:24
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-40-CA-63-34-E5 192.168.000.008 1 28/12/2007 07:45:54
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-48-54-13-23-E7 192.168.000.009 1 28/12/2007 10:22:51
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-48-54-13-22-78 192.168.000.010 1 27/12/2007 12:45:53
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-40-CA-63-34-6A 192.168.000.011 1 20/12/2007 09:46:24
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-40-CA-63-34-CD 192.168.000.012 1 11/12/2007 15:49:57
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-03-93-D9-71-94 192.168.000.014 1 28/12/2007 10:23:08
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-08-54-02-00-78 192.168.000.024 1 12/12/2007 18:19:31
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-40-CA-63-35-15 192.168.000.025 1 28/12/2007 07:16:40
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-40-CA-63-34-E3 192.168.000.029 1 28/12/2007 08:57:33
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-0C-6E-DE-2B-FD 192.168.000.030 1 28/12/2007 08:12:27
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-40-CA-63-34-F2 192.168.000.032 1 28/12/2007 08:36:31
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-40-CA-63-34-F8 192.168.000.033 1 28/12/2007 08:14:59
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-0C-6E-DE-2B-C8 192.168.000.034 1 13/12/2006 11:33:52
07/02/2036 06:28:15
-------------------------------------------------------------------------------
H ACT 00-40-CA-63-34-82 192.168.000.035 1 28/12/2007 08:12:12
07/02/2036 06:28:15
-------------------------------------------------------------------------------
P EXP 00-0C-0C-01-5C-81 192.168.000.131 1 29/11/2007 10:59:42
29/11/2007 20:59:42
-------------------------------------------------------------------------------
P EXP 00-0C-0C-01-5B-BE 192.168.000.132 1 07/12/2007 10:17:12
07/12/2007 20:17:12
-------------------------------------------------------------------------------
P EXP 00-40-CA-63-34-B8 192.168.000.133 1 11/12/2007 21:58:05
12/12/2007 07:58:05
-------------------------------------------------------------------------------
P EXP 00-0C-29-52-67-31 192.168.000.134 1 17/12/2007 17:59:25
18/12/2007 03:59:25
-------------------------------------------------------------------------------
P EXP 00-16-36-EA-44-84 192.168.000.135 1 19/12/2007 10:10:38
19/12/2007 20:10:38
-------------------------------------------------------------------------------
P EXP 00-E0-4C-03-27-BC 192.168.000.136 1 18/12/2007 17:29:46
19/12/2007 03:29:46
-------------------------------------------------------------------------------
P EXP 00-0D-60-CE-7D-1D 192.168.000.150 1 07/11/2007 13:53:53
07/11/2007 23:53:53
-------------------------------------------------------------------------------
P EXP 00-E0-00-9B-D5-BB 192.168.000.151 1 08/08/2007 14:24:57
09/08/2007 00:24:57
-------------------------------------------------------------------------------
P EXP 00-07-95-BF-3A-7E 192.168.000.152 1 02/10/2007 10:36:55
02/10/2007 20:36:55
-------------------------------------------------------------------------------
P EXP 00-02-3F-0D-D5-A0 192.168.000.153 1 28/09/2007 07:22:33
28/09/2007 17:22:33
-------------------------------------------------------------------------------
P EXP 00-90-33-0F-02-EE 192.168.000.154 1 05/11/2007 18:18:39
06/11/2007 04:18:39
-------------------------------------------------------------------------------
P EXP 00-0F-20-CC-22-3C 192.168.000.155 1 17/10/2007 16:09:36
18/10/2007 02:09:36
-------------------------------------------------------------------------------
P EXP 00-16-6F-41-4B-EE 192.168.000.156 1 26/10/2007 13:42:41
26/10/2007 23:42:41
-------------------------------------------------------------------------------
P EXP 00-18-41-08-A0-74 192.168.000.157 1 25/10/2007 12:39:59
25/10/2007 22:39:59
-------------------------------------------------------------------------------
P ACT 00-40-CA-63-34-97 192.168.000.158 1 28/12/2007 07:45:26
28/12/2007 17:45:26
-------------------------------------------------------------------------------
P EXP 00-15-F2-03-06-4C 192.168.000.159 1 03/10/2007 08:01:28
03/10/2007 18:01:28
-------------------------------------------------------------------------------
P EXP 00-4F-4E-12-42-B9 192.168.000.160 1 19/11/2007 07:29:56
19/11/2007 17:29:56
-------------------------------------------------------------------------------
P ACT 00-09-45-52-65-5B 192.168.000.161 1 28/12/2007 10:07:13
28/12/2007 20:07:13
-------------------------------------------------------------------------------
P EXP 00-A0-D1-38-A4-14 192.168.000.163 1 07/09/2007 14:59:33
08/09/2007 00:59:33
-------------------------------------------------------------------------------
P EXP 00-16-D4-F2-06-A3 192.168.000.164 1 26/10/2007 15:32:37
27/10/2007 01:32:37
-------------------------------------------------------------------------------
P REL 00-40-8C-80-40-C2 192.168.000.165 1 23/11/2007 10:40:17
23/11/2007 10:42:40
-------------------------------------------------------------------------------
P ACT 00-09-45-52-10-44 192.168.000.166 1 28/12/2007 08:34:23
28/12/2007 18:34:23
-------------------------------------------------------------------------------
P EXP 00-03-93-D9-71-94 192.168.000.167 1 14/09/2007 06:40:59
14/09/2007 16:40:59
-------------------------------------------------------------------------------
P EXP 00-40-CA-63-34-C7 192.168.000.169 1 16/11/2007 10:00:05
16/11/2007 20:00:05
-------------------------------------------------------------------------------
P EXP 00-15-F2-59-09-7C 192.168.000.170 1 20/11/2007 15:31:45
21/11/2007 01:31:45
-------------------------------------------------------------------------------
P ACT 00-07-85-51-F5-D6 192.168.000.171 1 28/12/2007 09:53:45
28/12/2007 19:53:45
-------------------------------------------------------------------------------
P EXP 00-11-D8-70-A6-1D 192.168.000.172 1 30/08/2007 08:00:15
30/08/2007 18:00:15
-------------------------------------------------------------------------------
P EXP 00-0C-0C-01-48-AA 192.168.000.173 1 26/09/2007 12:34:27
26/09/2007 22:34:27
-------------------------------------------------------------------------------
P ACT 00-40-CA-63-34-99 192.168.000.174 1 28/12/2007 09:45:49
28/12/2007 19:45:49
-------------------------------------------------------------------------------
P EXP 00-0C-0C-01-48-BE 192.168.000.175 1 26/09/2007 12:33:29
26/09/2007 22:33:29
-------------------------------------------------------------------------------
P EXP 00-09-45-63-97-70 192.168.000.176 1 03/09/2007 11:54:48
03/09/2007 21:54:48
-------------------------------------------------------------------------------
P EXP 00-16-36-3E-1B-CB 192.168.000.177 1 16/11/2007 16:00:02
17/11/2007 02:00:02
-------------------------------------------------------------------------------
P EXP 00-1D-60-70-BE-1A 192.168.000.178 1 16/10/2007 08:24:22
16/10/2007 18:24:22
-------------------------------------------------------------------------------
P EXP 00-40-F4-BC-F5-3D 192.168.000.179 1 07/12/2007 13:54:03
07/12/2007 23:54:03
-------------------------------------------------------------------------------
Meaning of the most important parameters:

O
Origin of the binding [H: allocated from host tables; P: allocated from IP pools of one of subnets from subnets table; ?: origin unknown].

ST
State of the binding [REL: released; ACT:active, EXP: expired, ABD: abandoned, UNK: unknown (error state)].

MAC
The binded MAC address of the DHCP client.

IP
The IP address assigned to the DHCP client with the MAC address.

PROF
The identifier of DHCP profile from profiles table.

Last request(GMT)
The GMT date and time value when the lease was assigned/renewed the last time.

Expiry on(GMT)
The GMT date and time value when the lease will expire.

Binding records can also be cleared, however it should carefully evaluated by the user. The user interface allows to clear all the records currently present in the database in memory and/or to clear a specific record by specifying the IP address binded to the client. In both cases the user confirmation is requested before the command execution.

Here there are few samples of bindings clear commands:

[15:00:45] ABILIS_CPX:c dhcp bind ip:192.168.0.161

YOU ARE GOING TO DELETE THE SPECIFIED DHCP BINDING ENTRY FROM THE DATA BASE IN MEMORY.
DO YOU WANT TO PROCEES (Y/N)? Y

COMMAND EXECUTED
[15:00:45] ABILIS_CPX:c dhcp bind:a

YOU ARE GOING TO DELETE THE WHOLE CONTENT OF THE DHCP BINDINGS DATA BASE IN MEMORY.
DO YOU WANT TO PROCEES (Y/N)? Y

COMMAND EXECUTED
//-------------------------------------
The DNS Relay feature allows the system to appear as a DNS server to other IP stations while it simply forwards the requests to real DNS servers, and their responses are forwarded back to the original requesters.

The Abilis CPX DNS Resolver first requests the primary DNS Server. After 500 milliseconds, if it doesn't get any response, it forwards the same query to both primary and secondary server; if after 1 second, no response is received, another request is sent to both servers. In case of no answer, the same procedure is repeated after 1 second and after 2 seconds. If the DNS Resolver doesn't get any answer within 4 seconds, it terminates the procedure.

This procedure is repeated for a number of times equal to the value set in the RTY parameter. The delay (in seconds) between two subsequent queries can be set with the DELAY parameter.

The example below shows how to configure the DNS Resouce as Resolver.

[16:37:46] ABILIS_CPX:s p dns act:yes primary:62.94.0.1 secondary:62.94.0.2

COMMAND EXECUTED

[16:39:44] ABILIS_CPX:d p dns

RES:Dns - Not Saved (SAVE CONF), Not Refreshed (INIT) -------------------------
------------------------------------------------------------------------
Run DESCR:Domain_Name_System
LOG:NO ACT:YES
locport:53 SRCADD:R-ID (192.168.001.001) TOS:0-N
- Resolver -------------------------------------------------------------
PRIMARY:062.094.000.001 SECONDARY:062.094.000.002
DELAY:5 RTY:1
CACHE:NO cache-size:500
- Relay/Server ---------------------------------------------------------
RELAY:NO relay-size:500 RELAY-TOUT:10
SERVER:NO
IPSRC:* IPSRCLIST:#

Caution
To activate the changes made on the upper case parameters, execute the initialization command init res:dns.; while to set act the changes made on the lowercase parameters a save conf and an Abilis restart are required (i.e. with warm start command).

In the example above, CACHING is disabled (CACHE:NO). If CACHE:YES , when a DNS resolver (i.e. client) receives a DNS response, it caches the response for some time; this time depends on the size of the cache (cache-size parameter).
The DNS Relay feature allows the system to appear as a DNS server to other IP stations while it simply forwards the requests to real DNS servers, and their responses are forwarded back to the original requesters. So, when Abilis acts as DNS relay it actually acts as an “intermediate” between the requester and the real DNS servers.

The method is absolutely necessary when Abilis is used in a LAN as a router with NAT+PAT with a dial-up PPP connection. In this situation the address of DNS servers may not be known in advance because they are discovered at PPP connection establishment, and therefore they cannot be configured in the stations: the address of Abilis is configured instead, which in turn will forward the request to the DNS servers addresses obtained by PPP.

The method can also be used to simplify the configuration of the lan stations: lans are configured with the same address for both “default gateway” and “DNS server”, the CPX will forward the requests to the configured DNS which may be easily changed by the CPX administrator at any moment, and for all the stations.

The example below shows how to configure the DNS Resouce as Relay.

17.4.1. DNS Resource as Server

To configure the DNS Resouce as a Server type the following command:

[11:56:50] ABILIS_CPX:s p dns act:yes server:yes

COMMAND EXECUTED

[11:57:20] ABILIS_CPX:d p dns

RES:Dns - Not Saved (SAVE CONF), Not Refreshed (INIT) -------------------------
------------------------------------------------------------------------
DESCR:Domain_Name_System
LOG:NO ACT:YES
locport:53 SRCADD:R-ID (192.168.001.001) TOS:0-N
- Resolver -------------------------------------------------------------
PRIMARY:# SECONDARY:#
DELAY:5 RTY:1
CACHE:NO cache-size:500
- Relay/Server ---------------------------------------------------------
RELAY:NO relay-size:500 RELAY-TOUT:10
SERVER:YES
IPSRC:* IPSRCLIST:#
It is possible to filter the IP addresses allowed to the DNS service by combining the parameters IPSRC and IPSRCLIST.

In the following example, the “DNS_Allowed” list will be created and the range of IP from 192.168.1.10 to 192.168.1.50 will be added; otherwise, the address 192.168.1.100 will be set as the IP address Source.
DNS server can store up to 300 definitions (association between IP address and name): they are stored in the DNS table. The table can be displayed with the command d dns. By typing d dns ? command, it is possible to display the meaning of all the fields.

[10:44:46] ABILIS_CPX:d dns

Total records:0 Direct Lookup:0 Reverse Lookup:0 D&R Lookup:0

-------------------------------------------------------------------------------
ID: DIR: NAME: IP: TTL:
-------------------------------------------------------------------------------
*** NO DNS SERVER ENTRIES DEFINED ***
Meaning of the fields:

ID
DNS table entry identifier

DIR
Usage of the record [D (direct): domain names are translated into IP addresses; R (reverse): it is allowed the inverse lookup of the DNS record; DR (direct and reverse): the two features are allowed].

NAME
domain name.

IP
IP address.

TTL
The Time To Live sets the duration storage into a DNS cache system before it's considered expired.

The previous DNS records Table can be managed with these commands:

d dns : displays all Local DNS server table entries;

d dns filter:val [filter:val] : displays any Local DNS server table entry matching the specified filter(s);

a dns id:val name: ip: [par:val] : adds a Local DNS server table entry;

c dns id:val : clears a Local DNS server table entry;

s dns id:val [par:val] : sets parameters of a Local DNS server table entry.

Let's see an example of a DNS table configuration: let's assign to the IP addresses 192.168.1.20 and 192.168.1.30 the domain names john.lan and frank.lan; the first entry will be set as direct, while the second as "both" (direct+reverse).
//-------------------------------------
//-------------------------------------
//-------------------------------------
//-------------------------------------
//-------------------------------------
//
//-------------------------------------
// dns zone transfer: tcp--#53
// exchange database information between
// clients-servers
//
// dns relay:
// disabled: dsl router will handout the ip address of the isp iDNS
server address diretly to dhcp clients.
// enabled: gives the dhcp clients the router address for dns
// lookup and relay the request to isp dns servers.
// later the router will caching the response.
//
//
// |firewall, NAT, ACL...dns Proxy
// |
// clients----> dsl router -------> ISP dns server
// |
// router ip addr
|______>relay: sendto(isp_dns_ip)
<------recvfrom(isp_dns_ip)
//
// name ip time_t mac_addr AAA CNAME A
<--------reply to dns request.

//
//
// dproxy-nextgen dns proxy
// caching in a file (hasr disk)--cookie
// config.name_server_pnds[#]
// dns_req_t *head;
// timeout
// dns port; 53 (tcp, udp)
//------------------------------------
FILE *fp = fopen(config.cache_file, "r");
printf("%d, %s\n", __FUNCTION__, __LINE__);
int name_host_lookup(char *name) {
if (name == NULL || name[o] == '\0\)
return 0;
while (fgets(line, SIZE, fp)) {
host_ip = strtok(line, \t\r\n");
inet_aton(host_ip, &addr);
host_name = strtok(NULL, " \r\t\n");
if (host_name, strcasecmp(host_name, name)) {
strncpy(ip, host_ip, size);
fclose(fp);
return 1;
}
}
}

rewind(fp);
system("ping_connect");
// cache replace with same name
unlink(old_fp);
// configuration
const struct config_t conf[] = {
{},
{},
{0,0,0,0}

};
// dns_request_t *list
add_list(list **head, req_t)
new->next = (head)->next;
*head = new -malloc();
del_list()
find_list()
dns_read_packet(sock, req_t)
req->cnt = recvfrom(sock, m->buf, sz, 0, &sa, len);
memcpy(req->src_addr, &sa.sin_addr, sz);
req->port = ntohs(sa.sin_port);
req->cache = 0;
dns_decode_req(req_t);
dns_write_packet(sock, in_addr, port, req_t)
memset(&sa, 0, sz);
memcpy(&sa.sin_addr.s_addr, &in, sz);
sa.sin_port = htons(port);
sa.sin_family = AF_INET;
ret = sendto(sock, req->buf, sz, 0, &sa, sz);

int logg(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vsnprintf(tmp, len, fmt, ap);
va_end(ap);
}

is_dns_cache()
if(stat("/var/rmp/dns_cache", &stats) == 0)
return 1;
int if_fetch( *ife)
fd = socket(AF_IENT, SOCK_DGRAM, 0);
ioctl(ds, siocgifaddr, &ifr);
int dns_init()
socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ip.s_addr = INADDR_ANY;
sa.sin_famuly = AF_INET;
memcpy(&sa.sin_addr, &ip, sz);
sa.sin_port = htons(PORT);
bind();
FD_ZERO(&rfds);
FD_SET();
cache_purge();
int islocalhost(char *name)
fp = fopen(file, "r");
rewind(fp);
while(!feof(fp)) {
fscanf(fp, "", ip_name);
}
fclose(fp);
int dns_main_loop()
while (not_quit)
ret= select(sz, &rfds, 0, 0, &tv);
if (ret)
dns_read_packet(dns_sock, &req_t);
dns_handle_req(&m);
else
//resolv.conf
stat(..);
syslog(LOG_INFO, ..);

else // timeout
// resend to another name server from List:
dns_construct_err_reply();
dns_write_oacket();
dns_req_list = dns_req_list_remove(this one);
1G

int main()
signal(SIGHUP, sig_hup); ==> signal(SIGHUP, ); conf_load(file_name);
get_options();
dns_init();
config.daemon_mode();
dns_main_loop();











// linux kernel model driver
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) && \
(LINUX_VERSION_CODE < KERNEL_VERSION(2, 7, 0))
#include
#endif



//wake_up_interrutible(q)
//wait_event_interruptible_timeout(q,c,t)
//set_page_reserved(virt_to_vage(vpa))
//clear_page_reserved(virt_to_page(vpa))
// pci_get_device()
// pci_resources_start()
// pci_resources_flags()
// pci_resources_len()
// pci_enable_device()
// pci_disable_device()
release_region();
request_region();

MODULE_AUTHOR("aaa, aaa");
MODULE_DESCRIPTION(DEV_MODEL, " driver " VErSION);
MODULE_LICENSE("GPL");
MODULE_SU{PORTED_DEVICE(DEV_MODEl);

int gsc_irq_isr(int irq, void *dev_id, ISR_ARGs) {
handled = gsc_irq_isr_common(irq, dev_id);
return = handled ? IRQ_HANDLED : IRQ_NONE;

return (irq);
}

int gsc_proc_get_info(
char *page,
char **start,
off_t offset,
int count) {
i = gsc_proc_read(,,,,); ==> read_proc();
}

// hardware.c
// read(intr_ctrl_stat(device),
// intr contr register
// intr mask register
// intr status register
// config register








int no_of_ones(int n)
{
iny cnt=0;
while(n>0)
{
if(n&1)
cnt++;
n=n>>1;
}
return cnt;
}



int bitcount (unsigned int n) {
int count = 0 ;
while (n) {
count++ ;
n &= (n - 1) ;
}
return count ;
}




trie:
prefix tree---suffix trie

Delve Networks » Data Structures Ideas Object Oriented Design
Tom on July 17, 2009 | Question #173669 (Report Dup) | Edit | History
You have more than 3 million entries of phone numbers. You have to create a phone book just like the one we have on the new phones these days. You type the name, and the numbers that match the letters you typed shows up on your phone.

For e.g: When you type 'K' all numbers under K appear,then you say "i"...all numbers under "Ki" appear..so on and so forth.

How will you design/architecture this type of search? Discuss data structures you would use whats the worst case for your design?


i think this question has already been asked in other threas...i guess the best solution from the context of efficiency is to use suffix trees and hence TRIE...they do exactly the same thing as what we are looking for...hope this helps. thankx



Introduction

Trie is an ordered tree data structure that uses strings as keys. Unlike Binary Trees, Tries do not store keys associated with the node. The key is actually determined based on the position of the node on the tree. Any descendants of a node shares a common prefix of the key string associated with that node. Hence, trie is also called as Prefix Tree. The word "trie" comes from Retrieval, and it is pronounced as "try". To read more about Trie click here.

Since this data structure is a prefix tree, trie is commonly used in Dictionaries, Phone Directories and matching algorithms. Trie is best-suited for phone directory (any matching application for that matter) because it is very efficient in matching strings.

So I have decided to implement Trie myself in C#. I have created three classes:

Node: Represents a single tree node;
NodeCollection: Represents the children of a node;
Trie: Trie implementation to insert and search nodes.
Implementation

Node: Node represents a basic tree node. Node implements both Depth First and Breadth First algorithms to search its children. It also contains its Parent node and Children node. Node has a key and a Value. Key contains the single character and the value has the actual value of the node. The actual key of the node will be determined by suffixing the single character to its parent's key. Node has a special property called IsTerminal. This property is set to true if the key or a value represents a complete string. See the picture below:





//Inserts Names into the Trie data structure
public static Node InsertNode(string name, Node root)
{
//Is name null?
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException("Null Key");

//set the index, start inserting characters
int index = 1;

//key
string key;

//start with the root node
Node currentNode = root;

//loop for all charecters in the name
while (index <= name.Length)
{
//get the key character
key = name[index - 1].ToString();

//does the node with same key already exist?
Node resultNode = currentNode.Children.GetNodeByKey(key);

//No, this is a new key
if (resultNode == null)
{
//Add a node
Node newNode = new Node(key, name.Substring(0, index));
//If reached the last charaecter, this is a valid full name
if (index == name.Length)
newNode.IsTerminal = true;

//add the node to currentNode(i.e. Root node for the first time)
currentNode.Children.Add(newNode);

//set as the current node
currentNode = newNode;
}
else
{
//node already exist, set as tghe current node
//and move to the next character in the name
currentNode = resultNode;
}

//move to the next character in the name
index++;
}

//all done, return root node
return root;
}
The Insert method inserts the string as one character at a time. It starts with the first character; if the first character doesn't already exist in the root node it adds a new node with the new character and returns the new node. Otherwise it returns the node with the fist character for adding remaining characters. It loops until it adds the entire string. Once it reaches the last character, it marks that node as a terminal node because this node represents a complete string in the tree hierarchy.

The Find methods is implemented by Depth First search algorithm. The tree is searched until the complete string is found. Below is the code.

Collapse
//Find a node given the key("Jo")

public static bool Find(Node node, string key)
{
//Is key empty
if (string.IsNullOrEmpty(key))
return true;//terminal Node


//get the first character
string first = key.Substring(0, 1);

//get the tail: key - first character
string tail = key.Substring(1);

Node curNode = node.Children.GetNodeByKey(first);

//loop until you locate the key i.e. "Jo"
if (curNode != null)
{
return Find(curNode, tail);
}
else
{
//not found, return false
return false;
}
}
I've attached the entire source code above. The source code contains the Trie class library and a console application to test the Trie library. The console application loads a set of names (stored in names.txt in debug folder) in to the tree and provides options to run Depth First & Breadth First algorithm. The application also provides options for Directory Look-Up and Find option.

The class library can be further used to develop a web based phone directory. The data can also be stored on the client (it is too small) and the Trie can be implemented in JavaScript.

Happy Coding,
Madhu





//============

#include
#include
#include
using namespace std;

class name {
string str;
public:
name() {
str = "";
}
name(string s) {
str = s;
}
string get() {
return str;
}

};


bool operator<(name a, name b) { // Define less than relative to name objects.
return a.get() < b.get();
}

class phoneNum {
string str;
public:
phoneNum() {
str = "";
}
phoneNum(string s) {
str = s;
}
string get() {
return str;
}
};


int main()
{
multimap directory;

directory.insert(pair(name("T"), phoneNum("555-4533")));
directory.insert(pair(name("T"), phoneNum("555-9999")));
directory.insert(pair(name("C"), phoneNum("555-9678")));

string str;
cout << "Enter name: ";
cin >> str;

multimap::iterator p;

p = directory.find(str);
if(p != directory.end()) {
do {
cout << "Phone number: " << p->second.get();
cout << endl;
p++;
} while(p != directory.upper_bound(str));
}
else
cout << "Name not in directory.\n";

return 0;
}






//=====4==

#include
#include
using namespace std;

int main()
{
map mapObject;
int i;

for(i = 0; i <10; i++) {
mapObject.insert(pair('A'+i, i));
}

char ch;
cout << "Enter key: ";
cin >> ch;

map::iterator p;

p = mapObject.find(ch);
if(p != mapObject.end())
cout << p->second;
else
cout << "Key not in map.\n";

return 0;
}

//======5===============

#include
#include
#include
using namespace std;

class StringClass {
char str[20];
public:
StringClass() {
strcpy(str, "");
}
StringClass(char *s) {
strcpy(str, s);
}
char *get() {
return str;
}
};

// must define less than relative to StringClass objects
bool operator<(StringClass a, StringClass b)
{
return strcmp(a.get(), b.get()) < 0;
}

class opposite {
char str[20];
public:
opposite() {
strcmp(str, "");
}
opposite(char *s) {
strcpy(str, s);
}
char *get() {
return str;
}
};


int main()
{
map mapObject;

mapObject.insert(pair(StringClass("yes"), opposite("no")));
mapObject.insert(pair(StringClass("good"), opposite("bad")));
mapObject.insert(pair(StringClass("left"), opposite("right")));
mapObject.insert(pair(StringClass("up"), opposite("down")));

char str[80];
cout << "Enter word: ";
cin >> str;

map::iterator p;

p = mapObject.find(StringClass(str));
if(p != mapObject.end())
cout << "Opposite: " << p->second.get();
else
cout << "Word not in map.\n";

return 0;
}

//===6=====

#include
#include
using namespace std;
int main()
{
map mapObject;
int i;
for(i = 0; i < 26; i++)
mapObject.insert(pair('A' + i, 65 + i));
map::iterator p;
for(p = mapObject.begin(); p != mapObject.end(); p++) {
cout << p->first << " has ASCII value of ";
cout << p->second << endl;
}
return 0;
}



#include
#include
using namespace std;

int main()
{
map mapObject;
int i;

for(i = 0; i < 26; i++)
mapObject.insert(pair('A' + i, 65 + i));

char ch;
cout << "Enter key: ";
cin >> ch;

cout << "Its ASCII value is " << mapObject[ ch ];

return 0;
}






#include
#include
using namespace std;

int main()
{
map mapObject;
pair::iterator, bool> res;

res = mapObject.insert(pair('A', 65));
if(res.second)
cout << "Insertion occured.\n";

res = mapObject.insert(pair('A', 99));
if(!res.second)
cout << "Duplicate not allowed.\n";

map::iterator p;

p = mapObject.find('A');
cout << "Its ASCII value is " << p->second;

return 0;
}










#include
#include
#include
#include
using namespace std;

int main()
{
map > mapObject;

mapObject["A"] = 20;
mapObject["B"] = 19;
mapObject["C"] = 10;

map >::iterator p;

for(p = mapObject.begin(); p != mapObject.end(); p++) {
cout << p->first << " has value of ";
cout << p->second << endl;
}

return 0;
}




#include
#include
#include
using namespace std;

int main()
{
multimap names;
string n;

names.insert(pair("Z", "F"));
names.insert(pair("Z", "A"));

names.insert(pair("S", "T"));
names.insert(pair("S", "A"));
names.insert(pair("S", "J"));

names.insert(pair("D", "H"));
names.insert(pair("D", "W"));
names.insert(pair("D", "R"));

multimap::iterator p;

cout << "Enter last name: ";
cin >> n;

p = names.find(n);
if(p != names.end()) { // found a name
do {
cout << n << ", " << p->second;
cout << endl;
p++;
} while (p != names.upper_bound(n));
}
else{
cout << "Name not found.\n";
}
return 0;
}






#include
#include
using namespace std;

int main()
{
map mapObject;
int i;

for(i = 0; i <26; i++) {
mapObject.insert(pair('A'+i, 65+i));
}

char ch;
cout << "Enter key: ";
cin >> ch;

map::iterator p;

p = mapObject.find(ch);
if(p != mapObject.end())
cout << "Its ASCII value is " << p->second;
else
cout << "Key not in map.\n";

return 0;
}



#include
#include
#include
using namespace std;

int main()
{
map directory;

directory.insert(pair("T", "4444"));
directory.insert(pair("C", "9999"));
directory.insert(pair("J", "8888"));
directory.insert(pair("R", "0000"));

string s;
cout << "Enter name: ";
cin >> s;

map::iterator p;

p = directory.find(s);
if(p != directory.end())
cout << "Phone number: " << p->second;
else
cout << "Name not in directory.\n";

return 0;
}



#include
#include
#include
#include
using namespace std;

int main()
{
map hist;

ifstream in( "inFile" );

string word;
while ( in >> word )
hist[ word ]++;

in.close();

typedef map::const_iterator CI;
for ( CI iter = hist.begin(); iter != hist.end(); ++iter )
cout << iter->first << '\t' << iter->second << endl;
return 0;
}






Dictionary (data structure)
In computing, an associative array, also known as a map or table, is an abstract data type very closely related to the mathematical concept of a function. Conceptually, an associative array is composed of a collection of keys and a collection of values, and each key is associated with one value. The operation of finding the value associated with a key is called a lookup or indexing, and this is the most important operation supported by an associative array. The relationship between a key and its value is sometimes called a mapping or binding. For example, if the value associated with the key "bob" is 7, we see say that our array maps "bob" to 7.
The operations that are usually defined for an associative array are:

Add: Bind a new key to a new value
Reassign: Bind an old key to a new value
Remove: Unbind a key from a value and remove it from the key set
Lookup: Find the value (if any) that is bound to a key
Examples

One can think of a telephone book as an example of an associative array, where names are the keys and phone numbers are the values. Another example would be a dictionary where words are the keys and definitions are the values. A database is a sort of generalized associative array.

Need more examples

Data Structures for Associative Arrays

Associative arrays are usually used when lookup is the most frequent operation. For this reason, implementations are usually designed to allow speedy lookup, at the expense of slower insertion and a larger storage footprint than other data structures (such as association lists).

Efficient Representations

There are two main efficient data structures used to represent associative arrays, the hash table and the self-balancing binary search tree. Relative advantages and disadvantages include:
Hash tables have faster average lookup and insertion time (O(1)), while balanced binary trees have faster worst-case lookup and insertion time (O(log n) instead of O(n)). These make trees more useful in real-time and interactive systems, and hash tables more useful for very large arrays.
Hash tables have more compact storage for small value types, especially when the values are bits.
There are simple persistent versions of balanced binary trees, which are especially prominent in functional languages.
Building a hash table requires a good hash function for the key type, which can be difficult to write, while balanced binary trees only require a less-than operator on the keys.
Balanced binary trees allow one to efficiently iterate over the keys in order, a highly expensive feat for a hash table.
Balanced binary trees can be easily adapted to efficiently assign a single value to a large ordered range of keys.
Association Lists

A simple but generally inefficient type of association map is an association list, which simply stores a list of key/value pairs, and each lookup scans through the list looking for a key match. Strong advantages of association lists include:

No knowledge is needed about the keys, such as an order or a hash function.
For small associative arrays, common in some applications, association lists can take less time and space than other data structures.
Insertions are worst-case constant time.
The disadvantage, however, is that remove and lookup operations take O(n) worst-case and average time. In particular, looking up a key which is not present will scan the entire list. This particular case can be mitigated by storing the list in sorted order, but this destroys constant-time insertion.
Specialized Representations

If the keys have a specific type, one can often use specialized data structures to gain performance. For example, integer-keyed maps can be implemented using Patricia trees or Judy arrays, and are useful space-saving replacements for sparse arrays. Because this type of data structure can perform longest-prefix matching, they're particularly useful in applications where a single value is assigned to most of a large range of keys with a common prefix except for a few exceptions, such as in routing tables.

String-keyed maps can avoid extra comparisons during lookups by using tries.

Language Support

Associative arrays are known by many names in different programming languages. In Smalltalk and Python they are called dictionaries; in Perl they are called hashes; in Java they are called hashmaps [1] and in Common Lisp they are called hash tables. "Hash table" is also the name of the most common data structure used to store an associative array. In the scripting language Lua, associative arrays, called tables, are used as the primitive building block for all data structures, even arrays.

Associative arrays can be implemented in any programming language, and one or more implementations of them is typically found either built into the language or the standard library distributed with it (C is a noticeable exception, as neither the language nor the standard library directly provide one. It is not difficult to write one in C, though).

In Smalltalk

In Smalltalk a dictionary is used:

phonebook := Dictionary new. phonebook at: 'Sally Smart' put: '555-9999'. phonebook at: 'John Doe' put: '555-1212'. phonebook at: 'J. Random Hacker' put: '553-1337'.

To access an entry the message #at: is sent to the dictionary object. phonebook at: 'Sally Smart' gives '555-9999'

In C++

C++ also has a form of associative array called std::map. One could create a map with the same information as above using C++ with the following code:
#include #include

int main() { std::map phone_book; phone_book["Sally Smart"] = "555-9999"; phone_book["John Doe"] = "555-1212"; phone_book["J. Random Hacker"] = "553-1337"; return 0; }

In C++, std::map allows keys and values to be different data types, but all of the keys in a particular map must be of the same base type. The same must be true for all of the values. Although std::map is typically implemented using a self-balancing binary search tree, the SGI STL also provides a std::hash_map which has the algorithmic benefits of a hash table.

In Lisp

In Lisp and Scheme, association lists are commonly used, as in the following S-expression:

'(("Sally Smart" . "555-9999") ("John Doe" . "555-1212") ("J. Random Hacker" . "553-1337"))

The syntax (x . y) is used to indicate a pair. Keys and values need not be the same type within an alist. Lisp and Scheme provide operations to manipulate alists in ways similar to associative arrays.



class BSTNode {
private:
int value;
BSTNode* left;
BSTNode* right;
public:
BSTNode(int value) {
this->value = value;
left = NULL;
right = NULL;
}
};

class BinarySearchTree {
private:
BSTNode* root;
public:
BinarySearchTree() {
root = NULL;
}
};

bool BinarySearchTree::add(int value) {
if (root == NULL) {
root = new BSTNode(value);
return true;
} else
return root->add(value);
}

bool BSTNode::add(int value) {
if (value == this->value)
return false;
else if (value < this->value) {
if (left == NULL) {
left = new BSTNode(value);
return true;
} else
return left->add(value);
} else if (value > this->value) {
if (right == NULL) {
right = new BSTNode(value);
return true;
} else
return right->add(value);
}
return false;
}




bool BinarySearchTree::search(int value) {
if (root == NULL)
return false;
else
return root->search(value);
}

bool BSTNode::search(int value) {
if (value == this->value)
return true;
else if (value < this->value) {
if (left == NULL)
return false;
else
return left->search(value);
} else if (value > this->value) {
if (right == NULL)
return false;
else
return right->search(value);
}
return false;
}
bool BinarySearchTree::remove(int value) {
if (root == NULL)
return false;
else {
if (root->getValue() == value) {
BSTNode auxRoot(0);
auxRoot.setLeftChild(root);
BSTNode* removedNode = root->remove(value, &auxRoot);
root = auxRoot.getLeft();
if (removedNode != NULL) {
delete removedNode;
return true;
} else
return false;
} else {
BSTNode* removedNode = root->remove(value, NULL);
if (removedNode != NULL) {
delete removedNode;
return true;
} else
return false;
}
}
}

BSTNode* BSTNode::remove(int value, BSTNode *parent) {
if (value < this->value) {
if (left != NULL)
return left->remove(value, this);
else
return NULL;
} else if (value > this->value) {
if (right != NULL)
return right->remove(value, this);
else
return NULL;
} else {
if (left != NULL && right != NULL) {
this->value = right->minValue();
return right->remove(this->value, this);
} else if (parent->left == this) {
parent->left = (left != NULL) ? left : right;
return this;
} else if (parent->right == this) {
parent->right = (left != NULL) ? left : right;
return this;
}
}
}

int BSTNode::minValue() {
if (left == NULL)
return value;
else
return left->minValue();
}



#! /usr/bin/perl

# word frequency count

while(<>) { # iterate over lines in named file
tr/A-Za-z/ /cs; # remove punctuation
foreach $word (split(' ', lc $_)) { # each word in line, lc is lowercase
$freq{$word}++; # increment frequency count for word
}
}
foreach $word (sort keys %freq) { # sort words found
print "$word $freq{$word}\n"; # print word with its frequency
}





int a[] = {1,2,3,4,5};
Binarysearch(a[],low,high,key)
{
mid = (low+high)/2

if(a[mid] == key)
return TRUE;
else if(a[mid] > key)
Binarysearch(a[],low,mid,key);
else
Binarsearch( a[],mid,high,key);
}


for sure it could be legal.
===================================
int gg=0;

int& function()
{
return gg;
}

int main()
{
function()=6;
std::cout<return 0;
}

Reply to Comment

Reservoir Sampling
A simple random sampling strategy to produce a sample without replacement from a stream of data - that is, in one pass: O(N)

Want to sample s instances - uniformly at random without replacement - from a population size of n records, where n is not known.

Figuring out n would require 2 passes. Reservoir sampling achieves this in 1 pass.
A reservoir R here is simply an array of size s. Let D be data stream of size n

Algorithm:

R[s];
Store first s elements into R.
for each element in position k = s+1 to n ,
accept it with probability s/k
if accepted, choose a random element from R to replace. // replace R[rand()/s]: srand(time);
Partial analysis:

Base case is trivial. For the k+1st case, the probability a given element i with position <= k is in R is s/k. The prob. i is replaced is the probability k+1st element is chosen multiplied by i being chosen to be replaced, which is: s/(k+1) * 1/s = 1/(k+1), and prob that i is not replaced is k/k+1.

So any given element's probability of lasting after k+1 rounds is: (chosen in k steps, and not removed in k steps)

= s/k * k/(k+1), which is s/(k+1).

So, when k+1 = n, any element is present with probability s/n.

Distributing Reservoir Sampling

It is very simple to distribute the reservoir sampling algorithm to n nodes.

Split the data stream into n partitions, one for each node. Apply reservoir sampling with reservoir size s, the final reservoir size, on each of the partitions. Finally, aggregate each reservoir into a final reservoir sample by carrying out reservoir sampling on them.

Lets say you split data of size n into 2 nodes, where each partition is of size n/2. Sub-reservoirs R1 and R2 are each of size s.

Probability that a record will be in sub-reservoir is:
s / (n/2) = 2s/n

The Probability that a record will end up in the final reservoir given it is in a sub-reservoir is: s/(2s) = 1/2.

It follows that the probability any given record will end up in the final reservoir is:
2s/n * 1/2 = s/n


ShiftArray(char *arr, int index) {
for(int i = index; arr[i] != '\0'; i++) {
Swap(arr[i-index],arr[i]);
}
}

void shift(char str[], int i) {
if (i <= 0) return; // no op


int len = strlen(str);



if (i >= len) return; // no op



char* tmp = new char[i];



strncpy(tmp, str, i);



str[0] = 'c';



for (int j = i; j < len; ++j) str[j - i] = str[j];



strncpy(str + len - i, tmp, i);
delete[] tmp;
cout << str << endl;
}
#include
#include

int main() {

char *p = "12345";
char p1[] = "34567";

printf("p = %d, p = %d, p1=%d, p1=%d\n", sizeof(p), strlen(p),
sizeof(p1), strlen(p1));

}
#include

int faindLevel(TREE *t, int levelCOunt, int data) {
int left, right;
if (!t)
return -1;

if (t->data == data)
return 1;
else {
left = findLevel(t->left, level, data);
right = findLevel(t->right, leve, data);
return (left== -1) right : left;
}

}
#include
#include

int main () {
char ss[30] = "12345";
char tt[40] = "12345\0";
char aa[] = "1234567";
char bb[] = "1234567\0";
printf("ss=%d, tt=%d, aa=%d, bb=%d\n",
sizeof(ss), sizeof(tt),
sizeof(aa),
sizeof(bb));

printf("strlen, ss=%d, tt=%d, aa=%d, bb=%d,\n",
strlen(ss),
strlen(tt),
strlen(aa),
strlen(bb)
);

// 30 40 8 9
// 5 5 7 7
}
#include
#include
int main () {
int i = 0;
char x[6] = "1234567890";
char a[] = "1234567890";
char *p = "123456789012";
char *p2;

// 11 8 8 6
printf("sizeof a=%d, p=%d p2=%d, x=%d\n",
sizeof(a), sizeof(p),
sizeof(p2),
sizeof(x)
);

// 1 2 3 4 5 6 ? ? ? ?
for (i = 0; i < 10; i++) {
printf("x[%d] = %c\n", i, x[i]);
}

return 0;
}
#include
#include

typedef struct ss_s {
int x;
float y;
} ss_t;

ss_t ff[10];



int main() {

// LP: 8B
// 8, 80 8 B
// *ff = ff[0]
printf(" ff=%d, size=%d, y=%d, \n", sizeof(ss_t), sizeof(ff), sizeof(*ff));



return 0;

}
#include
#include

int main() {
char *str = "";
char *str1 = "a";

char str2[] = "ab";

// pointer type:
// 8 0
// 8 1
printf("sizeof=%d, strlen=%d\n", sizeof(str), strlen(str));
printf("sizeof=%d, strlen=%d\n", sizeof(str1), strlen(str1));

// 3 and 2
// str3[] is an array: init to 3 B spaces.
printf("sizeof=%d, strlen=%d\n", sizeof(str2), strlen(str2));


// 7 and 4
// srt4 is array.
char str4[7] = "abcd";
printf("sizeof=%d, strlen=%d\n", sizeof(str4), strlen(str4));

// 7 and 7
char str5[7] = "abcd123";
printf("sizeof=%d, strlen=%d\n", sizeof(str5), strlen(str5));



// 7 and 7
char str6[7] = "abcd1234";
printf("sizeof=%d, strlen=%d\n", sizeof(str6), strlen(str6));

// 1 and 7
char str7[1] = "abcd1234";
printf("sizeof=%d, strlen=%d\n", sizeof(str7), strlen(str7));

// 0 and 6
char str8[0] = "abcd123";
printf("sizeof=%d, strlen=%d\n", sizeof(str8), strlen(str8));
return 0;

}
#include

/**
# no need level arg;
# BFSearch, DFsearch
# use queue qt;
# use stack st do the tracing
*/

// THIS IS BFS
int faindLevel(TREE *t, int data) {
int level = 0;
int left, right;

if (!t)
return -1;
if (t->data == data)
return 1;
else {
left = findLevel(t->left, data);
right = findLevel(t->right, data);
level++;
return (left== -1) right : left;
}

}


// BFS
int getDepth(node *t, int x) {
queue q;
q.push(t);

int i = 0;

do {
if (q.front->value >= x) return (int)log2(i+1);

if (q.front->left) q.push(q.front()->left);

if (q.front->right) q.push(q.front()->right);

q.pop();
++i;
} while(!q.empty());

return -1;

}


//=========================
void link(node* root) {
queue q;
node* cur = root;
q.push(root);
q.push(NULL);
do {
cur = q.front();
q.pop();

if (cur) {
cur->adj = q.front();
if (cur->left) q.push(cur->left);
if (cur->right) q.push(cur->right);
} else {
if(q.front() == NULL) return;
q.push(NULL);
}
} while (!q.empty());
}


// remove dup node ina list
void remove_dup(node *cur) {
if (cur) {
node *tmp = cur->next;
if (tmp && cur->value = tmp->value)
cur->next = tmp->next,
delete tmp,
remove_dup(cur);
else
remove_dup(cur->next);
}
}
// 1-2-3-3-3-4-4-5-5-6-6
// ==> 1-2
// p--cur--nn
node * remove_dup() {
if (!head) returnn NULL;

node *p = NULL;
node *cur = head;
node *nn = cur->next;

while (cur) {
nn = cur->next;

val = cur->value;
while (nn) {
if (val == nn->value) {
tmp = nn;
cur->next = nn->next;
nn = nn->next;
free(tmp);
flag = 1;
}
else {
break;
}
}
if (flag) {
p->next = cur->next;
free(cur);
cur = nn;
} else {
p = cur;
cur = cur->next;
}


}
return head;
}



// 1-2-3-3-3-4-5 ==> 1-2-3-4-5
remove()
{
cur1 = head;
while (cur1) {
val = cur1->value;
cur2 = cur1->next;
while (cur2) {
if (val == cur2->value) {
tmp = cur2;
cur2 = cur2->next;
free(tmp);
}
}

cur1 = cur1->next;
}
}

}

// correct one
void RemoveDuplicated(node* HEAD){
node* previous_node=HEAD;
node* current_node = HEAD->next;
node* tmp_node=NULL;
bool just_deleted = false;

while(current_node){
tmp_node = current_node->next;
if(tmp_node && current_node->value == tmp_node->value){
current_node->next = tmp_node->next;
delete tmp_node;

just_deleted = true;
}
else {
if(just_deleted){
//delete current node
previous_node->next = current_node->next;
delete current_node;
current_node = previous_node->next;

just_deleted = false;
}
previous_node = current_node;
current_node = current_node->next;

}
}

No comments:

Post a Comment