/usr/sbin/pppd connect '/usr/sbin/chat -v -f /etc/ppp/chat-isp ' \ user marco_corvi@geocities.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@geocities.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