POSA_LEAKSMS/firmware/config/lwipopts.h
유창욱 90f121e14c chore: import codebase with security hardening
SHT30 온습도 모니터링 시스템 전체 소스(서버 PHP, STM32 펌웨어, SQL, 테스트).
전체 코드리뷰에서 도출된 보안 하드닝 10건 반영:
- 요청 서명 HMAC-SHA256 전환(펌웨어 sig.c/서버 config.php/호스트 패리티 동시)
- 재전송 방어 + 기본 API_KEY fail-closed + 디바이스 문자열 정제(api/sensor_data.php)
- 오프라인 SMS 중복 발송 경합 제거(cron_heartbeat.php, 원자적 선점)
- CSV 수식 주입 방지(monthly_report.php), 감사로그 회전 락(retention_cleanup.php)
- 브루트포스 카운터 원자화(login.php), 예시 TOTP 비밀키 무효화, 마이그레이션 멱등화

_backup/(하드코딩 실 비밀값 포함)·config.local.php·런타임 상태는 .gitignore 제외.
2026-06-20 09:37:40 +09:00

206 lines
13 KiB
C

/* =============================================================================
* lwipopts.h - LwIP 설정 (STM32F407 + LAN8720 RMII + FreeRTOS)
*
* 타깃: Cortex-M4F @168MHz, 192KB SRAM(+64KB CCM). RAM 이 빠듯하므로
* 풀/버퍼 크기를 보수적으로 잡되 HTTPS(mbedTLS over TCP) 1 커넥션 +
* DHCP/DNS/SNTP(UDP) 가 동작하도록 충분히 둔다.
*
* 동작 모드: NO_SYS=0 (RTOS). LwIP 의 tcpip 스레드가 모든 코어 처리를
* 직렬화하고, 애플리케이션은 sockets/netconn API 로 접근한다.
* ethernetif.c 의 RX 는 별도 FreeRTOS 태스크에서 tcpip_input() 으로
* pbuf 를 밀어 넣는다.
*
* 빌드: 이 헤더는 third_party/lwip(vendored) 의 헤더보다 먼저 include 경로상
* 발견되어야 한다(컴파일러 -I config 우선). 폐쇄망 빌드: 외부 fetch 없음.
* ===========================================================================*/
#ifndef LWIPOPTS_H
#define LWIPOPTS_H
#include <stdint.h> /* SNTP_SET_SYSTEM_TIME 캐스팅용 */
/* ── OS / 스레딩 ─────────────────────────────────────────────────────────── */
/* NO_SYS=0 : FreeRTOS 위에서 동작 (sys_arch.c 가 sys_* 를 제공해야 함). */
#define NO_SYS 0
#define SYS_LIGHTWEIGHT_PROT 1
#define LWIP_TCPIP_CORE_LOCKING 1
#define LWIP_TCPIP_CORE_LOCKING_INPUT 0
/* sys_now()/sys_jiffies() 는 sys_arch.c(또는 cc.h) 에서 FreeRTOS 틱 기반 제공.
* LWIP_TIMEVAL_PRIVATE=0 으로 newlib 의 struct timeval 사용. */
#define LWIP_TIMEVAL_PRIVATE 0
/* ── 메모리 모델 ─────────────────────────────────────────────────────────── */
/* 4바이트 정렬(Cortex-M4 DMA/워드 접근 안정). */
#define MEM_ALIGNMENT 4U
/* C 라이브러리 malloc 대신 LwIP 내부 힙 사용(결정적, 단편화 회피). */
#define MEM_LIBC_MALLOC 0
#define MEMP_MEM_MALLOC 0
/* 핵심 힙: pbuf PBUF_RAM, TCP 송신 큐 등에서 사용. 16KB. */
#define MEM_SIZE (16 * 1024)
/* ── 메모리 풀(memp) ─────────────────────────────────────────────────────── */
#define MEMP_NUM_PBUF 16 /* PBUF_ROM/REF 용 헤더 */
#define MEMP_NUM_UDP_PCB 6 /* DHCP + DNS + SNTP + 여유 */
#define MEMP_NUM_TCP_PCB 5 /* 동시 TCP 연결(HTTPS 1 + 여유) */
#define MEMP_NUM_TCP_PCB_LISTEN 2
#define MEMP_NUM_TCP_SEG 16
#define MEMP_NUM_REASSDATA 4
#define MEMP_NUM_FRAG_PBUF 8
#define MEMP_NUM_ARP_QUEUE 6
#define MEMP_NUM_NETBUF 4
#define MEMP_NUM_NETCONN 6
#define MEMP_NUM_TCPIP_MSG_API 8
#define MEMP_NUM_TCPIP_MSG_INPKT 12
#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 4)
/* ── PBUF 풀(수신 경로) ──────────────────────────────────────────────────── */
/* DMA 수신 디스크립터/재조립용. PBUF_POOL_SIZE * PBUF_POOL_BUFSIZE 만큼 RAM 점유. */
#define PBUF_POOL_SIZE 12
/* 이더넷 프레임(1500 MTU + 14 헤더) 한 조각에 담기도록. 4바이트 정렬은 LwIP 가 처리. */
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(1524)
/* TCP/IP/이더넷 헤더 선두 여유(송신 시 헤더 prepend 용). */
#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE)
#define PBUF_LINK_ENCAPSULATION_HLEN 0
/* RMII/HAL_ETH 는 보통 패딩 불필요(2바이트 정렬 트릭 미사용). */
#define ETH_PAD_SIZE 0
/* ── ARP ─────────────────────────────────────────────────────────────────── */
#define LWIP_ARP 1
#define ARP_TABLE_SIZE 10
#define ARP_QUEUEING 1
/* ── IP / ICMP ───────────────────────────────────────────────────────────── */
#define LWIP_IPV4 1
#define LWIP_IPV6 0
#define IP_FORWARD 0
#define IP_REASSEMBLY 1
#define IP_FRAG 1
#define LWIP_ICMP 1
#define LWIP_RAW 0
#define LWIP_BROADCAST_PING 0
/* ── DHCP ────────────────────────────────────────────────────────────────── */
#define LWIP_DHCP 1
/* DHCP 후 gratuitous ARP 로 IP 충돌 점검. */
#define LWIP_DHCP_DOES_ACD_CHECK 0
/* ── AUTOIP (사용 안 함) ─────────────────────────────────────────────────── */
#define LWIP_AUTOIP 0
/* ── DNS ─────────────────────────────────────────────────────────────────── */
#define LWIP_DNS 1
#define DNS_TABLE_SIZE 4
#define DNS_MAX_NAME_LENGTH 256
#define DNS_MAX_SERVERS 2
/* ── UDP ─────────────────────────────────────────────────────────────────── */
#define LWIP_UDP 1
#define LWIP_UDPLITE 0
/* ── TCP ─────────────────────────────────────────────────────────────────── */
#define LWIP_TCP 1
#define TCP_TTL 255
/* MSS = MTU(1500) - IP(20) - TCP(20). */
#define TCP_MSS 1460
/* 송신 버퍼: TLS 레코드(최대 ~16KB)를 한 번에 큐잉할 필요는 없고, mbedTLS 가
* 작은 청크로 write 하므로 4*MSS 면 충분. RAM 절약. */
#define TCP_SND_BUF (4 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * TCP_SND_BUF) / TCP_MSS)
/* 수신 윈도우: HTTPS 응답(JSON 짧음) 위주라 4*MSS. */
#define TCP_WND (4 * TCP_MSS)
#define TCP_QUEUE_OOSEQ 1
#define LWIP_TCP_SACK_OUT 0
#define TCP_LISTEN_BACKLOG 0
/* ── Netconn / Socket API (mbedTLS 가 BSD 소켓 사용) ─────────────────────── */
#define LWIP_NETCONN 1
#define LWIP_SOCKET 1
/* mbedTLS net_sockets.c 와의 식별자 충돌 방지: read/write/close 등은 lwip_ 접두. */
#define LWIP_COMPAT_SOCKETS 0
#define LWIP_POSIX_SOCKETS_IO_NAMES 0
#define LWIP_SOCKET_SELECT 1
#define LWIP_SO_RCVTIMEO 1 /* recv 타임아웃(HTTP_TIMEOUT) */
#define LWIP_SO_SNDTIMEO 1
#define LWIP_SO_RCVBUF 1
#define SO_REUSE 1
#define LWIP_TCP_KEEPALIVE 1
/* ── 콜백 / 상태 ─────────────────────────────────────────────────────────── */
#define LWIP_NETIF_STATUS_CALLBACK 1 /* IP 할당 감지(net_wait_up) */
#define LWIP_NETIF_LINK_CALLBACK 1 /* 케이블 링크 업/다운 감지 */
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETIF_API 1
/* ── 체크섬 (HAL_ETH 가 하드웨어 체크섬 오프로드 가능; 여기선 SW 로 안전하게) ─ */
/* 일부 STM32 ETH 는 RX 하드웨어 체크섬을 지원하나, 디스크립터 설정과 결합되므로
* 이식성/안정성 위해 LwIP 의 SW 체크섬을 사용한다. 필요 시 ethernetif.c 의
* DMA 설정과 함께 CHECKSUM_GEN/CHECK_* 를 0 으로 내려 오프로드할 수 있다.
* TODO(hw): 하드웨어 오프로드로 CPU 절감 시 아래를 0 으로 내리고 DMA 설정 동기화. */
#define CHECKSUM_GEN_IP 1
#define CHECKSUM_GEN_UDP 1
#define CHECKSUM_GEN_TCP 1
#define CHECKSUM_GEN_ICMP 1
#define CHECKSUM_CHECK_IP 1
#define CHECKSUM_CHECK_UDP 1
#define CHECKSUM_CHECK_TCP 1
#define CHECKSUM_CHECK_ICMP 1
/* ── 스레드 우선순위/스택 (FreeRTOS) ─────────────────────────────────────── */
/* LwIP 우선순위는 FreeRTOS 절대 우선순위. 애플리케이션 태스크보다 약간 높게 둬서
* 네트워크 처리가 굶지 않도록 한다. configMAX_PRIORITIES 가 7 이라고 가정.
* TODO(hw): FreeRTOSConfig.h 의 configMAX_PRIORITIES 와 정합 확인. */
#define TCPIP_THREAD_NAME "tcpip"
#define TCPIP_THREAD_STACKSIZE 1024 /* 워드 단위(StackType_t) */
#define TCPIP_THREAD_PRIO (5)
#define TCPIP_MBOX_SIZE 12
#define DEFAULT_THREAD_NAME "lwip_def"
#define DEFAULT_THREAD_STACKSIZE 512
#define DEFAULT_THREAD_PRIO (3)
#define DEFAULT_UDP_RECVMBOX_SIZE 8
#define DEFAULT_TCP_RECVMBOX_SIZE 12
#define DEFAULT_RAW_RECVMBOX_SIZE 8
#define DEFAULT_ACCEPTMBOX_SIZE 8
/* ethernetif RX 태스크가 사용할 우선순위/스택(ethernetif.c 에서 참조). */
#define ETHIF_RX_THREAD_NAME "eth_rx"
#define ETHIF_RX_THREAD_STACKSIZE 512
#define ETHIF_RX_THREAD_PRIO (6) /* tcpip 보다 약간 높게 */
/* ── SNTP 애플리케이션 (apps/sntp) ───────────────────────────────────────── */
/* timesync.c 가 sntp_init() 호출. 시스템 시간 콜백으로 RTC 반영. */
extern void timesync_apply_epoch(uint32_t unix_seconds);
#define SNTP_SERVER_DNS 1 /* pool.ntp.org 등 호스트명 사용 */
#define SNTP_SUPPORT 1
#define SNTP_CHECK_RESPONSE 1 /* 응답 무결성(원본 타임스탬프) 검증 */
#define SNTP_COMP_ROUNDTRIP 0
#define SNTP_STARTUP_DELAY 0 /* 부팅 후 즉시 첫 요청 */
#define SNTP_RECV_TIMEOUT 6000
/* 폴 주기: 동기 후엔 자주 갱신 불필요. 1시간(서버 보고 주기와 동일 수준). */
#define SNTP_UPDATE_DELAY (60u * 60u * 1000u)
/* 시스템 시간 설정 훅: LwIP 가 획득한 초 단위 Unix 시간을 RTC 로 반영. */
#define SNTP_SET_SYSTEM_TIME(sec) do { timesync_apply_epoch((uint32_t)(sec)); } while (0)
/* 마이크로초 정밀도는 불필요(_US 버전 미정의). */
/* ── 통계 / 디버그 ───────────────────────────────────────────────────────── */
#define LWIP_STATS 0
#define LWIP_STATS_DISPLAY 0
/* 운영 빌드에서는 디버그 끔. 필요 시 개별 *_DEBUG 를 LWIP_DBG_ON 으로. */
#define LWIP_DEBUG 0
#define LWIP_NOASSERT 0 /* assert 유지(개발 단계 안전) */
/* ── 기타 ────────────────────────────────────────────────────────────────── */
#define LWIP_PROVIDE_ERRNO 1 /* newlib errno 와 분리(독립 errno 제공) */
#define LWIP_NETIF_TX_SINGLE_PBUF 1 /* 송신 시 단일 pbuf 선호(HAL_ETH 단순화) */
#define LWIP_RAND() ((u32_t)bsp_rand32())
/* LWIP_RAND 용: 하드웨어 RNG 기반 32비트 난수(bsp/별도 모듈 제공).
* TODO(hw): bsp.c 또는 rng.c 에서 bsp_rand32() 를 RNG 페리페럴로 구현.
* (현재 net.c 에 약한 대체 구현이 있을 수 있음) */
uint32_t bsp_rand32(void);
#endif /* LWIPOPTS_H */