1 /* $NetBSD: sock.c,v 1.5 2018/02/04 08:19:42 mrg Exp $ */ 2 3 /* 4 * sock.c (C) 1995-1998 Darren Reed 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 7 * 8 */ 9 #if !defined(lint) 10 static __attribute__((__used__)) const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed"; 11 static __attribute__((__used__)) const char rcsid[] = "@(#)Id: sock.c,v 1.1.1.2 2012/07/22 13:44:38 darrenr"; 12 #endif 13 #include <sys/param.h> 14 #include <sys/types.h> 15 #include <sys/time.h> 16 #include <sys/stat.h> 17 #include <stdbool.h> 18 #if defined(__NetBSD__) && defined(__vax__) 19 /* 20 * XXX need to declare boolean_t for _KERNEL <sys/files.h> 21 * which ends up including <sys/device.h> for vax. See PR#32907 22 * for further details. 23 */ 24 typedef int boolean_t; 25 #endif 26 #ifndef ultrix 27 #include <fcntl.h> 28 #endif 29 #if (__FreeBSD_version >= 300000) 30 # include <sys/dirent.h> 31 #else 32 # include <sys/dir.h> 33 #endif 34 #if !defined(__osf__) 35 # ifdef __NetBSD__ 36 # include <machine/lock.h> 37 # include <sys/mutex.h> 38 # endif 39 # define _KERNEL 40 # define KERNEL 41 # ifdef ultrix 42 # undef LOCORE 43 # include <sys/smp_lock.h> 44 # endif 45 # include <sys/file.h> 46 # undef _KERNEL 47 # undef KERNEL 48 #endif 49 #include <nlist.h> 50 #if defined(__FreeBSD__) 51 #include <sys/user.h> 52 #endif 53 #include <sys/socket.h> 54 #include <sys/socketvar.h> 55 #include <sys/proc.h> 56 #if !defined(ultrix) && !defined(hpux) && !defined(__osf__) 57 # include <kvm.h> 58 #endif 59 #ifdef sun 60 #include <sys/systm.h> 61 #include <sys/session.h> 62 #endif 63 #if BSD >= 199103 64 #include <sys/sysctl.h> 65 #include <sys/filedesc.h> 66 #include <paths.h> 67 #endif 68 #include <math.h> 69 #include <netinet/in.h> 70 #include <netinet/in_systm.h> 71 #include <netinet/ip.h> 72 #include <netinet/tcp.h> 73 #include <net/if.h> 74 #ifndef __osf__ 75 # include <net/route.h> 76 #endif 77 #include <netinet/ip_var.h> 78 #include <netinet/in_pcb.h> 79 #include <netinet/tcp_timer.h> 80 #include <netinet/tcp_var.h> 81 #include <stdio.h> 82 #include <unistd.h> 83 #include <string.h> 84 #include <stdlib.h> 85 #include <stddef.h> 86 #include <pwd.h> 87 #include "ipsend.h" 88 89 90 int nproc; 91 struct proc *proc; 92 93 #ifndef KMEM 94 # ifdef _PATH_KMEM 95 # define KMEM _PATH_KMEM 96 # endif 97 #endif 98 #ifndef KERNEL 99 # ifdef _PATH_UNIX 100 # define KERNEL _PATH_UNIX 101 # endif 102 #endif 103 #ifndef KMEM 104 # define KMEM "/dev/kmem" 105 #endif 106 #ifndef KERNEL 107 # define KERNEL "/vmunix" 108 #endif 109 110 111 #if BSD < 199103 112 static struct proc *getproc __P((void)); 113 #else 114 static struct kinfo_proc *getproc __P((void)); 115 #endif 116 117 118 int kmemcpy(buf, pos, n) 119 char *buf; 120 void *pos; 121 int n; 122 { 123 static int kfd = -1; 124 off_t offset = (u_long)pos; 125 126 if (kfd == -1) 127 kfd = open(KMEM, O_RDONLY); 128 129 if (lseek(kfd, offset, SEEK_SET) == -1) 130 { 131 perror("lseek"); 132 return -1; 133 } 134 if (read(kfd, buf, n) == -1) 135 { 136 perror("read"); 137 return -1; 138 } 139 return n; 140 } 141 142 struct nlist names[4] = { 143 { "_proc" }, 144 { "_nproc" }, 145 #ifdef ultrix 146 { "_u" }, 147 #else 148 { NULL }, 149 #endif 150 { NULL } 151 }; 152 153 #if BSD < 199103 154 static struct proc *getproc() 155 { 156 struct proc *p; 157 pid_t pid = getpid(); 158 int siz, n; 159 160 n = nlist(KERNEL, names); 161 if (n != 0) 162 { 163 fprintf(stderr, "nlist(%#x) == %d\n", names, n); 164 return NULL; 165 } 166 if (KMCPY(&nproc, names[1].n_value, sizeof(nproc)) == -1) 167 { 168 fprintf(stderr, "read nproc (%#x)\n", names[1].n_value); 169 return NULL; 170 } 171 siz = nproc * sizeof(struct proc); 172 if (KMCPY(&p, names[0].n_value, sizeof(p)) == -1) 173 { 174 fprintf(stderr, "read(%#x,%#x,%d) proc\n", 175 names[0].n_value, &p, sizeof(p)); 176 return NULL; 177 } 178 proc = (struct proc *)malloc(siz); 179 if (KMCPY(proc, p, siz) == -1) 180 { 181 fprintf(stderr, "read(%#x,%#x,%d) proc\n", 182 p, proc, siz); 183 return NULL; 184 } 185 186 p = proc; 187 188 for (n = nproc; n; n--, p++) 189 if (p->p_pid == pid) 190 break; 191 if (!n) 192 return NULL; 193 194 return p; 195 } 196 197 198 struct tcpcb *find_tcp(fd, ti) 199 int fd; 200 struct tcpiphdr *ti; 201 { 202 struct tcpcb *t; 203 struct inpcb *i; 204 struct socket *s; 205 struct user *up; 206 struct proc *p; 207 struct file *f, **o; 208 209 if (!(p = getproc())) 210 return NULL; 211 up = (struct user *)malloc(sizeof(*up)); 212 #ifndef ultrix 213 if (KMCPY(up, p->p_uarea, sizeof(*up)) == -1) 214 { 215 fprintf(stderr, "read(%#x,%#x) failed\n", p, p->p_uarea); 216 return NULL; 217 } 218 #else 219 if (KMCPY(up, names[2].n_value, sizeof(*up)) == -1) 220 { 221 fprintf(stderr, "read(%#x,%#x) failed\n", p, names[2].n_value); 222 return NULL; 223 } 224 #endif 225 226 o = (struct file **)calloc(1, sizeof(*o) * (up->u_lastfile + 1)); 227 if (KMCPY(o, up->u_ofile, (up->u_lastfile + 1) * sizeof(*o)) == -1) 228 { 229 fprintf(stderr, "read(%#x,%#x,%d) - u_ofile - failed\n", 230 up->u_ofile, o, sizeof(*o)); 231 return NULL; 232 } 233 f = (struct file *)calloc(1, sizeof(*f)); 234 if (KMCPY(f, o[fd], sizeof(*f)) == -1) 235 { 236 fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n", 237 up->u_ofile[fd], f, sizeof(*f)); 238 return NULL; 239 } 240 241 s = (struct socket *)calloc(1, sizeof(*s)); 242 if (KMCPY(s, f->f_data, sizeof(*s)) == -1) 243 { 244 fprintf(stderr, "read(%#x,%#x,%d) - f_data - failed\n", 245 o[fd], s, sizeof(*s)); 246 return NULL; 247 } 248 249 i = (struct inpcb *)calloc(1, sizeof(*i)); 250 if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) 251 { 252 fprintf(stderr, "kvm_read(%#x,%#x,%d) - so_pcb - failed\n", 253 s->so_pcb, i, sizeof(*i)); 254 return NULL; 255 } 256 257 t = (struct tcpcb *)calloc(1, sizeof(*t)); 258 if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) 259 { 260 fprintf(stderr, "read(%#x,%#x,%d) - inp_ppcb - failed\n", 261 i->inp_ppcb, t, sizeof(*t)); 262 return NULL; 263 } 264 return (struct tcpcb *)i->inp_ppcb; 265 } 266 #else 267 static struct kinfo_proc *getproc() 268 { 269 static struct kinfo_proc kp; 270 pid_t pid = getpid(); 271 int mib[4]; 272 size_t n; 273 274 mib[0] = CTL_KERN; 275 mib[1] = KERN_PROC; 276 mib[2] = KERN_PROC_PID; 277 mib[3] = pid; 278 279 n = sizeof(kp); 280 if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1) 281 { 282 perror("sysctl"); 283 return NULL; 284 } 285 return &kp; 286 } 287 288 289 struct tcpcb *find_tcp(tfd, ti) 290 int tfd; 291 struct tcpiphdr *ti; 292 { 293 struct tcpcb *t; 294 struct inpcb *i; 295 struct socket *s; 296 struct filedesc *fd; 297 struct kinfo_proc *p; 298 struct file *f, **o; 299 300 if (!(p = getproc())) 301 return NULL; 302 303 fd = (struct filedesc *)malloc(sizeof(*fd)); 304 if (fd == NULL) 305 return NULL; 306 #if defined( __FreeBSD_version) && __FreeBSD_version >= 500013 307 if (KMCPY(fd, p->ki_fd, sizeof(*fd)) == -1) 308 { 309 fprintf(stderr, "read(%#lx,%#lx) failed\n", 310 (u_long)p, (u_long)p->ki_fd); 311 free(fd); 312 return NULL; 313 } 314 #else 315 if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1) 316 { 317 fprintf(stderr, "read(%#lx,%#lx) failed\n", 318 (u_long)p, (u_long)p->kp_proc.p_fd); 319 free(fd); 320 return NULL; 321 } 322 #endif 323 324 o = NULL; 325 f = NULL; 326 s = NULL; 327 i = NULL; 328 t = NULL; 329 330 o = (struct file **)calloc(1, sizeof(*o) * (fd->fd_lastfile + 1)); 331 #if defined(__NetBSD_Version__) && __NetBSD_Version__ < 599001200 332 if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) 333 { 334 fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n", 335 (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o)); 336 goto finderror; 337 } 338 #else 339 if (KMCPY(o, &fd->fd_dt->dt_ff, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) 340 { 341 fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n", 342 (u_long)fd->fd_dt->dt_ff, (u_long)o, (u_long)sizeof(*o)); 343 goto finderror; 344 } 345 #endif 346 f = (struct file *)calloc(1, sizeof(*f)); 347 if (KMCPY(f, o[tfd], sizeof(*f)) == -1) 348 { 349 fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n", 350 (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f)); 351 goto finderror; 352 } 353 354 s = (struct socket *)calloc(1, sizeof(*s)); 355 if (KMCPY(s, f->f_data, sizeof(*s)) == -1) 356 { 357 fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n", 358 (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s)); 359 goto finderror; 360 } 361 362 i = (struct inpcb *)calloc(1, sizeof(*i)); 363 if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) 364 { 365 fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n", 366 (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i)); 367 goto finderror; 368 } 369 370 t = (struct tcpcb *)calloc(1, sizeof(*t)); 371 if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) 372 { 373 fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n", 374 (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t)); 375 goto finderror; 376 } 377 return (struct tcpcb *)i->inp_ppcb; 378 379 finderror: 380 if (o != NULL) 381 free(o); 382 if (f != NULL) 383 free(f); 384 if (s != NULL) 385 free(s); 386 if (i != NULL) 387 free(i); 388 if (t != NULL) 389 free(t); 390 return NULL; 391 } 392 #endif /* BSD < 199301 */ 393 394 int do_socket(dev, mtu, ti, gwip) 395 char *dev; 396 int mtu; 397 struct tcpiphdr *ti; 398 struct in_addr gwip; 399 { 400 struct sockaddr_in rsin, lsin; 401 struct tcpcb *t, tcb; 402 int fd, nfd; 403 socklen_t len; 404 405 printf("Dest. Port: %d\n", ti->ti_dport); 406 407 fd = socket(AF_INET, SOCK_STREAM, 0); 408 if (fd == -1) 409 { 410 perror("socket"); 411 return -1; 412 } 413 414 if (fcntl(fd, F_SETFL, FNDELAY) == -1) 415 { 416 perror("fcntl"); 417 return -1; 418 } 419 420 bzero((char *)&lsin, sizeof(lsin)); 421 lsin.sin_family = AF_INET; 422 bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 423 sizeof(struct in_addr)); 424 if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 425 { 426 perror("bind"); 427 return -1; 428 } 429 len = sizeof(lsin); 430 (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 431 ti->ti_sport = lsin.sin_port; 432 printf("sport %d\n", ntohs(lsin.sin_port)); 433 434 nfd = initdevice(dev, 1); 435 if (nfd == -1) 436 return -1; 437 438 if (!(t = find_tcp(fd, ti))) 439 return -1; 440 441 bzero((char *)&rsin, sizeof(rsin)); 442 rsin.sin_family = AF_INET; 443 bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 444 sizeof(struct in_addr)); 445 rsin.sin_port = ti->ti_dport; 446 if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 447 errno != EINPROGRESS) 448 { 449 perror("connect"); 450 return -1; 451 } 452 KMCPY(&tcb, t, sizeof(tcb)); 453 ti->ti_win = tcb.rcv_adv; 454 ti->ti_seq = tcb.snd_nxt - 1; 455 ti->ti_ack = tcb.rcv_nxt; 456 457 if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) 458 return -1; 459 (void)write(fd, "Hello World\n", 12); 460 sleep(2); 461 close(fd); 462 return 0; 463 } 464