1 /* 2 * sock.c (C) 1995-1998 Darren Reed 3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 * 6 */ 7 #include <sys/param.h> 8 #include <sys/types.h> 9 #include <sys/time.h> 10 #include <sys/stat.h> 11 #if defined(__NetBSD__) && defined(__vax__) 12 /* 13 * XXX need to declare boolean_t for _KERNEL <sys/files.h> 14 * which ends up including <sys/device.h> for vax. See PR#32907 15 * for further details. 16 */ 17 typedef int boolean_t; 18 #endif 19 #include <fcntl.h> 20 # include <sys/dirent.h> 21 # ifdef __NetBSD__ 22 # include <machine/lock.h> 23 # endif 24 # ifdef __FreeBSD__ 25 # define _WANT_FILE 26 # else 27 # define _KERNEL 28 # define KERNEL 29 # endif 30 # include <sys/file.h> 31 # ifdef __FreeBSD__ 32 # undef _WANT_FILE 33 # else 34 # undef _KERNEL 35 # undef KERNEL 36 # endif 37 #include <nlist.h> 38 #include <sys/user.h> 39 #include <sys/socket.h> 40 #define _WANT_SOCKET 41 #include <sys/socketvar.h> 42 #include <sys/proc.h> 43 # include <kvm.h> 44 #ifdef sun 45 #include <sys/systm.h> 46 #include <sys/session.h> 47 #endif 48 #include <sys/sysctl.h> 49 #include <sys/filedesc.h> 50 #include <paths.h> 51 #include <math.h> 52 #include <netinet/in.h> 53 #include <netinet/in_systm.h> 54 #include <netinet/ip.h> 55 #include <netinet/tcp.h> 56 #include <net/if.h> 57 # include <net/route.h> 58 #include <netinet/ip_var.h> 59 #define _WANT_INPCB 60 #include <netinet/in_pcb.h> 61 #define _WANT_TCPCB 62 #include <netinet/tcp_var.h> 63 #include <stdio.h> 64 #include <unistd.h> 65 #include <string.h> 66 #include <stdlib.h> 67 #include <stddef.h> 68 #include <pwd.h> 69 #include "ipsend.h" 70 71 72 int nproc; 73 struct proc *proc; 74 75 #ifndef KMEM 76 # ifdef _PATH_KMEM 77 # define KMEM _PATH_KMEM 78 # endif 79 #endif 80 #ifndef KERNEL 81 # ifdef _PATH_UNIX 82 # define KERNEL _PATH_UNIX 83 # endif 84 #endif 85 #ifndef KMEM 86 # define KMEM "/dev/kmem" 87 #endif 88 #ifndef KERNEL 89 # define KERNEL "/vmunix" 90 #endif 91 92 93 static struct kinfo_proc *getproc(void); 94 95 96 int 97 kmemcpy(char *buf, void *pos, int n) 98 { 99 static int kfd = -1; 100 off_t offset = (u_long)pos; 101 102 if (kfd == -1) 103 kfd = open(KMEM, O_RDONLY); 104 105 if (lseek(kfd, offset, SEEK_SET) == -1) 106 { 107 perror("lseek"); 108 return (-1); 109 } 110 if (read(kfd, buf, n) == -1) 111 { 112 perror("read"); 113 return (-1); 114 } 115 return (n); 116 } 117 118 struct nlist names[4] = { 119 { "_proc" }, 120 { "_nproc" }, 121 { NULL }, 122 { NULL } 123 }; 124 125 static struct 126 kinfo_proc *getproc(void) 127 { 128 static struct kinfo_proc kp; 129 pid_t pid = getpid(); 130 int mib[4]; 131 size_t n; 132 133 mib[0] = CTL_KERN; 134 mib[1] = KERN_PROC; 135 mib[2] = KERN_PROC_PID; 136 mib[3] = pid; 137 138 n = sizeof(kp); 139 if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1) 140 { 141 perror("sysctl"); 142 return (NULL); 143 } 144 return (&kp); 145 } 146 147 148 struct tcpcb * 149 find_tcp(int tfd, struct tcpiphdr *ti) 150 { 151 struct tcpcb *t; 152 struct inpcb *i; 153 struct socket *s; 154 struct filedesc *fd; 155 struct kinfo_proc *p; 156 struct file *f, **o; 157 158 if (!(p = getproc())) 159 return (NULL); 160 161 fd = (struct filedesc *)malloc(sizeof(*fd)); 162 if (fd == NULL) 163 return (NULL); 164 #if defined( __FreeBSD__) 165 if (KMCPY(fd, p->ki_fd, sizeof(*fd)) == -1) 166 { 167 fprintf(stderr, "read(%#lx,%#lx) failed\n", 168 (u_long)p, (u_long)p->ki_fd); 169 free(fd); 170 return (NULL); 171 } 172 #else 173 if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1) 174 { 175 fprintf(stderr, "read(%#lx,%#lx) failed\n", 176 (u_long)p, (u_long)p->kp_proc.p_fd); 177 free(fd); 178 return (NULL); 179 } 180 #endif 181 182 o = NULL; 183 f = NULL; 184 s = NULL; 185 i = NULL; 186 t = NULL; 187 188 o = (struct file **)calloc(fd->fd_lastfile + 1, sizeof(*o)); 189 if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) 190 { 191 fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n", 192 (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o)); 193 goto finderror; 194 } 195 f = (struct file *)calloc(1, sizeof(*f)); 196 if (KMCPY(f, o[tfd], sizeof(*f)) == -1) 197 { 198 fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n", 199 (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f)); 200 goto finderror; 201 } 202 203 s = (struct socket *)calloc(1, sizeof(*s)); 204 if (KMCPY(s, f->f_data, sizeof(*s)) == -1) 205 { 206 fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n", 207 (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s)); 208 goto finderror; 209 } 210 211 i = (struct inpcb *)calloc(1, sizeof(*i)); 212 if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) 213 { 214 fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n", 215 (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i)); 216 goto finderror; 217 } 218 219 t = (struct tcpcb *)calloc(1, sizeof(*t)); 220 if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) 221 { 222 fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n", 223 (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t)); 224 goto finderror; 225 } 226 return (struct tcpcb *)i->inp_ppcb; 227 228 finderror: 229 if (o != NULL) 230 free(o); 231 if (f != NULL) 232 free(f); 233 if (s != NULL) 234 free(s); 235 if (i != NULL) 236 free(i); 237 if (t != NULL) 238 free(t); 239 return (NULL); 240 } 241 242 int 243 do_socket(char *dev, int mtu, struct tcpiphdr *ti, struct in_addr gwip) 244 { 245 struct sockaddr_in rsin, lsin; 246 struct tcpcb *t, tcb; 247 int fd, nfd; 248 socklen_t len; 249 250 printf("Dest. Port: %d\n", ti->ti_dport); 251 252 fd = socket(AF_INET, SOCK_STREAM, 0); 253 if (fd == -1) 254 { 255 perror("socket"); 256 return (-1); 257 } 258 259 if (fcntl(fd, F_SETFL, FNDELAY) == -1) 260 { 261 perror("fcntl"); 262 return (-1); 263 } 264 265 bzero((char *)&lsin, sizeof(lsin)); 266 lsin.sin_family = AF_INET; 267 bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 268 sizeof(struct in_addr)); 269 if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 270 { 271 perror("bind"); 272 return (-1); 273 } 274 len = sizeof(lsin); 275 (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 276 ti->ti_sport = lsin.sin_port; 277 printf("sport %d\n", ntohs(lsin.sin_port)); 278 279 nfd = initdevice(dev, 1); 280 if (nfd == -1) 281 return (-1); 282 283 if (!(t = find_tcp(fd, ti))) 284 return (-1); 285 286 bzero((char *)&rsin, sizeof(rsin)); 287 rsin.sin_family = AF_INET; 288 bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 289 sizeof(struct in_addr)); 290 rsin.sin_port = ti->ti_dport; 291 if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 292 errno != EINPROGRESS) 293 { 294 perror("connect"); 295 return (-1); 296 } 297 KMCPY(&tcb, t, sizeof(tcb)); 298 ti->ti_win = tcb.rcv_adv; 299 ti->ti_seq = tcb.snd_nxt - 1; 300 ti->ti_ack = tcb.rcv_nxt; 301 302 if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) 303 return (-1); 304 (void)write(fd, "Hello World\n", 12); 305 sleep(2); 306 close(fd); 307 return (0); 308 } 309