/usr/sbin/pppd connect '/usr/sbin/chat -v -f /etc/ppp/chat-isp ' \ user marco_corvi@oocities.com -d -detach &
ABORT "NO CARRIER" ABORT "NO DIALTONE" ABORT "ERROR" ABORT "NO ANSWER" ABORT "BUSY" ECHO OFF SAY "Dialing your ISP ... \n" "" "at" OK "atz1" OK "atdt<ISP_NUMBER>" TIMEOUT 60 SAY "Waiting up to one minute ... \n" ECHO ON CONNECT ""
/sbin/ifconfig ppp_interface
Finally pppd uses an configuration file, /etc/ppp/options, which specifies
all the other options. Here is an example,
# /etc/ppp/options
#
/dev/cua1 # device (should try /dev/ttyS1)
# /dev/modem
57600 # speed (try 115200 !!!)
debug # debugging messages
lock # lock the device
modem # use modem control lines (CD): this is the default
# local # do not use modem contro lines (ignore CD)
hide-password # do not show password in syslog
logfile /etc/ppp/ppp.log # logfile for stat purposes
# record /etc/ppp/ppp.rec # record file for pppdump (must try)
crtscts # hw flow control
defaultroute # `route add default`
noipdefault # () disable local ip from hostname: peer must supply it
# see local_ip_address:remote_ip_address option
# usepeerdns # use if the provider does not supply DNS
# see /etc/resolv.conf
# allow-ip * # allow any ip_addr for the peer (w/o authentication)
asyncmap 0 # () no obsolete byte escaping
# mtu 552 # (can leave it disabled)
# mru 552 # (can leave it disabled: default 1500)
idle 180 # disconnect if we do not do anything for three minutes
deflate 15,15 # request peer deflate compresion (value range 8-15)
# must have kernel module for BSD compression
bsdcomp 15,15 # request peer bsd compression (value range 9-15, 15 max)
# pppd second choice (see man pppd)
# must have kernel module for BSD compression
predictor1 # request peer predictor-1 compression
# no effect unless kernel module supported
vj-max-slots 16 # number of VJ TCP/IP header compression slots (max 16)
Last the /etc/ppp/pap-secrets file should contain your login data
(so it should be readable only by root),
# Secrets for authentication using PAP # client server secret IP addresses marco_corvi@oocities.com * my_password
To terminate the connection send a SIGHUP to the pppd deamon,
kill -HUP ppd_pid
The network implementation does not strictly follow this model.
TCP provides initialization of a connection (three way handshake),
finilazation (FIN-ACK), and control.
TCP is session aware (logical ports).
IP provides fragmentation of long segments, and machine to machine
routing with the IP address system.
Finally ethernet encapsulates packets with their physical (MAC) address.
sock_setsockopt commands
SO_ATTACH_FILTER and SO_DETACH_FILTER are conditioned to it (see net/core/sock.c).
These act on the socket's sock.
The first copies the filter code from userspace in a temporary
sock_fprog, and calls sk_attach_filter.
The second sets to NULL the sock's filter, and calls
sk_filter_realease to free the filter:
this does some sock bookkeeping, and free the filter if its ref-count drops
to 0 (see include/net/sock.h).
sock_filter structure, which
is exactly as described in the paper:
16 bits of opcode, 8 bits of jump true, 8 of jump false, and 32 bits of multiuse field.
A filter program sock_fprog is an array of instructions:
it contains the len of the filter and a pointer to the instructions.
Finally a kernel sk_filter is a sock_fprog with prepended
a refcnt.
| Instrcution code | BPF_LD | load in A register | A = k, A = M[k], A = P[k], A = P[X=k] |
| BPF_LDX | load in X (index) register | X = k, X = M[k], X = len, X = 4*(P[k]&0xf) | |
| BPF_ST | store A register in scratch memory | M[k] = A | |
| BPF_STX | store X (index) register in scratch memory | M[k] = X | |
| BPF_ALU | perform arithmetical operations | A = A+k, A = A-k, A = A*k, A = A/k, A = A&k, A = A|k, A = A<<k, A = A>>k, A = A+X, A = A-X, A = A*X, ..., A = -A | |
| BPF_JMP | jump instructions | ... | |
| BPF_RET | return the number of accepted bytes | ret A, ret k | |
| BPF_MISC | miscellaneous instruction | X = A, A = X | |
| size | BPF_W | word (32 bits) | |
| BPF_H | half-word (16 bits) | ||
| BPF_B | byte (8 bits) | ||
| addressing mode | BPF_IMM | constant | |
| BPF_ABS | absolute packet offset | ||
| BPF_IND | relative packet offset | ||
| BPF_MEM | from scratch memory | ||
| BPF_LEN | packet length | ||
| BPF_MSH | ... | ||
| arithmetical operations | BPF_ADD | addition | A = A + k, A = A + X |
| BPF_SUB | subtraction | A = A - k, A = A - X | |
| BPF_MUL | multiplication | A = A * k, A = A * X | |
| BPF_DIV | division | A = A / k, A = A / X | |
| BPF_OR | bitwise or | A = A | k, A = A | X | |
| BPF_AND | bitwise and | A = A & k, A = A & X | |
| BPF_LSH | left shift | A = A << k, A = A << X | |
| BPF_RSH | right shift | A = A >> k, A = A >> X | |
| BPF_NEG | negative | A = - A | |
| jump instructions | BPF_JA | jump | pc += k |
| BPF_JEQ | jump if equal | pc += (A==k)? jt : jf pc += (A==X)? jt : jf |
|
| BPF_JGT | jump if greater | pc += (A>k)? jt : jf pc += (A>X)? jt : jf |
|
| BPF_JGE | jump if greater or equal | pc += (A>=k)? jt : jf pc += (A>=X)? jt : jf |
|
| BPF_JSET | jump if in set | pc += (A & k) ? jt : jf pc += (A & X) ? jt : jf |
|
| registers | BPF_K | constant | |
| BPF_X | index register | ||
| BPF_A | accumulator register | ||
| exchange instructions | BPF_TAX | copy A into X | X = A |
| BPF_TXA | copy X into A | A = X |
struct bpf_insn insns[] = {
BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_REVARP, 0, 3),
BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, REVARP_REQUEST, 0, 1),
BPF_STMT(BPF_RET+BPF_K, sizeof(struct ether_arp) + sizeof(struct ether_header)),
BPF_STMT(BPF_RET+BPF_K, 0),
};
socket is defined in the header file
include/linux/net.h and is rather short,
state, the socket_state;flags, ops, pointer to the protocol functions;inode, pointer to the associated inode;fasync_list, asynchronous wake-up list;file, sk, pointer to a struct sock;wait, wait queue head;type, socket type; passcred, proto_ops,
are the user interface API.
At the user level there is only one system call sys_socket();
the specific function is selected with an index.
Indeed the user systemcalls do not map 1-1 on the propotol functions.
bind(socket, umyaddr, addr_len), release(socket), connect(socket, uservaddr, addr_len, flags), listen(socket, len), accept(socket, new_socekt, flags), getname(socket, uaddr, addr_len, peer), sockedpair(socket_1, socket_2), setsockopt(socket, level, optname, optval, optlen), getsockopt(socket, level, optname, optval, optlen), sendmsg(socket, msghdr, len, cookie), recvmsg(socket, msghdr, len, flags, cookie), mmap(file, socket, vma), poll(file, socket, poll_table), ioctl(socket, cmd, arg), shutdown(socket, flags), sendpage(socket, page, offset, size, flags), proto structure is a function table with pointers to routines
for the IP protocol, that operate on the sock structure.
The functions are, mainly,
close(sock, timeout)connect(sock, uaddr, addr_len)disconnect(sock, flags)accept(sock, flags, error_pointer)ioctl(sock, cmd, arg)init(sock)destroy(sock)shutdown(sock, how)setsockopt(sock, level, optname, optval, optlen)getsockopt(sock, level, optname, optval, option)sendmsg(sock, msghdr, len)recvmsg(sock, msghdr, len)bind(sock, uaddr, addr_len)backlog_rcv(sock, sk_buff)get_port(sock, snum)inetsw.
At start three static protocols are added, SOCK_STREAM, SOCK_DGRAM, and SOCK_RAW.
These are permanent and cannot be modified.
Other protocols can be registered and unregistered with the functions
inet_register_protosw and inet_unregister_protosw
respectively. These take as parameter a pointer to a struct inet_protosw
which contains, among other things,
type and protocol, are the lookup key;prot points to a struct proto;ops points to a struct proto_ops;
sock is defined in the header include/net/sock.h,
and is rather large. There is a note in the source saying that it really should be
better organized.
Among other things it contains
daddr, and dport: the destination address and port;rcv_saddr, local reveiving (bound) address;num, local port;next, pprev, bind_next, bind_pprev
hash linkage pointers;state, connection state;saddr and sport, source address and port;family, address family;refcnt, reference count;sndbuf and rcvbuf,
size of sending and receiving buffer in bytes;sleep, a wait_queue_head for the sock;receive_queue, sk_buff_head of incoming packets;write_queue, sk_buff_head of outgoing packets;filter, pointer to a sk_filter;socket, pointer to the socket;sk_buff is defined in
include/linux/skbuff.h, and contains (besides other things)
next and prev, because the socket buffer
are tied together in a doubly linked list;list is the socket buffer list to which this sk_buff belongs;sk, the socket the owns this sk_buff;stamp, time of arrival;dev, network device on which this sk_buff arrived;h, a pointer to the transport layer header;nh, a pointer to the network layer header;mac, a pointer to the link layer header;cb[48], control buffer (for private data);len, length of actual data;protocol, packet protocol number from the driver;head, pointer to the head of buffer;data, pointer to the beginning of data;tail, pointer to the tail of data;end, pointer to the end of buffer;
Marco Corvi - 2003